Anti-Grain Geometry Tutorial
agg_rendering_buffer.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 // class rendering_buffer
17 //
18 //----------------------------------------------------------------------------
19 
20 #ifndef AGG_RENDERING_BUFFER_INCLUDED
21 #define AGG_RENDERING_BUFFER_INCLUDED
22 
23 #include <cstring>
24 #include "agg_array.h"
25 
26 namespace agg
27 {
28 
29  //===========================================================row_accessor
30  template<class T> class row_accessor
31  {
32  public:
34 
35  //-------------------------------------------------------------------
36  row_accessor() :
37  m_buf(0),
38  m_start(0),
39  m_width(0),
40  m_height(0),
41  m_stride(0)
42  {
43  }
44 
45  //--------------------------------------------------------------------
46  row_accessor(T* buf, unsigned width, unsigned height, int stride) :
47  m_buf(0),
48  m_start(0),
49  m_width(0),
50  m_height(0),
51  m_stride(0)
52  {
53  attach(buf, width, height, stride);
54  }
55 
56 
57  //--------------------------------------------------------------------
58  void attach(T* buf, unsigned width, unsigned height, int stride)
59  {
60  m_buf = m_start = buf;
61  m_width = width;
62  m_height = height;
63  m_stride = stride;
64  if(stride < 0)
65  {
66  m_start = m_buf - (AGG_INT64)(height - 1) * stride;
67  }
68  }
69 
70  //--------------------------------------------------------------------
71  AGG_INLINE T* buf() { return m_buf; }
72  AGG_INLINE const T* buf() const { return m_buf; }
73  AGG_INLINE unsigned width() const { return m_width; }
74  AGG_INLINE unsigned height() const { return m_height; }
75  AGG_INLINE int stride() const { return m_stride; }
76  AGG_INLINE unsigned stride_abs() const
77  {
78  return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
79  }
80 
81  //--------------------------------------------------------------------
82  AGG_INLINE T* row_ptr(int, int y, unsigned)
83  {
84  return m_start + y * (AGG_INT64)m_stride;
85  }
86  AGG_INLINE T* row_ptr(int y) { return m_start + y * (AGG_INT64)m_stride; }
87  AGG_INLINE const T* row_ptr(int y) const { return m_start + y * (AGG_INT64)m_stride; }
88  AGG_INLINE row_data row (int y) const
89  {
90  return row_data(0, m_width-1, row_ptr(y));
91  }
92 
93  //--------------------------------------------------------------------
94  template<class RenBuf>
95  void copy_from(const RenBuf& src)
96  {
97  unsigned h = height();
98  if(src.height() < h) h = src.height();
99 
100  unsigned l = stride_abs();
101  if(src.stride_abs() < l) l = src.stride_abs();
102 
103  l *= sizeof(T);
104 
105  unsigned y;
106  unsigned w = width();
107  for (y = 0; y < h; y++)
108  {
109  std::memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
110  }
111  }
112 
113  //--------------------------------------------------------------------
114  void clear(T value)
115  {
116  unsigned y;
117  unsigned w = width();
118  unsigned stride = stride_abs();
119  for(y = 0; y < height(); y++)
120  {
121  T* p = row_ptr(0, y, w);
122  unsigned x;
123  for(x = 0; x < stride; x++)
124  {
125  *p++ = value;
126  }
127  }
128  }
129 
130  private:
131  //--------------------------------------------------------------------
132  T* m_buf; // Pointer to renrdering buffer
133  T* m_start; // Pointer to first pixel depending on stride
134  unsigned m_width; // Width in pixels
135  unsigned m_height; // Height in pixels
136  int m_stride; // Number of bytes per row. Can be < 0
137  };
138 
139 
140 
141 
142  //==========================================================row_ptr_cache
143  template<class T> class row_ptr_cache
144  {
145  public:
146  typedef const_row_info<T> row_data;
147 
148  //-------------------------------------------------------------------
149  row_ptr_cache() :
150  m_buf(0),
151  m_rows(),
152  m_width(0),
153  m_height(0),
154  m_stride(0)
155  {
156  }
157 
158  //--------------------------------------------------------------------
159  row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) :
160  m_buf(0),
161  m_rows(),
162  m_width(0),
163  m_height(0),
164  m_stride(0)
165  {
166  attach(buf, width, height, stride);
167  }
168 
169  //--------------------------------------------------------------------
170  void attach(T* buf, unsigned width, unsigned height, int stride)
171  {
172  m_buf = buf;
173  m_width = width;
174  m_height = height;
175  m_stride = stride;
176  if(height > m_rows.size())
177  {
178  m_rows.resize(height);
179  }
180 
181  T* row_ptr = m_buf;
182 
183  if(stride < 0)
184  {
185  row_ptr = m_buf - (AGG_INT64)(height - 1) * stride;
186  }
187 
188  T** rows = &m_rows[0];
189 
190  while(height--)
191  {
192  *rows++ = row_ptr;
193  row_ptr += stride;
194  }
195  }
196 
197  //--------------------------------------------------------------------
198  AGG_INLINE T* buf() { return m_buf; }
199  AGG_INLINE const T* buf() const { return m_buf; }
200  AGG_INLINE unsigned width() const { return m_width; }
201  AGG_INLINE unsigned height() const { return m_height; }
202  AGG_INLINE int stride() const { return m_stride; }
203  AGG_INLINE unsigned stride_abs() const
204  {
205  return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
206  }
207 
208  //--------------------------------------------------------------------
209  AGG_INLINE T* row_ptr(int, int y, unsigned)
210  {
211  return m_rows[y];
212  }
213  AGG_INLINE T* row_ptr(int y) { return m_rows[y]; }
214  AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; }
215  AGG_INLINE row_data row (int y) const
216  {
217  return row_data(0, m_width-1, m_rows[y]);
218  }
219 
220  //--------------------------------------------------------------------
221  T const* const* rows() const { return &m_rows[0]; }
222 
223  //--------------------------------------------------------------------
224  template<class RenBuf>
225  void copy_from(const RenBuf& src)
226  {
227  unsigned h = height();
228  if(src.height() < h) h = src.height();
229 
230  unsigned l = stride_abs();
231  if(src.stride_abs() < l) l = src.stride_abs();
232 
233  l *= sizeof(T);
234 
235  unsigned y;
236  unsigned w = width();
237  for (y = 0; y < h; y++)
238  {
239  std::memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
240  }
241  }
242 
243  //--------------------------------------------------------------------
244  void clear(T value)
245  {
246  unsigned y;
247  unsigned w = width();
248  unsigned stride = stride_abs();
249  for(y = 0; y < height(); y++)
250  {
251  T* p = row_ptr(0, y, w);
252  unsigned x;
253  for(x = 0; x < stride; x++)
254  {
255  *p++ = value;
256  }
257  }
258  }
259 
260  private:
261  //--------------------------------------------------------------------
262  T* m_buf; // Pointer to renrdering buffer
263  pod_array<T*> m_rows; // Pointers to each row of the buffer
264  unsigned m_width; // Width in pixels
265  unsigned m_height; // Height in pixels
266  int m_stride; // Number of bytes per row. Can be < 0
267  };
268 
269 
270 
271 
272  //========================================================rendering_buffer
273  //
274  // The definition of the main type for accessing the rows in the frame
275  // buffer. It provides functionality to navigate to the rows in a
276  // rectangular matrix, from top to bottom or from bottom to top depending
277  // on stride.
278  //
279  // row_accessor is cheap to create/destroy, but performs one multiplication
280  // when calling row_ptr().
281  //
282  // row_ptr_cache creates an array of pointers to rows, so, the access
283  // via row_ptr() may be faster. But it requires memory allocation
284  // when creating. For example, on typical Intel Pentium hardware
285  // row_ptr_cache speeds span_image_filter_rgb_nn up to 10%
286  //
287  // It's used only in short hand typedefs like pixfmt_rgba32 and can be
288  // redefined in agg_config.h
289  // In real applications you can use both, depending on your needs
290  //------------------------------------------------------------------------
291 #ifdef AGG_RENDERING_BUFFER
292  typedef AGG_RENDERING_BUFFER rendering_buffer;
293 #else
294 // typedef row_ptr_cache<int8u> rendering_buffer;
295  typedef row_accessor<int8u> rendering_buffer;
296 #endif
297 
298 }
299 
300 
301 #endif
Definition: agg_arc.cpp:24