vfs: check userland buffers before reading them.
[haiku.git] / headers / libs / agg / agg_pixfmt_gray.h
blob08b3d7d3e5901b7798c1df2f1b654c2a305bbff1
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Adaptation for high precision colors has been sponsored by
17 // Liberty Technology Systems, Inc., visit http://lib-sys.com
19 // Liberty Technology Systems, Inc. is the provider of
20 // PostScript and PDF technology for software developers.
21 //
22 //----------------------------------------------------------------------------
24 #ifndef AGG_PIXFMT_GRAY_INCLUDED
25 #define AGG_PIXFMT_GRAY_INCLUDED
27 #include <string.h>
28 #include "agg_basics.h"
29 #include "agg_color_gray.h"
30 #include "agg_rendering_buffer.h"
32 namespace agg
35 //============================================================blender_gray
36 template<class ColorT> struct blender_gray
38 typedef ColorT color_type;
39 typedef typename color_type::value_type value_type;
40 typedef typename color_type::calc_type calc_type;
41 enum base_scale_e { base_shift = color_type::base_shift };
43 static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
44 unsigned alpha, unsigned cover=0)
46 *p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift);
51 //======================================================blender_gray_pre
52 template<class ColorT> struct blender_gray_pre
54 typedef ColorT color_type;
55 typedef typename color_type::value_type value_type;
56 typedef typename color_type::calc_type calc_type;
57 enum base_scale_e { base_shift = color_type::base_shift };
59 static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
60 unsigned alpha, unsigned cover)
62 alpha = color_type::base_mask - alpha;
63 cover = (cover + 1) << (base_shift - 8);
64 *p = (value_type)((*p * alpha + cv * cover) >> base_shift);
67 static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
68 unsigned alpha)
70 *p = (value_type)(((*p * (color_type::base_mask - alpha)) >> base_shift) + cv);
76 //=====================================================apply_gamma_dir_gray
77 template<class ColorT, class GammaLut> class apply_gamma_dir_gray
79 public:
80 typedef typename ColorT::value_type value_type;
82 apply_gamma_dir_gray(const GammaLut& gamma) : m_gamma(gamma) {}
84 AGG_INLINE void operator () (value_type* p)
86 *p = m_gamma.dir(*p);
89 private:
90 const GammaLut& m_gamma;
95 //=====================================================apply_gamma_inv_gray
96 template<class ColorT, class GammaLut> class apply_gamma_inv_gray
98 public:
99 typedef typename ColorT::value_type value_type;
101 apply_gamma_inv_gray(const GammaLut& gamma) : m_gamma(gamma) {}
103 AGG_INLINE void operator () (value_type* p)
105 *p = m_gamma.inv(*p);
108 private:
109 const GammaLut& m_gamma;
114 //=================================================pixfmt_alpha_blend_gray
115 template<class Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
116 class pixfmt_alpha_blend_gray
118 public:
119 typedef RenBuf rbuf_type;
120 typedef typename rbuf_type::row_data row_data;
121 typedef Blender blender_type;
122 typedef typename blender_type::color_type color_type;
123 typedef int order_type; // A fake one
124 typedef typename color_type::value_type value_type;
125 typedef typename color_type::calc_type calc_type;
126 enum base_scale_e
128 base_shift = color_type::base_shift,
129 base_scale = color_type::base_scale,
130 base_mask = color_type::base_mask,
131 pix_width = sizeof(value_type),
132 pix_step = Step,
133 pix_offset = Offset
136 private:
137 //--------------------------------------------------------------------
138 static AGG_INLINE void copy_or_blend_pix(value_type* p,
139 const color_type& c,
140 unsigned cover)
142 if (c.a)
144 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
145 if(alpha == base_mask)
147 *p = c.v;
149 else
151 Blender::blend_pix(p, c.v, alpha, cover);
157 static AGG_INLINE void copy_or_blend_pix(value_type* p,
158 const color_type& c)
160 if (c.a)
162 if(c.a == base_mask)
164 *p = c.v;
166 else
168 Blender::blend_pix(p, c.v, c.a);
174 public:
175 //--------------------------------------------------------------------
176 pixfmt_alpha_blend_gray(rbuf_type& rb) :
177 m_rbuf(&rb)
179 void attach(rbuf_type& rb) { m_rbuf = &rb; }
180 //--------------------------------------------------------------------
182 template<class PixFmt>
183 bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
185 rect_i r(x1, y1, x2, y2);
186 if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
188 int stride = pixf.stride();
189 m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
190 (r.x2 - r.x1) + 1,
191 (r.y2 - r.y1) + 1,
192 stride);
193 return true;
195 return false;
198 //--------------------------------------------------------------------
199 AGG_INLINE unsigned width() const { return m_rbuf->width(); }
200 AGG_INLINE unsigned height() const { return m_rbuf->height(); }
201 AGG_INLINE int stride() const { return m_rbuf->stride(); }
203 //--------------------------------------------------------------------
204 int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
205 const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
206 row_data row(int y) const { return m_rbuf->row(y); }
208 const int8u* pix_ptr(int x, int y) const
210 return m_rbuf->row_ptr(y) + x * Step + Offset;
213 int8u* pix_ptr(int x, int y)
215 return m_rbuf->row_ptr(y) + x * Step + Offset;
218 //--------------------------------------------------------------------
219 AGG_INLINE static void make_pix(int8u* p, const color_type& c)
221 *(value_type*)p = c.v;
224 //--------------------------------------------------------------------
225 AGG_INLINE color_type pixel(int x, int y) const
227 value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset;
228 return color_type(*p);
231 //--------------------------------------------------------------------
232 AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
234 *((value_type*)m_rbuf->row_ptr(x, y, 1) + x * Step + Offset) = c.v;
237 //--------------------------------------------------------------------
238 AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
240 copy_or_blend_pix((value_type*)
241 m_rbuf->row_ptr(x, y, 1) + x * Step + Offset,
243 cover);
247 //--------------------------------------------------------------------
248 AGG_INLINE void copy_hline(int x, int y,
249 unsigned len,
250 const color_type& c)
252 value_type* p = (value_type*)
253 m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
257 *p = c.v;
258 p += Step;
260 while(--len);
264 //--------------------------------------------------------------------
265 AGG_INLINE void copy_vline(int x, int y,
266 unsigned len,
267 const color_type& c)
271 value_type* p = (value_type*)
272 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
274 *p = c.v;
276 while(--len);
280 //--------------------------------------------------------------------
281 void blend_hline(int x, int y,
282 unsigned len,
283 const color_type& c,
284 int8u cover)
286 if (c.a)
288 value_type* p = (value_type*)
289 m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
291 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
292 if(alpha == base_mask)
296 *p = c.v;
297 p += Step;
299 while(--len);
301 else
305 Blender::blend_pix(p, c.v, alpha, cover);
306 p += Step;
308 while(--len);
314 //--------------------------------------------------------------------
315 void blend_vline(int x, int y,
316 unsigned len,
317 const color_type& c,
318 int8u cover)
320 if (c.a)
322 value_type* p;
323 calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
324 if(alpha == base_mask)
328 p = (value_type*)
329 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
331 *p = c.v;
333 while(--len);
335 else
339 p = (value_type*)
340 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
342 Blender::blend_pix(p, c.v, alpha, cover);
344 while(--len);
350 //--------------------------------------------------------------------
351 void blend_solid_hspan(int x, int y,
352 unsigned len,
353 const color_type& c,
354 const int8u* covers)
356 if (c.a)
358 value_type* p = (value_type*)
359 m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
363 calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
364 if(alpha == base_mask)
366 *p = c.v;
368 else
370 Blender::blend_pix(p, c.v, alpha, *covers);
372 p += Step;
373 ++covers;
375 while(--len);
380 //--------------------------------------------------------------------
381 void blend_solid_vspan(int x, int y,
382 unsigned len,
383 const color_type& c,
384 const int8u* covers)
386 if (c.a)
390 calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
392 value_type* p = (value_type*)
393 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
395 if(alpha == base_mask)
397 *p = c.v;
399 else
401 Blender::blend_pix(p, c.v, alpha, *covers);
403 ++covers;
405 while(--len);
410 //--------------------------------------------------------------------
411 void copy_color_hspan(int x, int y,
412 unsigned len,
413 const color_type* colors)
415 value_type* p = (value_type*)
416 m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
420 *p = colors->v;
421 p += Step;
422 ++colors;
424 while(--len);
428 //--------------------------------------------------------------------
429 void copy_color_vspan(int x, int y,
430 unsigned len,
431 const color_type* colors)
435 value_type* p = (value_type*)
436 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
437 *p = colors->v;
438 ++colors;
440 while(--len);
444 //--------------------------------------------------------------------
445 void blend_color_hspan(int x, int y,
446 unsigned len,
447 const color_type* colors,
448 const int8u* covers,
449 int8u cover)
451 value_type* p = (value_type*)
452 m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
454 if(covers)
458 copy_or_blend_pix(p, *colors++, *covers++);
459 p += Step;
461 while(--len);
463 else
465 if(cover == 255)
469 if(colors->a == base_mask)
471 *p = colors->v;
473 else
475 copy_or_blend_pix(p, *colors);
477 p += Step;
478 ++colors;
480 while(--len);
482 else
486 copy_or_blend_pix(p, *colors++, cover);
487 p += Step;
489 while(--len);
496 //--------------------------------------------------------------------
497 void blend_color_vspan(int x, int y,
498 unsigned len,
499 const color_type* colors,
500 const int8u* covers,
501 int8u cover)
503 value_type* p;
504 if(covers)
508 p = (value_type*)
509 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
511 copy_or_blend_pix(p, *colors++, *covers++);
513 while(--len);
515 else
517 if(cover == 255)
521 p = (value_type*)
522 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
524 if(colors->a == base_mask)
526 *p = colors->v;
528 else
530 copy_or_blend_pix(p, *colors);
532 ++colors;
534 while(--len);
536 else
540 p = (value_type*)
541 m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
543 copy_or_blend_pix(p, *colors++, cover);
545 while(--len);
550 //--------------------------------------------------------------------
551 template<class Function> void for_each_pixel(Function f)
553 unsigned y;
554 for(y = 0; y < height(); ++y)
556 row_data r = m_rbuf->row(y);
557 if(r.ptr)
559 unsigned len = r.x2 - r.x1 + 1;
561 value_type* p = (value_type*)
562 m_rbuf->row_ptr(r.x1, y, len) + r.x1 * Step + Offset;
566 f(p);
567 p += Step;
569 while(--len);
574 //--------------------------------------------------------------------
575 template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
577 for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
580 //--------------------------------------------------------------------
581 template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
583 for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
586 //--------------------------------------------------------------------
587 template<class RenBuf2>
588 void copy_from(const RenBuf2& from,
589 int xdst, int ydst,
590 int xsrc, int ysrc,
591 unsigned len)
593 const int8u* p = from.row_ptr(ysrc);
594 if(p)
596 memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
597 p + xsrc * pix_width,
598 len * pix_width);
602 private:
603 rbuf_type* m_rbuf;
606 typedef blender_gray<gray8> blender_gray8;
607 typedef blender_gray_pre<gray8> blender_gray8_pre;
608 typedef blender_gray<gray16> blender_gray16;
609 typedef blender_gray_pre<gray16> blender_gray16_pre;
611 typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8; //----pixfmt_gray8
612 typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre; //----pixfmt_gray8_pre
613 typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16; //----pixfmt_gray16
614 typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre; //----pixfmt_gray16_pre
617 #endif