Anti-Grain Geometry Tutorial
agg_image_accessors.h
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 #ifndef AGG_IMAGE_ACCESSORS_INCLUDED
17 #define AGG_IMAGE_ACCESSORS_INCLUDED
18 
19 #include "agg_basics.h"
20 
21 namespace agg
22 {
23 
24  //-----------------------------------------------------image_accessor_clip
25  template<class PixFmt> class image_accessor_clip
26  {
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 };
33 
35  explicit image_accessor_clip(pixfmt_type& pixf,
36  const color_type& bk) :
37  m_pixf(&pixf)
38  {
39  pixfmt_type::make_pix(m_bk_buf, bk);
40  }
41 
42  void attach(pixfmt_type& pixf)
43  {
44  m_pixf = &pixf;
45  }
46 
47  void background_color(const color_type& bk)
48  {
49  pixfmt_type::make_pix(m_bk_buf, bk);
50  }
51 
52  private:
53  AGG_INLINE const int8u* pixel() const
54  {
55  if(m_y >= 0 && m_y < (int)m_pixf->height() &&
56  m_x >= 0 && m_x < (int)m_pixf->width())
57  {
58  return m_pixf->pix_ptr(m_x, m_y);
59  }
60  return m_bk_buf;
61  }
62 
63  public:
64  AGG_INLINE const int8u* span(int x, int y, unsigned len)
65  {
66  m_x = m_x0 = x;
67  m_y = y;
68  if(y >= 0 && y < (int)m_pixf->height() &&
69  x >= 0 && x+(int)len <= (int)m_pixf->width())
70  {
71  return m_pix_ptr = m_pixf->pix_ptr(x, y);
72  }
73  m_pix_ptr = 0;
74  return pixel();
75  }
76 
77  AGG_INLINE const int8u* next_x()
78  {
79  if(m_pix_ptr) return m_pix_ptr += pix_width;
80  ++m_x;
81  return pixel();
82  }
83 
84  AGG_INLINE const int8u* next_y()
85  {
86  ++m_y;
87  m_x = m_x0;
88  if(m_pix_ptr &&
89  m_y >= 0 && m_y < (int)m_pixf->height())
90  {
91  return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
92  }
93  m_pix_ptr = 0;
94  return pixel();
95  }
96 
97  private:
98  const pixfmt_type* m_pixf;
99  int8u m_bk_buf[pix_width];
100  int m_x, m_x0, m_y;
101  const int8u* m_pix_ptr;
102  };
103 
104 
105 
106 
107  //--------------------------------------------------image_accessor_no_clip
108  template<class PixFmt> class image_accessor_no_clip
109  {
110  public:
111  typedef PixFmt pixfmt_type;
112  typedef typename pixfmt_type::color_type color_type;
113  typedef typename pixfmt_type::order_type order_type;
114  typedef typename pixfmt_type::value_type value_type;
115  enum pix_width_e { pix_width = pixfmt_type::pix_width };
116 
118  explicit image_accessor_no_clip(pixfmt_type& pixf) :
119  m_pixf(&pixf)
120  {}
121 
122  void attach(pixfmt_type& pixf)
123  {
124  m_pixf = &pixf;
125  }
126 
127  AGG_INLINE const int8u* span(int x, int y, unsigned)
128  {
129  m_x = x;
130  m_y = y;
131  return m_pix_ptr = m_pixf->pix_ptr(x, y);
132  }
133 
134  AGG_INLINE const int8u* next_x()
135  {
136  return m_pix_ptr += pix_width;
137  }
138 
139  AGG_INLINE const int8u* next_y()
140  {
141  ++m_y;
142  return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
143  }
144 
145  private:
146  const pixfmt_type* m_pixf;
147  int m_x, m_y;
148  const int8u* m_pix_ptr;
149  };
150 
151 
152 
153 
154  //----------------------------------------------------image_accessor_clone
155  template<class PixFmt> class image_accessor_clone
156  {
157  public:
158  typedef PixFmt pixfmt_type;
159  typedef typename pixfmt_type::color_type color_type;
160  typedef typename pixfmt_type::order_type order_type;
161  typedef typename pixfmt_type::value_type value_type;
162  enum pix_width_e { pix_width = pixfmt_type::pix_width };
163 
165  explicit image_accessor_clone(pixfmt_type& pixf) :
166  m_pixf(&pixf)
167  {}
168 
169  void attach(pixfmt_type& pixf)
170  {
171  m_pixf = &pixf;
172  }
173 
174  private:
175  AGG_INLINE const int8u* pixel() const
176  {
177  int x = m_x;
178  int y = m_y;
179  if(x < 0) x = 0;
180  if(y < 0) y = 0;
181  if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1;
182  if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
183  return m_pixf->pix_ptr(x, y);
184  }
185 
186  public:
187  AGG_INLINE const int8u* span(int x, int y, unsigned len)
188  {
189  m_x = m_x0 = x;
190  m_y = y;
191  if(y >= 0 && y < (int)m_pixf->height() &&
192  x >= 0 && x+len <= (int)m_pixf->width())
193  {
194  return m_pix_ptr = m_pixf->pix_ptr(x, y);
195  }
196  m_pix_ptr = 0;
197  return pixel();
198  }
199 
200  AGG_INLINE const int8u* next_x()
201  {
202  if(m_pix_ptr) return m_pix_ptr += pix_width;
203  ++m_x;
204  return pixel();
205  }
206 
207  AGG_INLINE const int8u* next_y()
208  {
209  ++m_y;
210  m_x = m_x0;
211  if(m_pix_ptr &&
212  m_y >= 0 && m_y < (int)m_pixf->height())
213  {
214  return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
215  }
216  m_pix_ptr = 0;
217  return pixel();
218  }
219 
220  private:
221  const pixfmt_type* m_pixf;
222  int m_x, m_x0, m_y;
223  const int8u* m_pix_ptr;
224  };
225 
226 
227 
228 
229 
230  //-----------------------------------------------------image_accessor_wrap
231  template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
232  {
233  public:
234  typedef PixFmt pixfmt_type;
235  typedef typename pixfmt_type::color_type color_type;
236  typedef typename pixfmt_type::order_type order_type;
237  typedef typename pixfmt_type::value_type value_type;
238  enum pix_width_e { pix_width = pixfmt_type::pix_width };
239 
241  explicit image_accessor_wrap(pixfmt_type& pixf) :
242  m_pixf(&pixf),
243  m_wrap_x(pixf.width()),
244  m_wrap_y(pixf.height())
245  {}
246 
247  void attach(pixfmt_type& pixf)
248  {
249  m_pixf = &pixf;
250  }
251 
252  AGG_INLINE const int8u* span(int x, int y, unsigned)
253  {
254  m_x = x;
255  m_row_ptr = m_pixf->pix_ptr(0, m_wrap_y(y));
256  return m_row_ptr + m_wrap_x(x) * pix_width;
257  }
258 
259  AGG_INLINE const int8u* next_x()
260  {
261  int x = ++m_wrap_x;
262  return m_row_ptr + x * pix_width;
263  }
264 
265  AGG_INLINE const int8u* next_y()
266  {
267  m_row_ptr = m_pixf->pix_ptr(0, ++m_wrap_y);
268  return m_row_ptr + m_wrap_x(m_x) * pix_width;
269  }
270 
271  private:
272  const pixfmt_type* m_pixf;
273  const int8u* m_row_ptr;
274  int m_x;
275  WrapX m_wrap_x;
276  WrapY m_wrap_y;
277  };
278 
279 
280 
281 
282  //--------------------------------------------------------wrap_mode_repeat
284  {
285  public:
286  wrap_mode_repeat() {}
287  wrap_mode_repeat(unsigned size) :
288  m_size(size),
289  m_add(size * (0x3FFFFFFF / size)),
290  m_value(0)
291  {}
292 
293  AGG_INLINE unsigned operator() (int v)
294  {
295  return m_value = (unsigned(v) + m_add) % m_size;
296  }
297 
298  AGG_INLINE unsigned operator++ ()
299  {
300  ++m_value;
301  if(m_value >= m_size) m_value = 0;
302  return m_value;
303  }
304  private:
305  unsigned m_size;
306  unsigned m_add;
307  unsigned m_value;
308  };
309 
310 
311  //---------------------------------------------------wrap_mode_repeat_pow2
313  {
314  public:
316  wrap_mode_repeat_pow2(unsigned size) : m_value(0)
317  {
318  m_mask = 1;
319  while(m_mask < size) m_mask = (m_mask << 1) | 1;
320  m_mask >>= 1;
321  }
322  AGG_INLINE unsigned operator() (int v)
323  {
324  return m_value = unsigned(v) & m_mask;
325  }
326  AGG_INLINE unsigned operator++ ()
327  {
328  ++m_value;
329  if(m_value > m_mask) m_value = 0;
330  return m_value;
331  }
332  private:
333  unsigned m_mask;
334  unsigned m_value;
335  };
336 
337 
338  //----------------------------------------------wrap_mode_repeat_auto_pow2
340  {
341  public:
343  wrap_mode_repeat_auto_pow2(unsigned size) :
344  m_size(size),
345  m_add(size * (0x3FFFFFFF / size)),
346  m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
347  m_value(0)
348  {}
349 
350  AGG_INLINE unsigned operator() (int v)
351  {
352  if(m_mask) return m_value = unsigned(v) & m_mask;
353  return m_value = (unsigned(v) + m_add) % m_size;
354  }
355  AGG_INLINE unsigned operator++ ()
356  {
357  ++m_value;
358  if(m_value >= m_size) m_value = 0;
359  return m_value;
360  }
361 
362  private:
363  unsigned m_size;
364  unsigned m_add;
365  unsigned m_mask;
366  unsigned m_value;
367  };
368 
369 
370  //-------------------------------------------------------wrap_mode_reflect
372  {
373  public:
374  wrap_mode_reflect() {}
375  wrap_mode_reflect(unsigned size) :
376  m_size(size),
377  m_size2(size * 2),
378  m_add(m_size2 * (0x3FFFFFFF / m_size2)),
379  m_value(0)
380  {}
381 
382  AGG_INLINE unsigned operator() (int v)
383  {
384  m_value = (unsigned(v) + m_add) % m_size2;
385  if(m_value >= m_size) return m_size2 - m_value - 1;
386  return m_value;
387  }
388 
389  AGG_INLINE unsigned operator++ ()
390  {
391  ++m_value;
392  if(m_value >= m_size2) m_value = 0;
393  if(m_value >= m_size) return m_size2 - m_value - 1;
394  return m_value;
395  }
396  private:
397  unsigned m_size;
398  unsigned m_size2;
399  unsigned m_add;
400  unsigned m_value;
401  };
402 
403 
404 
405  //--------------------------------------------------wrap_mode_reflect_pow2
407  {
408  public:
410  wrap_mode_reflect_pow2(unsigned size) : m_value(0)
411  {
412  m_mask = 1;
413  m_size = 1;
414  while(m_mask < size)
415  {
416  m_mask = (m_mask << 1) | 1;
417  m_size <<= 1;
418  }
419  }
420  AGG_INLINE unsigned operator() (int v)
421  {
422  m_value = unsigned(v) & m_mask;
423  if(m_value >= m_size) return m_mask - m_value;
424  return m_value;
425  }
426  AGG_INLINE unsigned operator++ ()
427  {
428  ++m_value;
429  m_value &= m_mask;
430  if(m_value >= m_size) return m_mask - m_value;
431  return m_value;
432  }
433  private:
434  unsigned m_size;
435  unsigned m_mask;
436  unsigned m_value;
437  };
438 
439 
440 
441  //---------------------------------------------wrap_mode_reflect_auto_pow2
443  {
444  public:
446  wrap_mode_reflect_auto_pow2(unsigned size) :
447  m_size(size),
448  m_size2(size * 2),
449  m_add(m_size2 * (0x3FFFFFFF / m_size2)),
450  m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
451  m_value(0)
452  {}
453 
454  AGG_INLINE unsigned operator() (int v)
455  {
456  m_value = m_mask ? unsigned(v) & m_mask :
457  (unsigned(v) + m_add) % m_size2;
458  if(m_value >= m_size) return m_size2 - m_value - 1;
459  return m_value;
460  }
461  AGG_INLINE unsigned operator++ ()
462  {
463  ++m_value;
464  if(m_value >= m_size2) m_value = 0;
465  if(m_value >= m_size) return m_size2 - m_value - 1;
466  return m_value;
467  }
468 
469  private:
470  unsigned m_size;
471  unsigned m_size2;
472  unsigned m_add;
473  unsigned m_mask;
474  unsigned m_value;
475  };
476 
477 
478 }
479 
480 
481 #endif
Definition: agg_arc.cpp:24