openMSX
PixelOperations.hh
Go to the documentation of this file.
1 #ifndef PIXELOPERATIONS_HH
2 #define PIXELOPERATIONS_HH
3 
4 #include "PixelFormat.hh"
5 #include "unreachable.hh"
6 #include "build-info.hh"
7 #include "Math.hh"
8 
9 namespace openmsx {
10 
11 template<typename Pixel> class PixelOpBase
12 {
13 public:
14  explicit PixelOpBase(const PixelFormat& format_)
15  : format(format_)
16  , blendMask(calcBlendMask())
17  {
18  }
19 
20  const PixelFormat& getPixelFormat() const { return format; }
21 
22  inline int getRmask() const { return format.getRmask(); }
23  inline int getGmask() const { return format.getGmask(); }
24  inline int getBmask() const { return format.getBmask(); }
25  inline int getAmask() const { return format.getAmask(); }
26  inline int getRshift() const { return format.getRshift(); }
27  inline int getGshift() const { return format.getGshift(); }
28  inline int getBshift() const { return format.getBshift(); }
29  inline int getAshift() const { return format.getAshift(); }
30  inline int getRloss() const { return format.getRloss(); }
31  inline int getGloss() const { return format.getGloss(); }
32  inline int getBloss() const { return format.getBloss(); }
33  inline int getAloss() const { return format.getAloss(); }
34 
42  inline Pixel getBlendMask() const { return blendMask; }
43 
48  static constexpr bool IS_RGB565 = false;
49 
50 private:
51  inline Pixel calcBlendMask() const
52  {
53  int rBit = ~(getRmask() << 1) & getRmask();
54  int gBit = ~(getGmask() << 1) & getGmask();
55  int bBit = ~(getBmask() << 1) & getBmask();
56  return ~(rBit | gBit | bBit);
57  }
58 
59  const PixelFormat& format;
60 
67  const Pixel blendMask;
68 };
69 
70 // Specialization for 32bpp
71 // No need to store 'blendMask' in a member variable.
72 template<> class PixelOpBase<unsigned>
73 {
74 public:
75  explicit PixelOpBase(const PixelFormat& format_)
76  : format(format_) {}
77 
78  const PixelFormat& getPixelFormat() const { return format; }
79 
80  inline int getRmask() const { return format.getRmask(); }
81  inline int getGmask() const { return format.getGmask(); }
82  inline int getBmask() const { return format.getBmask(); }
83  inline int getAmask() const { return format.getAmask(); }
84  inline int getRshift() const { return format.getRshift(); }
85  inline int getGshift() const { return format.getGshift(); }
86  inline int getBshift() const { return format.getBshift(); }
87  inline int getAshift() const { return format.getAshift(); }
88  inline int getRloss() const { return 0; }
89  inline int getGloss() const { return 0; }
90  inline int getBloss() const { return 0; }
91  inline int getAloss() const { return 0; }
92 
93  inline unsigned getBlendMask() const { return 0xFEFEFEFE; }
94 
95  static constexpr bool IS_RGB565 = false;
96 
97 private:
98  const PixelFormat& format;
99 };
100 
101 
102 #if PLATFORM_DINGUX
103 // Specialization for dingoo (16bpp)
104 // We know the exact pixel format for this platform. No need for any
105 // members in this class. All values can also be compile-time constant.
106 template<> class PixelOpBase<uint16_t>
107 {
108 public:
109  explicit PixelOpBase(const PixelFormat& /*format*/) {}
110 
111  const PixelFormat& getPixelFormat() const
112  {
113  static PixelFormat format(16,
114  0x001F, 0, 3,
115  0x07E0, 5, 2,
116  0xF800, 11, 3,
117  0x0000, 0, 8);
118  return format;
119  }
120 
121  inline int getRmask() const { return 0x001F; }
122  inline int getGmask() const { return 0x07E0; }
123  inline int getBmask() const { return 0xF800; }
124  inline int getAmask() const { return 0x0000; }
125  inline int getRshift() const { return 0; }
126  inline int getGshift() const { return 5; }
127  inline int getBshift() const { return 11; }
128  inline int getAshift() const { return 0; }
129  inline int getRloss() const { return 3; }
130  inline int getGloss() const { return 2; }
131  inline int getBloss() const { return 3; }
132  inline int getAloss() const { return 8; }
133 
134  inline uint16_t getBlendMask() const { return 0xF7DE; }
135 
136  static constexpr bool IS_RGB565 = true;
137 };
138 #endif
139 
140 
141 
142 template<typename Pixel> class PixelOperations : public PixelOpBase<Pixel>
143 {
144 public:
160 
161  explicit PixelOperations(const PixelFormat& format);
162 
165  inline unsigned red(Pixel p) const;
166  inline unsigned green(Pixel p) const;
167  inline unsigned blue(Pixel p) const;
168  inline unsigned alpha(Pixel p) const;
169 
170  // alpha is maximum
171  inline bool isFullyOpaque(Pixel p) const;
172  // alpha is minimum
173  inline bool isFullyTransparent(Pixel p) const;
174 
177  inline unsigned red256(Pixel p) const;
178  inline unsigned green256(Pixel p) const;
179  inline unsigned blue256(Pixel p) const;
180 
183  inline Pixel combine(unsigned r, unsigned g, unsigned b) const;
184  inline Pixel combine256(unsigned r, unsigned g, unsigned b) const;
185 
188  inline unsigned getMaxRed() const;
189  inline unsigned getMaxGreen() const;
190  inline unsigned getMaxBlue() const;
191 
196  template <unsigned w1, unsigned w2>
197  inline Pixel blend(Pixel p1, Pixel p2) const;
198  template <unsigned w1, unsigned w2, unsigned w3>
199  inline Pixel blend(Pixel p1, Pixel p2, Pixel p3) const;
200  template <unsigned w1, unsigned w2, unsigned w3, unsigned w4>
201  inline Pixel blend(Pixel p1, Pixel p2, Pixel p3, Pixel p4) const;
202  template <unsigned w1, unsigned w2, unsigned w3,
203  unsigned w4, unsigned w5, unsigned w6>
204  inline Pixel blend(Pixel p1, Pixel p2, Pixel p3,
205  Pixel p4, Pixel p5, Pixel p6) const;
206 
207  template <unsigned w1, unsigned w2>
208  inline Pixel blend2(const Pixel* p) const;
209  template <unsigned w1, unsigned w2, unsigned w3>
210  inline Pixel blend3(const Pixel* p) const;
211  template <unsigned w1, unsigned w2, unsigned w3, unsigned w4>
212  inline Pixel blend4(const Pixel* p) const;
213  template <unsigned w1, unsigned w2, unsigned w3,
214  unsigned w4, unsigned w5, unsigned w6>
215  inline Pixel blend6(const Pixel* p) const;
216 
225  static inline Pixel multiply(Pixel p, unsigned x);
226 
235  inline Pixel lerp(Pixel p1, Pixel p2, unsigned x) const;
236 
241  inline Pixel alphaBlend(Pixel p1, Pixel p2) const;
242 
243 private:
244  inline Pixel avgDown(Pixel p1, Pixel p2) const;
245  inline Pixel avgUp (Pixel p1, Pixel p2) const;
246 };
247 
248 
249 template <typename Pixel>
251  : PixelOpBase<Pixel>(format_)
252 {
253 }
254 
255 template <typename Pixel>
256 inline unsigned PixelOperations<Pixel>::red(Pixel p) const
257 {
258  if (sizeof(Pixel) == 4) {
259  return (p >> getRshift()) & 0xFF;
260  } else {
261  return (p & getRmask()) >> getRshift();
262  }
263 }
264 template <typename Pixel>
265 inline unsigned PixelOperations<Pixel>::green(Pixel p) const
266 {
267  if (sizeof(Pixel) == 4) {
268  return (p >> getGshift()) & 0xFF;
269  } else {
270  return (p & getGmask()) >> getGshift();
271  }
272 }
273 template <typename Pixel>
274 inline unsigned PixelOperations<Pixel>::blue(Pixel p) const
275 {
276  if (sizeof(Pixel) == 4) {
277  return (p >> getBshift()) & 0xFF;
278  } else {
279  return (p & getBmask()) >> getBshift();
280  }
281 }
282 template <typename Pixel>
283 inline unsigned PixelOperations<Pixel>::alpha(Pixel p) const
284 {
285  if (sizeof(Pixel) == 4) {
286  return (p >> getAshift()) & 0xFF;
287  } else {
288  UNREACHABLE; return 0;
289  //return (p & getAmask()) >> getAshift();
290  }
291 }
292 
293 template <typename Pixel>
295 {
296  if (sizeof(Pixel) == 4) {
297  return alpha(p) == 255;
298  } else {
299  return p != 0x0001;
300  }
301 }
302 template <typename Pixel>
304 {
305  if (sizeof(Pixel) == 4) {
306  return alpha(p) == 0;
307  } else {
308  return p == 0x0001;
309  }
310 }
311 
312 template <typename Pixel>
313 inline unsigned PixelOperations<Pixel>::red256(Pixel p) const
314 {
315  if (sizeof(Pixel) == 4) {
316  return (p >> getRshift()) & 0xFF;
317  } else {
318  return ((p >> getRshift()) << getRloss()) & 0xFF;
319  }
320 }
321 template <typename Pixel>
322 inline unsigned PixelOperations<Pixel>::green256(Pixel p) const
323 {
324  if (sizeof(Pixel) == 4) {
325  return (p >> getGshift()) & 0xFF;
326  } else {
327  return ((p >> getGshift()) << getGloss()) & 0xFF;
328  }
329 }
330 template <typename Pixel>
331 inline unsigned PixelOperations<Pixel>::blue256(Pixel p) const
332 {
333  if (sizeof(Pixel) == 4) {
334  return (p >> getBshift()) & 0xFF;
335  } else {
336  return ((p >> getBshift()) << getBloss()) & 0xFF;
337  }
338 }
339 
340 template <typename Pixel>
342  unsigned r, unsigned g, unsigned b) const
343 {
344  return Pixel((r << getRshift()) |
345  (g << getGshift()) |
346  (b << getBshift()));
347 }
348 
349 template <typename Pixel>
351  unsigned r, unsigned g, unsigned b) const
352 {
353  if (sizeof(Pixel) == 4) {
354  return Pixel((r << getRshift()) |
355  (g << getGshift()) |
356  (b << getBshift()));
357  } else {
358  return Pixel(((r >> getRloss()) << getRshift()) |
359  ((g >> getGloss()) << getGshift()) |
360  ((b >> getBloss()) << getBshift()));
361  }
362 }
363 
364 template <typename Pixel>
365 inline unsigned PixelOperations<Pixel>::getMaxRed() const
366 {
367  if (sizeof(Pixel) == 4) {
368  return 255;
369  } else {
370  return 255 >> getRloss();
371  }
372 }
373 template <typename Pixel>
374 inline unsigned PixelOperations<Pixel>::getMaxGreen() const
375 {
376  if (sizeof(Pixel) == 4) {
377  return 255;
378  } else {
379  return 255 >> getGloss();
380  }
381 }
382 template <typename Pixel>
383 inline unsigned PixelOperations<Pixel>::getMaxBlue() const
384 {
385  if (sizeof(Pixel) == 4) {
386  return 255;
387  } else {
388  return 255 >> getBloss();
389  }
390 }
391 
392 template<typename Pixel>
394 {
395  // Average can be calculated as:
396  // floor((x + y) / 2.0) = (x & y) + (x ^ y) / 2
397  // see "Average of Integers" on http://aggregate.org/MAGIC/
398  return (p1 & p2) + (((p1 ^ p2) & getBlendMask()) >> 1);
399 }
400 template<typename Pixel>
401 inline Pixel PixelOperations<Pixel>::avgUp(Pixel p1, Pixel p2) const
402 {
403  // Similar to above, but rounds up
404  // ceil((x + y) / 2.0) = (x | y) - (x ^ y) / 2
405  return (p1 | p2) - (((p1 ^ p2) & getBlendMask()) >> 1);
406 }
407 
408 template<typename Pixel>
409 template<unsigned w1, unsigned w2>
411 {
412  static const unsigned total = w1 + w2;
413  if (w1 == 0) {
414  return p2;
415  } else if (w1 > w2) {
416  return blend<w2, w1>(p2, p1);
417 
418  } else if (w1 == w2) {
419  // <1,1>
420  return avgDown(p1, p2);
421  } else if ((3 * w1) == w2) {
422  // <1,3>
423  Pixel p11 = avgDown(p1, p2);
424  return avgUp(p11, p2);
425  } else if ((7 * w1) == w2) {
426  // <1,7>
427  Pixel p11 = avgDown(p1, p2);
428  Pixel p13 = avgDown(p11, p2);
429  return avgUp(p13, p2);
430  } else if ((5 * w1) == (3 * w2)) {
431  // <3,5> mix rounding up/down to get a more accurate result
432  Pixel p11 = avgUp (p1, p2);
433  Pixel p13 = avgDown(p11, p2);
434  return avgDown(p11, p13);
435 
436  } else if (!Math::ispow2(total)) {
437  // approximate with weights that sum to 256 (or 64)
438  // e.g. approximate <1,2> as <85,171> (or <21,43>)
439  // ww1 = round(256 * w1 / total) ww2 = 256 - ww1
440  constexpr unsigned newTotal = IS_RGB565 ? 64 : 256;
441  constexpr unsigned ww1 = (2 * w1 * newTotal + total) / (2 * total);
442  constexpr unsigned ww2 = 256 - ww1;
443  return blend<ww1, ww2>(p1, p2);
444 
445  } else if (sizeof(Pixel) == 4) {
446  unsigned l2 = Math::log2p1(total) - 1;
447  unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
448  (p2 & 0x00FF00FF) * w2
449  ) >> l2) & 0x00FF00FF;
450  unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
451  ((p2 & 0xFF00FF00) >> l2) * w2
452  ) & 0xFF00FF00;
453  return c1 | c2;
454 
455  } else if (IS_RGB565) {
456  if (total > 64) {
457  // reduce to maximum 6-bit
458  // note: DIV64 only exists to work around a
459  // division by zero in dead code
460  constexpr unsigned DIV64 = (total > 64) ? 64 : 1;
461  constexpr unsigned factor = total / DIV64;
462  constexpr unsigned round = factor / 2;
463  constexpr unsigned ww1 = (w1 + round) / factor;
464  constexpr unsigned ww2 = 64 - ww1;
465  return blend<ww1, ww2>(p1, p2);
466  } else {
467  unsigned l2 = Math::log2p1(total) - 1;
468  unsigned c1 = (((unsigned(p1) & 0xF81F) * w1) +
469  ((unsigned(p2) & 0xF81F) * w2)) & (0xF81F << l2);
470  unsigned c2 = (((unsigned(p1) & 0x07E0) * w1) +
471  ((unsigned(p2) & 0x07E0) * w2)) & (0x07E0 << l2);
472  return (c1 | c2) >> l2;
473  }
474 
475  } else {
476  // generic version
477  unsigned r = (red (p1) * w1 + red (p2) * w2) / total;
478  unsigned g = (green(p1) * w1 + green(p2) * w2) / total;
479  unsigned b = (blue (p1) * w1 + blue (p2) * w2) / total;
480  return combine(r, g, b);
481  }
482 }
483 
484 template <typename Pixel>
485 template <unsigned w1, unsigned w2, unsigned w3>
487 {
488  constexpr unsigned total = w1 + w2 + w3;
489  if ((sizeof(Pixel) == 4) && Math::ispow2(total)) {
490  unsigned l2 = Math::log2p1(total) - 1;
491  unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
492  (p2 & 0x00FF00FF) * w2 +
493  (p3 & 0x00FF00FF) * w3) >> l2) & 0x00FF00FF;
494  unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
495  ((p2 & 0xFF00FF00) >> l2) * w2 +
496  ((p3 & 0xFF00FF00) >> l2) * w3) & 0xFF00FF00;
497  return c1 | c2;
498  } else {
499  unsigned r = (red (p1) * w1 + red (p2) * w2 + red (p3) * w3) / total;
500  unsigned g = (green(p1) * w1 + green(p2) * w2 + green(p3) * w3) / total;
501  unsigned b = (blue (p1) * w1 + blue (p2) * w2 + blue (p3) * w3) / total;
502  return combine(r, g, b);
503  }
504 }
505 
506 template <typename Pixel>
507 template <unsigned w1, unsigned w2, unsigned w3, unsigned w4>
509  Pixel p1, Pixel p2, Pixel p3, Pixel p4) const
510 {
511  constexpr unsigned total = w1 + w2 + w3 + w4;
512  if ((sizeof(Pixel) == 4) && Math::ispow2(total)) {
513  unsigned l2 = Math::log2p1(total) - 1;
514  unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
515  (p2 & 0x00FF00FF) * w2 +
516  (p3 & 0x00FF00FF) * w3 +
517  (p4 & 0x00FF00FF) * w4) >> l2) & 0x00FF00FF;
518  unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
519  ((p2 & 0xFF00FF00) >> l2) * w2 +
520  ((p3 & 0xFF00FF00) >> l2) * w3 +
521  ((p4 & 0xFF00FF00) >> l2) * w4) & 0xFF00FF00;
522  return c1 | c2;
523  } else {
524  unsigned r = (red (p1) * w1 + red (p2) * w2 +
525  red (p3) * w3 + red (p4) * w4) / total;
526  unsigned g = (green(p1) * w1 + green(p2) * w2 +
527  green(p3) * w3 + green(p4) * w4) / total;
528  unsigned b = (blue (p1) * w1 + blue (p2) * w2 +
529  blue (p3) * w3 + blue (p4) * w4) / total;
530  return combine(r, g, b);
531  }
532 }
533 
534 template <typename Pixel>
535 template <unsigned w1, unsigned w2, unsigned w3,
536  unsigned w4, unsigned w5, unsigned w6>
538  Pixel p1, Pixel p2, Pixel p3, Pixel p4, Pixel p5, Pixel p6) const
539 {
540  constexpr unsigned total = w1 + w2 + w3 + w4 + w5 + w6;
541  if ((sizeof(Pixel) == 4) && Math::ispow2(total)) {
542  unsigned l2 = Math::log2p1(total) - 1;
543  unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
544  (p2 & 0x00FF00FF) * w2 +
545  (p3 & 0x00FF00FF) * w3 +
546  (p4 & 0x00FF00FF) * w4 +
547  (p5 & 0x00FF00FF) * w5 +
548  (p6 & 0x00FF00FF) * w6) >> l2) & 0x00FF00FF;
549  unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
550  ((p2 & 0xFF00FF00) >> l2) * w2 +
551  ((p3 & 0xFF00FF00) >> l2) * w3 +
552  ((p4 & 0xFF00FF00) >> l2) * w4 +
553  ((p5 & 0xFF00FF00) >> l2) * w5 +
554  ((p6 & 0xFF00FF00) >> l2) * w6) & 0xFF00FF00;
555  return c1 | c2;
556  } else {
557  unsigned r = (red (p1) * w1 + red (p2) * w2 +
558  red (p3) * w3 + red (p4) * w4 +
559  red (p5) * w5 + red (p6) * w6) / total;
560  unsigned g = (green(p1) * w1 + green(p2) * w2 +
561  green(p3) * w3 + green(p4) * w4 +
562  green(p5) * w5 + green(p6) * w6) / total;
563  unsigned b = (blue (p1) * w1 + blue (p2) * w2 +
564  blue (p3) * w3 + blue (p4) * w4 +
565  blue (p5) * w5 + blue (p6) * w6) / total;
566  return combine(r, g, b);
567  }
568 }
569 
570 
571 template <typename Pixel>
572 template <unsigned w1, unsigned w2>
574 {
575  return blend<w1, w2>(p[0], p[1]);
576 }
577 
578 template <typename Pixel>
579 template <unsigned w1, unsigned w2, unsigned w3>
581 {
582  return blend<w1, w2, w3>(p[0], p[1], p[2]);
583 }
584 
585 template <typename Pixel>
586 template <unsigned w1, unsigned w2, unsigned w3, unsigned w4>
588 {
589  return blend<w1, w2, w3, w4>(p[0], p[1], p[2], p[3]);
590 }
591 
592 template <typename Pixel>
593 template <unsigned w1, unsigned w2, unsigned w3,
594  unsigned w4, unsigned w5, unsigned w6>
596 {
597  return blend<w1, w2, w3, w4, w5, w6>(p[0], p[1], p[2], p[3], p[4], p[5]);
598 }
599 
600 template <typename Pixel>
602 {
603  if (sizeof(Pixel) == 4) {
604  return ((((p & 0x00FF00FF) * x) & 0xFF00FF00) >> 8)
605  | ((((p >> 8) & 0x00FF00FF) * x) & 0xFF00FF00);
606  } else {
607  UNREACHABLE; return 0;
608  }
609 }
610 
611 template <typename Pixel>
612 inline Pixel PixelOperations<Pixel>::lerp(Pixel p1, Pixel p2, unsigned x) const
613 {
614  if (sizeof(Pixel) == 4) { // 32 bpp
615  unsigned rb1 = (p1 >> 0) & 0x00FF00FF;
616  unsigned ag1 = (p1 >> 8) & 0x00FF00FF;
617  unsigned rb2 = (p2 >> 0) & 0x00FF00FF;
618  unsigned ag2 = (p2 >> 8) & 0x00FF00FF;
619 
620  // Note: the subtraction for the lower component can 'borrow' from
621  // the higher component. Though in the full calculation this error
622  // magically cancels out.
623  unsigned trb = ((rb2 - rb1) * x) >> 8;
624  unsigned tag = ((ag2 - ag1) * x) >> 0;
625 
626  unsigned rb = ((trb + rb1) << 0) & 0x00FF00FF;
627  unsigned ag = (tag + (ag1 << 8)) & 0xFF00FF00;
628 
629  return rb | ag;
630 
631  } else if (IS_RGB565) {
632  unsigned rb1 = p1 & 0xF81F;
633  unsigned rb2 = p2 & 0xF81F;
634  unsigned g1 = p1 & 0x07E0;
635  unsigned g2 = p2 & 0x07E0;
636 
637  x >>= 2;
638  unsigned trb = ((rb2 - rb1) * x) >> 6;
639  unsigned tg = ((g2 - g1 ) * x) >> 6;
640 
641  unsigned rb = (trb + rb1) & 0xF81F;
642  unsigned g = (tg + g1 ) & 0x07E0;
643 
644  return rb | g;
645 
646  } else {
647  int r1 = red(p1), r2 = red(p2);
648  int g1 = green(p1), g2 = green(p2);
649  int b1 = blue(p1), b2 = blue(p2);
650 
651  // note: '/ 256' is not the same as '>> 8' for signed numbers
652  int r = ((r2 - r1) * x) / 256 + r1;
653  int g = ((g2 - g1) * x) / 256 + g1;
654  int b = ((b2 - b1) * x) / 256 + b1;
655 
656  return combine(r, g, b);
657  }
658 }
659 
660 template <typename Pixel>
662 {
663  if (sizeof(Pixel) == 2) {
664  // TODO keep magic value in sync with OutputSurface::getKeyColor()
665  return (p1 == 0x0001) ? p2 : p1;
666  } else {
667  unsigned a = alpha(p1);
668  // Note: 'a' is [0..255], while lerp() expects [0..256].
669  // We ignore this small error.
670  return lerp(p2, p1, a);
671  }
672 }
673 
674 } // namespace openmsx
675 
676 #endif
openmsx::PixelOpBase::getGshift
int getGshift() const
Definition: PixelOperations.hh:27
openmsx::DiskImageUtils::format
void format(SectorAccessibleDisk &disk, bool dos1)
Format the given disk (= a single partition).
Definition: DiskImageUtils.cc:182
openmsx::PixelOpBase::getRloss
int getRloss() const
Definition: PixelOperations.hh:30
openmsx::PixelOpBase< unsigned >::getBmask
int getBmask() const
Definition: PixelOperations.hh:82
p3
mat3 p3(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 0, 9))
cstd::round
constexpr double round(double x)
Definition: cstd.hh:318
openmsx::PixelOpBase::getBshift
int getBshift() const
Definition: PixelOperations.hh:28
openmsx::PixelOperations
Definition: PixelOperations.hh:142
openmsx::PixelOpBase< unsigned >::getAmask
int getAmask() const
Definition: PixelOperations.hh:83
openmsx::PixelOpBase::getBmask
int getBmask() const
Definition: PixelOperations.hh:24
openmsx::PixelOperations::blue256
unsigned blue256(Pixel p) const
Definition: PixelOperations.hh:331
openmsx::PixelOperations::combine256
Pixel combine256(unsigned r, unsigned g, unsigned b) const
Definition: PixelOperations.hh:350
openmsx::PixelOpBase< unsigned >::getBloss
int getBloss() const
Definition: PixelOperations.hh:90
openmsx::PixelOpBase< unsigned >::getAloss
int getAloss() const
Definition: PixelOperations.hh:91
openmsx::PixelFormat::getGmask
unsigned getGmask() const
Definition: PixelFormat.hh:26
openmsx::PixelOperations::alpha
unsigned alpha(Pixel p) const
Definition: PixelOperations.hh:283
openmsx::PixelFormat::getRloss
unsigned getRloss() const
Definition: PixelFormat.hh:35
openmsx::PixelOperations::PixelOperations
PixelOperations(const PixelFormat &format)
Definition: PixelOperations.hh:250
openmsx::PixelFormat::getGshift
unsigned getGshift() const
Definition: PixelFormat.hh:31
Math::ispow2
constexpr bool ispow2(T x) noexcept
Is the given number an integral power of two? That is, does it have exactly one 1-bit in binary repre...
Definition: Math.hh:57
openmsx::PixelOpBase::getGmask
int getGmask() const
Definition: PixelOperations.hh:23
openmsx::PixelFormat
Definition: PixelFormat.hh:8
openmsx::Keys::combine
KeyCode combine(KeyCode key, KeyCode modifier)
Convenience method to create key combinations (hides ugly casts).
Definition: Keys.hh:234
openmsx::PixelFormat::getBloss
unsigned getBloss() const
Definition: PixelFormat.hh:37
openmsx::PixelOperations::alphaBlend
Pixel alphaBlend(Pixel p1, Pixel p2) const
Perform alpha blending of two pixels.
Definition: PixelOperations.hh:661
openmsx::PixelFormat::getGloss
unsigned getGloss() const
Definition: PixelFormat.hh:36
openmsx::PixelFormat::getRmask
unsigned getRmask() const
Definition: PixelFormat.hh:25
openmsx::PixelFormat::getBmask
unsigned getBmask() const
Definition: PixelFormat.hh:27
openmsx::PixelOpBase::getAmask
int getAmask() const
Definition: PixelOperations.hh:25
openmsx::PixelOpBase< unsigned >::getGshift
int getGshift() const
Definition: PixelOperations.hh:85
openmsx::Pixel
uint32_t Pixel
Definition: GLHQLiteScaler.cc:93
UNREACHABLE
#define UNREACHABLE
Definition: unreachable.hh:38
openmsx::PixelOpBase::getAloss
int getAloss() const
Definition: PixelOperations.hh:33
openmsx::PixelFormat::getAshift
unsigned getAshift() const
Definition: PixelFormat.hh:33
openmsx::PixelOpBase::getRshift
int getRshift() const
Definition: PixelOperations.hh:26
openmsx::PixelOpBase::getBlendMask
Pixel getBlendMask() const
Returns a constant that is useful to calculate the average of two pixel values.
Definition: PixelOperations.hh:42
openmsx::PixelFormat::getAmask
unsigned getAmask() const
Definition: PixelFormat.hh:28
openmsx::PixelOpBase
Definition: PixelOperations.hh:11
openmsx::PixelOpBase< unsigned >::getBshift
int getBshift() const
Definition: PixelOperations.hh:86
w3
vec3 w3(-1, -2, 2)
openmsx::PixelOperations::green
unsigned green(Pixel p) const
Definition: PixelOperations.hh:265
build-info.hh
openmsx::PixelOperations::lerp
Pixel lerp(Pixel p1, Pixel p2, unsigned x) const
Perform linear interpolation between two pixels.
Definition: PixelOperations.hh:612
openmsx::PixelOperations::green256
unsigned green256(Pixel p) const
Definition: PixelOperations.hh:322
openmsx::PixelOperations::blend6
Pixel blend6(const Pixel *p) const
Definition: PixelOperations.hh:595
openmsx::PixelOpBase< unsigned >::getGloss
int getGloss() const
Definition: PixelOperations.hh:89
openmsx::PixelOperations::blend3
Pixel blend3(const Pixel *p) const
Definition: PixelOperations.hh:580
g
int g
Definition: ScopedAssign_test.cc:20
openmsx::PixelOpBase< unsigned >::getBlendMask
unsigned getBlendMask() const
Definition: PixelOperations.hh:93
openmsx::PixelOpBase::getBloss
int getBloss() const
Definition: PixelOperations.hh:32
openmsx::PixelOperations::multiply
static Pixel multiply(Pixel p, unsigned x)
Perform a component wise multiplication of a pixel with an 8-bit fractional value: result = (pixel * ...
Definition: PixelOperations.hh:601
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1419
Math::log2p1
constexpr T log2p1(T x) noexcept
Returns the number of bits needed to store the value 'x', that is: for x==0 : 0 for x!...
Definition: Math.hh:39
openmsx::PixelOpBase::getAshift
int getAshift() const
Definition: PixelOperations.hh:29
openmsx::PixelOpBase::IS_RGB565
static constexpr bool IS_RGB565
Return true if it's statically known that the pixelformat has a 5-6-5 format (not specified wihich co...
Definition: PixelOperations.hh:48
openmsx::PixelOpBase::getPixelFormat
const PixelFormat & getPixelFormat() const
Definition: PixelOperations.hh:20
openmsx::PixelOperations::getMaxRed
unsigned getMaxRed() const
Get maximum component value.
Definition: PixelOperations.hh:365
openmsx::PixelOpBase< unsigned >::getGmask
int getGmask() const
Definition: PixelOperations.hh:81
openmsx::PixelOpBase::getGloss
int getGloss() const
Definition: PixelOperations.hh:31
p4
mat4 p4(vec4(1, 2, 3, 4), vec4(3, 4, 5, 6), vec4(5, 0, 7, 8), vec4(7, 8, 9, 0))
openmsx::PixelOpBase< unsigned >::getRshift
int getRshift() const
Definition: PixelOperations.hh:84
openmsx::PixelOperations::red256
unsigned red256(Pixel p) const
Same as above, but result is scaled to [0..255].
Definition: PixelOperations.hh:313
openmsx::PixelOperations::red
unsigned red(Pixel p) const
Extract RGB componts.
Definition: PixelOperations.hh:256
openmsx::PixelOpBase::getRmask
int getRmask() const
Definition: PixelOperations.hh:22
openmsx::PixelOperations::blend2
Pixel blend2(const Pixel *p) const
Definition: PixelOperations.hh:573
openmsx::PixelOpBase< unsigned >::getPixelFormat
const PixelFormat & getPixelFormat() const
Definition: PixelOperations.hh:78
openmsx::PixelOpBase< unsigned >::getRmask
int getRmask() const
Definition: PixelOperations.hh:80
w4
vec4 w4(-1, 2, 2, -6)
openmsx::PixelOperations::getMaxGreen
unsigned getMaxGreen() const
Definition: PixelOperations.hh:374
openmsx::PixelOperations::blend
Pixel blend(Pixel p1, Pixel p2) const
Blend the given colors into a single color.
Definition: PixelOperations.hh:410
openmsx::PixelOpBase::PixelOpBase
PixelOpBase(const PixelFormat &format_)
Definition: PixelOperations.hh:14
openmsx::PixelFormat::getRshift
unsigned getRshift() const
Definition: PixelFormat.hh:30
unreachable.hh
openmsx::PixelOperations::isFullyOpaque
bool isFullyOpaque(Pixel p) const
Definition: PixelOperations.hh:294
Math.hh
PixelFormat.hh
openmsx::PixelOpBase< unsigned >::getRloss
int getRloss() const
Definition: PixelOperations.hh:88
openmsx::PixelOperations::blue
unsigned blue(Pixel p) const
Definition: PixelOperations.hh:274
openmsx::PixelOperations::blend4
Pixel blend4(const Pixel *p) const
Definition: PixelOperations.hh:587
openmsx::PixelOperations::isFullyTransparent
bool isFullyTransparent(Pixel p) const
Definition: PixelOperations.hh:303
openmsx::PixelOperations::getMaxBlue
unsigned getMaxBlue() const
Definition: PixelOperations.hh:383
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::PixelFormat::getAloss
unsigned getAloss() const
Definition: PixelFormat.hh:38
openmsx::PixelFormat::getBshift
unsigned getBshift() const
Definition: PixelFormat.hh:32
openmsx::PixelOpBase< unsigned >::getAshift
int getAshift() const
Definition: PixelOperations.hh:87
openmsx::PixelOperations::combine
Pixel combine(unsigned r, unsigned g, unsigned b) const
Combine RGB components to a pixel.
Definition: PixelOperations.hh:341
openmsx::PixelOpBase< unsigned >::PixelOpBase
PixelOpBase(const PixelFormat &format_)
Definition: PixelOperations.hh:75