Perceptual Color

interlacingpass.cpp
1// SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR MIT
3
4// Own header
5#include "interlacingpass.h"
6
7#include "helpermath.h"
8#include <qglobal.h>
9#include <qmath.h>
10#include <type_traits>
11
12namespace PerceptualColor
13{
14/**
15 * @brief Rounds to the nearest positive odd integer.
16 *
17 * @param value The value to be rounded.
18 *
19 * @returns Rounds to the nearest positive odd integer.
20 */
21int InterlacingPass::roundToNearestPositiveOdd(const double value)
22{
23 // Round to next odd integer.
24 int rounded = qRound((value - 1.0) / 2.0) * 2 + 1;
25 return qMax(1, rounded); // Smallest existing odd integer is: 1
26}
27
28/** @brief Constructor
29 *
30 * Constructs an object for a new interlacing cycle.
31 *
32 * @param passCount Number of passes within this interlacing cycle.
33 * This should be a positive odd number. If it isn’t, it will be
34 * rounded to the next valid number. Use <tt>7</tt>
35 * for <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>
36 * interlacing, or any other positive odd number for
37 * <a href="https://en.wikipedia.org/wiki/Adam7_algorithm">Adam7</a>-like
38 * interlacing, but with a different number of steps.
39 *
40 * @sa @ref make() provides compile-time checking for valid <tt>passCount</tt>
41 * numbers.
42 */
43InterlacingPass::InterlacingPass(const double passCount)
44{
45 const int roundedPassCount = roundToNearestPositiveOdd(passCount);
46
47 const int floorOfHalfCoundown = qFloor(roundedPassCount / 2.0);
48 const int baseSize = qRound(qPow(2, floorOfHalfCoundown));
49
50 countdown = roundedPassCount;
51 rectangleSize.setWidth(baseSize);
52 rectangleSize.setHeight(baseSize);
53 columnFrequency = baseSize;
54 columnOffset = 0;
55 lineFrequency = baseSize;
56 lineOffset = 0;
57}
58
59/** @brief Switches to the next pass, reducing @ref countdown by 1 and
60 * changing all other values accordingly.
61 *
62 * If @ref countdown ≤ 0 than nothing happens. */
63void InterlacingPass::switchToNextPass()
64{
65 if (countdown <= 1) {
66 return;
67 }
68
69 countdown--;
70
71 const int floorOfHalfCoundown = qFloor(countdown / 2.0);
72 const int baseSize = qRound(qPow(2, floorOfHalfCoundown));
73
74 if (isOdd(countdown)) {
75 rectangleSize.setWidth(baseSize);
76 rectangleSize.setHeight(baseSize);
77 columnFrequency = baseSize;
78 columnOffset = 0;
79 lineFrequency = baseSize * 2;
80 lineOffset = baseSize;
81 } else {
82 const int halfBaseSize = baseSize / 2; // Dividing without rounding
83 // problems because baseSize is always an even number (it’s always
84 // a power of two and bigger than 2 while countdown is ≥ 1).
85 rectangleSize.setWidth(halfBaseSize);
86 rectangleSize.setHeight(baseSize);
87 columnFrequency = baseSize;
88 columnOffset = halfBaseSize;
89 lineFrequency = baseSize;
90 lineOffset = 0;
91 }
92}
93
94static_assert(std::is_trivially_copyable_v<InterlacingPass>);
95
96static_assert(std::is_standard_layout_v<InterlacingPass>);
97
98} // namespace PerceptualColor
The namespace of this library.
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 12:03:13 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.