agg_rendering_buffer.h 9.8 KB

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