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 // Own header 0005 #include "interlacingpass.h" 0006 0007 #include "helpermath.h" 0008 #include <qglobal.h> 0009 #include <qmath.h> 0010 #include <type_traits> 0011 0012 namespace PerceptualColor 0013 { 0014 /** @brief Constructor 0015 * 0016 * Constructs an object for a new interlacing cycle. 0017 * 0018 * @param passCount Number of passes within this interlacing cycle. This MUST 0019 * be a positive odd number (otherwise an exception is thrown). Use <tt>7</tt> 0020 * for <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a> 0021 * interlacing, or any other positive odd number for 0022 * <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>-like 0023 * interlacing, but with a different number of steps. 0024 * 0025 * @exception int Thrown when the parameter is not a positive odd number. */ 0026 InterlacingPass::InterlacingPass(const int passCount) 0027 { 0028 if (!isOdd(passCount)) { 0029 throw 0; 0030 } 0031 if (passCount < 1) { 0032 throw 0; 0033 } 0034 0035 const int floorOfHalfCoundown = qFloor(passCount / 2.0); 0036 const int baseSize = qRound(qPow(2, floorOfHalfCoundown)); 0037 0038 countdown = passCount; 0039 rectangleSize.setWidth(baseSize); 0040 rectangleSize.setHeight(baseSize); 0041 columnFrequency = baseSize; 0042 columnOffset = 0; 0043 lineFrequency = baseSize; 0044 lineOffset = 0; 0045 } 0046 0047 /** @brief Switches to the next pass, reducing @ref countdown by 1 and 0048 * changing all other values accordingly. 0049 * 0050 * If @ref countdown ≤ 0 than nothing happens. */ 0051 void InterlacingPass::switchToNextPass() 0052 { 0053 if (countdown <= 1) { 0054 return; 0055 } 0056 0057 countdown--; 0058 0059 const int floorOfHalfCoundown = qFloor(countdown / 2.0); 0060 const int baseSize = qRound(qPow(2, floorOfHalfCoundown)); 0061 0062 if (isOdd(countdown)) { 0063 rectangleSize.setWidth(baseSize); 0064 rectangleSize.setHeight(baseSize); 0065 columnFrequency = baseSize; 0066 columnOffset = 0; 0067 lineFrequency = baseSize * 2; 0068 lineOffset = baseSize; 0069 } else { 0070 const int halfBaseSize = baseSize / 2; // Dividing without rounding 0071 // problems because baseSize is always an even number (it’s always 0072 // a power of two and bigger than 2 while countdown is ≥ 1). 0073 rectangleSize.setWidth(halfBaseSize); 0074 rectangleSize.setHeight(baseSize); 0075 columnFrequency = baseSize; 0076 columnOffset = halfBaseSize; 0077 lineFrequency = baseSize; 0078 lineOffset = 0; 0079 } 0080 } 0081 0082 static_assert(std::is_trivially_copyable_v<InterlacingPass>); 0083 0084 static_assert(std::is_standard_layout_v<InterlacingPass>); 0085 0086 } // namespace PerceptualColor