update dev300-m58
[ooovba.git] / agg / inc / agg_pixfmt_rgb_packed.h
blob621c27e23662ba49cc752033cbb46ac9a5b109c1
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.3
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 //===============================================pixel_formats_rgb_packed
792 template<class Blender> class pixel_formats_rgb_packed
794 public:
795 typedef rendering_buffer::row_data row_data;
796 typedef typename Blender::color_type color_type;
797 typedef typename Blender::pixel_type pixel_type;
798 typedef typename color_type::value_type value_type;
799 typedef typename color_type::calc_type calc_type;
800 enum
802 base_shift = color_type::base_shift,
803 base_size = color_type::base_size,
804 base_mask = color_type::base_mask
807 private:
808 //--------------------------------------------------------------------
809 AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
811 if (c.a)
813 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
814 if(alpha == base_mask)
816 *p = m_blender.make_pix(c.r, c.g, c.b);
818 else
820 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
825 //--------------------------------------------------------------------
826 AGG_INLINE void copy_or_blend_opaque_pix(pixel_type* p, const color_type& c, unsigned cover)
828 if(cover == 255)
830 *p = m_blender.make_pix(c.r, c.g, c.b);
832 else
834 m_blender.blend_pix(p, c.r, c.g, c.b, (cover + 1) << (base_shift - 8), cover);
839 public:
840 //--------------------------------------------------------------------
841 pixel_formats_rgb_packed(rendering_buffer& rb) :
842 m_rbuf(&rb)
845 //--------------------------------------------------------------------
846 Blender& blender() { return m_blender; }
848 //--------------------------------------------------------------------
849 AGG_INLINE unsigned width() const { return m_rbuf->width(); }
850 AGG_INLINE unsigned height() const { return m_rbuf->height(); }
852 //--------------------------------------------------------------------
853 AGG_INLINE color_type pixel(int x, int y) const
855 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
856 return m_blender.make_color(((pixel_type*)m_rbuf->row(y))[x]);
859 //--------------------------------------------------------------------
860 row_data span(int x, int y) const
862 return row_data(x,
863 width() - 1,
864 m_rbuf->row(y) + x * sizeof(pixel_type));
867 //--------------------------------------------------------------------
868 AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
870 ((pixel_type*)m_rbuf->row(y))[x] = m_blender.make_pix(c.r, c.g, c.b);
873 //--------------------------------------------------------------------
874 AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
876 copy_or_blend_pix((pixel_type*)m_rbuf->row(y) + x, c, cover);
880 //--------------------------------------------------------------------
881 AGG_INLINE void copy_hline(int x, int y,
882 unsigned len,
883 const color_type& c)
885 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
886 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
889 *p++ = v;
891 while(--len);
895 //--------------------------------------------------------------------
896 AGG_INLINE void copy_vline(int x, int y,
897 unsigned len,
898 const color_type& c)
900 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
901 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
904 *p = v;
905 p = (pixel_type*)m_rbuf->next_row(p);
907 while(--len);
911 //--------------------------------------------------------------------
912 void blend_hline(int x, int y,
913 unsigned len,
914 const color_type& c,
915 int8u cover)
917 if (c.a)
919 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
920 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
921 if(alpha == base_mask)
923 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
926 *p++ = v;
928 while(--len);
930 else
934 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
935 ++p;
937 while(--len);
943 //--------------------------------------------------------------------
944 void blend_vline(int x, int y,
945 unsigned len,
946 const color_type& c,
947 int8u cover)
949 if (c.a)
951 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
952 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
953 if(alpha == base_mask)
955 pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
958 *p = v;
959 p = (pixel_type*)m_rbuf->next_row(p);
961 while(--len);
963 else
967 m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
968 p = (pixel_type*)m_rbuf->next_row(p);
970 while(--len);
976 //--------------------------------------------------------------------
977 void blend_solid_hspan(int x, int y,
978 unsigned len,
979 const color_type& c,
980 const int8u* covers)
982 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
985 copy_or_blend_pix(p, c, *covers++);
986 ++p;
988 while(--len);
992 //--------------------------------------------------------------------
993 void blend_solid_vspan(int x, int y,
994 unsigned len,
995 const color_type& c,
996 const int8u* covers)
998 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
1001 copy_or_blend_pix(p, c, *covers++);
1002 p = (pixel_type*)m_rbuf->next_row(p);
1004 while(--len);
1008 //--------------------------------------------------------------------
1009 void blend_color_hspan(int x, int y,
1010 unsigned len,
1011 const color_type* colors,
1012 const int8u* covers,
1013 int8u cover)
1015 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
1018 copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover);
1020 while(--len);
1024 //--------------------------------------------------------------------
1025 void blend_color_vspan(int x, int y,
1026 unsigned len,
1027 const color_type* colors,
1028 const int8u* covers,
1029 int8u cover)
1031 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
1034 copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
1035 p = (pixel_type*)m_rbuf->next_row(p);
1037 while(--len);
1041 //--------------------------------------------------------------------
1042 void blend_opaque_color_hspan(int x, int y,
1043 unsigned len,
1044 const color_type* colors,
1045 const int8u* covers,
1046 int8u cover)
1048 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
1049 if(covers)
1053 copy_or_blend_opaque_pix(p++, *colors++, *covers++);
1055 while(--len);
1057 else
1059 if(cover == 255)
1063 *p++ = m_blender.make_pix(colors->r, colors->g, colors->b);
1064 ++colors;
1066 while(--len);
1068 else
1072 copy_or_blend_opaque_pix(p++, *colors++, cover);
1074 while(--len);
1080 //--------------------------------------------------------------------
1081 void blend_opaque_color_vspan(int x, int y,
1082 unsigned len,
1083 const color_type* colors,
1084 const int8u* covers,
1085 int8u cover)
1087 pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
1088 if(covers)
1092 copy_or_blend_opaque_pix(p, *colors++, *covers++);
1093 p = (pixel_type*)m_rbuf->next_row(p);
1095 while(--len);
1097 else
1099 if(cover == 255)
1103 *p = m_blender.make_pix(colors->r, colors->g, colors->b);
1104 p = (value_type*)m_rbuf->next_row(p);
1105 ++colors;
1107 while(--len);
1109 else
1113 copy_or_blend_opaque_pix(p, *colors++, cover);
1114 p = (value_type*)m_rbuf->next_row(p);
1116 while(--len);
1122 //--------------------------------------------------------------------
1123 void copy_from(const rendering_buffer& from,
1124 int xdst, int ydst,
1125 int xsrc, int ysrc,
1126 unsigned len)
1128 memmove((pixel_type*)m_rbuf->row(ydst) + xdst,
1129 (pixel_type*)from.row(ysrc) + xsrc,
1130 sizeof(pixel_type) * len);
1134 //--------------------------------------------------------------------
1135 template<class SrcPixelFormatRenderer>
1136 void blend_from(const SrcPixelFormatRenderer& from,
1137 const int8u* psrc_,
1138 int xdst, int ydst,
1139 int xsrc, int ysrc,
1140 unsigned len)
1142 typedef typename SrcPixelFormatRenderer::order_type src_order;
1144 const value_type* psrc = (const value_type*)psrc_;
1145 pixel_type* pdst = (pixel_type*)m_rbuf->row(ydst) + xdst;
1148 value_type alpha = psrc[src_order::A];
1149 if(alpha)
1151 if(alpha == base_mask)
1153 *pdst = m_blender.make_pix(psrc[src_order::R],
1154 psrc[src_order::G],
1155 psrc[src_order::B]);
1157 else
1159 m_blender.blend_pix(pdst,
1160 psrc[src_order::R],
1161 psrc[src_order::G],
1162 psrc[src_order::B],
1163 alpha,
1164 255);
1167 psrc += 4;
1168 ++pdst;
1170 while(--len);
1174 private:
1175 rendering_buffer* m_rbuf;
1176 Blender m_blender;
1179 typedef pixel_formats_rgb_packed<blender_rgb555> pixfmt_rgb555; //----pixfmt_rgb555
1180 typedef pixel_formats_rgb_packed<blender_rgb565> pixfmt_rgb565; //----pixfmt_rgb565
1182 typedef pixel_formats_rgb_packed<blender_rgb555_pre> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
1183 typedef pixel_formats_rgb_packed<blender_rgb565_pre> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre
1185 typedef pixel_formats_rgb_packed<blender_rgbAAA> pixfmt_rgbAAA; //----pixfmt_rgbAAA
1186 typedef pixel_formats_rgb_packed<blender_bgrAAA> pixfmt_bgrAAA; //----pixfmt_bgrAAA
1187 typedef pixel_formats_rgb_packed<blender_rgbBBA> pixfmt_rgbBBA; //----pixfmt_rgbBBA
1188 typedef pixel_formats_rgb_packed<blender_bgrABB> pixfmt_bgrABB; //----pixfmt_bgrABB
1190 typedef pixel_formats_rgb_packed<blender_rgbAAA_pre> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre
1191 typedef pixel_formats_rgb_packed<blender_bgrAAA_pre> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre
1192 typedef pixel_formats_rgb_packed<blender_rgbBBA_pre> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre
1193 typedef pixel_formats_rgb_packed<blender_bgrABB_pre> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre
1196 //-----------------------------------------------------pixfmt_rgb555_gamma
1197 template<class Gamma> class pixfmt_rgb555_gamma :
1198 public pixel_formats_rgb_packed<blender_rgb555_gamma<Gamma> >
1200 public:
1201 pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) :
1202 pixel_formats_rgb_packed<blender_rgb555_gamma<Gamma> >(rb)
1204 this->blender().gamma(g);
1209 //-----------------------------------------------------pixfmt_rgb565_gamma
1210 template<class Gamma> class pixfmt_rgb565_gamma :
1211 public pixel_formats_rgb_packed<blender_rgb565_gamma<Gamma> >
1213 public:
1214 pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) :
1215 pixel_formats_rgb_packed<blender_rgb565_gamma<Gamma> >(rb)
1217 this->blender().gamma(g);
1222 //-----------------------------------------------------pixfmt_rgbAAA_gamma
1223 template<class Gamma> class pixfmt_rgbAAA_gamma :
1224 public pixel_formats_rgb_packed<blender_rgbAAA_gamma<Gamma> >
1226 public:
1227 pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1228 pixel_formats_rgb_packed<blender_rgbAAA_gamma<Gamma> >(rb)
1230 this->blender().gamma(g);
1235 //-----------------------------------------------------pixfmt_bgrAAA_gamma
1236 template<class Gamma> class pixfmt_bgrAAA_gamma :
1237 public pixel_formats_rgb_packed<blender_bgrAAA_gamma<Gamma> >
1239 public:
1240 pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1241 pixel_formats_rgb_packed<blender_bgrAAA_gamma<Gamma> >(rb)
1243 this->blender().gamma(g);
1248 //-----------------------------------------------------pixfmt_rgbBBA_gamma
1249 template<class Gamma> class pixfmt_rgbBBA_gamma :
1250 public pixel_formats_rgb_packed<blender_rgbBBA_gamma<Gamma> >
1252 public:
1253 pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) :
1254 pixel_formats_rgb_packed<blender_rgbBBA_gamma<Gamma> >(rb)
1256 this->blender().gamma(g);
1261 //-----------------------------------------------------pixfmt_bgrABB_gamma
1262 template<class Gamma> class pixfmt_bgrABB_gamma :
1263 public pixel_formats_rgb_packed<blender_bgrABB_gamma<Gamma> >
1265 public:
1266 pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) :
1267 pixel_formats_rgb_packed<blender_bgrABB_gamma<Gamma> >(rb)
1269 this->blender().gamma(g);
1276 #endif