openMSX
HQ3xScaler.cc
Go to the documentation of this file.
1/*
2Original code: Copyright (C) 2003 MaxSt ( maxst@hiend3d.com )
3openMSX adaptation by Wouter Vermaelen
4
5License: LGPL
6
7Visit the HiEnd3D site for info:
8 http://www.hiend3d.com/hq2x.html
9*/
10
11#include "HQ3xScaler.hh"
12#include "HQCommon.hh"
13#include "LineScalers.hh"
14#include "unreachable.hh"
15#include "xrange.hh"
16#include "build-info.hh"
17#include <cstdint>
18
19namespace openmsx {
20
21template<std::unsigned_integral Pixel> struct HQ_1x1on3x3
22{
23 void operator()(std::span<const Pixel> in0, std::span<const Pixel> in1, std::span<const Pixel> in2,
24 std::span<Pixel> out0, std::span<Pixel> out1, std::span<Pixel> out2,
25 std::span<uint16_t> edgeBuf, EdgeHQ edgeOp);
26};
27
28template<std::unsigned_integral Pixel>
30 std::span<const Pixel> in0, std::span<const Pixel> in1, std::span<const Pixel> in2,
31 std::span<Pixel> out0, std::span<Pixel> out1, std::span<Pixel> out2,
32 std::span<uint16_t> edgeBuf,
33 EdgeHQ edgeOp)
34{
35 auto srcWidth = edgeBuf.size();
36 assert(in0.size() == srcWidth);
37 assert(in1.size() == srcWidth);
38 assert(in2.size() == srcWidth);
39 assert(out0.size() == 3 * srcWidth);
40 assert(out1.size() == 3 * srcWidth);
41 assert(out2.size() == 3 * srcWidth);
42
43 unsigned c2 = readPixel(in0[0]); unsigned c3 = c2;
44 unsigned c5 = readPixel(in1[0]); unsigned c6 = c5;
45 unsigned c8 = readPixel(in2[0]); unsigned c9 = c8;
46
47 unsigned pattern = 0;
48 if (edgeOp(c5, c8)) pattern |= 3 << 6;
49 if (edgeOp(c5, c2)) pattern |= 3 << 9;
50
51 for (auto x : xrange(srcWidth)) {
52 unsigned c1 = c2;
53 unsigned c4 = c5;
54 unsigned c7 = c8;
55 c2 = c3;
56 c5 = c6;
57 c8 = c9;
58 if (x != srcWidth - 1) {
59 c3 = readPixel(in0[x + 1]);
60 c6 = readPixel(in1[x + 1]);
61 c9 = readPixel(in2[x + 1]);
62 }
63
64 pattern = (pattern >> 6) & 0x001F; // left overlap
65 // overlaps with left
66 //if (edgeOp(c8, c4)) pattern |= 1 << 0; // B - l: c5-c9 6
67 //if (edgeOp(c5, c7)) pattern |= 1 << 1; // B - l: c6-c8 7
68 //if (edgeOp(c5, c4)) pattern |= 1 << 2; // l: c5-c6 8
69 // overlaps with top and left
70 //if (edgeOp(c5, c1)) pattern |= 1 << 3; // l: c2-c6 9, t: c4-c8 0
71 //if (edgeOp(c4, c2)) pattern |= 1 << 4; // l: c5-c3 10, t: c5-c7 1
72 // non-overlapping pixels
73 if (edgeOp(c5, c8)) pattern |= 1 << 5; // B
74 if (edgeOp(c5, c9)) pattern |= 1 << 6; // BR
75 if (edgeOp(c6, c8)) pattern |= 1 << 7; // BR
76 if (edgeOp(c5, c6)) pattern |= 1 << 8; // R
77 // overlaps with top
78 //if (edgeOp(c2, c6)) pattern |= 1 << 9; // R - t: c5-c9 6
79 //if (edgeOp(c5, c3)) pattern |= 1 << 10; // R - t: c6-c8 7
80 //if (edgeOp(c5, c2)) pattern |= 1 << 11; // t: c5-c8 5
81 pattern |= ((edgeBuf[x] & (1 << 5) ) << 6) |
82 ((edgeBuf[x] & ((1 << 6) | (1 << 7))) << 3);
83 edgeBuf[x] = pattern;
84
85 unsigned pixel0, pixel1, pixel2, pixel3, pixel4,
86 pixel5, pixel6, pixel7, pixel8;
87
88#include "HQ3xScaler-1x1to3x3.nn"
89
90 out0[3 * x + 0] = writePixel<Pixel>(pixel0);
91 out0[3 * x + 1] = writePixel<Pixel>(pixel1);
92 out0[3 * x + 2] = writePixel<Pixel>(pixel2);
93 out1[3 * x + 0] = writePixel<Pixel>(pixel3);
94 out1[3 * x + 1] = writePixel<Pixel>(pixel4);
95 out1[3 * x + 2] = writePixel<Pixel>(pixel5);
96 out2[3 * x + 0] = writePixel<Pixel>(pixel6);
97 out2[3 * x + 1] = writePixel<Pixel>(pixel7);
98 out2[3 * x + 2] = writePixel<Pixel>(pixel8);
99 }
100}
101
102
103
104template<std::unsigned_integral Pixel>
106 : Scaler3<Pixel>(pixelOps_)
107 , pixelOps(pixelOps_)
108{
109}
110
111template<std::unsigned_integral Pixel>
113 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
114 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
115{
116 PolyScale<Pixel, Scale_2on3<Pixel>> postScale(pixelOps);
117 EdgeHQ edgeOp = createEdgeHQ(pixelOps);
118 doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
119 src, srcStartY, srcEndY, srcWidth,
120 dst, dstStartY, dstEndY);
121}
122
123template<std::unsigned_integral Pixel>
125 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
126 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
127{
129 EdgeHQ edgeOp = createEdgeHQ(pixelOps);
130 doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
131 src, srcStartY, srcEndY, srcWidth,
132 dst, dstStartY, dstEndY);
133}
134
135template<std::unsigned_integral Pixel>
137 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
138 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
139{
140 PolyScale<Pixel, Scale_4on3<Pixel>> postScale(pixelOps);
141 EdgeHQ edgeOp = createEdgeHQ(pixelOps);
142 doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
143 src, srcStartY, srcEndY, srcWidth,
144 dst, dstStartY, dstEndY);
145}
146
147template<std::unsigned_integral Pixel>
149 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
150 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
151{
152 PolyScale<Pixel, Scale_2on1<Pixel>> postScale(pixelOps);
153 EdgeHQ edgeOp = createEdgeHQ(pixelOps);
154 doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
155 src, srcStartY, srcEndY, srcWidth,
156 dst, dstStartY, dstEndY);
157}
158
159template<std::unsigned_integral Pixel>
161 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
162 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
163{
164 PolyScale<Pixel, Scale_8on3<Pixel>> postScale(pixelOps);
165 EdgeHQ edgeOp = createEdgeHQ(pixelOps);
166 doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
167 src, srcStartY, srcEndY, srcWidth,
168 dst, dstStartY, dstEndY);
169}
170
171template<std::unsigned_integral Pixel>
173 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
174 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
175{
176 PolyScale<Pixel, Scale_4on1<Pixel>> postScale(pixelOps);
177 EdgeHQ edgeOp = createEdgeHQ(pixelOps);
178 doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
179 src, srcStartY, srcEndY, srcWidth,
180 dst, dstStartY, dstEndY);
181}
182
183// Force template instantiation.
184#if HAVE_16BPP
185template class HQ3xScaler<uint16_t>;
186#endif
187#if HAVE_32BPP
188template class HQ3xScaler<uint32_t>;
189#endif
190
191} // namespace openmsx
Interface for getting lines from a video frame.
Definition: FrameSource.hh:20
Runs the hq3x scaler algorithm.
Definition: HQ3xScaler.hh:13
void scale1x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:124
void scale4x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:172
void scale4x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:136
void scale2x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:112
void scale2x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:148
HQ3xScaler(const PixelOperations< Pixel > &pixelOps)
Definition: HQ3xScaler.cc:105
void scale8x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:160
Polymorphic wrapper around another line scaler.
Definition: LineScalers.hh:313
Base class for 3x scalers.
Definition: Scaler3.hh:12
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
EdgeHQ createEdgeHQ(const PixelOperations< Pixel > &pixelOps)
Definition: HQCommon.hh:86
uint32_t readPixel(Pixel p)
Definition: HQCommon.hh:19
void operator()(std::span< const Pixel > in0, std::span< const Pixel > in1, std::span< const Pixel > in2, std::span< Pixel > out0, std::span< Pixel > out1, std::span< Pixel > out2, std::span< uint16_t > edgeBuf, EdgeHQ edgeOp)
Definition: HQ3xScaler.cc:29
constexpr auto xrange(T e)
Definition: xrange.hh:133