HQ3xLiteScaler.cc 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. Original code: Copyright (C) 2003 MaxSt ( maxst@hiend3d.com )
  3. openMSX adaptation by Wouter Vermaelen
  4. License: LGPL
  5. Visit the HiEnd3D site for info:
  6. http://www.hiend3d.com/hq2x.html
  7. */
  8. #include "HQ3xLiteScaler.hh"
  9. #include "HQCommon.hh"
  10. #include "LineScalers.hh"
  11. #include "unreachable.hh"
  12. #include "build-info.hh"
  13. #include <cstdint>
  14. namespace openmsx {
  15. template <typename Pixel> struct HQLite_1x1on3x3
  16. {
  17. void operator()(const Pixel* in0, const Pixel* in1, const Pixel* in2,
  18. Pixel* out0, Pixel* out1, Pixel* out2,
  19. unsigned srcWidth, unsigned* edgeBuf, EdgeHQLite edgeOp)
  20. __restrict;
  21. };
  22. template <typename Pixel>
  23. void HQLite_1x1on3x3<Pixel>::operator()(
  24. const Pixel* __restrict in0, const Pixel* __restrict in1,
  25. const Pixel* __restrict in2,
  26. Pixel* __restrict out0, Pixel* __restrict out1,
  27. Pixel* __restrict out2,
  28. unsigned srcWidth, unsigned* __restrict edgeBuf,
  29. EdgeHQLite /*edgeOp*/) __restrict
  30. {
  31. unsigned c2, c4, c5, c6, c8, c9;
  32. c2 = readPixel(in0[0]);
  33. c5 = c6 = readPixel(in1[0]);
  34. c8 = c9 = readPixel(in2[0]);
  35. unsigned pattern = 0;
  36. if (c5 != c8) pattern |= 3 << 6;
  37. if (c5 != c2) pattern |= 3 << 9;
  38. for (unsigned x = 0; x < srcWidth; ++x) {
  39. c4 = c5; c5 = c6; c8 = c9;
  40. if (x != srcWidth - 1) {
  41. c6 = readPixel(in1[x + 1]);
  42. c9 = readPixel(in2[x + 1]);
  43. }
  44. pattern = (pattern >> 6) & 0x001F; // left overlap
  45. // overlaps with left
  46. //if (c8 != c4) pattern |= 1 << 0; // B - l: c5-c9 6
  47. //if (c5 != c7) pattern |= 1 << 1; // B - l: c6-c8 7
  48. //if (c5 != c4) pattern |= 1 << 2; // l: c5-c6 8
  49. // overlaps with top and left
  50. //if (c5 != c1) pattern |= 1 << 3; // l: c2-c6 9, t: c4-c8 0
  51. //if (c4 != c2) pattern |= 1 << 4; // l: c5-c3 10, t: c5-c7 1
  52. // non-overlapping pixels
  53. if (c5 != c8) pattern |= 1 << 5; // B
  54. if (c5 != c9) pattern |= 1 << 6; // BR
  55. if (c6 != c8) pattern |= 1 << 7; // BR
  56. if (c5 != c6) pattern |= 1 << 8; // R
  57. // overlaps with top
  58. //if (c2 != c6) pattern |= 1 << 9; // R - t: c5-c9 6
  59. //if (c5 != c3) pattern |= 1 << 10; // R - t: c6-c8 7
  60. //if (c5 != c2) pattern |= 1 << 11; // t: c5-c8 5
  61. pattern |= ((edgeBuf[x] & (1 << 5) ) << 6) |
  62. ((edgeBuf[x] & ((1 << 6) | (1 << 7))) << 3);
  63. edgeBuf[x] = pattern;
  64. unsigned pixel0, pixel1, pixel2, pixel3, pixel4,
  65. pixel5, pixel6, pixel7, pixel8;
  66. #include "HQ3xLiteScaler-1x1to3x3.nn"
  67. out0[3 * x + 0] = writePixel<Pixel>(pixel0);
  68. out0[3 * x + 1] = writePixel<Pixel>(pixel1);
  69. out0[3 * x + 2] = writePixel<Pixel>(pixel2);
  70. out1[3 * x + 0] = writePixel<Pixel>(pixel3);
  71. out1[3 * x + 1] = writePixel<Pixel>(pixel4);
  72. out1[3 * x + 2] = writePixel<Pixel>(pixel5);
  73. out2[3 * x + 0] = writePixel<Pixel>(pixel6);
  74. out2[3 * x + 1] = writePixel<Pixel>(pixel7);
  75. out2[3 * x + 2] = writePixel<Pixel>(pixel8);
  76. }
  77. }
  78. template <class Pixel>
  79. HQ3xLiteScaler<Pixel>::HQ3xLiteScaler(const PixelOperations<Pixel>& pixelOps_)
  80. : Scaler3<Pixel>(pixelOps_)
  81. , pixelOps(pixelOps_)
  82. {
  83. }
  84. template <class Pixel>
  85. void HQ3xLiteScaler<Pixel>::scale2x1to9x3(FrameSource& src,
  86. unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
  87. ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
  88. {
  89. PolyScale<Pixel, Scale_2on3<Pixel>> postScale(pixelOps);
  90. EdgeHQLite edgeOp;
  91. doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
  92. src, srcStartY, srcEndY, srcWidth,
  93. dst, dstStartY, dstEndY, (srcWidth * 9) / 2);
  94. }
  95. template <class Pixel>
  96. void HQ3xLiteScaler<Pixel>::scale1x1to3x3(FrameSource& src,
  97. unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
  98. ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
  99. {
  100. PolyScale<Pixel, Scale_1on1<Pixel>> postScale;
  101. EdgeHQLite edgeOp;
  102. doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
  103. src, srcStartY, srcEndY, srcWidth,
  104. dst, dstStartY, dstEndY, srcWidth * 3);
  105. }
  106. template <class Pixel>
  107. void HQ3xLiteScaler<Pixel>::scale4x1to9x3(FrameSource& src,
  108. unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
  109. ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
  110. {
  111. PolyScale<Pixel, Scale_4on3<Pixel>> postScale(pixelOps);
  112. EdgeHQLite edgeOp;
  113. doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
  114. src, srcStartY, srcEndY, srcWidth,
  115. dst, dstStartY, dstEndY, (srcWidth * 9) / 4);
  116. }
  117. template <class Pixel>
  118. void HQ3xLiteScaler<Pixel>::scale2x1to3x3(FrameSource& src,
  119. unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
  120. ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
  121. {
  122. PolyScale<Pixel, Scale_2on1<Pixel>> postScale(pixelOps);
  123. EdgeHQLite edgeOp;
  124. doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
  125. src, srcStartY, srcEndY, srcWidth,
  126. dst, dstStartY, dstEndY, (srcWidth * 3) / 2);
  127. }
  128. template <class Pixel>
  129. void HQ3xLiteScaler<Pixel>::scale8x1to9x3(FrameSource& src,
  130. unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
  131. ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
  132. {
  133. PolyScale<Pixel, Scale_8on3<Pixel>> postScale(pixelOps);
  134. EdgeHQLite edgeOp;
  135. doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
  136. src, srcStartY, srcEndY, srcWidth,
  137. dst, dstStartY, dstEndY, (srcWidth * 9) / 8);
  138. }
  139. template <class Pixel>
  140. void HQ3xLiteScaler<Pixel>::scale4x1to3x3(FrameSource& src,
  141. unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
  142. ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
  143. {
  144. PolyScale<Pixel, Scale_4on1<Pixel>> postScale(pixelOps);
  145. EdgeHQLite edgeOp;
  146. doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
  147. src, srcStartY, srcEndY, srcWidth,
  148. dst, dstStartY, dstEndY, (srcWidth * 3) / 4);
  149. }
  150. // Force template instantiation.
  151. #if HAVE_16BPP
  152. template class HQ3xLiteScaler<uint16_t>;
  153. #endif
  154. #if HAVE_32BPP
  155. template class HQ3xLiteScaler<uint32_t>;
  156. #endif
  157. } // namespace openmsx