File indexing completed on 2024-05-12 04:44:33

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 #ifndef InterlacingPass_H
0005 #define InterlacingPass_H
0006 
0007 #include "helpermath.h"
0008 #include <qsize.h>
0009 
0010 namespace PerceptualColor
0011 {
0012 /** @internal
0013  *
0014  * @brief Describes an interlacing pass.
0015  *
0016  * Objects of this class provide information about interlacing passes
0017  * for <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>-like
0018  * interlacing.
0019  *
0020  * To do <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>
0021  * interlacing, construct an object of this class with a <tt>passCount</tt>
0022  * of <tt>7</tt>. Do the first pass using the values provided
0023  * by this object. Then, call @ref switchToNextPass to update the
0024  * values and do the next interlacing pass.
0025  *
0026  * The pixels in your image are divided in lines, who in turn are subdivided
0027  * in columns. Within each interlacing pass, go through every
0028  * @ref lineFrequency th line, starting with the line at @ref lineOffset.
0029  * Within each line, go through every @ref columnFrequency th column, starting
0030  * with @ref columnOffset. Draw a rectangle with the size @ref rectangleSize
0031  * who’s top-left pixel is at the current column and line.
0032  *
0033  * @note As this is just an internal class which is not part of the public API,
0034  * there is direct access to its data members for simplicity reasons. However,
0035  * it is not allowed to change them directly! Use them read-only. */
0036 class InterlacingPass final
0037 {
0038 public:
0039     /** @brief Constructor
0040      *
0041      * Constructs an object for a new interlacing cycle.
0042      *
0043      * @tparam passCount Number of passes within this interlacing
0044      * cycle. This MUST be a positive odd number. Use <tt>7</tt>
0045      * for <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>
0046      * interlacing, or any other positive odd number for
0047      * <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>-like
0048      * interlacing, but with a different number of steps.
0049      *
0050      * @returns A corresponding object. */
0051     template<int passCount>
0052     static InterlacingPass make()
0053     {
0054         static_assert(passCount > 0, "passCount must be positive.");
0055         static_assert(isOdd(passCount), "passCount must be odd.");
0056         return InterlacingPass(passCount);
0057     }
0058 
0059     void switchToNextPass();
0060 
0061     /** @brief Size of the rectangles drawn during this pass. */
0062     QSize rectangleSize;
0063     /** @brief Draw a rectangle every umpteenth column. */
0064     int columnFrequency;
0065     /** @brief First column on a given line to draw a rectangle. */
0066     int columnOffset;
0067     /** @brief Draw a rectangle every umpteenth line. */
0068     int lineFrequency;
0069     /** @brief First line to process. */
0070     int lineOffset;
0071     /** @brief Pass countdown.
0072      *
0073      * Inverse counting of the interlacing passes.
0074      *
0075      * Example for
0076      * <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>:
0077      *
0078      * |    Pass     | @ref countdown |
0079      * | :---------- | :------------: |
0080      * | 1st         |       7        |
0081      * | 2nd         |       6        |
0082      * | 3rd         |       5        |
0083      * | 4th         |       4        |
0084      * | 5th         |       3        |
0085      * | 6th         |       2        |
0086      * | 7th (last)  |       1        | */
0087     int countdown;
0088 
0089 private:
0090     explicit InterlacingPass(const int passCount);
0091 
0092     /** @internal @brief Only for unit tests. */
0093     friend class TestInterlacingPass;
0094 };
0095 
0096 } // namespace PerceptualColor
0097 
0098 #endif // InterlacingPass_H