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_GRAY_INCLUDED
25 #define AGG_PIXFMT_GRAY_INCLUDED
26 
27 #include <string.h>
28 #include "agg_pixfmt_base.h"
29 #include "agg_rendering_buffer.h"
30 
31 namespace agg
32 {
33 
34     //============================================================blender_gray
35     template<class ColorT> struct blender_gray
36     {
37         typedef ColorT color_type;
38         typedef typename color_type::value_type value_type;
39         typedef typename color_type::calc_type calc_type;
40         typedef typename color_type::long_type long_type;
41 
42         // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's
43         // compositing function. Since the render buffer is opaque we skip the
44         // initial premultiply and final demultiply.
45 
blend_pixblender_gray46         static AGG_INLINE void blend_pix(value_type* p,
47             value_type cv, value_type alpha, cover_type cover)
48         {
49             blend_pix(p, cv, color_type::mult_cover(alpha, cover));
50         }
51 
blend_pixblender_gray52         static AGG_INLINE void blend_pix(value_type* p,
53             value_type cv, value_type alpha)
54         {
55             *p = color_type::lerp(*p, cv, alpha);
56         }
57     };
58 
59 
60     //======================================================blender_gray_pre
61     template<class ColorT> struct blender_gray_pre
62     {
63         typedef ColorT color_type;
64         typedef typename color_type::value_type value_type;
65         typedef typename color_type::calc_type calc_type;
66         typedef typename color_type::long_type long_type;
67 
68         // Blend pixels using the premultiplied form of Alvy-Ray Smith's
69         // compositing function.
70 
blend_pixblender_gray_pre71         static AGG_INLINE void blend_pix(value_type* p,
72             value_type cv, value_type alpha, cover_type cover)
73         {
74             blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover));
75         }
76 
blend_pixblender_gray_pre77         static AGG_INLINE void blend_pix(value_type* p,
78             value_type cv, value_type alpha)
79         {
80             *p = color_type::prelerp(*p, cv, alpha);
81         }
82     };
83 
84 
85 
86     //=====================================================apply_gamma_dir_gray
87     template<class ColorT, class GammaLut> class apply_gamma_dir_gray
88     {
89     public:
90         typedef typename ColorT::value_type value_type;
91 
apply_gamma_dir_gray(const GammaLut & gamma)92         apply_gamma_dir_gray(const GammaLut& gamma) : m_gamma(gamma) {}
93 
operator()94         AGG_INLINE void operator () (value_type* p)
95         {
96             *p = m_gamma.dir(*p);
97         }
98 
99     private:
100         const GammaLut& m_gamma;
101     };
102 
103 
104 
105     //=====================================================apply_gamma_inv_gray
106     template<class ColorT, class GammaLut> class apply_gamma_inv_gray
107     {
108     public:
109         typedef typename ColorT::value_type value_type;
110 
apply_gamma_inv_gray(const GammaLut & gamma)111         apply_gamma_inv_gray(const GammaLut& gamma) : m_gamma(gamma) {}
112 
operator()113         AGG_INLINE void operator () (value_type* p)
114         {
115             *p = m_gamma.inv(*p);
116         }
117 
118     private:
119         const GammaLut& m_gamma;
120     };
121 
122 
123 
124     //=================================================pixfmt_alpha_blend_gray
125     template<class Blender, class RenBuf, unsigned Step = 1, unsigned Offset = 0>
126     class pixfmt_alpha_blend_gray
127     {
128     public:
129         typedef pixfmt_gray_tag pixfmt_category;
130         typedef RenBuf   rbuf_type;
131         typedef typename rbuf_type::row_data row_data;
132         typedef Blender  blender_type;
133         typedef typename blender_type::color_type color_type;
134         typedef int                               order_type; // A fake one
135         typedef typename color_type::value_type   value_type;
136         typedef typename color_type::calc_type    calc_type;
137         enum
138         {
139             pix_width = sizeof(value_type) * Step,
140             pix_step = Step,
141             pix_offset = Offset,
142         };
143         struct pixel_type
144         {
145             value_type c[pix_step];
146 
setpixel_type147             void set(value_type v)
148             {
149                 c[0] = v;
150             }
151 
setpixel_type152             void set(const color_type& color)
153             {
154                 set(color.v);
155             }
156 
getpixel_type157             void get(value_type& v) const
158             {
159                 v = c[0];
160             }
161 
getpixel_type162             color_type get() const
163             {
164                 return color_type(c[0]);
165             }
166 
nextpixel_type167             pixel_type* next()
168             {
169                 return this + 1;
170             }
171 
nextpixel_type172             const pixel_type* next() const
173             {
174                 return this + 1;
175             }
176 
advancepixel_type177             pixel_type* advance(int n)
178             {
179                 return this + n;
180             }
181 
advancepixel_type182             const pixel_type* advance(int n) const
183             {
184                 return this + n;
185             }
186         };
187 
188     private:
189         //--------------------------------------------------------------------
blend_pix(pixel_type * p,value_type v,value_type a,unsigned cover)190         AGG_INLINE void blend_pix(pixel_type* p,
191             value_type v, value_type a,
192             unsigned cover)
193         {
194             blender_type::blend_pix(p->c, v, a, cover);
195         }
196 
197         //--------------------------------------------------------------------
blend_pix(pixel_type * p,value_type v,value_type a)198         AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a)
199         {
200             blender_type::blend_pix(p->c, v, a);
201         }
202 
203         //--------------------------------------------------------------------
blend_pix(pixel_type * p,const color_type & c,unsigned cover)204         AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover)
205         {
206             blender_type::blend_pix(p->c, c.v, c.a, cover);
207         }
208 
209         //--------------------------------------------------------------------
blend_pix(pixel_type * p,const color_type & c)210         AGG_INLINE void blend_pix(pixel_type* p, const color_type& c)
211         {
212             blender_type::blend_pix(p->c, c.v, c.a);
213         }
214 
215         //--------------------------------------------------------------------
copy_or_blend_pix(pixel_type * p,const color_type & c,unsigned cover)216         AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
217         {
218             if (!c.is_transparent())
219             {
220                 if (c.is_opaque() && cover == cover_mask)
221                 {
222                     p->set(c);
223                 }
224                 else
225                 {
226                     blend_pix(p, c, cover);
227                 }
228             }
229         }
230 
231         //--------------------------------------------------------------------
copy_or_blend_pix(pixel_type * p,const color_type & c)232         AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c)
233         {
234             if (!c.is_transparent())
235             {
236                 if (c.is_opaque())
237                 {
238                     p->set(c);
239                 }
240                 else
241                 {
242                     blend_pix(p, c);
243                 }
244             }
245         }
246 
247     public:
248         //--------------------------------------------------------------------
pixfmt_alpha_blend_gray(rbuf_type & rb)249         explicit pixfmt_alpha_blend_gray(rbuf_type& rb) :
250             m_rbuf(&rb)
251         {}
attach(rbuf_type & rb)252         void attach(rbuf_type& rb) { m_rbuf = &rb; }
253         //--------------------------------------------------------------------
254 
255         template<class PixFmt>
attach(PixFmt & pixf,int x1,int y1,int x2,int y2)256         bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
257         {
258             rect_i r(x1, y1, x2, y2);
259             if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
260             {
261                 int stride = pixf.stride();
262                 m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
263                                (r.x2 - r.x1) + 1,
264                                (r.y2 - r.y1) + 1,
265                                stride);
266                 return true;
267             }
268             return false;
269         }
270 
271         //--------------------------------------------------------------------
width()272         AGG_INLINE unsigned width()  const { return m_rbuf->width();  }
height()273         AGG_INLINE unsigned height() const { return m_rbuf->height(); }
stride()274         AGG_INLINE int      stride() const { return m_rbuf->stride(); }
275 
276         //--------------------------------------------------------------------
row_ptr(int y)277         int8u* row_ptr(int y)       { return m_rbuf->row_ptr(y); }
row_ptr(int y)278         const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
row(int y)279         row_data     row(int y)     const { return m_rbuf->row(y); }
280 
281         //--------------------------------------------------------------------
pix_ptr(int x,int y)282         AGG_INLINE int8u* pix_ptr(int x, int y)
283         {
284             return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
285         }
286 
pix_ptr(int x,int y)287         AGG_INLINE const int8u* pix_ptr(int x, int y) const
288         {
289             return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset);
290         }
291 
292         // Return pointer to pixel value, forcing row to be allocated.
pix_value_ptr(int x,int y,unsigned len)293         AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len)
294         {
295             return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset));
296         }
297 
298         // Return pointer to pixel value, or null if row not allocated.
pix_value_ptr(int x,int y)299         AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const
300         {
301             int8u* p = m_rbuf->row_ptr(y);
302             return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
303         }
304 
305         // Get pixel pointer from raw buffer pointer.
pix_value_ptr(void * p)306         AGG_INLINE static pixel_type* pix_value_ptr(void* p)
307         {
308             return (pixel_type*)((value_type*)p + pix_offset);
309         }
310 
311         // Get pixel pointer from raw buffer pointer.
pix_value_ptr(const void * p)312         AGG_INLINE static const pixel_type* pix_value_ptr(const void* p)
313         {
314             return (const pixel_type*)((const value_type*)p + pix_offset);
315         }
316 
317         //--------------------------------------------------------------------
write_plain_color(void * p,color_type c)318         AGG_INLINE static void write_plain_color(void* p, color_type c)
319         {
320             // Grayscale formats are implicitly premultiplied.
321             c.premultiply();
322             pix_value_ptr(p)->set(c);
323         }
324 
325         //--------------------------------------------------------------------
read_plain_color(const void * p)326         AGG_INLINE static color_type read_plain_color(const void* p)
327         {
328             return pix_value_ptr(p)->get();
329         }
330 
331         //--------------------------------------------------------------------
make_pix(int8u * p,const color_type & c)332         AGG_INLINE static void make_pix(int8u* p, const color_type& c)
333         {
334             ((pixel_type*)p)->set(c);
335         }
336 
337         //--------------------------------------------------------------------
pixel(int x,int y)338         AGG_INLINE color_type pixel(int x, int y) const
339         {
340             if (const pixel_type* p = pix_value_ptr(x, y))
341             {
342                 return p->get();
343             }
344             return color_type::no_color();
345         }
346 
347         //--------------------------------------------------------------------
copy_pixel(int x,int y,const color_type & c)348         AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
349         {
350             pix_value_ptr(x, y, 1)->set(c);
351         }
352 
353         //--------------------------------------------------------------------
blend_pixel(int x,int y,const color_type & c,int8u cover)354         AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
355         {
356             copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
357         }
358 
359         //--------------------------------------------------------------------
copy_hline(int x,int y,unsigned len,const color_type & c)360         AGG_INLINE void copy_hline(int x, int y,
361                                    unsigned len,
362                                    const color_type& c)
363         {
364             pixel_type* p = pix_value_ptr(x, y, len);
365             do
366             {
367                 p->set(c);
368                 p = p->next();
369             }
370             while(--len);
371         }
372 
373 
374         //--------------------------------------------------------------------
copy_vline(int x,int y,unsigned len,const color_type & c)375         AGG_INLINE void copy_vline(int x, int y,
376                                    unsigned len,
377                                    const color_type& c)
378         {
379             do
380             {
381                 pix_value_ptr(x, y++, 1)->set(c);
382             }
383             while (--len);
384         }
385 
386 
387         //--------------------------------------------------------------------
blend_hline(int x,int y,unsigned len,const color_type & c,int8u cover)388         void blend_hline(int x, int y,
389                          unsigned len,
390                          const color_type& c,
391                          int8u cover)
392         {
393             if (!c.is_transparent())
394             {
395                 pixel_type* p = pix_value_ptr(x, y, len);
396 
397                 if (c.is_opaque() && cover == cover_mask)
398                 {
399                     do
400                     {
401                         p->set(c);
402                         p = p->next();
403                     }
404                     while (--len);
405                 }
406                 else
407                 {
408                     do
409                     {
410                         blend_pix(p, c, cover);
411                         p = p->next();
412                     }
413                     while (--len);
414                 }
415             }
416         }
417 
418 
419         //--------------------------------------------------------------------
blend_vline(int x,int y,unsigned len,const color_type & c,int8u cover)420         void blend_vline(int x, int y,
421                          unsigned len,
422                          const color_type& c,
423                          int8u cover)
424         {
425             if (!c.is_transparent())
426             {
427                 if (c.is_opaque() && cover == cover_mask)
428                 {
429                     do
430                     {
431                         pix_value_ptr(x, y++, 1)->set(c);
432                     }
433                     while (--len);
434                 }
435                 else
436                 {
437                     do
438                     {
439                         blend_pix(pix_value_ptr(x, y++, 1), c, cover);
440                     }
441                     while (--len);
442                 }
443             }
444         }
445 
446 
447         //--------------------------------------------------------------------
blend_solid_hspan(int x,int y,unsigned len,const color_type & c,const int8u * covers)448         void blend_solid_hspan(int x, int y,
449                                unsigned len,
450                                const color_type& c,
451                                const int8u* covers)
452         {
453             if (!c.is_transparent())
454             {
455                 pixel_type* p = pix_value_ptr(x, y, len);
456 
457                 do
458                 {
459                     if (c.is_opaque() && *covers == cover_mask)
460                     {
461                         p->set(c);
462                     }
463                     else
464                     {
465                         blend_pix(p, c, *covers);
466                     }
467                     p = p->next();
468                     ++covers;
469                 }
470                 while (--len);
471             }
472         }
473 
474 
475         //--------------------------------------------------------------------
blend_solid_vspan(int x,int y,unsigned len,const color_type & c,const int8u * covers)476         void blend_solid_vspan(int x, int y,
477                                unsigned len,
478                                const color_type& c,
479                                const int8u* covers)
480         {
481             if (!c.is_transparent())
482             {
483                 do
484                 {
485                     pixel_type* p = pix_value_ptr(x, y++, 1);
486 
487                     if (c.is_opaque() && *covers == cover_mask)
488                     {
489                         p->set(c);
490                     }
491                     else
492                     {
493                         blend_pix(p, c, *covers);
494                     }
495                     ++covers;
496                 }
497                 while (--len);
498             }
499         }
500 
501 
502         //--------------------------------------------------------------------
copy_color_hspan(int x,int y,unsigned len,const color_type * colors)503         void copy_color_hspan(int x, int y,
504                               unsigned len,
505                               const color_type* colors)
506         {
507             pixel_type* p = pix_value_ptr(x, y, len);
508 
509             do
510             {
511                 p->set(*colors++);
512                 p = p->next();
513             }
514             while (--len);
515         }
516 
517 
518         //--------------------------------------------------------------------
copy_color_vspan(int x,int y,unsigned len,const color_type * colors)519         void copy_color_vspan(int x, int y,
520                               unsigned len,
521                               const color_type* colors)
522         {
523             do
524             {
525                 pix_value_ptr(x, y++, 1)->set(*colors++);
526             }
527             while (--len);
528         }
529 
530 
531         //--------------------------------------------------------------------
blend_color_hspan(int x,int y,unsigned len,const color_type * colors,const int8u * covers,int8u cover)532         void blend_color_hspan(int x, int y,
533                                unsigned len,
534                                const color_type* colors,
535                                const int8u* covers,
536                                int8u cover)
537         {
538             pixel_type* p = pix_value_ptr(x, y, len);
539 
540             if (covers)
541             {
542                 do
543                 {
544                     copy_or_blend_pix(p, *colors++, *covers++);
545                     p = p->next();
546                 }
547                 while (--len);
548             }
549             else
550             {
551                 if (cover == cover_mask)
552                 {
553                     do
554                     {
555                         copy_or_blend_pix(p, *colors++);
556                         p = p->next();
557                     }
558                     while (--len);
559                 }
560                 else
561                 {
562                     do
563                     {
564                         copy_or_blend_pix(p, *colors++, cover);
565                         p = p->next();
566                     }
567                     while (--len);
568                 }
569             }
570         }
571 
572 
573         //--------------------------------------------------------------------
blend_color_vspan(int x,int y,unsigned len,const color_type * colors,const int8u * covers,int8u cover)574         void blend_color_vspan(int x, int y,
575                                unsigned len,
576                                const color_type* colors,
577                                const int8u* covers,
578                                int8u cover)
579         {
580             if (covers)
581             {
582                 do
583                 {
584                     copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
585                 }
586                 while (--len);
587             }
588             else
589             {
590                 if (cover == cover_mask)
591                 {
592                     do
593                     {
594                         copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
595                     }
596                     while (--len);
597                 }
598                 else
599                 {
600                     do
601                     {
602                         copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
603                     }
604                     while (--len);
605                 }
606             }
607         }
608 
609         //--------------------------------------------------------------------
for_each_pixel(Function f)610         template<class Function> void for_each_pixel(Function f)
611         {
612             unsigned y;
613             for (y = 0; y < height(); ++y)
614             {
615                 row_data r = m_rbuf->row(y);
616                 if (r.ptr)
617                 {
618                     unsigned len = r.x2 - r.x1 + 1;
619                     pixel_type* p = pix_value_ptr(r.x1, y, len);
620                     do
621                     {
622                         f(p->c);
623                         p = p->next();
624                     }
625                     while (--len);
626                 }
627             }
628         }
629 
630         //--------------------------------------------------------------------
apply_gamma_dir(const GammaLut & g)631         template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
632         {
633             for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
634         }
635 
636         //--------------------------------------------------------------------
apply_gamma_inv(const GammaLut & g)637         template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
638         {
639             for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
640         }
641 
642         //--------------------------------------------------------------------
643         template<class RenBuf2>
copy_from(const RenBuf2 & from,int xdst,int ydst,int xsrc,int ysrc,unsigned len)644         void copy_from(const RenBuf2& from,
645                        int xdst, int ydst,
646                        int xsrc, int ysrc,
647                        unsigned len)
648         {
649             if (const int8u* p = from.row_ptr(ysrc))
650             {
651                 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
652                         p + xsrc * pix_width,
653                         len * pix_width);
654             }
655         }
656 
657         //--------------------------------------------------------------------
658         // Blend from single color, using grayscale surface as alpha channel.
659         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)660         void blend_from_color(const SrcPixelFormatRenderer& from,
661                               const color_type& color,
662                               int xdst, int ydst,
663                               int xsrc, int ysrc,
664                               unsigned len,
665                               int8u cover)
666         {
667             typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
668             typedef typename SrcPixelFormatRenderer::color_type src_color_type;
669 
670             if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
671             {
672                 pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
673 
674                 do
675                 {
676                     copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
677                     psrc = psrc->next();
678                     pdst = pdst->next();
679                 }
680                 while (--len);
681             }
682         }
683 
684         //--------------------------------------------------------------------
685         // Blend from color table, using grayscale surface as indexes into table.
686         // Obviously, this only works for integer value types.
687         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)688         void blend_from_lut(const SrcPixelFormatRenderer& from,
689                             const color_type* color_lut,
690                             int xdst, int ydst,
691                             int xsrc, int ysrc,
692                             unsigned len,
693                             int8u cover)
694         {
695             typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
696 
697             if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
698             {
699                 pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
700 
701                 do
702                 {
703                     copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
704                     psrc = psrc->next();
705                     pdst = pdst->next();
706                 }
707                 while (--len);
708             }
709         }
710 
711     private:
712         rbuf_type* m_rbuf;
713     };
714 
715     typedef blender_gray<gray8> blender_gray8;
716     typedef blender_gray<sgray8> blender_sgray8;
717     typedef blender_gray<gray16> blender_gray16;
718     typedef blender_gray<gray32> blender_gray32;
719 
720     typedef blender_gray_pre<gray8> blender_gray8_pre;
721     typedef blender_gray_pre<sgray8> blender_sgray8_pre;
722     typedef blender_gray_pre<gray16> blender_gray16_pre;
723     typedef blender_gray_pre<gray32> blender_gray32_pre;
724 
725     typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8;
726     typedef pixfmt_alpha_blend_gray<blender_sgray8, rendering_buffer> pixfmt_sgray8;
727     typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16;
728     typedef pixfmt_alpha_blend_gray<blender_gray32, rendering_buffer> pixfmt_gray32;
729 
730     typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre;
731     typedef pixfmt_alpha_blend_gray<blender_sgray8_pre, rendering_buffer> pixfmt_sgray8_pre;
732     typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre;
733     typedef pixfmt_alpha_blend_gray<blender_gray32_pre, rendering_buffer> pixfmt_gray32_pre;
734 }
735 
736 #endif
737 
738