[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]

details vigra/basicimage.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
00005 /*                                                                      */
00006 /*    This file is part of the VIGRA computer vision library.           */
00007 /*    ( Version 1.3.2, Jan 27 2005 )                                    */
00008 /*    You may use, modify, and distribute this software according       */
00009 /*    to the terms stated in the LICENSE file included in               */
00010 /*    the VIGRA distribution.                                           */
00011 /*                                                                      */
00012 /*    The VIGRA Website is                                              */
00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00014 /*    Please direct questions, bug reports, and contributions to        */
00015 /*        koethe@informatik.uni-hamburg.de                              */
00016 /*                                                                      */
00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
00020 /*                                                                      */
00021 /************************************************************************/
00022 
00023 #ifndef VIGRA_BASICIMAGE_HXX
00024 #define VIGRA_BASICIMAGE_HXX
00025 
00026 #include <memory>
00027 #include <algorithm>
00028 #include "vigra/utilities.hxx"
00029 #include "vigra/iteratortraits.hxx"
00030 #include "vigra/accessor.hxx"
00031 
00032 namespace vigra {
00033 
00034 template <class IMAGEITERATOR>
00035 class LineBasedColumnIteratorPolicy
00036 {
00037   public:
00038     typedef IMAGEITERATOR                             ImageIterator;
00039     typedef typename IMAGEITERATOR::LineStartIterator LineStartIterator;
00040     typedef typename IMAGEITERATOR::value_type        value_type;
00041     typedef typename IMAGEITERATOR::difference_type::MoveY
00042                                                       difference_type;
00043     typedef typename IMAGEITERATOR::reference         reference;
00044     typedef typename IMAGEITERATOR::index_reference   index_reference;
00045     typedef typename IMAGEITERATOR::pointer           pointer;
00046     typedef std::random_access_iterator_tag           iterator_category;
00047 
00048 
00049     struct BaseType
00050     {
00051         explicit BaseType(LineStartIterator c = LineStartIterator(),
00052                           difference_type o = 0)
00053         : line_start_(c), offset_(o)
00054         {}
00055 
00056         LineStartIterator line_start_;
00057         difference_type offset_;
00058     };
00059 
00060     static void initialize(BaseType &) {}
00061 
00062     static reference dereference(BaseType const & d)
00063         { return const_cast<reference>(*(*d.line_start_ + d.offset_)); }
00064 
00065     static index_reference dereference(BaseType const & d, difference_type n)
00066     {
00067         return const_cast<index_reference>(*(d.line_start_[n] + d.offset_));
00068     }
00069 
00070     static bool equal(BaseType const & d1, BaseType const & d2)
00071         { return d1.line_start_ == d2.line_start_; }
00072 
00073     static bool less(BaseType const & d1, BaseType const & d2)
00074         { return d1.line_start_ < d2.line_start_; }
00075 
00076     static difference_type difference(BaseType const & d1, BaseType const & d2)
00077         { return d1.line_start_ - d2.line_start_; }
00078 
00079     static void increment(BaseType & d)
00080         { ++d.line_start_; }
00081 
00082     static void decrement(BaseType & d)
00083         { --d.line_start_; }
00084 
00085     static void advance(BaseType & d, difference_type n)
00086         { d.line_start_ += n; }
00087 };
00088 
00089 /********************************************************/
00090 /*                                                      */
00091 /*                    BasicImageIterator                */
00092 /*                                                      */
00093 /********************************************************/
00094 
00095 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
00096     See \ref vigra::ImageIterator for documentation.
00097 
00098     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00099     Namespace: vigra
00100 */
00101 template <class IMAGEITERATOR, class PIXELTYPE,
00102           class REFERENCE, class POINTER, class LINESTARTITERATOR>
00103 class BasicImageIteratorBase
00104 {
00105   public:
00106     typedef BasicImageIteratorBase<IMAGEITERATOR,
00107             PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type;
00108 
00109     typedef LINESTARTITERATOR    LineStartIterator;
00110     typedef PIXELTYPE            value_type;
00111     typedef PIXELTYPE            PixelType;
00112     typedef REFERENCE            reference;
00113     typedef REFERENCE            index_reference;
00114     typedef POINTER              pointer;
00115     typedef Diff2D               difference_type;
00116     typedef image_traverser_tag  iterator_category;
00117     typedef POINTER              row_iterator;
00118     typedef IteratorAdaptor<LineBasedColumnIteratorPolicy<IMAGEITERATOR> >
00119                                  column_iterator;
00120 
00121     typedef int                  MoveX;
00122     typedef LINESTARTITERATOR    MoveY;
00123 
00124     MoveX x;
00125     MoveY y;
00126 
00127     IMAGEITERATOR & operator+=(difference_type const & s)
00128     {
00129         x += s.x;
00130         y += s.y;
00131         return static_cast<IMAGEITERATOR &>(*this);
00132     }
00133 
00134     IMAGEITERATOR & operator-=(difference_type const & s)
00135     {
00136         x -= s.x;
00137         y -= s.y;
00138         return static_cast<IMAGEITERATOR &>(*this);
00139     }
00140 
00141     IMAGEITERATOR operator+(difference_type const & s) const
00142     {
00143         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
00144 
00145         ret += s;
00146 
00147         return ret;
00148     }
00149 
00150     IMAGEITERATOR operator-(difference_type const & s) const
00151     {
00152         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
00153 
00154         ret -= s;
00155 
00156         return ret;
00157     }
00158 
00159     difference_type operator-(BasicImageIteratorBase const & rhs) const
00160     {
00161         return difference_type(x - rhs.x, y - rhs.y);
00162     }
00163 
00164     bool operator==(BasicImageIteratorBase const & rhs) const
00165     {
00166         return (x == rhs.x) && (y == rhs.y);
00167     }
00168 
00169     bool operator!=(BasicImageIteratorBase const & rhs) const
00170     {
00171         return (x != rhs.x) || (y != rhs.y);
00172     }
00173 
00174     reference operator*() const
00175     {
00176         return *(*y + x );
00177     }
00178 
00179     pointer operator->() const
00180     {
00181         return *y + x;
00182     }
00183 
00184     index_reference operator[](difference_type const & d) const
00185     {
00186         return *(*(y + d.y) + x + d.x);
00187     }
00188 
00189     index_reference operator()(int dx, int dy) const
00190     {
00191         return *(*(y + dy) + x + dx);
00192     }
00193 
00194     pointer operator[](int dy) const
00195     {
00196         return y[dy] + x;
00197     }
00198 
00199     row_iterator rowIterator() const
00200         { return *y + x; }
00201 
00202     column_iterator columnIterator() const
00203     {
00204         typedef typename column_iterator::BaseType Iter;
00205         return column_iterator(Iter(y, x));
00206     }
00207 
00208   protected:
00209     BasicImageIteratorBase(LINESTARTITERATOR const & line)
00210     : x(0),
00211       y(line)
00212     {}
00213 
00214     BasicImageIteratorBase(int ix, LINESTARTITERATOR const & line)
00215     : x(ix),
00216       y(line)
00217     {}
00218 
00219     BasicImageIteratorBase()
00220     : x(0),
00221       y(0)
00222     {}
00223 };
00224 
00225 /********************************************************/
00226 /*                                                      */
00227 /*                    BasicImageIterator                */
00228 /*                                                      */
00229 /********************************************************/
00230 
00231 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
00232     See \ref vigra::ImageIterator for documentation.
00233 
00234     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00235     Namespace: vigra
00236 */
00237 template <class PIXELTYPE, class ITERATOR>
00238 class BasicImageIterator
00239 : public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>,
00240                             PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR>
00241 {
00242   public:
00243 
00244     typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE,
00245                                 PIXELTYPE &, PIXELTYPE *, ITERATOR> Base;
00246 
00247 
00248     BasicImageIterator(ITERATOR line)
00249     : Base(line)
00250     {}
00251 
00252     BasicImageIterator()
00253     : Base()
00254     {}
00255 };
00256 
00257 /********************************************************/
00258 /*                                                      */
00259 /*                ConstBasicImageIterator               */
00260 /*                                                      */
00261 /********************************************************/
00262 
00263 /** Implementation of the standard const image iterator for \ref vigra::BasicImage.
00264     See \ref vigra::ConstImageIterator for documentation.
00265 
00266     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00267     Namespace: vigra
00268 */
00269 template <class PIXELTYPE, class ITERATOR>
00270 class ConstBasicImageIterator
00271 : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>,
00272                     PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR>
00273 {
00274   public:
00275 
00276     typedef BasicImageIteratorBase<ConstBasicImageIterator,
00277               PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> Base;
00278 
00279 
00280     ConstBasicImageIterator(ITERATOR line)
00281     : Base(line)
00282     {}
00283 
00284     ConstBasicImageIterator(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
00285     : Base(rhs.x, rhs.y)
00286     {}
00287 
00288     ConstBasicImageIterator()
00289     : Base()
00290     {}
00291 
00292     ConstBasicImageIterator &
00293     operator=(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
00294     {
00295         Base::x = rhs.x;
00296         Base::y = rhs.y;
00297         return *this;
00298     }
00299 
00300 };
00301 
00302 /********************************************************/
00303 /*                                                      */
00304 /*             definition of iterator traits            */
00305 /*                                                      */
00306 /********************************************************/
00307 
00308 
00309 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
00310 
00311 template <class T>
00312 struct IteratorTraits<BasicImageIterator<T, T**> >
00313 : public IteratorTraitsBase<BasicImageIterator<T, T**> >
00314 {
00315     typedef typename AccessorTraits<T>::default_accessor  DefaultAccessor;
00316     typedef DefaultAccessor                               default_accessor;
00317 };
00318 
00319 template <class T>
00320 struct IteratorTraits<ConstBasicImageIterator<T, T**> >
00321 : public IteratorTraitsBase<ConstBasicImageIterator<T, T**> >
00322 {
00323     typedef typename AccessorTraits<T>::default_const_accessor  DefaultAccessor;
00324     typedef DefaultAccessor                               default_accessor;
00325 };
00326 
00327 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00328 
00329 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
00330     template <>  \
00331     struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
00332     : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
00333     { \
00334         typedef typename AccessorTraits<VALUETYPE >::default_accessor  DefaultAccessor; \
00335         typedef DefaultAccessor                               default_accessor; \
00336     }; \
00337     \
00338     template <>  \
00339     struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
00340     : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
00341     { \
00342         typedef typename AccessorTraits<VALUETYPE >::default_const_accessor  DefaultAccessor; \
00343         typedef DefaultAccessor                               default_accessor; \
00344     };
00345 
00346 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
00347 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
00348 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
00349 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
00350 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
00351 
00352 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
00353 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00354 #undef VIGRA_PIXELTYPE
00355 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
00356 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00357 #undef VIGRA_PIXELTYPE
00358 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
00359 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00360 #undef VIGRA_PIXELTYPE
00361 #define VIGRA_PIXELTYPE TinyVector<short, 2>
00362 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00363 #undef VIGRA_PIXELTYPE
00364 #define VIGRA_PIXELTYPE TinyVector<short, 3>
00365 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00366 #undef VIGRA_PIXELTYPE
00367 #define VIGRA_PIXELTYPE TinyVector<short, 4>
00368 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00369 #undef VIGRA_PIXELTYPE
00370 #define VIGRA_PIXELTYPE TinyVector<int, 2>
00371 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00372 #undef VIGRA_PIXELTYPE
00373 #define VIGRA_PIXELTYPE TinyVector<int, 3>
00374 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00375 #undef VIGRA_PIXELTYPE
00376 #define VIGRA_PIXELTYPE TinyVector<int, 4>
00377 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00378 #undef VIGRA_PIXELTYPE
00379 #define VIGRA_PIXELTYPE TinyVector<float, 2>
00380 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00381 #undef VIGRA_PIXELTYPE
00382 #define VIGRA_PIXELTYPE TinyVector<float, 3>
00383 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00384 #undef VIGRA_PIXELTYPE
00385 #define VIGRA_PIXELTYPE TinyVector<float, 4>
00386 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00387 #undef VIGRA_PIXELTYPE
00388 #define VIGRA_PIXELTYPE TinyVector<double, 2>
00389 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00390 #undef VIGRA_PIXELTYPE
00391 #define VIGRA_PIXELTYPE TinyVector<double, 3>
00392 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00393 #undef VIGRA_PIXELTYPE
00394 #define VIGRA_PIXELTYPE TinyVector<double, 4>
00395 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00396 #undef VIGRA_PIXELTYPE
00397 
00398 #undef VIGRA_DEFINE_ITERATORTRAITS
00399 
00400 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00401 
00402 /********************************************************/
00403 /*                                                      */
00404 /*                     BasicImage                       */
00405 /*                                                      */
00406 /********************************************************/
00407 
00408 /** \brief Fundamental class template for images.
00409 
00410     A customized memory allocator can be specified as a templated argument
00411     ans passed in the constructor.
00412 
00413     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00414 
00415     Namespace: vigra
00416 */
00417 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
00418 class BasicImage
00419 {
00420   public:
00421 
00422         /** the BasicImage's pixel type
00423         */
00424     typedef PIXELTYPE value_type;
00425 
00426         /** the BasicImage's pixel type
00427         */
00428     typedef PIXELTYPE PixelType;
00429 
00430         /** the BasicImage's reference type (i.e. the
00431             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
00432         */
00433     typedef PIXELTYPE &       reference;
00434 
00435         /** the BasicImage's const reference type (i.e. the
00436             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
00437             when <TT>image</TT> is const)
00438         */
00439     typedef PIXELTYPE const & const_reference;
00440 
00441         /** the BasicImage's pointer type
00442         */
00443     typedef PIXELTYPE *       pointer;
00444 
00445         /** the BasicImage's const pointer type
00446         */
00447     typedef PIXELTYPE const * const_pointer;
00448 
00449         /** the BasicImage's 1D random access iterator
00450             (note: lower case 'iterator' is a STL compatible 1D random
00451              access iterator, don't confuse with capitalized Iterator)
00452         */
00453     typedef PIXELTYPE * iterator;
00454 
00455         /** deprecated, use <TT>iterator</TT> instead
00456         */
00457     typedef PIXELTYPE * ScanOrderIterator;
00458 
00459         /** the BasicImage's 1D random access const iterator
00460             (note: lower case 'const_iterator' is a STL compatible 1D
00461             random access const iterator)
00462         */
00463     typedef PIXELTYPE const * const_iterator;
00464 
00465         /** deprecated, use <TT>const_iterator</TT> instead
00466         */
00467     typedef PIXELTYPE const * ConstScanOrderIterator;
00468 
00469         /** the BasicImage's 2D random access iterator ('traverser')
00470         */
00471     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
00472 
00473         /** deprecated, use <TT>traverser</TT> instead
00474         */
00475     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
00476 
00477         /** the BasicImage's 2D random access const iterator ('const traverser')
00478         */
00479     typedef
00480         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00481         const_traverser;
00482 
00483         /** deprecated, use <TT>const_traverser</TT> instead
00484         */
00485     typedef
00486         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00487         ConstIterator;
00488 
00489         /** the BasicImage's difference type (argument type of image[diff])
00490         */
00491     typedef Diff2D difference_type;
00492 
00493          /** the BasicImage's size type (result type of image.size())
00494         */
00495     typedef Size2D size_type;
00496 
00497        /** the BasicImage's default accessor
00498         */
00499     typedef typename
00500           IteratorTraits<traverser>::DefaultAccessor Accessor;
00501 
00502         /** the BasicImage's default const accessor
00503         */
00504     typedef typename
00505           IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
00506 
00507         /** the BasicImage's allocator (default: std::allocator<value_type>)
00508         */
00509     typedef Alloc allocator_type;
00510 
00511     typedef Alloc Allocator;
00512     typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator;
00513 
00514         /** construct image of size 0x0
00515         */
00516     BasicImage()
00517     : data_(0),
00518       width_(0),
00519       height_(0)
00520     {}
00521 
00522         /** construct image of size 0x0, use the specified allocator.
00523         */
00524     explicit BasicImage(Alloc const & alloc)
00525     : data_(0),
00526       width_(0),
00527       height_(0),
00528       allocator_(alloc),
00529       pallocator_(alloc)
00530     {}
00531 
00532         /** construct image of size width x height, use the specified allocator.
00533         */
00534     BasicImage(int width, int height, Alloc const & alloc = Alloc())
00535     : data_(0),
00536       width_(0),
00537       height_(0),
00538       allocator_(alloc),
00539       pallocator_(alloc)
00540     {
00541         vigra_precondition((width >= 0) && (height >= 0),
00542              "BasicImage::BasicImage(int width, int height): "
00543              "width and height must be >= 0.\n");
00544 
00545         resize(width, height, value_type());
00546     }
00547 
00548         /** construct image of size size.x x size.y, use the specified allocator.
00549         */
00550     explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc())
00551     : data_(0),
00552       width_(0),
00553       height_(0),
00554       allocator_(alloc),
00555       pallocator_(alloc)
00556     {
00557         vigra_precondition((size.x >= 0) && (size.y >= 0),
00558              "BasicImage::BasicImage(Diff2D size): "
00559              "size.x and size.y must be >= 0.\n");
00560 
00561         resize(size.x, size.y, value_type());
00562     }
00563 
00564         /** construct image of size width*height and initialize every
00565         pixel with the value \a d (use this constructor, if
00566         value_type doesn't have a default constructor). 
00567         Use the specified allocator.
00568         */
00569     BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc())
00570     : data_(0),
00571       width_(0),
00572       height_(0),
00573       allocator_(alloc),
00574       pallocator_(alloc)
00575     {
00576         vigra_precondition((width >= 0) && (height >= 0),
00577              "BasicImage::BasicImage(int width, int height, value_type const & ): "
00578              "width and height must be >= 0.\n");
00579 
00580         resize(width, height, d);
00581     }
00582 
00583         /** construct image of size size.x x size.y and initialize
00584         every pixel with given data (use this constructor, if
00585         value_type doesn't have a default constructor). Use the specified allocator.
00586         */
00587     explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc())
00588     : data_(0),
00589       width_(0),
00590       height_(0),
00591       allocator_(alloc),
00592       pallocator_(alloc)
00593     {
00594         vigra_precondition((size.x >= 0) && (size.y >= 0),
00595              "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
00596              "size.x and size.y must be >= 0.\n");
00597 
00598         resize(size.x, size.y, d);
00599     }
00600 
00601 
00602         /** construct image of size width*height and copy the data from the
00603             given C-style array \a d. Use the specified allocator.
00604         */
00605     BasicImage(int width, int height, const_pointer d, Alloc const & alloc = Alloc())
00606     : data_(0),
00607       width_(0),
00608       height_(0),
00609       allocator_(alloc),
00610       pallocator_(alloc)
00611     {
00612         vigra_precondition((width >= 0) && (height >= 0),
00613              "BasicImage::BasicImage(int width, int height, const_pointer ): "
00614              "width and height must be >= 0.\n");
00615 
00616         resizeCopy(width, height, d);
00617     }
00618 
00619         /** construct image of size size.x x size.y  and copy the data from the
00620             given C-style array. Use the specified allocator.
00621         */
00622     explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc())
00623     : data_(0),
00624       width_(0),
00625       height_(0),
00626       allocator_(alloc),
00627       pallocator_(alloc)
00628     {
00629         vigra_precondition((size.x >= 0) && (size.y >= 0),
00630              "BasicImage::BasicImage(Diff2D const & size, const_pointer): "
00631              "size.x and size.y must be >= 0.\n");
00632 
00633         resizeCopy(size.x, size.y, d);
00634     }
00635 
00636         /** copy rhs image
00637         */
00638     BasicImage(const BasicImage & rhs)
00639     : data_(0),
00640       width_(0),
00641       height_(0),
00642       allocator_(rhs.allocator_),
00643       pallocator_(rhs.pallocator_)
00644     {
00645         resizeCopy(rhs);
00646     }
00647 
00648         /** destructor
00649         */
00650     ~BasicImage()
00651     {
00652         deallocate();
00653     }
00654 
00655         /** copy rhs image (image is resized if necessary)
00656         */
00657     BasicImage & operator=(const BasicImage & rhs);
00658 
00659         /** \deprecated set Image with const value
00660         */
00661     BasicImage & operator=(value_type pixel);
00662 
00663         /** set Image with const value
00664         */
00665     BasicImage & init(value_type const & pixel);
00666 
00667         /** reset image to specified size (dimensions must not be negative)
00668             (old data are kept if new size matches old size)
00669         */
00670     void resize(int width, int height)
00671     {
00672         if(width != width_ || height != height_)
00673             resize(width, height, value_type());
00674     }
00675 
00676         /** reset image to specified size (dimensions must not be negative)
00677             (old data are kept if new size matches old size)
00678         */
00679     void resize(difference_type const & size)
00680     {
00681         if(size.x != width_ || size.y != height_)
00682         {
00683             resize(size.x, size.y, value_type());
00684         }
00685     }
00686 
00687         /** reset image to specified size and initialize it with
00688             given data (use this if value_type doesn't have a default
00689             constructor, dimensions must not be negative,
00690             old data are kept if new size matches old size)
00691         */
00692     void resize(int width, int height, value_type const & d);
00693 
00694         /** resize image to given size and initialize by copying data
00695             from the C-style arra \a data.
00696         */
00697     void resizeCopy(int width, int height, const_pointer data);
00698 
00699         /** resize image to size of other image and copy it's data
00700         */
00701     void resizeCopy(const BasicImage & rhs)
00702     {
00703         resizeCopy(rhs.width(), rhs.height(), rhs.data_);
00704     }
00705 
00706         /** swap the internal data with the rhs image in constant time
00707         */
00708     void swap( BasicImage & rhs );
00709 
00710         /** width of Image
00711         */
00712     int width() const
00713     {
00714         return width_;
00715     }
00716 
00717         /** height of Image
00718         */
00719     int height() const
00720     {
00721         return height_;
00722     }
00723 
00724         /** size of Image
00725         */
00726     size_type size() const
00727     {
00728         return size_type(width(), height());
00729     }
00730 
00731         /** test whether a given coordinate is inside the image
00732         */
00733     bool isInside(difference_type const & d) const
00734     {
00735         return d.x >= 0 && d.y >= 0 &&
00736                d.x < width() && d.y < height();
00737     }
00738 
00739         /** access pixel at given location. <br>
00740         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00741         */
00742     reference operator[](difference_type const & d)
00743     {
00744         return lines_[d.y][d.x];
00745     }
00746 
00747         /** read pixel at given location. <br>
00748         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00749         */
00750     const_reference operator[](difference_type const & d) const
00751     {
00752         return lines_[d.y][d.x];
00753     }
00754 
00755         /** access pixel at given location. <br>
00756         usage: <TT> value_type value = image(1,2) </TT>
00757         */
00758     reference operator()(int dx, int dy)
00759     {
00760         return lines_[dy][dx];
00761     }
00762 
00763         /** read pixel at given location. <br>
00764         usage: <TT> value_type value = image(1,2) </TT>
00765         */
00766     const_reference operator()(int dx, int dy) const
00767     {
00768         return lines_[dy][dx];
00769     }
00770 
00771         /** access pixel at given location.
00772             Note that the 'x' index is the trailing index. <br>
00773         usage: <TT> value_type value = image[2][1] </TT>
00774         */
00775     pointer operator[](int dy)
00776     {
00777         return lines_[dy];
00778     }
00779 
00780         /** read pixel at given location.
00781             Note that the 'x' index is the trailing index. <br>
00782         usage: <TT> value_type value = image[2][1] </TT>
00783         */
00784     const_pointer operator[](int dy) const
00785     {
00786         return lines_[dy];
00787     }
00788 
00789         /** init 2D random access iterator poining to upper left pixel
00790         */
00791     traverser upperLeft()
00792     {
00793         vigra_precondition(data_ != 0,
00794           "BasicImage::upperLeft(): image must have non-zero size.");
00795         return traverser(lines_);
00796     }
00797 
00798         /** init 2D random access iterator poining to
00799          pixel(width, height), i.e. one pixel right and below lower right
00800          corner of the image as is common in C/C++.
00801         */
00802     traverser lowerRight()
00803     {
00804         vigra_precondition(data_ != 0,
00805           "BasicImage::lowerRight(): image must have non-zero size.");
00806         return upperLeft() + size();
00807     }
00808 
00809         /** init 2D random access const iterator poining to upper left pixel
00810         */
00811     const_traverser upperLeft() const
00812     {
00813         vigra_precondition(data_ != 0,
00814           "BasicImage::upperLeft(): image must have non-zero size.");
00815         return const_traverser(const_cast<PIXELTYPE **>(lines_));
00816     }
00817 
00818         /** init 2D random access const iterator poining to
00819          pixel(width, height), i.e. one pixel right and below lower right
00820          corner of the image as is common in C/C++.
00821         */
00822     const_traverser lowerRight() const
00823     {
00824         vigra_precondition(data_ != 0,
00825           "BasicImage::lowerRight(): image must have non-zero size.");
00826         return upperLeft() + size();
00827     }
00828 
00829         /** init 1D random access iterator pointing to first pixel
00830         */
00831     iterator begin()
00832     {
00833         vigra_precondition(data_ != 0,
00834           "BasicImage::begin(): image must have non-zero size.");
00835         return data_;
00836     }
00837 
00838         /** init 1D random access iterator pointing past the end
00839         */
00840     iterator end()
00841     {
00842         vigra_precondition(data_ != 0,
00843           "BasicImage::end(): image must have non-zero size.");
00844         return data_ + width() * height();
00845     }
00846 
00847         /** init 1D random access const iterator pointing to first pixel
00848         */
00849     const_iterator begin() const
00850     {
00851         vigra_precondition(data_ != 0,
00852           "BasicImage::begin(): image must have non-zero size.");
00853         return data_;
00854     }
00855 
00856         /** init 1D random access const iterator pointing past the end
00857         */
00858     const_iterator end() const
00859     {
00860         vigra_precondition(data_ != 0,
00861           "BasicImage::end(): image must have non-zero size.");
00862         return data_ + width() * height();
00863     }
00864 
00865         /** return default accessor
00866         */
00867     Accessor accessor()
00868     {
00869         return Accessor();
00870     }
00871 
00872         /** return default const accessor
00873         */
00874     ConstAccessor accessor() const
00875     {
00876         return ConstAccessor();
00877     }
00878 
00879   private:
00880 
00881     void deallocate();
00882 
00883     value_type ** initLineStartArray(value_type * data, int width, int height);
00884 
00885     PIXELTYPE * data_;
00886     PIXELTYPE ** lines_;
00887     int width_, height_;
00888     Alloc allocator_;
00889     LineAllocator pallocator_;
00890 };
00891 
00892 template <class PIXELTYPE, class Alloc>
00893 BasicImage<PIXELTYPE, Alloc> &
00894 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage<PIXELTYPE, Alloc> & rhs)
00895 {
00896     if(this != &rhs)
00897     {
00898         if((width() != rhs.width()) ||
00899            (height() != rhs.height()))
00900         {
00901             resizeCopy(rhs);
00902         }
00903         else
00904         {
00905             ConstScanOrderIterator is = rhs.begin();
00906             ConstScanOrderIterator iend = rhs.end();
00907             ScanOrderIterator id = begin();
00908 
00909             for(; is != iend; ++is, ++id) *id = *is;
00910         }
00911     }
00912     return *this;
00913 }
00914 
00915 template <class PIXELTYPE, class Alloc>
00916 BasicImage<PIXELTYPE, Alloc> &
00917 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel)
00918 {
00919     ScanOrderIterator i = begin();
00920     ScanOrderIterator iend = end();
00921 
00922     for(; i != iend; ++i) *i = pixel;
00923 
00924     return *this;
00925 }
00926 
00927 template <class PIXELTYPE, class Alloc>
00928 BasicImage<PIXELTYPE, Alloc> &
00929 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel)
00930 {
00931     ScanOrderIterator i = begin();
00932     ScanOrderIterator iend = end();
00933 
00934     for(; i != iend; ++i) *i = pixel;
00935 
00936     return *this;
00937 }
00938 
00939 template <class PIXELTYPE, class Alloc>
00940 void
00941 BasicImage<PIXELTYPE, Alloc>::resize(int width, int height, value_type const & d)
00942 {
00943     vigra_precondition((width >= 0) && (height >= 0),
00944          "BasicImage::resize(int width, int height, value_type const &): "
00945          "width and height must be >= 0.\n");
00946 
00947     if (width_ != width || height_ != height)  // change size?
00948     {
00949         value_type * newdata = 0;
00950         value_type ** newlines = 0;
00951         if(width*height > 0)
00952         {
00953             if (width*height != width_*height_) // different sizes, must reallocate
00954             {
00955                 newdata = allocator_.allocate(width*height);
00956                 std::uninitialized_fill_n(newdata, width*height, d);
00957                 newlines = initLineStartArray(newdata, width, height);
00958                 deallocate();
00959             }
00960             else // need only to reshape
00961             {
00962                 newdata = data_;
00963                 std::fill_n(newdata, width*height, d);
00964                 newlines = initLineStartArray(newdata, width, height);
00965                 pallocator_.deallocate(lines_, height_);
00966             }
00967         }
00968         else
00969         {
00970             deallocate();
00971         }
00972 
00973         data_ = newdata;
00974         lines_ = newlines;
00975         width_ = width;
00976         height_ = height;
00977     }
00978     else if(width*height > 0) // keep size, re-init data
00979     {
00980         std::fill_n(data_, width*height, d);
00981     }
00982 }
00983 
00984 
00985 template <class PIXELTYPE, class Alloc>
00986 void
00987 BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data)
00988 {
00989     int newsize = width*height;
00990     if (width_ != width || height_ != height)  // change size?
00991     {
00992         value_type * newdata = 0;
00993         value_type ** newlines = 0;
00994         if(newsize > 0)
00995         {
00996             if (newsize != width_*height_) // different sizes, must reallocate
00997             {
00998                 newdata = allocator_.allocate(newsize);
00999                 std::uninitialized_copy(data, data + newsize, newdata);
01000                 newlines = initLineStartArray(newdata, width, height);
01001                 deallocate();
01002             }
01003             else // need only to reshape
01004             {
01005                 newdata = data_;
01006                 std::copy(data, data + newsize, newdata);
01007                 newlines = initLineStartArray(newdata, width, height);
01008                 pallocator_.deallocate(lines_, height_);
01009             }
01010         }
01011         else
01012         {
01013             deallocate();
01014         }
01015 
01016         data_ = newdata;
01017         lines_ = newlines;
01018         width_ = width;
01019         height_ = height;
01020     }
01021     else if(newsize > 0) // keep size, copy data
01022     {
01023         std::copy(data, data + newsize, data_);
01024     }
01025 }
01026 
01027 template <class PIXELTYPE, class Alloc>
01028 void
01029 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage<PIXELTYPE, Alloc>& rhs )
01030 {
01031   if (&rhs!=this)
01032   {
01033     std::swap( data_, rhs.data_ );
01034     std::swap( lines_, rhs.lines_ );
01035     std::swap( width_, rhs.width_ );
01036     std::swap( height_, rhs.height_ );
01037   }
01038 }
01039 
01040 template <class PIXELTYPE, class Alloc>
01041 void
01042 BasicImage<PIXELTYPE, Alloc>::deallocate()
01043 {
01044     if(data_)
01045     {
01046         ScanOrderIterator i = begin();
01047         ScanOrderIterator iend = end();
01048 
01049         for(; i != iend; ++i)   (*i).~PIXELTYPE();
01050 
01051         allocator_.deallocate(data_, width()*height());
01052         pallocator_.deallocate(lines_, height_);
01053     }
01054 }
01055 
01056 template <class PIXELTYPE, class Alloc>
01057 PIXELTYPE **
01058 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height)
01059 {
01060     value_type ** lines = pallocator_.allocate(height);
01061     for(int y=0; y<height; ++y)
01062          lines[y] = data + y*width;
01063     return lines;
01064 }
01065 
01066 /********************************************************/
01067 /*                                                      */
01068 /*              argument object factories               */
01069 /*                                                      */
01070 /********************************************************/
01071 
01072 template <class PixelType, class Accessor, class Alloc>
01073 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01074               typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01075 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a)
01076 {
01077     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01078                   typename BasicImage<PixelType, Alloc>::const_traverser,
01079           Accessor>(img.upperLeft(),
01080                     img.lowerRight(),
01081                     a);
01082 }
01083 
01084 template <class PixelType, class Accessor, class Alloc>
01085 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01086 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
01087 {
01088     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01089                 Accessor>(img.upperLeft(), a);
01090 }
01091 
01092 template <class PixelType, class Accessor, class Alloc>
01093 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
01094               typename BasicImage<PixelType, Alloc>::traverser, Accessor>
01095 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a)
01096 {
01097     return triple<typename BasicImage<PixelType, Alloc>::traverser,
01098                   typename BasicImage<PixelType, Alloc>::traverser,
01099           Accessor>(img.upperLeft(),
01100                     img.lowerRight(),
01101                     a);
01102 }
01103 
01104 template <class PixelType, class Accessor, class Alloc>
01105 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
01106 destImage(BasicImage<PixelType, Alloc> & img, Accessor a)
01107 {
01108     return pair<typename BasicImage<PixelType, Alloc>::traverser,
01109                 Accessor>(img.upperLeft(), a);
01110 }
01111 
01112 template <class PixelType, class Accessor, class Alloc>
01113 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01114 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
01115 {
01116     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01117                 Accessor>(img.upperLeft(), a);
01118 }
01119 
01120 /****************************************************************/
01121 
01122 template <class PixelType, class Alloc>
01123 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01124               typename BasicImage<PixelType, Alloc>::const_traverser,
01125               typename BasicImage<PixelType, Alloc>::ConstAccessor>
01126 srcImageRange(BasicImage<PixelType, Alloc> const & img)
01127 {
01128     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01129                   typename BasicImage<PixelType, Alloc>::const_traverser,
01130                   typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01131                                                                  img.lowerRight(),
01132                                                                  img.accessor());
01133 }
01134 
01135 template <class PixelType, class Alloc>
01136 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
01137              typename BasicImage<PixelType, Alloc>::ConstAccessor>
01138 srcImage(BasicImage<PixelType, Alloc> const & img)
01139 {
01140     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01141                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01142                                                                img.accessor());
01143 }
01144 
01145 template <class PixelType, class Alloc>
01146 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
01147                typename BasicImage<PixelType, Alloc>::traverser,
01148                typename BasicImage<PixelType, Alloc>::Accessor>
01149 destImageRange(BasicImage<PixelType, Alloc> & img)
01150 {
01151     return triple<typename BasicImage<PixelType, Alloc>::traverser,
01152                   typename BasicImage<PixelType, Alloc>::traverser,
01153                   typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
01154                                                             img.lowerRight(),
01155                                                             img.accessor());
01156 }
01157 
01158 template <class PixelType, class Alloc>
01159 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
01160              typename BasicImage<PixelType, Alloc>::Accessor>
01161 destImage(BasicImage<PixelType, Alloc> & img)
01162 {
01163     return pair<typename BasicImage<PixelType, Alloc>::traverser,
01164                 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
01165                                                           img.accessor());
01166 }
01167 
01168 template <class PixelType, class Alloc>
01169 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
01170              typename BasicImage<PixelType, Alloc>::ConstAccessor>
01171 maskImage(BasicImage<PixelType, Alloc> const & img)
01172 {
01173     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01174                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01175                                                                img.accessor());
01176 }
01177 
01178 } // namespace vigra
01179 
01180 #endif // VIGRA_BASICIMAGE_HXX

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.3.2 (27 Jan 2005)