xref: /haiku/headers/libs/agg/agg_pixfmt_rgb.h (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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_INCLUDED
25 #define AGG_PIXFMT_RGB_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 
35     //=====================================================apply_gamma_dir_rgb
36     template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb
37     {
38     public:
39         typedef typename ColorT::value_type value_type;
40 
41         apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
42 
43         AGG_INLINE void operator () (value_type* p)
44         {
45             p[Order::R] = m_gamma.dir(p[Order::R]);
46             p[Order::G] = m_gamma.dir(p[Order::G]);
47             p[Order::B] = m_gamma.dir(p[Order::B]);
48         }
49 
50     private:
51         const GammaLut& m_gamma;
52     };
53 
54 
55 
56     //=====================================================apply_gamma_inv_rgb
57     template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb
58     {
59     public:
60         typedef typename ColorT::value_type value_type;
61 
62         apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {}
63 
64         AGG_INLINE void operator () (value_type* p)
65         {
66             p[Order::R] = m_gamma.inv(p[Order::R]);
67             p[Order::G] = m_gamma.inv(p[Order::G]);
68             p[Order::B] = m_gamma.inv(p[Order::B]);
69         }
70 
71     private:
72         const GammaLut& m_gamma;
73     };
74 
75 
76     //=========================================================blender_rgb
77     template<class ColorT, class Order> struct blender_rgb
78     {
79         typedef ColorT color_type;
80         typedef Order order_type;
81         typedef typename color_type::value_type value_type;
82         typedef typename color_type::calc_type calc_type;
83         enum base_scale_e { base_shift = color_type::base_shift };
84 
85         //--------------------------------------------------------------------
86         static AGG_INLINE void blend_pix(value_type* p,
87                                          unsigned cr, unsigned cg, unsigned cb,
88                                          unsigned alpha,
89                                          unsigned cover=0)
90         {
91             p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift);
92             p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift);
93             p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift);
94         }
95     };
96 
97 
98     //======================================================blender_rgb_pre
99     template<class ColorT, class Order> struct blender_rgb_pre
100     {
101         typedef ColorT color_type;
102         typedef Order order_type;
103         typedef typename color_type::value_type value_type;
104         typedef typename color_type::calc_type calc_type;
105         enum base_scale_e { base_shift = color_type::base_shift };
106 
107         //--------------------------------------------------------------------
108         static AGG_INLINE void blend_pix(value_type* p,
109                                          unsigned cr, unsigned cg, unsigned cb,
110                                          unsigned alpha,
111                                          unsigned cover)
112         {
113             alpha = color_type::base_mask - alpha;
114             cover = (cover + 1) << (base_shift - 8);
115             p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift);
116             p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift);
117             p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift);
118         }
119 
120         //--------------------------------------------------------------------
121         static AGG_INLINE void blend_pix(value_type* p,
122                                          unsigned cr, unsigned cg, unsigned cb,
123                                          unsigned alpha)
124         {
125             alpha = color_type::base_mask - alpha;
126             p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
127             p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
128             p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
129         }
130 
131     };
132 
133 
134 
135     //===================================================blender_rgb_gamma
136     template<class ColorT, class Order, class Gamma> class blender_rgb_gamma
137     {
138     public:
139         typedef ColorT color_type;
140         typedef Order order_type;
141         typedef Gamma gamma_type;
142         typedef typename color_type::value_type value_type;
143         typedef typename color_type::calc_type calc_type;
144         enum base_scale_e { base_shift = color_type::base_shift };
145 
146         //--------------------------------------------------------------------
147         blender_rgb_gamma() : m_gamma(0) {}
148         void gamma(const gamma_type& g) { m_gamma = &g; }
149 
150         //--------------------------------------------------------------------
151         AGG_INLINE void blend_pix(value_type* p,
152                                   unsigned cr, unsigned cg, unsigned cb,
153                                   unsigned alpha,
154                                   unsigned cover=0)
155         {
156             calc_type r = m_gamma->dir(p[Order::R]);
157             calc_type g = m_gamma->dir(p[Order::G]);
158             calc_type b = m_gamma->dir(p[Order::B]);
159             p[Order::R] = m_gamma->inv((((m_gamma->dir(cr) - r) * alpha) >> base_shift) + r);
160             p[Order::G] = m_gamma->inv((((m_gamma->dir(cg) - g) * alpha) >> base_shift) + g);
161             p[Order::B] = m_gamma->inv((((m_gamma->dir(cb) - b) * alpha) >> base_shift) + b);
162         }
163 
164     private:
165         const gamma_type* m_gamma;
166     };
167 
168 
169 
170 
171     //==================================================pixfmt_alpha_blend_rgb
172     template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb
173     {
174     public:
175         typedef RenBuf   rbuf_type;
176         typedef Blender  blender_type;
177         typedef typename rbuf_type::row_data row_data;
178         typedef typename blender_type::color_type color_type;
179         typedef typename blender_type::order_type order_type;
180         typedef typename color_type::value_type value_type;
181         typedef typename color_type::calc_type calc_type;
182         enum base_scale_e
183         {
184             base_shift = color_type::base_shift,
185             base_scale = color_type::base_scale,
186             base_mask  = color_type::base_mask,
187             pix_width  = sizeof(value_type) * 3
188         };
189 
190     private:
191         //--------------------------------------------------------------------
192         AGG_INLINE void copy_or_blend_pix(value_type* p,
193                                           const color_type& c,
194                                           unsigned cover)
195         {
196             if (c.a)
197             {
198                 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
199                 if(alpha == base_mask)
200                 {
201                     p[order_type::R] = c.r;
202                     p[order_type::G] = c.g;
203                     p[order_type::B] = c.b;
204                 }
205                 else
206                 {
207                     m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
208                 }
209             }
210         }
211 
212         //--------------------------------------------------------------------
213         AGG_INLINE void copy_or_blend_pix(value_type* p,
214                                           const color_type& c)
215         {
216             if (c.a)
217             {
218                 if(c.a == base_mask)
219                 {
220                     p[order_type::R] = c.r;
221                     p[order_type::G] = c.g;
222                     p[order_type::B] = c.b;
223                 }
224                 else
225                 {
226                     m_blender.blend_pix(p, c.r, c.g, c.b, c.a);
227                 }
228             }
229         }
230 
231 
232     public:
233         //--------------------------------------------------------------------
234         pixfmt_alpha_blend_rgb(rbuf_type& rb) :
235             m_rbuf(&rb)
236         {}
237         void attach(rbuf_type& rb) { m_rbuf = &rb; }
238 
239         //--------------------------------------------------------------------
240         template<class PixFmt>
241         bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
242         {
243             rect_i r(x1, y1, x2, y2);
244             if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
245             {
246                 int stride = pixf.stride();
247                 m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
248                                (r.x2 - r.x1) + 1,
249                                (r.y2 - r.y1) + 1,
250                                stride);
251                 return true;
252             }
253             return false;
254         }
255 
256         //--------------------------------------------------------------------
257         Blender& blender() { return m_blender; }
258 
259         //--------------------------------------------------------------------
260         AGG_INLINE unsigned width()  const { return m_rbuf->width();  }
261         AGG_INLINE unsigned height() const { return m_rbuf->height(); }
262         AGG_INLINE int      stride() const { return m_rbuf->stride(); }
263 
264         //--------------------------------------------------------------------
265         AGG_INLINE       int8u* row_ptr(int y)       { return m_rbuf->row_ptr(y); }
266         AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
267         AGG_INLINE row_data     row(int y)     const { return m_rbuf->row(y); }
268 
269         //--------------------------------------------------------------------
270         AGG_INLINE int8u* pix_ptr(int x, int y)
271         {
272             return m_rbuf->row_ptr(y) + x * pix_width;
273         }
274 
275         AGG_INLINE const int8u* pix_ptr(int x, int y) const
276         {
277             return m_rbuf->row_ptr(y) + x * pix_width;
278         }
279 
280         //--------------------------------------------------------------------
281         AGG_INLINE static void make_pix(int8u* p, const color_type& c)
282         {
283             ((value_type*)p)[order_type::R] = c.r;
284             ((value_type*)p)[order_type::G] = c.g;
285             ((value_type*)p)[order_type::B] = c.b;
286         }
287 
288         //--------------------------------------------------------------------
289         AGG_INLINE color_type pixel(int x, int y) const
290         {
291             value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x;
292             return color_type(p[order_type::R],
293                               p[order_type::G],
294                               p[order_type::B]);
295         }
296 
297         //--------------------------------------------------------------------
298         AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
299         {
300             value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x;
301             p[order_type::R] = c.r;
302             p[order_type::G] = c.g;
303             p[order_type::B] = c.b;
304         }
305 
306         //--------------------------------------------------------------------
307         AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
308         {
309             copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover);
310         }
311 
312 
313         //--------------------------------------------------------------------
314         AGG_INLINE void copy_hline(int x, int y,
315                                    unsigned len,
316                                    const color_type& c)
317         {
318             value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x;
319             do
320             {
321                 p[order_type::R] = c.r;
322                 p[order_type::G] = c.g;
323                 p[order_type::B] = c.b;
324                 p += 3;
325             }
326             while(--len);
327         }
328 
329 
330         //--------------------------------------------------------------------
331         AGG_INLINE void copy_vline(int x, int y,
332                                    unsigned len,
333                                    const color_type& c)
334         {
335             do
336             {
337                 value_type* p = (value_type*)
338                     m_rbuf->row_ptr(x, y++, 1) + x + x + x;
339                 p[order_type::R] = c.r;
340                 p[order_type::G] = c.g;
341                 p[order_type::B] = c.b;
342             }
343             while(--len);
344         }
345 
346 
347         //--------------------------------------------------------------------
348         void blend_hline(int x, int y,
349                          unsigned len,
350                          const color_type& c,
351                          int8u cover)
352         {
353             if (c.a)
354             {
355                 value_type* p = (value_type*)
356                     m_rbuf->row_ptr(x, y, len) + x + x + x;
357 
358                 calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8;
359                 if(alpha == base_mask)
360                 {
361                     do
362                     {
363                         p[order_type::R] = c.r;
364                         p[order_type::G] = c.g;
365                         p[order_type::B] = c.b;
366                         p += 3;
367                     }
368                     while(--len);
369                 }
370                 else
371                 {
372                     do
373                     {
374                         m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
375                         p += 3;
376                     }
377                     while(--len);
378                 }
379             }
380         }
381 
382 
383         //--------------------------------------------------------------------
384         void blend_vline(int x, int y,
385                          unsigned len,
386                          const color_type& c,
387                          int8u cover)
388         {
389             if (c.a)
390             {
391                 value_type* p;
392                 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
393                 if(alpha == base_mask)
394                 {
395                     do
396                     {
397                         p = (value_type*)
398                             m_rbuf->row_ptr(x, y++, 1) + x + x + x;
399 
400                         p[order_type::R] = c.r;
401                         p[order_type::G] = c.g;
402                         p[order_type::B] = c.b;
403                     }
404                     while(--len);
405                 }
406                 else
407                 {
408                     do
409                     {
410                         p = (value_type*)
411                             m_rbuf->row_ptr(x, y++, 1) + x + x + x;
412 
413                         m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
414                     }
415                     while(--len);
416                 }
417             }
418         }
419 
420 
421         //--------------------------------------------------------------------
422         void blend_solid_hspan(int x, int y,
423                                unsigned len,
424                                const color_type& c,
425                                const int8u* covers)
426         {
427             if (c.a)
428             {
429                 value_type* p = (value_type*)
430                     m_rbuf->row_ptr(x, y, len) + x + x + x;
431 
432                 do
433                 {
434                     calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
435                     if(alpha == base_mask)
436                     {
437                         p[order_type::R] = c.r;
438                         p[order_type::G] = c.g;
439                         p[order_type::B] = c.b;
440                     }
441                     else
442                     {
443                         m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers);
444                     }
445                     p += 3;
446                     ++covers;
447                 }
448                 while(--len);
449             }
450         }
451 
452 
453         //--------------------------------------------------------------------
454         void blend_solid_vspan(int x, int y,
455                                unsigned len,
456                                const color_type& c,
457                                const int8u* covers)
458         {
459             if (c.a)
460             {
461                 do
462                 {
463                     value_type* p = (value_type*)
464                         m_rbuf->row_ptr(x, y++, 1) + x + x + x;
465 
466                     calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
467                     if(alpha == base_mask)
468                     {
469                         p[order_type::R] = c.r;
470                         p[order_type::G] = c.g;
471                         p[order_type::B] = c.b;
472                     }
473                     else
474                     {
475                         m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers);
476                     }
477                     ++covers;
478                 }
479                 while(--len);
480             }
481         }
482 
483 
484         //--------------------------------------------------------------------
485         void copy_color_hspan(int x, int y,
486                               unsigned len,
487                               const color_type* colors)
488         {
489             value_type* p = (value_type*)
490                 m_rbuf->row_ptr(x, y, len) + x + x + x;
491 
492             do
493             {
494                 p[order_type::R] = colors->r;
495                 p[order_type::G] = colors->g;
496                 p[order_type::B] = colors->b;
497                 ++colors;
498                 p += 3;
499             }
500             while(--len);
501         }
502 
503 
504         //--------------------------------------------------------------------
505         void copy_color_vspan(int x, int y,
506                               unsigned len,
507                               const color_type* colors)
508         {
509             do
510             {
511                 value_type* p = (value_type*)
512                     m_rbuf->row_ptr(x, y++, 1) + x + x + x;
513                 p[order_type::R] = colors->r;
514                 p[order_type::G] = colors->g;
515                 p[order_type::B] = colors->b;
516                 ++colors;
517             }
518             while(--len);
519         }
520 
521 
522         //--------------------------------------------------------------------
523         void blend_color_hspan(int x, int y,
524                                unsigned len,
525                                const color_type* colors,
526                                const int8u* covers,
527                                int8u cover)
528         {
529             value_type* p = (value_type*)
530                 m_rbuf->row_ptr(x, y, len) + x + x + x;
531 
532             if(covers)
533             {
534                 do
535                 {
536                     copy_or_blend_pix(p, *colors++, *covers++);
537                     p += 3;
538                 }
539                 while(--len);
540             }
541             else
542             {
543                 if(cover == 255)
544                 {
545                     do
546                     {
547                         copy_or_blend_pix(p, *colors++);
548                         p += 3;
549                     }
550                     while(--len);
551                 }
552                 else
553                 {
554                     do
555                     {
556                         copy_or_blend_pix(p, *colors++, cover);
557                         p += 3;
558                     }
559                     while(--len);
560                 }
561             }
562         }
563 
564 
565 
566         //--------------------------------------------------------------------
567         void blend_color_vspan(int x, int y,
568                                unsigned len,
569                                const color_type* colors,
570                                const int8u* covers,
571                                int8u cover)
572         {
573             value_type* p;
574             if(covers)
575             {
576                 do
577                 {
578                     p = (value_type*)
579                         m_rbuf->row_ptr(x, y++, 1) + x + x + x;
580 
581                     copy_or_blend_pix(p, *colors++, *covers++);
582                 }
583                 while(--len);
584             }
585             else
586             {
587                 if(cover == 255)
588                 {
589                     do
590                     {
591                         p = (value_type*)
592                             m_rbuf->row_ptr(x, y++, 1) + x + x + x;
593 
594                         copy_or_blend_pix(p, *colors++);
595                     }
596                     while(--len);
597                 }
598                 else
599                 {
600                     do
601                     {
602                         p = (value_type*)
603                             m_rbuf->row_ptr(x, y++, 1) + x + x + x;
604 
605                         copy_or_blend_pix(p, *colors++, cover);
606                     }
607                     while(--len);
608                 }
609             }
610         }
611 
612         //--------------------------------------------------------------------
613         template<class Function> void for_each_pixel(Function f)
614         {
615             unsigned y;
616             for(y = 0; y < height(); ++y)
617             {
618                 row_data r = m_rbuf->row(y);
619                 if(r.ptr)
620                 {
621                     unsigned len = r.x2 - r.x1 + 1;
622                     value_type* p = (value_type*)
623                         m_rbuf->row_ptr(r.x1, y, len) + r.x1 * 3;
624                     do
625                     {
626                         f(p);
627                         p += 3;
628                     }
629                     while(--len);
630                 }
631             }
632         }
633 
634         //--------------------------------------------------------------------
635         template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
636         {
637             for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g));
638         }
639 
640         //--------------------------------------------------------------------
641         template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
642         {
643             for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g));
644         }
645 
646         //--------------------------------------------------------------------
647         template<class RenBuf2>
648         void copy_from(const RenBuf2& from,
649                        int xdst, int ydst,
650                        int xsrc, int ysrc,
651                        unsigned len)
652         {
653             const int8u* p = from.row_ptr(ysrc);
654             if(p)
655             {
656                 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
657                         p + xsrc * pix_width,
658                         len * pix_width);
659             }
660         }
661 
662 
663         //--------------------------------------------------------------------
664         template<class SrcPixelFormatRenderer>
665         void blend_from(const SrcPixelFormatRenderer& from,
666                         int xdst, int ydst,
667                         int xsrc, int ysrc,
668                         unsigned len,
669                         int8u cover)
670         {
671             typedef typename SrcPixelFormatRenderer::order_type src_order;
672 
673             const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
674             if(psrc)
675             {
676                 psrc += xsrc * 4;
677                 value_type* pdst =
678                     (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;
679 
680                 if(cover == 255)
681                 {
682                     do
683                     {
684                         value_type alpha = psrc[src_order::A];
685                         if(alpha)
686                         {
687                             if(alpha == base_mask)
688                             {
689                                 pdst[order_type::R] = psrc[src_order::R];
690                                 pdst[order_type::G] = psrc[src_order::G];
691                                 pdst[order_type::B] = psrc[src_order::B];
692                             }
693                             else
694                             {
695                                 m_blender.blend_pix(pdst,
696                                                     psrc[src_order::R],
697                                                     psrc[src_order::G],
698                                                     psrc[src_order::B],
699                                                     alpha);
700                             }
701                         }
702                         psrc += 4;
703                         pdst += 3;
704                     }
705                     while(--len);
706                 }
707                 else
708                 {
709                     color_type color;
710                     do
711                     {
712                         color.r = psrc[src_order::R];
713                         color.g = psrc[src_order::G];
714                         color.b = psrc[src_order::B];
715                         color.a = psrc[src_order::A];
716                         copy_or_blend_pix(pdst, color, cover);
717                         psrc += 4;
718                         pdst += 3;
719                     }
720                     while(--len);
721                 }
722             }
723         }
724 
725     private:
726         rbuf_type* m_rbuf;
727         Blender    m_blender;
728     };
729 
730     typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8,  order_rgb>, rendering_buffer> pixfmt_rgb24;    //----pixfmt_rgb24
731     typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8,  order_bgr>, rendering_buffer> pixfmt_bgr24;    //----pixfmt_bgr24
732     typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48;    //----pixfmt_rgb48
733     typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48;    //----pixfmt_bgr48
734 
735     typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8,  order_rgb>, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre
736     typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8,  order_bgr>, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre
737     typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre
738     typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre
739 
740     //-----------------------------------------------------pixfmt_rgb24_gamma
741     template<class Gamma> class pixfmt_rgb24_gamma :
742     public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>
743     {
744     public:
745         pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) :
746             pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>(rb)
747         {
748             this->blender().gamma(g);
749         }
750     };
751 
752     //-----------------------------------------------------pixfmt_bgr24_gamma
753     template<class Gamma> class pixfmt_bgr24_gamma :
754     public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>
755     {
756     public:
757         pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) :
758             pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>(rb)
759         {
760             this->blender().gamma(g);
761         }
762     };
763 
764     //-----------------------------------------------------pixfmt_rgb48_gamma
765     template<class Gamma> class pixfmt_rgb48_gamma :
766     public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>
767     {
768     public:
769         pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) :
770             pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>(rb)
771         {
772             this->blender().gamma(g);
773         }
774     };
775 
776     //-----------------------------------------------------pixfmt_bgr48_gamma
777     template<class Gamma> class pixfmt_bgr48_gamma :
778     public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>
779     {
780     public:
781         pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) :
782             pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>(rb)
783         {
784             this->blender().gamma(g);
785         }
786     };
787 
788 
789 }
790 
791 #endif
792 
793