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 //----------------------------------------------------------------------------
15 //
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
18 //
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
23 
24 #ifndef AGG_PIXFMT_RGB_PACKED_INCLUDED
25 #define AGG_PIXFMT_RGB_PACKED_INCLUDED
26 
27 #include <string.h>
28 #include "agg_basics.h"
29 #include "agg_color_rgba.h"
30 #include "agg_rendering_buffer.h"
31 
32 namespace agg
33 {
34     //=========================================================blender_rgb555
35     struct blender_rgb555
36     {
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;
41 
blend_pixblender_rgb55542         static AGG_INLINE void blend_pix(pixel_type* p,
43                                          unsigned cr, unsigned cg, unsigned cb,
44                                          unsigned alpha,
45                                          unsigned)
46         {
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);
55         }
56 
make_pixblender_rgb55557         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
58         {
59             return (pixel_type)(((r & 0xF8) << 7) |
60                                 ((g & 0xF8) << 2) |
61                                  (b >> 3) | 0x8000);
62         }
63 
make_colorblender_rgb55564         static AGG_INLINE color_type make_color(pixel_type p)
65         {
66             return color_type((p >> 7) & 0xF8,
67                               (p >> 2) & 0xF8,
68                               (p << 3) & 0xF8);
69         }
70     };
71 
72 
73     //=====================================================blender_rgb555_pre
74     struct blender_rgb555_pre
75     {
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;
80 
blend_pixblender_rgb555_pre81         static AGG_INLINE void blend_pix(pixel_type* p,
82                                          unsigned cr, unsigned cg, unsigned cb,
83                                          unsigned alpha,
84                                          unsigned cover)
85         {
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);
95         }
96 
make_pixblender_rgb555_pre97         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
98         {
99             return (pixel_type)(((r & 0xF8) << 7) |
100                                 ((g & 0xF8) << 2) |
101                                  (b >> 3) | 0x8000);
102         }
103 
make_colorblender_rgb555_pre104         static AGG_INLINE color_type make_color(pixel_type p)
105         {
106             return color_type((p >> 7) & 0xF8,
107                               (p >> 2) & 0xF8,
108                               (p << 3) & 0xF8);
109         }
110     };
111 
112 
113 
114 
115     //=====================================================blender_rgb555_gamma
116     template<class Gamma> class blender_rgb555_gamma
117     {
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;
124 
blender_rgb555_gamma()125         blender_rgb555_gamma() : m_gamma(0) {}
gamma(const gamma_type & g)126         void gamma(const gamma_type& g) { m_gamma = &g; }
127 
blend_pix(pixel_type * p,unsigned cr,unsigned cg,unsigned cb,unsigned alpha,unsigned)128         AGG_INLINE void blend_pix(pixel_type* p,
129                                   unsigned cr, unsigned cg, unsigned cb,
130                                   unsigned alpha,
131                                   unsigned)
132         {
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);
141         }
142 
make_pix(unsigned r,unsigned g,unsigned b)143         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
144         {
145             return (pixel_type)(((r & 0xF8) << 7) |
146                                 ((g & 0xF8) << 2) |
147                                  (b >> 3) | 0x8000);
148         }
149 
make_color(pixel_type p)150         static AGG_INLINE color_type make_color(pixel_type p)
151         {
152             return color_type((p >> 7) & 0xF8,
153                               (p >> 2) & 0xF8,
154                               (p << 3) & 0xF8);
155         }
156 
157     private:
158         const Gamma* m_gamma;
159     };
160 
161 
162 
163 
164 
165     //=========================================================blender_rgb565
166     struct blender_rgb565
167     {
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;
172 
blend_pixblender_rgb565173         static AGG_INLINE void blend_pix(pixel_type* p,
174                                          unsigned cr, unsigned cg, unsigned cb,
175                                          unsigned alpha,
176                                          unsigned)
177         {
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));
186         }
187 
make_pixblender_rgb565188         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
189         {
190             return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
191         }
192 
make_colorblender_rgb565193         static AGG_INLINE color_type make_color(pixel_type p)
194         {
195             return color_type((p >> 8) & 0xF8,
196                               (p >> 3) & 0xFC,
197                               (p << 3) & 0xF8);
198         }
199     };
200 
201 
202 
203     //=====================================================blender_rgb565_pre
204     struct blender_rgb565_pre
205     {
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;
210 
blend_pixblender_rgb565_pre211         static AGG_INLINE void blend_pix(pixel_type* p,
212                                          unsigned cr, unsigned cg, unsigned cb,
213                                          unsigned alpha,
214                                          unsigned cover)
215         {
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));
225         }
226 
make_pixblender_rgb565_pre227         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
228         {
229             return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
230         }
231 
make_colorblender_rgb565_pre232         static AGG_INLINE color_type make_color(pixel_type p)
233         {
234             return color_type((p >> 8) & 0xF8,
235                               (p >> 3) & 0xFC,
236                               (p << 3) & 0xF8);
237         }
238     };
239 
240 
241 
242     //=====================================================blender_rgb565_gamma
243     template<class Gamma> class blender_rgb565_gamma
244     {
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;
251 
blender_rgb565_gamma()252         blender_rgb565_gamma() : m_gamma(0) {}
gamma(const gamma_type & g)253         void gamma(const gamma_type& g) { m_gamma = &g; }
254 
blend_pix(pixel_type * p,unsigned cr,unsigned cg,unsigned cb,unsigned alpha,unsigned)255         AGG_INLINE void blend_pix(pixel_type* p,
256                                   unsigned cr, unsigned cg, unsigned cb,
257                                   unsigned alpha,
258                                   unsigned)
259         {
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));
268         }
269 
make_pix(unsigned r,unsigned g,unsigned b)270         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
271         {
272             return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
273         }
274 
make_color(pixel_type p)275         static AGG_INLINE color_type make_color(pixel_type p)
276         {
277             return color_type((p >> 8) & 0xF8,
278                               (p >> 3) & 0xFC,
279                               (p << 3) & 0xF8);
280         }
281 
282     private:
283         const Gamma* m_gamma;
284     };
285 
286 
287 
288     //=====================================================blender_rgbAAA
289     struct blender_rgbAAA
290     {
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;
295 
blend_pixblender_rgbAAA296         static AGG_INLINE void blend_pix(pixel_type* p,
297                                          unsigned cr, unsigned cg, unsigned cb,
298                                          unsigned alpha,
299                                          unsigned)
300         {
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);
309         }
310 
make_pixblender_rgbAAA311         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
312         {
313             return (pixel_type)(((r & 0xFFC0) << 14) |
314                                 ((g & 0xFFC0) << 4) |
315                                  (b >> 6) | 0xC0000000);
316         }
317 
make_colorblender_rgbAAA318         static AGG_INLINE color_type make_color(pixel_type p)
319         {
320             return color_type((p >> 14) & 0xFFC0,
321                               (p >> 4)  & 0xFFC0,
322                               (p << 6)  & 0xFFC0);
323         }
324     };
325 
326 
327 
328     //==================================================blender_rgbAAA_pre
329     struct blender_rgbAAA_pre
330     {
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;
335 
blend_pixblender_rgbAAA_pre336         static AGG_INLINE void blend_pix(pixel_type* p,
337                                          unsigned cr, unsigned cg, unsigned cb,
338                                          unsigned alpha,
339                                          unsigned cover)
340         {
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);
351         }
352 
make_pixblender_rgbAAA_pre353         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
354         {
355             return (pixel_type)(((r & 0xFFC0) << 14) |
356                                 ((g & 0xFFC0) << 4) |
357                                  (b >> 6) | 0xC0000000);
358         }
359 
make_colorblender_rgbAAA_pre360         static AGG_INLINE color_type make_color(pixel_type p)
361         {
362             return color_type((p >> 14) & 0xFFC0,
363                               (p >> 4)  & 0xFFC0,
364                               (p << 6)  & 0xFFC0);
365         }
366     };
367 
368 
369 
370     //=================================================blender_rgbAAA_gamma
371     template<class Gamma> class blender_rgbAAA_gamma
372     {
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;
379 
blender_rgbAAA_gamma()380         blender_rgbAAA_gamma() : m_gamma(0) {}
gamma(const gamma_type & g)381         void gamma(const gamma_type& g) { m_gamma = &g; }
382 
blend_pix(pixel_type * p,unsigned cr,unsigned cg,unsigned cb,unsigned alpha,unsigned)383         AGG_INLINE void blend_pix(pixel_type* p,
384                                   unsigned cr, unsigned cg, unsigned cb,
385                                   unsigned alpha,
386                                   unsigned)
387         {
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);
396         }
397 
make_pix(unsigned r,unsigned g,unsigned b)398         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
399         {
400             return (pixel_type)(((r & 0xFFC0) << 14) |
401                                 ((g & 0xFFC0) << 4) |
402                                  (b >> 6) | 0xC0000000);
403         }
404 
make_color(pixel_type p)405         static AGG_INLINE color_type make_color(pixel_type p)
406         {
407             return color_type((p >> 14) & 0xFFC0,
408                               (p >> 4)  & 0xFFC0,
409                               (p << 6)  & 0xFFC0);
410         }
411     private:
412         const Gamma* m_gamma;
413     };
414 
415 
416     //=====================================================blender_bgrAAA
417     struct blender_bgrAAA
418     {
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;
423 
blend_pixblender_bgrAAA424         static AGG_INLINE void blend_pix(pixel_type* p,
425                                          unsigned cr, unsigned cg, unsigned cb,
426                                          unsigned alpha,
427                                          unsigned)
428         {
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);
437         }
438 
make_pixblender_bgrAAA439         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
440         {
441             return (pixel_type)(((b & 0xFFC0) << 14) |
442                                 ((g & 0xFFC0) << 4) |
443                                  (r >> 6) | 0xC0000000);
444         }
445 
make_colorblender_bgrAAA446         static AGG_INLINE color_type make_color(pixel_type p)
447         {
448             return color_type((p << 6)  & 0xFFC0,
449                               (p >> 4)  & 0xFFC0,
450                               (p >> 14) & 0xFFC0);
451         }
452     };
453 
454 
455 
456     //=================================================blender_bgrAAA_pre
457     struct blender_bgrAAA_pre
458     {
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;
463 
blend_pixblender_bgrAAA_pre464         static AGG_INLINE void blend_pix(pixel_type* p,
465                                          unsigned cr, unsigned cg, unsigned cb,
466                                          unsigned alpha,
467                                          unsigned cover)
468         {
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);
479         }
480 
make_pixblender_bgrAAA_pre481         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
482         {
483             return (pixel_type)(((b & 0xFFC0) << 14) |
484                                 ((g & 0xFFC0) << 4) |
485                                  (r >> 6) | 0xC0000000);
486         }
487 
make_colorblender_bgrAAA_pre488         static AGG_INLINE color_type make_color(pixel_type p)
489         {
490             return color_type((p << 6)  & 0xFFC0,
491                               (p >> 4)  & 0xFFC0,
492                               (p >> 14) & 0xFFC0);
493         }
494     };
495 
496 
497 
498     //=================================================blender_bgrAAA_gamma
499     template<class Gamma> class blender_bgrAAA_gamma
500     {
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;
507 
blender_bgrAAA_gamma()508         blender_bgrAAA_gamma() : m_gamma(0) {}
gamma(const gamma_type & g)509         void gamma(const gamma_type& g) { m_gamma = &g; }
510 
blend_pix(pixel_type * p,unsigned cr,unsigned cg,unsigned cb,unsigned alpha,unsigned)511         AGG_INLINE void blend_pix(pixel_type* p,
512                                   unsigned cr, unsigned cg, unsigned cb,
513                                   unsigned alpha,
514                                   unsigned)
515         {
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);
524         }
525 
make_pix(unsigned r,unsigned g,unsigned b)526         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
527         {
528             return (pixel_type)(((b & 0xFFC0) << 14) |
529                                 ((g & 0xFFC0) << 4) |
530                                  (r >> 6) | 0xC0000000);
531         }
532 
make_color(pixel_type p)533         static AGG_INLINE color_type make_color(pixel_type p)
534         {
535             return color_type((p << 6)  & 0xFFC0,
536                               (p >> 4)  & 0xFFC0,
537                               (p >> 14) & 0xFFC0);
538         }
539 
540     private:
541         const Gamma* m_gamma;
542     };
543 
544 
545 
546     //=====================================================blender_rgbBBA
547     struct blender_rgbBBA
548     {
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;
553 
blend_pixblender_rgbBBA554         static AGG_INLINE void blend_pix(pixel_type* p,
555                                          unsigned cr, unsigned cg, unsigned cb,
556                                          unsigned alpha,
557                                          unsigned)
558         {
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));
567         }
568 
make_pixblender_rgbBBA569         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
570         {
571             return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
572         }
573 
make_colorblender_rgbBBA574         static AGG_INLINE color_type make_color(pixel_type p)
575         {
576             return color_type((p >> 16) & 0xFFE0,
577                               (p >> 5)  & 0xFFE0,
578                               (p << 6)  & 0xFFC0);
579         }
580     };
581 
582 
583     //=================================================blender_rgbBBA_pre
584     struct blender_rgbBBA_pre
585     {
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;
590 
blend_pixblender_rgbBBA_pre591         static AGG_INLINE void blend_pix(pixel_type* p,
592                                          unsigned cr, unsigned cg, unsigned cb,
593                                          unsigned alpha,
594                                          unsigned cover)
595         {
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));
606         }
607 
make_pixblender_rgbBBA_pre608         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
609         {
610             return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
611         }
612 
make_colorblender_rgbBBA_pre613         static AGG_INLINE color_type make_color(pixel_type p)
614         {
615             return color_type((p >> 16) & 0xFFE0,
616                               (p >> 5)  & 0xFFE0,
617                               (p << 6)  & 0xFFC0);
618         }
619     };
620 
621 
622 
623     //=================================================blender_rgbBBA_gamma
624     template<class Gamma> class blender_rgbBBA_gamma
625     {
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;
632 
blender_rgbBBA_gamma()633         blender_rgbBBA_gamma() : m_gamma(0) {}
gamma(const gamma_type & g)634         void gamma(const gamma_type& g) { m_gamma = &g; }
635 
blend_pix(pixel_type * p,unsigned cr,unsigned cg,unsigned cb,unsigned alpha,unsigned)636         AGG_INLINE void blend_pix(pixel_type* p,
637                                   unsigned cr, unsigned cg, unsigned cb,
638                                   unsigned alpha,
639                                   unsigned)
640         {
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 ));
649         }
650 
make_pix(unsigned r,unsigned g,unsigned b)651         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
652         {
653             return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
654         }
655 
make_color(pixel_type p)656         static AGG_INLINE color_type make_color(pixel_type p)
657         {
658             return color_type((p >> 16) & 0xFFE0,
659                               (p >> 5)  & 0xFFE0,
660                               (p << 6)  & 0xFFC0);
661         }
662 
663     private:
664         const Gamma* m_gamma;
665     };
666 
667 
668     //=====================================================blender_bgrABB
669     struct blender_bgrABB
670     {
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;
675 
blend_pixblender_bgrABB676         static AGG_INLINE void blend_pix(pixel_type* p,
677                                          unsigned cr, unsigned cg, unsigned cb,
678                                          unsigned alpha,
679                                          unsigned)
680         {
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));
689         }
690 
make_pixblender_bgrABB691         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
692         {
693             return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
694         }
695 
make_colorblender_bgrABB696         static AGG_INLINE color_type make_color(pixel_type p)
697         {
698             return color_type((p << 5)  & 0xFFE0,
699                               (p >> 6)  & 0xFFE0,
700                               (p >> 16) & 0xFFC0);
701         }
702     };
703 
704 
705     //=================================================blender_bgrABB_pre
706     struct blender_bgrABB_pre
707     {
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;
712 
blend_pixblender_bgrABB_pre713         static AGG_INLINE void blend_pix(pixel_type* p,
714                                          unsigned cr, unsigned cg, unsigned cb,
715                                          unsigned alpha,
716                                          unsigned cover)
717         {
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));
728         }
729 
make_pixblender_bgrABB_pre730         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
731         {
732             return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
733         }
734 
make_colorblender_bgrABB_pre735         static AGG_INLINE color_type make_color(pixel_type p)
736         {
737             return color_type((p << 5)  & 0xFFE0,
738                               (p >> 6)  & 0xFFE0,
739                               (p >> 16) & 0xFFC0);
740         }
741     };
742 
743 
744 
745     //=================================================blender_bgrABB_gamma
746     template<class Gamma> class blender_bgrABB_gamma
747     {
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;
754 
blender_bgrABB_gamma()755         blender_bgrABB_gamma() : m_gamma(0) {}
gamma(const gamma_type & g)756         void gamma(const gamma_type& g) { m_gamma = &g; }
757 
blend_pix(pixel_type * p,unsigned cr,unsigned cg,unsigned cb,unsigned alpha,unsigned)758         AGG_INLINE void blend_pix(pixel_type* p,
759                                   unsigned cr, unsigned cg, unsigned cb,
760                                   unsigned alpha,
761                                   unsigned)
762         {
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 ));
771         }
772 
make_pix(unsigned r,unsigned g,unsigned b)773         static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
774         {
775             return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
776         }
777 
make_color(pixel_type p)778         static AGG_INLINE color_type make_color(pixel_type p)
779         {
780             return color_type((p << 5)  & 0xFFE0,
781                               (p >> 6)  & 0xFFE0,
782                               (p >> 16) & 0xFFC0);
783         }
784 
785     private:
786         const Gamma* m_gamma;
787     };
788 
789 
790 
791     //===========================================pixfmt_alpha_blend_rgb_packed
792     template<class Blender,  class RenBuf> class pixfmt_alpha_blend_rgb_packed
793     {
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
804         {
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),
809         };
810 
811     private:
812         //--------------------------------------------------------------------
copy_or_blend_pix(pixel_type * p,const color_type & c,unsigned cover)813         AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
814         {
815             if (c.a)
816             {
817                 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
818                 if(alpha == base_mask)
819                 {
820                     *p = m_blender.make_pix(c.r, c.g, c.b);
821                 }
822                 else
823                 {
824                     m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
825                 }
826             }
827         }
828 
829     public:
830         //--------------------------------------------------------------------
pixfmt_alpha_blend_rgb_packed(rbuf_type & rb)831         explicit pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {}
attach(rbuf_type & rb)832         void attach(rbuf_type& rb) { m_rbuf = &rb; }
833 
834         //--------------------------------------------------------------------
835         template<class PixFmt>
attach(PixFmt & pixf,int x1,int y1,int x2,int y2)836         bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
837         {
838             rect_i r(x1, y1, x2, y2);
839             if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
840             {
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;
847             }
848             return false;
849         }
850 
blender()851         Blender& blender() { return m_blender; }
852 
853         //--------------------------------------------------------------------
width()854         AGG_INLINE unsigned width()  const { return m_rbuf->width();  }
height()855         AGG_INLINE unsigned height() const { return m_rbuf->height(); }
stride()856         AGG_INLINE int      stride() const { return m_rbuf->stride(); }
857 
858         //--------------------------------------------------------------------
row_ptr(int y)859         AGG_INLINE       int8u* row_ptr(int y)       { return m_rbuf->row_ptr(y); }
row_ptr(int y)860         AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
row(int y)861         AGG_INLINE row_data     row(int y)     const { return m_rbuf->row(y); }
862 
863         //--------------------------------------------------------------------
pix_ptr(int x,int y)864         AGG_INLINE int8u* pix_ptr(int x, int y)
865         {
866             return m_rbuf->row_ptr(y) + x * pix_width;
867         }
868 
pix_ptr(int x,int y)869         AGG_INLINE const int8u* pix_ptr(int x, int y) const
870         {
871             return m_rbuf->row_ptr(y) + x * pix_width;
872         }
873 
874         //--------------------------------------------------------------------
make_pix(int8u * p,const color_type & c)875         AGG_INLINE void make_pix(int8u* p, const color_type& c)
876         {
877             *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b);
878         }
879 
880         //--------------------------------------------------------------------
pixel(int x,int y)881         AGG_INLINE color_type pixel(int x, int y) const
882         {
883             return m_blender.make_color(((pixel_type*)m_rbuf->row_ptr(y))[x]);
884         }
885 
886         //--------------------------------------------------------------------
copy_pixel(int x,int y,const color_type & c)887         AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
888         {
889             ((pixel_type*)
890                 m_rbuf->row_ptr(x, y, 1))[x] =
891                     m_blender.make_pix(c.r, c.g, c.b);
892         }
893 
894         //--------------------------------------------------------------------
blend_pixel(int x,int y,const color_type & c,int8u cover)895         AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
896         {
897             copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y, 1) + x, c, cover);
898         }
899 
900         //--------------------------------------------------------------------
copy_hline(int x,int y,unsigned len,const color_type & c)901         AGG_INLINE void copy_hline(int x, int y,
902                                    unsigned len,
903                                    const color_type& c)
904         {
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);
907             do
908             {
909                 *p++ = v;
910             }
911             while(--len);
912         }
913 
914         //--------------------------------------------------------------------
copy_vline(int x,int y,unsigned len,const color_type & c)915         AGG_INLINE void copy_vline(int x, int y,
916                                    unsigned len,
917                                    const color_type& c)
918         {
919             pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
920             do
921             {
922                 pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
923                 *p = v;
924             }
925             while(--len);
926         }
927 
928         //--------------------------------------------------------------------
blend_hline(int x,int y,unsigned len,const color_type & c,int8u cover)929         void blend_hline(int x, int y,
930                          unsigned len,
931                          const color_type& c,
932                          int8u cover)
933         {
934             if (c.a)
935             {
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)
939                 {
940                     pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
941                     do
942                     {
943                         *p++ = v;
944                     }
945                     while(--len);
946                 }
947                 else
948                 {
949                     do
950                     {
951                         m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
952                         ++p;
953                     }
954                     while(--len);
955                 }
956             }
957         }
958 
959         //--------------------------------------------------------------------
blend_vline(int x,int y,unsigned len,const color_type & c,int8u cover)960         void blend_vline(int x, int y,
961                          unsigned len,
962                          const color_type& c,
963                          int8u cover)
964         {
965             if (c.a)
966             {
967                 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
968                 if(alpha == base_mask)
969                 {
970                     pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
971                     do
972                     {
973                         ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v;
974                     }
975                     while(--len);
976                 }
977                 else
978                 {
979                     do
980                     {
981                         m_blender.blend_pix(
982                             (pixel_type*)m_rbuf->row_ptr(x, y++, 1),
983                             c.r, c.g, c.b, alpha, cover);
984                     }
985                     while(--len);
986                 }
987             }
988         }
989 
990         //--------------------------------------------------------------------
blend_solid_hspan(int x,int y,unsigned len,const color_type & c,const int8u * covers)991         void blend_solid_hspan(int x, int y,
992                                unsigned len,
993                                const color_type& c,
994                                const int8u* covers)
995         {
996             pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
997             do
998             {
999                 copy_or_blend_pix(p, c, *covers++);
1000                 ++p;
1001             }
1002             while(--len);
1003         }
1004 
1005         //--------------------------------------------------------------------
blend_solid_vspan(int x,int y,unsigned len,const color_type & c,const int8u * covers)1006         void blend_solid_vspan(int x, int y,
1007                                unsigned len,
1008                                const color_type& c,
1009                                const int8u* covers)
1010         {
1011             do
1012             {
1013                 copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x,
1014                                   c, *covers++);
1015             }
1016             while(--len);
1017         }
1018 
1019         //--------------------------------------------------------------------
copy_color_hspan(int x,int y,unsigned len,const color_type * colors)1020         void copy_color_hspan(int x, int y,
1021                               unsigned len,
1022                               const color_type* colors)
1023         {
1024             pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
1025             do
1026             {
1027                 *p++ = m_blender.make_pix(colors->r, colors->g, colors->b);
1028                 ++colors;
1029             }
1030             while(--len);
1031         }
1032 
1033         //--------------------------------------------------------------------
copy_color_vspan(int x,int y,unsigned len,const color_type * colors)1034         void copy_color_vspan(int x, int y,
1035                               unsigned len,
1036                               const color_type* colors)
1037         {
1038             do
1039             {
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;
1043             }
1044             while(--len);
1045         }
1046 
1047         //--------------------------------------------------------------------
blend_color_hspan(int x,int y,unsigned len,const color_type * colors,const int8u * covers,int8u cover)1048         void blend_color_hspan(int x, int y,
1049                                unsigned len,
1050                                const color_type* colors,
1051                                const int8u* covers,
1052                                int8u cover)
1053         {
1054             pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
1055             do
1056             {
1057                 copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover);
1058             }
1059             while(--len);
1060         }
1061 
1062         //--------------------------------------------------------------------
blend_color_vspan(int x,int y,unsigned len,const color_type * colors,const int8u * covers,int8u cover)1063         void blend_color_vspan(int x, int y,
1064                                unsigned len,
1065                                const color_type* colors,
1066                                const int8u* covers,
1067                                int8u cover)
1068         {
1069             do
1070             {
1071                 copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x,
1072                                   *colors++, covers ? *covers++ : cover);
1073             }
1074             while(--len);
1075         }
1076 
1077         //--------------------------------------------------------------------
1078         template<class RenBuf2>
copy_from(const RenBuf2 & from,int xdst,int ydst,int xsrc,int ysrc,unsigned len)1079         void copy_from(const RenBuf2& from,
1080                        int xdst, int ydst,
1081                        int xsrc, int ysrc,
1082                        unsigned len)
1083         {
1084             const int8u* p = from.row_ptr(ysrc);
1085             if(p)
1086             {
1087                 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
1088                         p + xsrc * pix_width,
1089                         len * pix_width);
1090             }
1091         }
1092 
1093         //--------------------------------------------------------------------
1094         template<class SrcPixelFormatRenderer>
blend_from(const SrcPixelFormatRenderer & from,int xdst,int ydst,int xsrc,int ysrc,unsigned len,int8u cover)1095         void blend_from(const SrcPixelFormatRenderer& from,
1096                         int xdst, int ydst,
1097                         int xsrc, int ysrc,
1098                         unsigned len,
1099                         int8u cover)
1100         {
1101             typedef typename SrcPixelFormatRenderer::order_type src_order;
1102 
1103             const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
1104             if(psrc)
1105             {
1106                 psrc += xsrc * 4;
1107                 pixel_type* pdst =
1108                     (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
1109                 do
1110                 {
1111                     value_type alpha = psrc[src_order::A];
1112                     if(alpha)
1113                     {
1114                         if(alpha == base_mask && cover == 255)
1115                         {
1116                             *pdst = m_blender.make_pix(psrc[src_order::R],
1117                                                        psrc[src_order::G],
1118                                                        psrc[src_order::B]);
1119                         }
1120                         else
1121                         {
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);
1128                         }
1129                     }
1130                     psrc += 4;
1131                     ++pdst;
1132                 }
1133                 while(--len);
1134             }
1135         }
1136 
1137         //--------------------------------------------------------------------
1138         template<class SrcPixelFormatRenderer>
blend_from_color(const SrcPixelFormatRenderer & from,const color_type & color,int xdst,int ydst,int xsrc,int ysrc,unsigned len,int8u cover)1139         void blend_from_color(const SrcPixelFormatRenderer& from,
1140                               const color_type& color,
1141                               int xdst, int ydst,
1142                               int xsrc, int ysrc,
1143                               unsigned len,
1144                               int8u cover)
1145         {
1146             typedef typename SrcPixelFormatRenderer::value_type src_value_type;
1147             typedef typename SrcPixelFormatRenderer::color_type src_color_type;
1148             const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
1149             if(psrc)
1150             {
1151                 psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset;
1152                 pixel_type* pdst =
1153                     (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
1154 
1155                 do
1156                 {
1157                     m_blender.blend_pix(pdst,
1158                                         color.r, color.g, color.b, color.a,
1159                                         cover);
1160                     psrc += SrcPixelFormatRenderer::pix_step;
1161                     ++pdst;
1162                 }
1163                 while(--len);
1164             }
1165         }
1166 
1167         //--------------------------------------------------------------------
1168         template<class SrcPixelFormatRenderer>
blend_from_lut(const SrcPixelFormatRenderer & from,const color_type * color_lut,int xdst,int ydst,int xsrc,int ysrc,unsigned len,int8u cover)1169         void blend_from_lut(const SrcPixelFormatRenderer& from,
1170                             const color_type* color_lut,
1171                             int xdst, int ydst,
1172                             int xsrc, int ysrc,
1173                             unsigned len,
1174                             int8u cover)
1175         {
1176             typedef typename SrcPixelFormatRenderer::value_type src_value_type;
1177             const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
1178             if(psrc)
1179             {
1180                 psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset;
1181                 pixel_type* pdst =
1182                     (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
1183 
1184                 do
1185                 {
1186                     const color_type& color = color_lut[*psrc];
1187                     m_blender.blend_pix(pdst,
1188                                         color.r, color.g, color.b, color.a,
1189                                         cover);
1190                     psrc += SrcPixelFormatRenderer::pix_step;
1191                     ++pdst;
1192                 }
1193                 while(--len);
1194             }
1195         }
1196 
1197 
1198 
1199     private:
1200         rbuf_type* m_rbuf;
1201         Blender    m_blender;
1202     };
1203 
1204     typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555, rendering_buffer> pixfmt_rgb555; //----pixfmt_rgb555
1205     typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565, rendering_buffer> pixfmt_rgb565; //----pixfmt_rgb565
1206 
1207     typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555_pre, rendering_buffer> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
1208     typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565_pre, rendering_buffer> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre
1209 
1210     typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA, rendering_buffer> pixfmt_rgbAAA; //----pixfmt_rgbAAA
1211     typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA, rendering_buffer> pixfmt_bgrAAA; //----pixfmt_bgrAAA
1212     typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA, rendering_buffer> pixfmt_rgbBBA; //----pixfmt_rgbBBA
1213     typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB, rendering_buffer> pixfmt_bgrABB; //----pixfmt_bgrABB
1214 
1215     typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_pre, rendering_buffer> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre
1216     typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_pre, rendering_buffer> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre
1217     typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_pre, rendering_buffer> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre
1218     typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB_pre, rendering_buffer> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre
1219 
1220 
1221     //-----------------------------------------------------pixfmt_rgb555_gamma
1222     template<class Gamma> class pixfmt_rgb555_gamma :
1223     public pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
1224                                          rendering_buffer>
1225     {
1226     public:
pixfmt_rgb555_gamma(rendering_buffer & rb,const Gamma & g)1227         pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) :
1228             pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
1229                                           rendering_buffer>(rb)
1230         {
1231             this->blender().gamma(g);
1232         }
1233     };
1234 
1235 
1236     //-----------------------------------------------------pixfmt_rgb565_gamma
1237     template<class Gamma> class pixfmt_rgb565_gamma :
1238     public pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>
1239     {
1240     public:
pixfmt_rgb565_gamma(rendering_buffer & rb,const Gamma & g)1241         pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) :
1242             pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>(rb)
1243         {
1244             this->blender().gamma(g);
1245         }
1246     };
1247 
1248 
1249     //-----------------------------------------------------pixfmt_rgbAAA_gamma
1250     template<class Gamma> class pixfmt_rgbAAA_gamma :
1251     public pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
1252                                          rendering_buffer>
1253     {
1254     public:
pixfmt_rgbAAA_gamma(rendering_buffer & rb,const Gamma & g)1255         pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1256             pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
1257                                           rendering_buffer>(rb)
1258         {
1259             this->blender().gamma(g);
1260         }
1261     };
1262 
1263 
1264     //-----------------------------------------------------pixfmt_bgrAAA_gamma
1265     template<class Gamma> class pixfmt_bgrAAA_gamma :
1266     public pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
1267                                          rendering_buffer>
1268     {
1269     public:
pixfmt_bgrAAA_gamma(rendering_buffer & rb,const Gamma & g)1270         pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) :
1271             pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
1272                                           rendering_buffer>(rb)
1273         {
1274             this->blender().gamma(g);
1275         }
1276     };
1277 
1278 
1279     //-----------------------------------------------------pixfmt_rgbBBA_gamma
1280     template<class Gamma> class pixfmt_rgbBBA_gamma :
1281     public pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
1282                                          rendering_buffer>
1283     {
1284     public:
pixfmt_rgbBBA_gamma(rendering_buffer & rb,const Gamma & g)1285         pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) :
1286             pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
1287                                           rendering_buffer>(rb)
1288         {
1289             this->blender().gamma(g);
1290         }
1291     };
1292 
1293 
1294     //-----------------------------------------------------pixfmt_bgrABB_gamma
1295     template<class Gamma> class pixfmt_bgrABB_gamma :
1296     public pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
1297                                          rendering_buffer>
1298     {
1299     public:
pixfmt_bgrABB_gamma(rendering_buffer & rb,const Gamma & g)1300         pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) :
1301             pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
1302                                           rendering_buffer>(rb)
1303         {
1304             this->blender().gamma(g);
1305         }
1306     };
1307 
1308 
1309 }
1310 
1311 #endif
1312 
1313