1 #ifndef PIXELOPERATIONS_HH
2 #define PIXELOPERATIONS_HH
15 , blendMask(calcBlendMask())
21 inline int getRmask()
const {
return format.Rmask; }
22 inline int getGmask()
const {
return format.Gmask; }
23 inline int getBmask()
const {
return format.Bmask; }
24 inline int getAmask()
const {
return format.Amask; }
25 inline int getRshift()
const {
return format.Rshift; }
26 inline int getGshift()
const {
return format.Gshift; }
27 inline int getBshift()
const {
return format.Bshift; }
28 inline int getAshift()
const {
return format.Ashift; }
29 inline int getRloss()
const {
return format.Rloss; }
30 inline int getGloss()
const {
return format.Gloss; }
31 inline int getBloss()
const {
return format.Bloss; }
32 inline int getAloss()
const {
return format.Aloss; }
50 inline Pixel calcBlendMask()
const
55 return ~(rBit | gBit | bBit);
58 const SDL_PixelFormat& format;
66 const Pixel blendMask;
79 inline int getRmask()
const {
return format.Rmask; }
80 inline int getGmask()
const {
return format.Gmask; }
81 inline int getBmask()
const {
return format.Bmask; }
82 inline int getAmask()
const {
return format.Amask; }
83 inline int getRshift()
const {
return format.Rshift; }
84 inline int getGshift()
const {
return format.Gshift; }
85 inline int getBshift()
const {
return format.Bshift; }
86 inline int getAshift()
const {
return format.Ashift; }
97 const SDL_PixelFormat& format;
112 static SDL_PixelFormat format;
113 format.palette =
nullptr;
114 format.BitsPerPixel = 16;
115 format.BytesPerPixel = 2;
124 format.Rmask = 0x001F;
125 format.Gmask = 0x07E0;
126 format.Bmask = 0xF800;
127 format.Amask = 0x0000;
131 inline int getRmask()
const {
return 0x001F; }
132 inline int getGmask()
const {
return 0x07E0; }
133 inline int getBmask()
const {
return 0xF800; }
134 inline int getAmask()
const {
return 0x0000; }
135 inline int getRshift()
const {
return 0; }
136 inline int getGshift()
const {
return 5; }
137 inline int getBshift()
const {
return 11; }
138 inline int getAshift()
const {
return 0; }
139 inline int getRloss()
const {
return 3; }
140 inline int getGloss()
const {
return 2; }
141 inline int getBloss()
const {
return 3; }
142 inline int getAloss()
const {
return 8; }
144 inline unsigned short getBlendMask()
const {
return 0xF7DE; }
193 inline Pixel combine(
unsigned r,
unsigned g,
unsigned b)
const;
206 template <
unsigned w1,
unsigned w2>
208 template <
unsigned w1,
unsigned w2,
unsigned w3>
210 template <
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
212 template <
unsigned w1,
unsigned w2,
unsigned w3,
213 unsigned w4,
unsigned w5,
unsigned w6>
217 template <
unsigned w1,
unsigned w2>
219 template <
unsigned w1,
unsigned w2,
unsigned w3>
221 template <
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
223 template <
unsigned w1,
unsigned w2,
unsigned w3,
224 unsigned w4,
unsigned w5,
unsigned w6>
259 template <
typename Pixel>
265 template <
typename Pixel>
268 if (
sizeof(
Pixel) == 4) {
269 return (p >> getRshift()) & 0xFF;
271 return (p & getRmask()) >> getRshift();
274 template <
typename Pixel>
277 if (
sizeof(
Pixel) == 4) {
278 return (p >> getGshift()) & 0xFF;
280 return (p & getGmask()) >> getGshift();
283 template <
typename Pixel>
286 if (
sizeof(
Pixel) == 4) {
287 return (p >> getBshift()) & 0xFF;
289 return (p & getBmask()) >> getBshift();
292 template <
typename Pixel>
295 if (
sizeof(
Pixel) == 4) {
296 return (p >> getAshift()) & 0xFF;
303 template <
typename Pixel>
306 if (
sizeof(
Pixel) == 4) {
307 return alpha(p) == 255;
312 template <
typename Pixel>
315 if (
sizeof(
Pixel) == 4) {
316 return alpha(p) == 0;
322 template <
typename Pixel>
325 if (
sizeof(
Pixel) == 4) {
326 return (p >> getRshift()) & 0xFF;
328 return ((p >> getRshift()) << getRloss()) & 0xFF;
331 template <
typename Pixel>
334 if (
sizeof(
Pixel) == 4) {
335 return (p >> getGshift()) & 0xFF;
337 return ((p >> getGshift()) << getGloss()) & 0xFF;
340 template <
typename Pixel>
343 if (
sizeof(
Pixel) == 4) {
344 return (p >> getBshift()) & 0xFF;
346 return ((p >> getBshift()) << getBloss()) & 0xFF;
350 template <
typename Pixel>
352 unsigned r,
unsigned g,
unsigned b)
const
354 return Pixel((r << getRshift()) |
359 template <
typename Pixel>
361 unsigned r,
unsigned g,
unsigned b)
const
363 if (
sizeof(
Pixel) == 4) {
364 return Pixel((r << getRshift()) |
368 return Pixel(((r >> getRloss()) << getRshift()) |
369 ((g >> getGloss()) << getGshift()) |
370 ((b >> getBloss()) << getBshift()));
374 template <
typename Pixel>
377 if (
sizeof(
Pixel) == 4) {
380 return 255 >> getRloss();
383 template <
typename Pixel>
386 if (
sizeof(
Pixel) == 4) {
389 return 255 >> getGloss();
392 template <
typename Pixel>
395 if (
sizeof(
Pixel) == 4) {
398 return 255 >> getBloss();
408 static const unsigned log2 = 0;
412 template<
typename Pixel>
418 return (p1 & p2) + (((p1 ^ p2) & getBlendMask()) >> 1);
420 template<
typename Pixel>
425 return (p1 | p2) - (((p1 ^ p2) & getBlendMask()) >> 1);
428 template<
typename Pixel>
429 template<
unsigned w1,
unsigned w2>
432 static const unsigned total = w1 + w2;
435 }
else if (w1 > w2) {
436 return blend<w2, w1>(p2, p1);
438 }
else if (w1 == w2) {
440 return avgDown(p1, p2);
441 }
else if ((3 * w1) == w2) {
443 Pixel p11 = avgDown(p1, p2);
444 return avgUp(p11, p2);
445 }
else if ((7 * w1) == w2) {
447 Pixel p11 = avgDown(p1, p2);
448 Pixel p13 = avgDown(p11, p2);
449 return avgUp(p13, p2);
450 }
else if ((5 * w1) == (3 * w2)) {
452 Pixel p11 = avgUp (p1, p2);
453 Pixel p13 = avgDown(p11, p2);
454 return avgDown(p11, p13);
460 static const unsigned newTotal = IS_RGB565 ? 64 : 256;
461 static const unsigned ww1 = (2 * w1 * newTotal + total) / (2 * total);
462 static const unsigned ww2 = 256 - ww1;
463 return blend<ww1, ww2>(p1, p2);
465 }
else if (
sizeof(
Pixel) == 4) {
467 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
468 (p2 & 0x00FF00FF) * w2
469 ) >> l2) & 0x00FF00FF;
470 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
471 ((p2 & 0xFF00FF00) >> l2) * w2
475 }
else if (IS_RGB565) {
480 static const unsigned DIV64 = (total > 64) ? 64 : 1;
481 static const unsigned factor = total / DIV64;
482 static const unsigned round = factor / 2;
483 static const unsigned ww1 = (w1 + round) / factor;
484 static const unsigned ww2 = 64 - ww1;
485 return blend<ww1, ww2>(p1, p2);
488 unsigned c1 = (((unsigned(p1) & 0xF81F) * w1) +
489 ((unsigned(p2) & 0xF81F) * w2)) & (0xF81F << l2);
490 unsigned c2 = (((unsigned(p1) & 0x07E0) * w1) +
491 ((unsigned(p2) & 0x07E0) * w2)) & (0x07E0 << l2);
492 return (c1 | c2) >> l2;
497 unsigned r = (red (p1) * w1 + red (p2) * w2) / total;
498 unsigned g = (green(p1) * w1 + green(p2) * w2) / total;
499 unsigned b = (blue (p1) * w1 + blue (p2) * w2) / total;
504 template <
typename Pixel>
505 template <
unsigned w1,
unsigned w2,
unsigned w3>
508 static const unsigned total = w1 + w2 + w3;
511 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
512 (p2 & 0x00FF00FF) * w2 +
513 (p3 & 0x00FF00FF) * w3) >> l2) & 0x00FF00FF;
514 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
515 ((p2 & 0xFF00FF00) >> l2) * w2 +
516 ((p3 & 0xFF00FF00) >> l2) * w3) & 0xFF00FF00;
519 unsigned r = (red (p1) * w1 + red (p2) * w2 + red (p3) * w3) / total;
520 unsigned g = (green(p1) * w1 + green(p2) * w2 + green(p3) * w3) / total;
521 unsigned b = (blue (p1) * w1 + blue (p2) * w2 + blue (p3) * w3) / total;
526 template <
typename Pixel>
527 template <
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
531 static const unsigned total = w1 + w2 + w3 + w4;
534 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
535 (p2 & 0x00FF00FF) * w2 +
536 (p3 & 0x00FF00FF) * w3 +
537 (p4 & 0x00FF00FF) * w4) >> l2) & 0x00FF00FF;
538 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
539 ((p2 & 0xFF00FF00) >> l2) * w2 +
540 ((p3 & 0xFF00FF00) >> l2) * w3 +
541 ((p4 & 0xFF00FF00) >> l2) * w4) & 0xFF00FF00;
544 unsigned r = (red (p1) * w1 + red (p2) * w2 +
545 red (p3) * w3 + red (p4) * w4) / total;
546 unsigned g = (green(p1) * w1 + green(p2) * w2 +
547 green(p3) * w3 + green(p4) * w4) / total;
548 unsigned b = (blue (p1) * w1 + blue (p2) * w2 +
549 blue (p3) * w3 + blue (p4) * w4) / total;
554 template <
typename Pixel>
555 template <
unsigned w1,
unsigned w2,
unsigned w3,
556 unsigned w4,
unsigned w5,
unsigned w6>
560 static const unsigned total = w1 + w2 + w3 + w4 + w5 + w6;
563 unsigned c1 = (((p1 & 0x00FF00FF) * w1 +
564 (p2 & 0x00FF00FF) * w2 +
565 (p3 & 0x00FF00FF) * w3 +
566 (p4 & 0x00FF00FF) * w4 +
567 (p5 & 0x00FF00FF) * w5 +
568 (p6 & 0x00FF00FF) * w6) >> l2) & 0x00FF00FF;
569 unsigned c2 = (((p1 & 0xFF00FF00) >> l2) * w1 +
570 ((p2 & 0xFF00FF00) >> l2) * w2 +
571 ((p3 & 0xFF00FF00) >> l2) * w3 +
572 ((p4 & 0xFF00FF00) >> l2) * w4 +
573 ((p5 & 0xFF00FF00) >> l2) * w5 +
574 ((p6 & 0xFF00FF00) >> l2) * w6) & 0xFF00FF00;
577 unsigned r = (red (p1) * w1 + red (p2) * w2 +
578 red (p3) * w3 + red (p4) * w4 +
579 red (p5) * w5 + red (p6) * w6) / total;
580 unsigned g = (green(p1) * w1 + green(p2) * w2 +
581 green(p3) * w3 + green(p4) * w4 +
582 green(p5) * w5 + green(p6) * w6) / total;
583 unsigned b = (blue (p1) * w1 + blue (p2) * w2 +
584 blue (p3) * w3 + blue (p4) * w4 +
585 blue (p5) * w5 + blue (p6) * w6) / total;
591 template <
typename Pixel>
592 template <
unsigned w1,
unsigned w2>
595 return blend<w1, w2>(p[0], p[1]);
598 template <
typename Pixel>
599 template <
unsigned w1,
unsigned w2,
unsigned w3>
602 return blend<w1, w2, w3>(p[0], p[1], p[2]);
605 template <
typename Pixel>
606 template <
unsigned w1,
unsigned w2,
unsigned w3,
unsigned w4>
609 return blend<w1, w2, w3, w4>(p[0], p[1], p[2], p[3]);
612 template <
typename Pixel>
613 template <
unsigned w1,
unsigned w2,
unsigned w3,
614 unsigned w4,
unsigned w5,
unsigned w6>
617 return blend<w1, w2, w3, w4, w5, w6>(p[0], p[1], p[2], p[3], p[4], p[5]);
620 template <
typename Pixel>
623 if (
sizeof(
Pixel) == 4) {
624 return ((((p & 0x00FF00FF) * x) & 0xFF00FF00) >> 8)
625 | ((((p >> 8) & 0x00FF00FF) * x) & 0xFF00FF00);
631 template <
typename Pixel>
634 if (
sizeof(
Pixel) == 4) {
635 unsigned rb1 = (p1 >> 0) & 0x00FF00FF;
636 unsigned ag1 = (p1 >> 8) & 0x00FF00FF;
637 unsigned rb2 = (p2 >> 0) & 0x00FF00FF;
638 unsigned ag2 = (p2 >> 8) & 0x00FF00FF;
643 unsigned trb = ((rb2 - rb1) * x) >> 8;
644 unsigned tag = ((ag2 - ag1) * x) >> 0;
646 unsigned rb = ((trb + rb1) << 0) & 0x00FF00FF;
647 unsigned ag = (tag + (ag1 << 8)) & 0xFF00FF00;
651 }
else if (IS_RGB565) {
652 unsigned rb1 = p1 & 0xF81F;
653 unsigned rb2 = p2 & 0xF81F;
654 unsigned g1 = p1 & 0x07E0;
655 unsigned g2 = p2 & 0x07E0;
658 unsigned trb = ((rb2 - rb1) * x) >> 6;
659 unsigned tg = ((g2 - g1 ) * x) >> 6;
661 unsigned rb = (trb + rb1) & 0xF81F;
662 unsigned g = (tg + g1 ) & 0x07E0;
667 int r1 = red(p1), r2 = red(p2);
668 int g1 = green(p1), g2 = green(p2);
669 int b1 = blue(p1), b2 = blue(p2);
672 int r = ((r2 - r1) * x) / 256 + r1;
673 int g = ((g2 - g1) * x) / 256 + g1;
674 int b = ((b2 - b1) * x) / 256 + b1;
680 template <
typename Pixel>
683 if (
sizeof(
Pixel) == 2) {
685 return (p1 == 0x0001) ? p2 : p1;
687 unsigned a = alpha(p1);
690 return lerp(p2, p1, a);