24template<std::
unsigned_
integral Pixel>
30template<std::
unsigned_
integral Pixel>
33 std::span<const Pixel> src0, std::span<const Pixel> src1, std::span<const Pixel> src2)
35 auto srcWidth = src0.size();
36 assert(src0.size() == srcWidth);
37 assert(src1.size() == srcWidth);
38 assert(src2.size() == srcWidth);
39 assert(dst.size() == 3 * srcWidth);
53 Pixel right = src1[1];
57 dst[1] = (mid != right) && (top != bot) &&
58 (((top == mid) && (mid != src0[1])) ||
59 ((top == right) && (mid != top)))
61 dst[2] = (mid != right) && (top != bot) && (top == right)
65 for (
auto x :
xrange(1u, srcWidth - 1)) {
71 dst[3 * x + 0] = (left != right) && (top != bot) &&
74 dst[3 * x + 1] = (left != right) && (top != bot) &&
75 (((top == left ) && (mid != src0[x + 1])) ||
76 ((top == right) && (mid != src0[x - 1])))
78 dst[3 * x + 2] = (left != right) && (top != bot) &&
86 top = src0[srcWidth - 1];
87 bot = src2[srcWidth - 1];
88 dst[3 * srcWidth - 3] = (left != mid) && (top != bot) && (top ==left)
90 dst[3 * srcWidth - 2] = (left != mid) && (top != bot) &&
91 (((top == left) && (mid != top)) ||
92 ((top == mid ) && (mid != src0[srcWidth - 2])))
94 dst[3 * srcWidth - 1] = mid;
97template<std::
unsigned_
integral Pixel>
98void Scale3xScaler<Pixel>::scaleLine1on3Mid(
100 std::span<const Pixel> src0, std::span<const Pixel> src1, std::span<const Pixel> src2)
102 auto srcWidth = src0.size();
103 assert(src0.size() == srcWidth);
104 assert(src1.size() == srcWidth);
105 assert(src2.size() == srcWidth);
106 assert(dst.size() == 3 * srcWidth);
121 Pixel right = src1[1];
126 dst[2] = (mid != right) && (top != bot) &&
127 (((right == top) && (mid != src2[1])) ||
128 ((right == bot) && (mid != src0[1])))
132 for (
auto x :
xrange(1u, srcWidth - 1)) {
138 dst[3 * x + 0] = (left != right) && (top != bot) &&
139 (((left == top) && (mid != src2[x - 1])) ||
140 ((left == bot) && (mid != src0[x - 1])))
142 dst[3 * x + 1] = mid;
143 dst[3 * x + 2] = (left != right) && (top != bot) &&
144 (((right == top) && (mid != src2[x + 1])) ||
145 ((right == bot) && (mid != src0[x + 1])))
152 top = src0[srcWidth - 1];
153 bot = src2[srcWidth - 1];
154 dst[3 * srcWidth - 3] = (left != mid) && (top != bot) &&
155 (((left == top) && (mid != src2[srcWidth - 2])) ||
156 ((left == bot) && (mid != src0[srcWidth - 2])))
158 dst[3 * srcWidth - 2] = mid;
159 dst[3 * srcWidth - 1] = mid;
162template<std::
unsigned_
integral Pixel>
164 unsigned srcStartY,
unsigned ,
unsigned srcWidth,
171 auto srcY = narrow<int>(srcStartY);
172 auto srcPrev = src.
getLine(srcY - 1, buf0);
173 auto srcCurr = src.
getLine(srcY + 0, buf1);
175 for (
unsigned dstY = dstStartY; dstY < dstEndY; srcY += 1, dstY += 3) {
176 auto srcNext = src.
getLine(srcY + 1, buf2);
179 scaleLine1on3Half(dstUpper, srcPrev, srcCurr, srcNext);
183 scaleLine1on3Mid(dstMiddle, srcPrev, srcCurr, srcNext);
187 scaleLine1on3Half(dstLower, srcNext, srcCurr, srcPrev);
Interface for getting lines from a video frame.
std::span< const Pixel > getLine(int line, std::span< Pixel > buf) const
Gets a pointer to the pixels of the given line number.
Runs the Scale3x scaler algorithm.
void scale1x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Scale3xScaler(const PixelOperations< Pixel > &pixelOps)
Base class for 3x scalers.
virtual void releaseLine(unsigned y, std::span< Pixel > buf)=0
virtual std::span< Pixel > acquireLine(unsigned y)=0
This file implemented 3 utility functions:
void swap(openmsx::MemBuffer< T > &l, openmsx::MemBuffer< T > &r) noexcept
#define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH)
constexpr auto xrange(T e)