Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_image_accessors.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 
00025 #ifndef AGG_IMAGE_ACCESSORS_INCLUDED
00026 #define AGG_IMAGE_ACCESSORS_INCLUDED
00027 
00028 #include "agg_basics.h"
00029 
00030 namespace agg
00031 {
00032 
00033     //-----------------------------------------------------image_accessor_clip
00034     template<class PixFmt> class image_accessor_clip
00035     {
00036     public:
00037         typedef PixFmt   pixfmt_type;
00038         typedef typename pixfmt_type::color_type color_type;
00039         typedef typename pixfmt_type::order_type order_type;
00040         typedef typename pixfmt_type::value_type value_type;
00041         enum pix_width_e { pix_width = pixfmt_type::pix_width };
00042 
00043         image_accessor_clip() {}
00044         explicit image_accessor_clip(const pixfmt_type& pixf, 
00045                                      const color_type& bk) : 
00046             m_pixf(&pixf)
00047         {
00048             pixfmt_type::make_pix(m_bk_buf, bk);
00049         }
00050 
00051         void attach(const pixfmt_type& pixf)
00052         {
00053             m_pixf = &pixf;
00054         }
00055 
00056         void background_color(const color_type& bk)
00057         {
00058             pixfmt_type::make_pix(m_bk_buf, bk);
00059         }
00060 
00061     private:
00062         AGG_INLINE const int8u* pixel() const
00063         {
00064             if(m_y >= 0 && m_y < (int)m_pixf->height() &&
00065                m_x >= 0 && m_x < (int)m_pixf->width())
00066             {
00067                 return m_pixf->pix_ptr(m_x, m_y);
00068             }
00069             return m_bk_buf;
00070         }
00071 
00072     public:
00073         AGG_INLINE const int8u* span(int x, int y, unsigned len)
00074         {
00075             m_x = m_x0 = x;
00076             m_y = y;
00077             if(y >= 0 && y < (int)m_pixf->height() &&
00078                x >= 0 && x+(int)len <= (int)m_pixf->width())
00079             {
00080                 return m_pix_ptr = m_pixf->pix_ptr(x, y);
00081             }
00082             m_pix_ptr = 0;
00083             return pixel();
00084         }
00085 
00086         AGG_INLINE const int8u* next_x()
00087         {
00088             if(m_pix_ptr) return m_pix_ptr += pix_width;
00089             ++m_x;
00090             return pixel();
00091         }
00092 
00093         AGG_INLINE const int8u* next_y()
00094         {
00095             ++m_y;
00096             m_x = m_x0;
00097             if(m_pix_ptr && 
00098                m_y >= 0 && m_y < (int)m_pixf->height())
00099             {
00100                 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
00101             }
00102             m_pix_ptr = 0;
00103             return pixel();
00104         }
00105 
00106     private:
00107         const pixfmt_type* m_pixf;
00108         int8u              m_bk_buf[4];
00109         int                m_x, m_x0, m_y;
00110         const int8u*       m_pix_ptr;
00111     };
00112 
00113 
00114 
00115 
00116     //--------------------------------------------------image_accessor_no_clip
00117     template<class PixFmt> class image_accessor_no_clip
00118     {
00119     public:
00120         typedef PixFmt   pixfmt_type;
00121         typedef typename pixfmt_type::color_type color_type;
00122         typedef typename pixfmt_type::order_type order_type;
00123         typedef typename pixfmt_type::value_type value_type;
00124         enum pix_width_e { pix_width = pixfmt_type::pix_width };
00125 
00126         image_accessor_no_clip() {}
00127         explicit image_accessor_no_clip(const pixfmt_type& pixf) : 
00128             m_pixf(&pixf) 
00129         {}
00130 
00131         void attach(const pixfmt_type& pixf)
00132         {
00133             m_pixf = &pixf;
00134         }
00135 
00136         AGG_INLINE const int8u* span(int x, int y, unsigned)
00137         {
00138             m_x = x;
00139             m_y = y;
00140             return m_pix_ptr = m_pixf->pix_ptr(x, y);
00141         }
00142 
00143         AGG_INLINE const int8u* next_x()
00144         {
00145             return m_pix_ptr += pix_width;
00146         }
00147 
00148         AGG_INLINE const int8u* next_y()
00149         {
00150             ++m_y;
00151             return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
00152         }
00153 
00154     private:
00155         const pixfmt_type* m_pixf;
00156         int                m_x, m_y;
00157         const int8u*       m_pix_ptr;
00158     };
00159 
00160 
00161 
00162 
00163     //----------------------------------------------------image_accessor_clone
00164     template<class PixFmt> class image_accessor_clone
00165     {
00166     public:
00167         typedef PixFmt   pixfmt_type;
00168         typedef typename pixfmt_type::color_type color_type;
00169         typedef typename pixfmt_type::order_type order_type;
00170         typedef typename pixfmt_type::value_type value_type;
00171         enum pix_width_e { pix_width = pixfmt_type::pix_width };
00172 
00173         image_accessor_clone() {}
00174         explicit image_accessor_clone(const pixfmt_type& pixf) : 
00175             m_pixf(&pixf) 
00176         {}
00177 
00178         void attach(const pixfmt_type& pixf)
00179         {
00180             m_pixf = &pixf;
00181         }
00182 
00183     private:
00184         AGG_INLINE const int8u* pixel() const
00185         {
00186             register int x = m_x;
00187             register int y = m_y;
00188             if(x < 0) x = 0;
00189             if(y < 0) y = 0;
00190             if(x >= (int)m_pixf->width())  x = m_pixf->width() - 1;
00191             if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
00192             return m_pixf->pix_ptr(x, y);
00193         }
00194 
00195     public:
00196         AGG_INLINE const int8u* span(int x, int y, unsigned len)
00197         {
00198             m_x = m_x0 = x;
00199             m_y = y;
00200             if(y >= 0 && y < (int)m_pixf->height() &&
00201                x >= 0 && x+len <= (int)m_pixf->width())
00202             {
00203                 return m_pix_ptr = m_pixf->pix_ptr(x, y);
00204             }
00205             m_pix_ptr = 0;
00206             return pixel();
00207         }
00208 
00209         AGG_INLINE const int8u* next_x()
00210         {
00211             if(m_pix_ptr) return m_pix_ptr += pix_width;
00212             ++m_x;
00213             return pixel();
00214         }
00215 
00216         AGG_INLINE const int8u* next_y()
00217         {
00218             ++m_y;
00219             m_x = m_x0;
00220             if(m_pix_ptr && 
00221                m_y >= 0 && m_y < (int)m_pixf->height())
00222             {
00223                 return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
00224             }
00225             m_pix_ptr = 0;
00226             return pixel();
00227         }
00228 
00229     private:
00230         const pixfmt_type* m_pixf;
00231         int                m_x, m_x0, m_y;
00232         const int8u*       m_pix_ptr;
00233     };
00234 
00235 
00236 
00237 
00238 
00239     //-----------------------------------------------------image_accessor_wrap
00240     template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
00241     {
00242     public:
00243         typedef PixFmt   pixfmt_type;
00244         typedef typename pixfmt_type::color_type color_type;
00245         typedef typename pixfmt_type::order_type order_type;
00246         typedef typename pixfmt_type::value_type value_type;
00247         enum pix_width_e { pix_width = pixfmt_type::pix_width };
00248 
00249         image_accessor_wrap() {}
00250         explicit image_accessor_wrap(const pixfmt_type& pixf) : 
00251             m_pixf(&pixf), 
00252             m_wrap_x(pixf.width()), 
00253             m_wrap_y(pixf.height())
00254         {}
00255 
00256         void attach(const pixfmt_type& pixf)
00257         {
00258             m_pixf = &pixf;
00259         }
00260 
00261         AGG_INLINE const int8u* span(int x, int y, unsigned)
00262         {
00263             m_x = x;
00264             m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
00265             return m_row_ptr + m_wrap_x(x) * pix_width;
00266         }
00267 
00268         AGG_INLINE const int8u* next_x()
00269         {
00270             int x = ++m_wrap_x;
00271             return m_row_ptr + x * pix_width;
00272         }
00273 
00274         AGG_INLINE const int8u* next_y()
00275         {
00276             m_row_ptr = m_pixf->row_ptr(++m_wrap_y);
00277             return m_row_ptr + m_wrap_x(m_x) * pix_width;
00278         }
00279 
00280     private:
00281         const pixfmt_type* m_pixf;
00282         const int8u*       m_row_ptr;
00283         int                m_x;
00284         WrapX              m_wrap_x;
00285         WrapY              m_wrap_y;
00286     };
00287 
00288 
00289 
00290 
00291     //--------------------------------------------------------wrap_mode_repeat
00292     class wrap_mode_repeat
00293     {
00294     public:
00295         wrap_mode_repeat() {}
00296         wrap_mode_repeat(unsigned size) : 
00297             m_size(size), 
00298             m_add(size * (0x3FFFFFFF / size)),
00299             m_value(0)
00300         {}
00301 
00302         AGG_INLINE unsigned operator() (int v)
00303         { 
00304             return m_value = (unsigned(v) + m_add) % m_size; 
00305         }
00306 
00307         AGG_INLINE unsigned operator++ ()
00308         {
00309             ++m_value;
00310             if(m_value >= m_size) m_value = 0;
00311             return m_value;
00312         }
00313     private:
00314         unsigned m_size;
00315         unsigned m_add;
00316         unsigned m_value;
00317     };
00318 
00319 
00320     //---------------------------------------------------wrap_mode_repeat_pow2
00321     class wrap_mode_repeat_pow2
00322     {
00323     public:
00324         wrap_mode_repeat_pow2() {}
00325         wrap_mode_repeat_pow2(unsigned size) : m_value(0)
00326         {
00327             m_mask = 1;
00328             while(m_mask < size) m_mask = (m_mask << 1) | 1;
00329             m_mask >>= 1;
00330         }
00331         AGG_INLINE unsigned operator() (int v)
00332         { 
00333             return m_value = unsigned(v) & m_mask;
00334         }
00335         AGG_INLINE unsigned operator++ ()
00336         {
00337             ++m_value;
00338             if(m_value > m_mask) m_value = 0;
00339             return m_value;
00340         }
00341     private:
00342         unsigned m_mask;
00343         unsigned m_value;
00344     };
00345 
00346 
00347     //----------------------------------------------wrap_mode_repeat_auto_pow2
00348     class wrap_mode_repeat_auto_pow2
00349     {
00350     public:
00351         wrap_mode_repeat_auto_pow2() {}
00352         wrap_mode_repeat_auto_pow2(unsigned size) :
00353             m_size(size),
00354             m_add(size * (0x3FFFFFFF / size)),
00355             m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
00356             m_value(0)
00357         {}
00358 
00359         AGG_INLINE unsigned operator() (int v) 
00360         { 
00361             if(m_mask) return m_value = unsigned(v) & m_mask;
00362             return m_value = (unsigned(v) + m_add) % m_size;
00363         }
00364         AGG_INLINE unsigned operator++ ()
00365         {
00366             ++m_value;
00367             if(m_value >= m_size) m_value = 0;
00368             return m_value;
00369         }
00370 
00371     private:
00372         unsigned m_size;
00373         unsigned m_add;
00374         unsigned m_mask;
00375         unsigned m_value;
00376     };
00377 
00378 
00379     //-------------------------------------------------------wrap_mode_reflect
00380     class wrap_mode_reflect
00381     {
00382     public:
00383         wrap_mode_reflect() {}
00384         wrap_mode_reflect(unsigned size) : 
00385             m_size(size), 
00386             m_size2(size * 2),
00387             m_add(m_size2 * (0x3FFFFFFF / m_size2)),
00388             m_value(0)
00389         {}
00390 
00391         AGG_INLINE unsigned operator() (int v)
00392         { 
00393             m_value = (unsigned(v) + m_add) % m_size2;
00394             if(m_value >= m_size) return m_size2 - m_value - 1;
00395             return m_value;
00396         }
00397 
00398         AGG_INLINE unsigned operator++ ()
00399         {
00400             ++m_value;
00401             if(m_value >= m_size2) m_value = 0;
00402             if(m_value >= m_size) return m_size2 - m_value - 1;
00403             return m_value;
00404         }
00405     private:
00406         unsigned m_size;
00407         unsigned m_size2;
00408         unsigned m_add;
00409         unsigned m_value;
00410     };
00411 
00412 
00413 
00414     //--------------------------------------------------wrap_mode_reflect_pow2
00415     class wrap_mode_reflect_pow2
00416     {
00417     public:
00418         wrap_mode_reflect_pow2() {}
00419         wrap_mode_reflect_pow2(unsigned size) : m_value(0)
00420         {
00421             m_mask = 1;
00422             m_size = 1;
00423             while(m_mask < size) 
00424             {
00425                 m_mask = (m_mask << 1) | 1;
00426                 m_size <<= 1;
00427             }
00428         }
00429         AGG_INLINE unsigned operator() (int v)
00430         { 
00431             m_value = unsigned(v) & m_mask;
00432             if(m_value >= m_size) return m_mask - m_value;
00433             return m_value;
00434         }
00435         AGG_INLINE unsigned operator++ ()
00436         {
00437             ++m_value;
00438             m_value &= m_mask;
00439             if(m_value >= m_size) return m_mask - m_value;
00440             return m_value;
00441         }
00442     private:
00443         unsigned m_size;
00444         unsigned m_mask;
00445         unsigned m_value;
00446     };
00447 
00448 
00449 
00450     //---------------------------------------------wrap_mode_reflect_auto_pow2
00451     class wrap_mode_reflect_auto_pow2
00452     {
00453     public:
00454         wrap_mode_reflect_auto_pow2() {}
00455         wrap_mode_reflect_auto_pow2(unsigned size) :
00456             m_size(size),
00457             m_size2(size * 2),
00458             m_add(m_size2 * (0x3FFFFFFF / m_size2)),
00459             m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
00460             m_value(0)
00461         {}
00462 
00463         AGG_INLINE unsigned operator() (int v) 
00464         { 
00465             m_value = m_mask ? unsigned(v) & m_mask : 
00466                               (unsigned(v) + m_add) % m_size2;
00467             if(m_value >= m_size) return m_size2 - m_value - 1;
00468             return m_value;            
00469         }
00470         AGG_INLINE unsigned operator++ ()
00471         {
00472             ++m_value;
00473             if(m_value >= m_size2) m_value = 0;
00474             if(m_value >= m_size) return m_size2 - m_value - 1;
00475             return m_value;
00476         }
00477 
00478     private:
00479         unsigned m_size;
00480         unsigned m_size2;
00481         unsigned m_add;
00482         unsigned m_mask;
00483         unsigned m_value;
00484     };
00485 
00486 
00487 }
00488 
00489 
00490 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines