btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / libs / agg / agg_image_accessors.h
blobd551dbc6247f1fde1f329ff090fd334056f2ea55
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 #ifndef AGG_IMAGE_ACCESSORS_INCLUDED
17 #define AGG_IMAGE_ACCESSORS_INCLUDED
19 #include "agg_basics.h"
21 namespace agg
24 //-----------------------------------------------------image_accessor_clip
25 template<class PixFmt> class image_accessor_clip
27 public:
28 typedef PixFmt pixfmt_type;
29 typedef typename pixfmt_type::color_type color_type;
30 typedef typename pixfmt_type::order_type order_type;
31 typedef typename pixfmt_type::value_type value_type;
32 enum pix_width_e { pix_width = pixfmt_type::pix_width };
34 image_accessor_clip() {}
35 image_accessor_clip(const pixfmt_type& pixf, const color_type& bk) :
36 m_pixf(&pixf)
38 pixfmt_type::make_pix(m_bk_buf, bk);
41 void attach(const pixfmt_type& pixf)
43 m_pixf = &pixf;
46 void background_color(const color_type& bk)
48 pixfmt_type::make_pix(m_bk_buf, bk);
51 private:
52 AGG_INLINE const int8u* pixel() const
54 if(m_y >= 0 && m_y < (int)m_pixf->height() &&
55 m_x >= 0 && m_x < (int)m_pixf->width())
57 return m_pixf->pix_ptr(m_x, m_y);
59 return m_bk_buf;
62 public:
63 AGG_INLINE const int8u* span(int x, int y, unsigned len)
65 m_x = m_x0 = x;
66 m_y = y;
67 if(y >= 0 && y < (int)m_pixf->height() &&
68 x >= 0 && x+(int)len <= (int)m_pixf->width())
70 return m_pix_ptr = m_pixf->pix_ptr(x, y);
72 m_pix_ptr = 0;
73 return pixel();
76 AGG_INLINE const int8u* next_x()
78 if(m_pix_ptr) return m_pix_ptr += pix_width;
79 ++m_x;
80 return pixel();
83 AGG_INLINE const int8u* next_y()
85 ++m_y;
86 m_x = m_x0;
87 if(m_pix_ptr &&
88 m_y >= 0 && m_y < (int)m_pixf->height())
90 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
92 m_pix_ptr = 0;
93 return pixel();
96 private:
97 const pixfmt_type* m_pixf;
98 int8u m_bk_buf[4];
99 int m_x, m_x0, m_y;
100 const int8u* m_pix_ptr;
106 //--------------------------------------------------image_accessor_no_clip
107 template<class PixFmt> class image_accessor_no_clip
109 public:
110 typedef PixFmt pixfmt_type;
111 typedef typename pixfmt_type::color_type color_type;
112 typedef typename pixfmt_type::order_type order_type;
113 typedef typename pixfmt_type::value_type value_type;
114 enum pix_width_e { pix_width = pixfmt_type::pix_width };
116 image_accessor_no_clip() {}
117 image_accessor_no_clip(const pixfmt_type& pixf) : m_pixf(&pixf) {}
119 void attach(const pixfmt_type& pixf)
121 m_pixf = &pixf;
124 AGG_INLINE const int8u* span(int x, int y, unsigned)
126 m_x = x;
127 m_y = y;
128 return m_pix_ptr = m_pixf->pix_ptr(x, y);
131 AGG_INLINE const int8u* next_x()
133 return m_pix_ptr += pix_width;
136 AGG_INLINE const int8u* next_y()
138 ++m_y;
139 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
142 private:
143 const pixfmt_type* m_pixf;
144 int m_x, m_y;
145 const int8u* m_pix_ptr;
151 //----------------------------------------------------image_accessor_clone
152 template<class PixFmt> class image_accessor_clone
154 public:
155 typedef PixFmt pixfmt_type;
156 typedef typename pixfmt_type::color_type color_type;
157 typedef typename pixfmt_type::order_type order_type;
158 typedef typename pixfmt_type::value_type value_type;
159 enum pix_width_e { pix_width = pixfmt_type::pix_width };
161 image_accessor_clone() {}
162 image_accessor_clone(const pixfmt_type& pixf) : m_pixf(&pixf) {}
164 void attach(const pixfmt_type& pixf)
166 m_pixf = &pixf;
169 private:
170 AGG_INLINE const int8u* pixel() const
172 register int x = m_x;
173 register int y = m_y;
174 if(x < 0) x = 0;
175 if(y < 0) y = 0;
176 if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1;
177 if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
178 return m_pixf->pix_ptr(x, y);
181 public:
182 AGG_INLINE const int8u* span(int x, int y, unsigned len)
184 m_x = m_x0 = x;
185 m_y = y;
186 if(y >= 0 && y < (int)m_pixf->height() &&
187 x >= 0 && (int)(x+len) <= (int)m_pixf->width())
189 return m_pix_ptr = m_pixf->pix_ptr(x, y);
191 m_pix_ptr = 0;
192 return pixel();
195 AGG_INLINE const int8u* next_x()
197 if(m_pix_ptr) return m_pix_ptr += pix_width;
198 ++m_x;
199 return pixel();
202 AGG_INLINE const int8u* next_y()
204 ++m_y;
205 m_x = m_x0;
206 if(m_pix_ptr &&
207 m_y >= 0 && m_y < (int)m_pixf->height())
209 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
211 m_pix_ptr = 0;
212 return pixel();
215 private:
216 const pixfmt_type* m_pixf;
217 int m_x, m_x0, m_y;
218 const int8u* m_pix_ptr;
225 //-----------------------------------------------------image_accessor_wrap
226 template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
228 public:
229 typedef PixFmt pixfmt_type;
230 typedef typename pixfmt_type::color_type color_type;
231 typedef typename pixfmt_type::order_type order_type;
232 typedef typename pixfmt_type::value_type value_type;
233 enum pix_width_e { pix_width = pixfmt_type::pix_width };
235 image_accessor_wrap() {}
236 image_accessor_wrap(const pixfmt_type& pixf) :
237 m_pixf(&pixf),
238 m_wrap_x(pixf.width()),
239 m_wrap_y(pixf.height())
242 void attach(const pixfmt_type& pixf)
244 m_pixf = &pixf;
247 AGG_INLINE const int8u* span(int x, int y, unsigned)
249 m_x = x;
250 m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
251 return m_row_ptr + m_wrap_x(x) * pix_width;
254 AGG_INLINE const int8u* next_x()
256 int x = ++m_wrap_x;
257 return m_row_ptr + x * pix_width;
260 AGG_INLINE const int8u* next_y()
262 m_row_ptr = m_pixf->row_ptr(++m_wrap_y);
263 return m_row_ptr + m_wrap_x(m_x) * pix_width;
266 private:
267 const pixfmt_type* m_pixf;
268 const int8u* m_row_ptr;
269 int m_x;
270 WrapX m_wrap_x;
271 WrapY m_wrap_y;
277 //--------------------------------------------------------wrap_mode_repeat
278 class wrap_mode_repeat
280 public:
281 wrap_mode_repeat() {}
282 wrap_mode_repeat(unsigned size) :
283 m_size(size),
284 m_add(size * (0x3FFFFFFF / size)),
285 m_value(0)
288 AGG_INLINE unsigned operator() (int v)
290 return m_value = (unsigned(v) + m_add) % m_size;
293 AGG_INLINE unsigned operator++ ()
295 ++m_value;
296 if(m_value >= m_size) m_value = 0;
297 return m_value;
299 private:
300 unsigned m_size;
301 unsigned m_add;
302 unsigned m_value;
306 //---------------------------------------------------wrap_mode_repeat_pow2
307 class wrap_mode_repeat_pow2
309 public:
310 wrap_mode_repeat_pow2() {}
311 wrap_mode_repeat_pow2(unsigned size) : m_value(0)
313 m_mask = 1;
314 while(m_mask < size) m_mask = (m_mask << 1) | 1;
315 m_mask >>= 1;
317 AGG_INLINE unsigned operator() (int v)
319 return m_value = unsigned(v) & m_mask;
321 AGG_INLINE unsigned operator++ ()
323 ++m_value;
324 if(m_value > m_mask) m_value = 0;
325 return m_value;
327 private:
328 unsigned m_mask;
329 unsigned m_value;
333 //----------------------------------------------wrap_mode_repeat_auto_pow2
334 class wrap_mode_repeat_auto_pow2
336 public:
337 wrap_mode_repeat_auto_pow2() {}
338 wrap_mode_repeat_auto_pow2(unsigned size) :
339 m_size(size),
340 m_add(size * (0x3FFFFFFF / size)),
341 m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
342 m_value(0)
345 AGG_INLINE unsigned operator() (int v)
347 if(m_mask) return m_value = unsigned(v) & m_mask;
348 return m_value = (unsigned(v) + m_add) % m_size;
350 AGG_INLINE unsigned operator++ ()
352 ++m_value;
353 if(m_value >= m_size) m_value = 0;
354 return m_value;
357 private:
358 unsigned m_size;
359 unsigned m_add;
360 unsigned m_mask;
361 unsigned m_value;
365 //-------------------------------------------------------wrap_mode_reflect
366 class wrap_mode_reflect
368 public:
369 wrap_mode_reflect() {}
370 wrap_mode_reflect(unsigned size) :
371 m_size(size),
372 m_size2(size * 2),
373 m_add(m_size2 * (0x3FFFFFFF / m_size2)),
374 m_value(0)
377 AGG_INLINE unsigned operator() (int v)
379 m_value = (unsigned(v) + m_add) % m_size2;
380 if(m_value >= m_size) return m_size2 - m_value - 1;
381 return m_value;
384 AGG_INLINE unsigned operator++ ()
386 ++m_value;
387 if(m_value >= m_size2) m_value = 0;
388 if(m_value >= m_size) return m_size2 - m_value - 1;
389 return m_value;
391 private:
392 unsigned m_size;
393 unsigned m_size2;
394 unsigned m_add;
395 unsigned m_value;
400 //--------------------------------------------------wrap_mode_reflect_pow2
401 class wrap_mode_reflect_pow2
403 public:
404 wrap_mode_reflect_pow2() {}
405 wrap_mode_reflect_pow2(unsigned size) : m_value(0)
407 m_mask = 1;
408 m_size = 1;
409 while(m_mask < size)
411 m_mask = (m_mask << 1) | 1;
412 m_size <<= 1;
415 AGG_INLINE unsigned operator() (int v)
417 m_value = unsigned(v) & m_mask;
418 if(m_value >= m_size) return m_mask - m_value;
419 return m_value;
421 AGG_INLINE unsigned operator++ ()
423 ++m_value;
424 m_value &= m_mask;
425 if(m_value >= m_size) return m_mask - m_value;
426 return m_value;
428 private:
429 unsigned m_size;
430 unsigned m_mask;
431 unsigned m_value;
436 //---------------------------------------------wrap_mode_reflect_auto_pow2
437 class wrap_mode_reflect_auto_pow2
439 public:
440 wrap_mode_reflect_auto_pow2() {}
441 wrap_mode_reflect_auto_pow2(unsigned size) :
442 m_size(size),
443 m_size2(size * 2),
444 m_add(m_size2 * (0x3FFFFFFF / m_size2)),
445 m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
446 m_value(0)
449 AGG_INLINE unsigned operator() (int v)
451 m_value = m_mask ? unsigned(v) & m_mask :
452 (unsigned(v) + m_add) % m_size2;
453 if(m_value >= m_size) return m_size2 - m_value - 1;
454 return m_value;
456 AGG_INLINE unsigned operator++ ()
458 ++m_value;
459 if(m_value >= m_size2) m_value = 0;
460 if(m_value >= m_size) return m_size2 - m_value - 1;
461 return m_value;
464 private:
465 unsigned m_size;
466 unsigned m_size2;
467 unsigned m_add;
468 unsigned m_mask;
469 unsigned m_value;
476 #endif