Make UEFI boot-platform build again
[haiku.git] / headers / libs / agg / agg_pixfmt_rgb_packed.h
blob7868085250f9c8877039da68a92b4b453990e48c
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
24 #ifndef AGG_PIXFMT_RGB_PACKED_INCLUDED
25 #define AGG_PIXFMT_RGB_PACKED_INCLUDED
27 #include <string.h>
28 #include "agg_basics.h"
29 #include "agg_color_rgba.h"
30 #include "agg_rendering_buffer.h"
32 namespace agg
34 //=========================================================blender_rgb555
35 struct blender_rgb555
37 typedef rgba8 color_type;
38 typedef color_type::value_type value_type;
39 typedef color_type::calc_type calc_type;
40 typedef int16u pixel_type;
42 static AGG_INLINE void blend_pix(pixel_type* p,
43 unsigned cr, unsigned cg, unsigned cb,
44 unsigned alpha,
45 unsigned)
47 pixel_type rgb = *p;
48 calc_type r = (rgb >> 7) & 0xF8;
49 calc_type g = (rgb >> 2) & 0xF8;
50 calc_type b = (rgb << 3) & 0xF8;
51 *p = (pixel_type)
52 (((((cr - r) * alpha + (r << 8)) >> 1) & 0x7C00) |
53 ((((cg - g) * alpha + (g << 8)) >> 6) & 0x03E0) |
54 (((cb - b) * alpha + (b << 8)) >> 11) | 0x8000);
57 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
59 return (pixel_type)(((r & 0xF8) << 7) |
60 ((g & 0xF8) << 2) |
61 (b >> 3) | 0x8000);
64 static AGG_INLINE color_type make_color(pixel_type p)
66 return color_type((p >> 7) & 0xF8,
67 (p >> 2) & 0xF8,
68 (p << 3) & 0xF8);
73 //=====================================================blender_rgb555_pre
74 struct blender_rgb555_pre
76 typedef rgba8 color_type;
77 typedef color_type::value_type value_type;
78 typedef color_type::calc_type calc_type;
79 typedef int16u pixel_type;
81 static AGG_INLINE void blend_pix(pixel_type* p,
82 unsigned cr, unsigned cg, unsigned cb,
83 unsigned alpha,
84 unsigned cover)
86 alpha = color_type::base_mask - alpha;
87 pixel_type rgb = *p;
88 calc_type r = (rgb >> 7) & 0xF8;
89 calc_type g = (rgb >> 2) & 0xF8;
90 calc_type b = (rgb << 3) & 0xF8;
91 *p = (pixel_type)
92 ((((r * alpha + cr * cover) >> 1) & 0x7C00) |
93 (((g * alpha + cg * cover) >> 6) & 0x03E0) |
94 ((b * alpha + cb * cover) >> 11) | 0x8000);
97 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
99 return (pixel_type)(((r & 0xF8) << 7) |
100 ((g & 0xF8) << 2) |
101 (b >> 3) | 0x8000);
104 static AGG_INLINE color_type make_color(pixel_type p)
106 return color_type((p >> 7) & 0xF8,
107 (p >> 2) & 0xF8,
108 (p << 3) & 0xF8);
115 //=====================================================blender_rgb555_gamma
116 template<class Gamma> class blender_rgb555_gamma
118 public:
119 typedef rgba8 color_type;
120 typedef color_type::value_type value_type;
121 typedef color_type::calc_type calc_type;
122 typedef int16u pixel_type;
123 typedef Gamma gamma_type;
125 blender_rgb555_gamma() : m_gamma(0) {}
126 void gamma(const gamma_type& g) { m_gamma = &g; }
128 AGG_INLINE void blend_pix(pixel_type* p,
129 unsigned cr, unsigned cg, unsigned cb,
130 unsigned alpha,
131 unsigned)
133 pixel_type rgb = *p;
134 calc_type r = m_gamma->dir((rgb >> 7) & 0xF8);
135 calc_type g = m_gamma->dir((rgb >> 2) & 0xF8);
136 calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
137 *p = (pixel_type)
138 (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 7) & 0x7C00) |
139 ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 2) & 0x03E0) |
140 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3) | 0x8000);
143 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
145 return (pixel_type)(((r & 0xF8) << 7) |
146 ((g & 0xF8) << 2) |
147 (b >> 3) | 0x8000);
150 static AGG_INLINE color_type make_color(pixel_type p)
152 return color_type((p >> 7) & 0xF8,
153 (p >> 2) & 0xF8,
154 (p << 3) & 0xF8);
157 private:
158 const Gamma* m_gamma;
165 //=========================================================blender_rgb565
166 struct blender_rgb565
168 typedef rgba8 color_type;
169 typedef color_type::value_type value_type;
170 typedef color_type::calc_type calc_type;
171 typedef int16u pixel_type;
173 static AGG_INLINE void blend_pix(pixel_type* p,
174 unsigned cr, unsigned cg, unsigned cb,
175 unsigned alpha,
176 unsigned)
178 pixel_type rgb = *p;
179 calc_type r = (rgb >> 8) & 0xF8;
180 calc_type g = (rgb >> 3) & 0xFC;
181 calc_type b = (rgb << 3) & 0xF8;
182 *p = (pixel_type)
183 (((((cr - r) * alpha + (r << 8)) ) & 0xF800) |
184 ((((cg - g) * alpha + (g << 8)) >> 5) & 0x07E0) |
185 (((cb - b) * alpha + (b << 8)) >> 11));
188 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
190 return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
193 static AGG_INLINE color_type make_color(pixel_type p)
195 return color_type((p >> 8) & 0xF8,
196 (p >> 3) & 0xFC,
197 (p << 3) & 0xF8);
203 //=====================================================blender_rgb565_pre
204 struct blender_rgb565_pre
206 typedef rgba8 color_type;
207 typedef color_type::value_type value_type;
208 typedef color_type::calc_type calc_type;
209 typedef int16u pixel_type;
211 static AGG_INLINE void blend_pix(pixel_type* p,
212 unsigned cr, unsigned cg, unsigned cb,
213 unsigned alpha,
214 unsigned cover)
216 alpha = color_type::base_mask - alpha;
217 pixel_type rgb = *p;
218 calc_type r = (rgb >> 8) & 0xF8;
219 calc_type g = (rgb >> 3) & 0xFC;
220 calc_type b = (rgb << 3) & 0xF8;
221 *p = (pixel_type)
222 ((((r * alpha + cr * cover) ) & 0xF800) |
223 (((g * alpha + cg * cover) >> 5 ) & 0x07E0) |
224 ((b * alpha + cb * cover) >> 11));
227 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
229 return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
232 static AGG_INLINE color_type make_color(pixel_type p)
234 return color_type((p >> 8) & 0xF8,
235 (p >> 3) & 0xFC,
236 (p << 3) & 0xF8);
242 //=====================================================blender_rgb565_gamma
243 template<class Gamma> class blender_rgb565_gamma
245 public:
246 typedef rgba8 color_type;
247 typedef color_type::value_type value_type;
248 typedef color_type::calc_type calc_type;
249 typedef int16u pixel_type;
250 typedef Gamma gamma_type;
252 blender_rgb565_gamma() : m_gamma(0) {}
253 void gamma(const gamma_type& g) { m_gamma = &g; }
255 AGG_INLINE void blend_pix(pixel_type* p,
256 unsigned cr, unsigned cg, unsigned cb,
257 unsigned alpha,
258 unsigned)
260 pixel_type rgb = *p;
261 calc_type r = m_gamma->dir((rgb >> 8) & 0xF8);
262 calc_type g = m_gamma->dir((rgb >> 3) & 0xFC);
263 calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
264 *p = (pixel_type)
265 (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 8) & 0xF800) |
266 ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 3) & 0x07E0) |
267 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3));
270 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
272 return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
275 static AGG_INLINE color_type make_color(pixel_type p)
277 return color_type((p >> 8) & 0xF8,
278 (p >> 3) & 0xFC,
279 (p << 3) & 0xF8);
282 private:
283 const Gamma* m_gamma;
288 //=====================================================blender_rgbAAA
289 struct blender_rgbAAA
291 typedef rgba16 color_type;
292 typedef color_type::value_type value_type;
293 typedef color_type::calc_type calc_type;
294 typedef int32u pixel_type;
296 static AGG_INLINE void blend_pix(pixel_type* p,
297 unsigned cr, unsigned cg, unsigned cb,
298 unsigned alpha,
299 unsigned)
301 pixel_type rgb = *p;
302 calc_type r = (rgb >> 14) & 0xFFC0;
303 calc_type g = (rgb >> 4) & 0xFFC0;
304 calc_type b = (rgb << 6) & 0xFFC0;
305 *p = (pixel_type)
306 (((((cr - r) * alpha + (r << 16)) >> 2) & 0x3FF00000) |
307 ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
308 (((cb - b) * alpha + (b << 16)) >> 22) | 0xC0000000);
311 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
313 return (pixel_type)(((r & 0xFFC0) << 14) |
314 ((g & 0xFFC0) << 4) |
315 (b >> 6) | 0xC0000000);
318 static AGG_INLINE color_type make_color(pixel_type p)
320 return color_type((p >> 14) & 0xFFC0,
321 (p >> 4) & 0xFFC0,
322 (p << 6) & 0xFFC0);
328 //==================================================blender_rgbAAA_pre
329 struct blender_rgbAAA_pre
331 typedef rgba16 color_type;
332 typedef color_type::value_type value_type;
333 typedef color_type::calc_type calc_type;
334 typedef int32u pixel_type;
336 static AGG_INLINE void blend_pix(pixel_type* p,
337 unsigned cr, unsigned cg, unsigned cb,
338 unsigned alpha,
339 unsigned cover)
341 alpha = color_type::base_mask - alpha;
342 cover = (cover + 1) << (color_type::base_shift - 8);
343 pixel_type rgb = *p;
344 calc_type r = (rgb >> 14) & 0xFFC0;
345 calc_type g = (rgb >> 4) & 0xFFC0;
346 calc_type b = (rgb << 6) & 0xFFC0;
347 *p = (pixel_type)
348 ((((r * alpha + cr * cover) >> 2) & 0x3FF00000) |
349 (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
350 ((b * alpha + cb * cover) >> 22) | 0xC0000000);
353 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
355 return (pixel_type)(((r & 0xFFC0) << 14) |
356 ((g & 0xFFC0) << 4) |
357 (b >> 6) | 0xC0000000);
360 static AGG_INLINE color_type make_color(pixel_type p)
362 return color_type((p >> 14) & 0xFFC0,
363 (p >> 4) & 0xFFC0,
364 (p << 6) & 0xFFC0);
370 //=================================================blender_rgbAAA_gamma
371 template<class Gamma> class blender_rgbAAA_gamma
373 public:
374 typedef rgba16 color_type;
375 typedef color_type::value_type value_type;
376 typedef color_type::calc_type calc_type;
377 typedef int32u pixel_type;
378 typedef Gamma gamma_type;
380 blender_rgbAAA_gamma() : m_gamma(0) {}
381 void gamma(const gamma_type& g) { m_gamma = &g; }
383 AGG_INLINE void blend_pix(pixel_type* p,
384 unsigned cr, unsigned cg, unsigned cb,
385 unsigned alpha,
386 unsigned)
388 pixel_type rgb = *p;
389 calc_type r = m_gamma->dir((rgb >> 14) & 0xFFC0);
390 calc_type g = m_gamma->dir((rgb >> 4) & 0xFFC0);
391 calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0);
392 *p = (pixel_type)
393 (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 14) & 0x3FF00000) |
394 ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
395 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ) | 0xC0000000);
398 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
400 return (pixel_type)(((r & 0xFFC0) << 14) |
401 ((g & 0xFFC0) << 4) |
402 (b >> 6) | 0xC0000000);
405 static AGG_INLINE color_type make_color(pixel_type p)
407 return color_type((p >> 14) & 0xFFC0,
408 (p >> 4) & 0xFFC0,
409 (p << 6) & 0xFFC0);
411 private:
412 const Gamma* m_gamma;
416 //=====================================================blender_bgrAAA
417 struct blender_bgrAAA
419 typedef rgba16 color_type;
420 typedef color_type::value_type value_type;
421 typedef color_type::calc_type calc_type;
422 typedef int32u pixel_type;
424 static AGG_INLINE void blend_pix(pixel_type* p,
425 unsigned cr, unsigned cg, unsigned cb,
426 unsigned alpha,
427 unsigned)
429 pixel_type bgr = *p;
430 calc_type b = (bgr >> 14) & 0xFFC0;
431 calc_type g = (bgr >> 4) & 0xFFC0;
432 calc_type r = (bgr << 6) & 0xFFC0;
433 *p = (pixel_type)
434 (((((cb - b) * alpha + (b << 16)) >> 2) & 0x3FF00000) |
435 ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
436 (((cr - r) * alpha + (r << 16)) >> 22) | 0xC0000000);
439 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
441 return (pixel_type)(((b & 0xFFC0) << 14) |
442 ((g & 0xFFC0) << 4) |
443 (r >> 6) | 0xC0000000);
446 static AGG_INLINE color_type make_color(pixel_type p)
448 return color_type((p << 6) & 0xFFC0,
449 (p >> 4) & 0xFFC0,
450 (p >> 14) & 0xFFC0);
456 //=================================================blender_bgrAAA_pre
457 struct blender_bgrAAA_pre
459 typedef rgba16 color_type;
460 typedef color_type::value_type value_type;
461 typedef color_type::calc_type calc_type;
462 typedef int32u pixel_type;
464 static AGG_INLINE void blend_pix(pixel_type* p,
465 unsigned cr, unsigned cg, unsigned cb,
466 unsigned alpha,
467 unsigned cover)
469 alpha = color_type::base_mask - alpha;
470 cover = (cover + 1) << (color_type::base_shift - 8);
471 pixel_type bgr = *p;
472 calc_type b = (bgr >> 14) & 0xFFC0;
473 calc_type g = (bgr >> 4) & 0xFFC0;
474 calc_type r = (bgr << 6) & 0xFFC0;
475 *p = (pixel_type)
476 ((((b * alpha + cb * cover) >> 2) & 0x3FF00000) |
477 (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
478 ((r * alpha + cr * cover) >> 22) | 0xC0000000);
481 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
483 return (pixel_type)(((b & 0xFFC0) << 14) |
484 ((g & 0xFFC0) << 4) |
485 (r >> 6) | 0xC0000000);
488 static AGG_INLINE color_type make_color(pixel_type p)
490 return color_type((p << 6) & 0xFFC0,
491 (p >> 4) & 0xFFC0,
492 (p >> 14) & 0xFFC0);
498 //=================================================blender_bgrAAA_gamma
499 template<class Gamma> class blender_bgrAAA_gamma
501 public:
502 typedef rgba16 color_type;
503 typedef color_type::value_type value_type;
504 typedef color_type::calc_type calc_type;
505 typedef int32u pixel_type;
506 typedef Gamma gamma_type;
508 blender_bgrAAA_gamma() : m_gamma(0) {}
509 void gamma(const gamma_type& g) { m_gamma = &g; }
511 AGG_INLINE void blend_pix(pixel_type* p,
512 unsigned cr, unsigned cg, unsigned cb,
513 unsigned alpha,
514 unsigned)
516 pixel_type bgr = *p;
517 calc_type b = m_gamma->dir((bgr >> 14) & 0xFFC0);
518 calc_type g = m_gamma->dir((bgr >> 4) & 0xFFC0);
519 calc_type r = m_gamma->dir((bgr << 6) & 0xFFC0);
520 *p = (pixel_type)
521 (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 14) & 0x3FF00000) |
522 ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
523 (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 6 ) | 0xC0000000);
526 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
528 return (pixel_type)(((b & 0xFFC0) << 14) |
529 ((g & 0xFFC0) << 4) |
530 (r >> 6) | 0xC0000000);
533 static AGG_INLINE color_type make_color(pixel_type p)
535 return color_type((p << 6) & 0xFFC0,
536 (p >> 4) & 0xFFC0,
537 (p >> 14) & 0xFFC0);
540 private:
541 const Gamma* m_gamma;
546 //=====================================================blender_rgbBBA
547 struct blender_rgbBBA
549 typedef rgba16 color_type;
550 typedef color_type::value_type value_type;
551 typedef color_type::calc_type calc_type;
552 typedef int32u pixel_type;
554 static AGG_INLINE void blend_pix(pixel_type* p,
555 unsigned cr, unsigned cg, unsigned cb,
556 unsigned alpha,
557 unsigned)
559 pixel_type rgb = *p;
560 calc_type r = (rgb >> 16) & 0xFFE0;
561 calc_type g = (rgb >> 5) & 0xFFE0;
562 calc_type b = (rgb << 6) & 0xFFC0;
563 *p = (pixel_type)
564 (((((cr - r) * alpha + (r << 16)) ) & 0xFFE00000) |
565 ((((cg - g) * alpha + (g << 16)) >> 11) & 0x001FFC00) |
566 (((cb - b) * alpha + (b << 16)) >> 22));
569 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
571 return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
574 static AGG_INLINE color_type make_color(pixel_type p)
576 return color_type((p >> 16) & 0xFFE0,
577 (p >> 5) & 0xFFE0,
578 (p << 6) & 0xFFC0);
583 //=================================================blender_rgbBBA_pre
584 struct blender_rgbBBA_pre
586 typedef rgba16 color_type;
587 typedef color_type::value_type value_type;
588 typedef color_type::calc_type calc_type;
589 typedef int32u pixel_type;
591 static AGG_INLINE void blend_pix(pixel_type* p,
592 unsigned cr, unsigned cg, unsigned cb,
593 unsigned alpha,
594 unsigned cover)
596 alpha = color_type::base_mask - alpha;
597 cover = (cover + 1) << (color_type::base_shift - 8);
598 pixel_type rgb = *p;
599 calc_type r = (rgb >> 16) & 0xFFE0;
600 calc_type g = (rgb >> 5) & 0xFFE0;
601 calc_type b = (rgb << 6) & 0xFFC0;
602 *p = (pixel_type)
603 ((((r * alpha + cr * cover) ) & 0xFFE00000) |
604 (((g * alpha + cg * cover) >> 11) & 0x001FFC00) |
605 ((b * alpha + cb * cover) >> 22));
608 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
610 return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
613 static AGG_INLINE color_type make_color(pixel_type p)
615 return color_type((p >> 16) & 0xFFE0,
616 (p >> 5) & 0xFFE0,
617 (p << 6) & 0xFFC0);
623 //=================================================blender_rgbBBA_gamma
624 template<class Gamma> class blender_rgbBBA_gamma
626 public:
627 typedef rgba16 color_type;
628 typedef color_type::value_type value_type;
629 typedef color_type::calc_type calc_type;
630 typedef int32u pixel_type;
631 typedef Gamma gamma_type;
633 blender_rgbBBA_gamma() : m_gamma(0) {}
634 void gamma(const gamma_type& g) { m_gamma = &g; }
636 AGG_INLINE void blend_pix(pixel_type* p,
637 unsigned cr, unsigned cg, unsigned cb,
638 unsigned alpha,
639 unsigned)
641 pixel_type rgb = *p;
642 calc_type r = m_gamma->dir((rgb >> 16) & 0xFFE0);
643 calc_type g = m_gamma->dir((rgb >> 5) & 0xFFE0);
644 calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0);
645 *p = (pixel_type)
646 (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 16) & 0xFFE00000) |
647 ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 5 ) & 0x001FFC00) |
648 (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ));
651 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
653 return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
656 static AGG_INLINE color_type make_color(pixel_type p)
658 return color_type((p >> 16) & 0xFFE0,
659 (p >> 5) & 0xFFE0,
660 (p << 6) & 0xFFC0);
663 private:
664 const Gamma* m_gamma;
668 //=====================================================blender_bgrABB
669 struct blender_bgrABB
671 typedef rgba16 color_type;
672 typedef color_type::value_type value_type;
673 typedef color_type::calc_type calc_type;
674 typedef int32u pixel_type;
676 static AGG_INLINE void blend_pix(pixel_type* p,
677 unsigned cr, unsigned cg, unsigned cb,
678 unsigned alpha,
679 unsigned)
681 pixel_type bgr = *p;
682 calc_type b = (bgr >> 16) & 0xFFC0;
683 calc_type g = (bgr >> 6) & 0xFFE0;
684 calc_type r = (bgr << 5) & 0xFFE0;
685 *p = (pixel_type)
686 (((((cb - b) * alpha + (b << 16)) ) & 0xFFC00000) |
687 ((((cg - g) * alpha + (g << 16)) >> 10) & 0x003FF800) |
688 (((cr - r) * alpha + (r << 16)) >> 21));
691 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
693 return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
696 static AGG_INLINE color_type make_color(pixel_type p)
698 return color_type((p << 5) & 0xFFE0,
699 (p >> 6) & 0xFFE0,
700 (p >> 16) & 0xFFC0);
705 //=================================================blender_bgrABB_pre
706 struct blender_bgrABB_pre
708 typedef rgba16 color_type;
709 typedef color_type::value_type value_type;
710 typedef color_type::calc_type calc_type;
711 typedef int32u pixel_type;
713 static AGG_INLINE void blend_pix(pixel_type* p,
714 unsigned cr, unsigned cg, unsigned cb,
715 unsigned alpha,
716 unsigned cover)
718 alpha = color_type::base_mask - alpha;
719 cover = (cover + 1) << (color_type::base_shift - 8);
720 pixel_type bgr = *p;
721 calc_type b = (bgr >> 16) & 0xFFC0;
722 calc_type g = (bgr >> 6) & 0xFFE0;
723 calc_type r = (bgr << 5) & 0xFFE0;
724 *p = (pixel_type)
725 ((((b * alpha + cb * cover) ) & 0xFFC00000) |
726 (((g * alpha + cg * cover) >> 10) & 0x003FF800) |
727 ((r * alpha + cr * cover) >> 21));
730 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
732 return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
735 static AGG_INLINE color_type make_color(pixel_type p)
737 return color_type((p << 5) & 0xFFE0,
738 (p >> 6) & 0xFFE0,
739 (p >> 16) & 0xFFC0);
745 //=================================================blender_bgrABB_gamma
746 template<class Gamma> class blender_bgrABB_gamma
748 public:
749 typedef rgba16 color_type;
750 typedef color_type::value_type value_type;
751 typedef color_type::calc_type calc_type;
752 typedef int32u pixel_type;
753 typedef Gamma gamma_type;
755 blender_bgrABB_gamma() : m_gamma(0) {}
756 void gamma(const gamma_type& g) { m_gamma = &g; }
758 AGG_INLINE void blend_pix(pixel_type* p,
759 unsigned cr, unsigned cg, unsigned cb,
760 unsigned alpha,
761 unsigned)
763 pixel_type bgr = *p;
764 calc_type b = m_gamma->dir((bgr >> 16) & 0xFFC0);
765 calc_type g = m_gamma->dir((bgr >> 6) & 0xFFE0);
766 calc_type r = m_gamma->dir((bgr << 5) & 0xFFE0);
767 *p = (pixel_type)
768 (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 16) & 0xFFC00000) |
769 ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 6 ) & 0x003FF800) |
770 (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 5 ));
773 static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
775 return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
778 static AGG_INLINE color_type make_color(pixel_type p)
780 return color_type((p << 5) & 0xFFE0,
781 (p >> 6) & 0xFFE0,
782 (p >> 16) & 0xFFC0);
785 private:
786 const Gamma* m_gamma;
791 //===========================================pixfmt_alpha_blend_rgb_packed
792 template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb_packed
794 public:
795 typedef RenBuf rbuf_type;
796 typedef typename rbuf_type::row_data row_data;
797 typedef Blender blender_type;
798 typedef typename blender_type::color_type color_type;
799 typedef typename blender_type::pixel_type pixel_type;
800 typedef int order_type; // A fake one
801 typedef typename color_type::value_type value_type;
802 typedef typename color_type::calc_type calc_type;
803 enum base_scale_e
805 base_shift = color_type::base_shift,
806 base_scale = color_type::base_scale,
807 base_mask = color_type::base_mask,
808 pix_width = sizeof(pixel_type)
811 private:
812 //--------------------------------------------------------------------
813 AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
815 if (c.a)
817 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
818 if(alpha == base_mask)
820 *p = m_blender.make_pix(c.r, c.g, c.b);
822 else
824 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
829 public:
830 //--------------------------------------------------------------------
831 pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {}
832 void attach(rbuf_type& rb) { m_rbuf = &rb; }
834 //--------------------------------------------------------------------
835 template<class PixFmt>
836 bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
838 rect_i r(x1, y1, x2, y2);
839 if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
841 int stride = pixf.stride();
842 m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
843 (r.x2 - r.x1) + 1,
844 (r.y2 - r.y1) + 1,
845 stride);
846 return true;
848 return false;
851 Blender& blender() { return m_blender; }
853 //--------------------------------------------------------------------
854 AGG_INLINE unsigned width() const { return m_rbuf->width(); }
855 AGG_INLINE unsigned height() const { return m_rbuf->height(); }
856 AGG_INLINE int stride() const { return m_rbuf->stride(); }
858 //--------------------------------------------------------------------
859 AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
860 AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
861 AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
863 //--------------------------------------------------------------------
864 AGG_INLINE int8u* pix_ptr(int x, int y)
866 return m_rbuf->row_ptr(y) + x * pix_width;
869 AGG_INLINE const int8u* pix_ptr(int x, int y) const
871 return m_rbuf->row_ptr(y) + x * pix_width;
874 //--------------------------------------------------------------------
875 AGG_INLINE void make_pix(int8u* p, const color_type& c)
877 *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b);
880 //--------------------------------------------------------------------
881 AGG_INLINE color_type pixel(int x, int y) const
883 return m_blender.make_color(((pixel_type*)m_rbuf->row_ptr(y))[x]);
886 //--------------------------------------------------------------------
887 AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
889 ((pixel_type*)
890 m_rbuf->row_ptr(x, y, 1))[x] =
891 m_blender.make_pix(c.r, c.g, c.b);
894 //--------------------------------------------------------------------
895 AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
897 copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y, 1) + x, c, cover);
900 //--------------------------------------------------------------------
901 AGG_INLINE void copy_hline(int x, int y,
902 unsigned len,
903 const color_type& c)
905 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
906 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
909 *p++ = v;
911 while(--len);
914 //--------------------------------------------------------------------
915 AGG_INLINE void copy_vline(int x, int y,
916 unsigned len,
917 const color_type& c)
919 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
922 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
923 *p = v;
925 while(--len);
928 //--------------------------------------------------------------------
929 void blend_hline(int x, int y,
930 unsigned len,
931 const color_type& c,
932 int8u cover)
934 if (c.a)
936 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
937 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
938 if(alpha == base_mask)
940 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
943 *p++ = v;
945 while(--len);
947 else
951 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
952 ++p;
954 while(--len);
959 //--------------------------------------------------------------------
960 void blend_vline(int x, int y,
961 unsigned len,
962 const color_type& c,
963 int8u cover)
965 if (c.a)
967 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
968 if(alpha == base_mask)
970 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
973 ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v;
975 while(--len);
977 else
981 m_blender.blend_pix(
982 (pixel_type*)m_rbuf->row_ptr(x, y++, 1),
983 c.r, c.g, c.b, alpha, cover);
985 while(--len);
990 //--------------------------------------------------------------------
991 void blend_solid_hspan(int x, int y,
992 unsigned len,
993 const color_type& c,
994 const int8u* covers)
996 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
999 copy_or_blend_pix(p, c, *covers++);
1000 ++p;
1002 while(--len);
1005 //--------------------------------------------------------------------
1006 void blend_solid_vspan(int x, int y,
1007 unsigned len,
1008 const color_type& c,
1009 const int8u* covers)
1013 copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x,
1014 c, *covers++);
1016 while(--len);
1019 //--------------------------------------------------------------------
1020 void copy_color_hspan(int x, int y,
1021 unsigned len,
1022 const color_type* colors)
1024 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
1027 *p++ = m_blender.make_pix(colors->r, colors->g, colors->b);
1028 ++colors;
1030 while(--len);
1033 //--------------------------------------------------------------------
1034 void copy_color_vspan(int x, int y,
1035 unsigned len,
1036 const color_type* colors)
1040 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
1041 *p = m_blender.make_pix(colors->r, colors->g, colors->b);
1042 ++colors;
1044 while(--len);
1047 //--------------------------------------------------------------------
1048 void blend_color_hspan(int x, int y,
1049 unsigned len,
1050 const color_type* colors,
1051 const int8u* covers,
1052 int8u cover)
1054 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
1057 copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover);
1059 while(--len);
1062 //--------------------------------------------------------------------
1063 void blend_color_vspan(int x, int y,
1064 unsigned len,
1065 const color_type* colors,
1066 const int8u* covers,
1067 int8u cover)
1071 copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x,
1072 *colors++, covers ? *covers++ : cover);
1074 while(--len);
1077 //--------------------------------------------------------------------
1078 template<class RenBuf2>
1079 void copy_from(const RenBuf2& from,
1080 int xdst, int ydst,
1081 int xsrc, int ysrc,
1082 unsigned len)
1084 const int8u* p = from.row_ptr(ysrc);
1085 if(p)
1087 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
1088 p + xsrc * pix_width,
1089 len * pix_width);
1093 //--------------------------------------------------------------------
1094 template<class SrcPixelFormatRenderer>
1095 void blend_from(const SrcPixelFormatRenderer& from,
1096 int xdst, int ydst,
1097 int xsrc, int ysrc,
1098 unsigned len,
1099 int8u cover)
1101 typedef typename SrcPixelFormatRenderer::order_type src_order;
1103 const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
1104 if(psrc)
1106 psrc += xsrc * 4;
1107 pixel_type* pdst =
1108 (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
1111 value_type alpha = psrc[src_order::A];
1112 if(alpha)
1114 if(alpha == base_mask && cover == 255)
1116 *pdst = m_blender.make_pix(psrc[src_order::R],
1117 psrc[src_order::G],
1118 psrc[src_order::B]);
1120 else
1122 m_blender.blend_pix(pdst,
1123 psrc[src_order::R],
1124 psrc[src_order::G],
1125 psrc[src_order::B],
1126 alpha,
1127 cover);
1130 psrc += 4;
1131 ++pdst;
1133 while(--len);
1137 private:
1138 rbuf_type* m_rbuf;
1139 Blender m_blender;
1142 typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555, rendering_buffer> pixfmt_rgb555; //----pixfmt_rgb555
1143 typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565, rendering_buffer> pixfmt_rgb565; //----pixfmt_rgb565
1145 typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555_pre, rendering_buffer> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
1146 typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565_pre, rendering_buffer> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre
1148 typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA, rendering_buffer> pixfmt_rgbAAA; //----pixfmt_rgbAAA
1149 typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA, rendering_buffer> pixfmt_bgrAAA; //----pixfmt_bgrAAA
1150 typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA, rendering_buffer> pixfmt_rgbBBA; //----pixfmt_rgbBBA
1151 typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB, rendering_buffer> pixfmt_bgrABB; //----pixfmt_bgrABB
1153 typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_pre, rendering_buffer> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre
1154 typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_pre, rendering_buffer> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre
1155 typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_pre, rendering_buffer> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre
1156 typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB_pre, rendering_buffer> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre
1159 //-----------------------------------------------------pixfmt_rgb555_gamma
1160 template<class Gamma> class pixfmt_rgb555_gamma :
1161 public pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
1162 rendering_buffer>
1164 public:
1165 pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) :
1166 pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
1167 rendering_buffer>(rb)
1169 this->blender().gamma(g);
1174 //-----------------------------------------------------pixfmt_rgb565_gamma
1175 template<class Gamma> class pixfmt_rgb565_gamma :
1176 public pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>
1178 public:
1179 pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) :
1180 pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>(rb)
1182 this->blender().gamma(g);
1187 //-----------------------------------------------------pixfmt_rgbAAA_gamma
1188 template<class Gamma> class pixfmt_rgbAAA_gamma :
1189 public pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
1190 rendering_buffer>
1192 public:
1193 pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1194 pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
1195 rendering_buffer>(rb)
1197 this->blender().gamma(g);
1202 //-----------------------------------------------------pixfmt_bgrAAA_gamma
1203 template<class Gamma> class pixfmt_bgrAAA_gamma :
1204 public pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
1205 rendering_buffer>
1207 public:
1208 pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1209 pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
1210 rendering_buffer>(rb)
1212 this->blender().gamma(g);
1217 //-----------------------------------------------------pixfmt_rgbBBA_gamma
1218 template<class Gamma> class pixfmt_rgbBBA_gamma :
1219 public pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
1220 rendering_buffer>
1222 public:
1223 pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) :
1224 pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
1225 rendering_buffer>(rb)
1227 this->blender().gamma(g);
1232 //-----------------------------------------------------pixfmt_bgrABB_gamma
1233 template<class Gamma> class pixfmt_bgrABB_gamma :
1234 public pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
1235 rendering_buffer>
1237 public:
1238 pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) :
1239 pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
1240 rendering_buffer>(rb)
1242 this->blender().gamma(g);
1249 #endif