[ 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.3, Aug 18 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     typedef VigraTrueType                                 hasConstantStrides;
00318 };
00319 
00320 template <class T>
00321 struct IteratorTraits<ConstBasicImageIterator<T, T**> >
00322 : public IteratorTraitsBase<ConstBasicImageIterator<T, T**> >
00323 {
00324     typedef typename AccessorTraits<T>::default_const_accessor  DefaultAccessor;
00325     typedef DefaultAccessor                               default_accessor;
00326     typedef VigraTrueType                                 hasConstantStrides;
00327 };
00328 
00329 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00330 
00331 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
00332     template <>  \
00333     struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
00334     : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
00335     { \
00336         typedef typename AccessorTraits<VALUETYPE >::default_accessor  DefaultAccessor; \
00337         typedef DefaultAccessor                               default_accessor; \
00338         typedef VigraTrueType                                 hasConstantStrides; \
00339     }; \
00340     \
00341     template <>  \
00342     struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
00343     : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
00344     { \
00345         typedef typename AccessorTraits<VALUETYPE >::default_const_accessor  DefaultAccessor; \
00346         typedef DefaultAccessor                               default_accessor; \
00347         typedef VigraTrueType                                 hasConstantStrides; \
00348     };
00349 
00350 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
00351 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
00352 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
00353 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
00354 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
00355 
00356 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
00357 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00358 #undef VIGRA_PIXELTYPE
00359 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
00360 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00361 #undef VIGRA_PIXELTYPE
00362 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
00363 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00364 #undef VIGRA_PIXELTYPE
00365 #define VIGRA_PIXELTYPE TinyVector<short, 2>
00366 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00367 #undef VIGRA_PIXELTYPE
00368 #define VIGRA_PIXELTYPE TinyVector<short, 3>
00369 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00370 #undef VIGRA_PIXELTYPE
00371 #define VIGRA_PIXELTYPE TinyVector<short, 4>
00372 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00373 #undef VIGRA_PIXELTYPE
00374 #define VIGRA_PIXELTYPE TinyVector<int, 2>
00375 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00376 #undef VIGRA_PIXELTYPE
00377 #define VIGRA_PIXELTYPE TinyVector<int, 3>
00378 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00379 #undef VIGRA_PIXELTYPE
00380 #define VIGRA_PIXELTYPE TinyVector<int, 4>
00381 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00382 #undef VIGRA_PIXELTYPE
00383 #define VIGRA_PIXELTYPE TinyVector<float, 2>
00384 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00385 #undef VIGRA_PIXELTYPE
00386 #define VIGRA_PIXELTYPE TinyVector<float, 3>
00387 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00388 #undef VIGRA_PIXELTYPE
00389 #define VIGRA_PIXELTYPE TinyVector<float, 4>
00390 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00391 #undef VIGRA_PIXELTYPE
00392 #define VIGRA_PIXELTYPE TinyVector<double, 2>
00393 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00394 #undef VIGRA_PIXELTYPE
00395 #define VIGRA_PIXELTYPE TinyVector<double, 3>
00396 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00397 #undef VIGRA_PIXELTYPE
00398 #define VIGRA_PIXELTYPE TinyVector<double, 4>
00399 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00400 #undef VIGRA_PIXELTYPE
00401 
00402 #undef VIGRA_DEFINE_ITERATORTRAITS
00403 
00404 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00405 
00406 /********************************************************/
00407 /*                                                      */
00408 /*                     BasicImage                       */
00409 /*                                                      */
00410 /********************************************************/
00411 
00412 /** \brief Fundamental class template for images.
00413 
00414     A customized memory allocator can be specified as a templated argument
00415     ans passed in the constructor.
00416 
00417     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00418 
00419     Namespace: vigra
00420 */
00421 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
00422 class BasicImage
00423 {
00424   public:
00425 
00426         /** the BasicImage's pixel type
00427         */
00428     typedef PIXELTYPE value_type;
00429 
00430         /** the BasicImage's pixel type
00431         */
00432     typedef PIXELTYPE PixelType;
00433 
00434         /** the BasicImage's reference type (i.e. the
00435             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
00436         */
00437     typedef PIXELTYPE &       reference;
00438 
00439         /** the BasicImage's const reference type (i.e. the
00440             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
00441             when <TT>image</TT> is const)
00442         */
00443     typedef PIXELTYPE const & const_reference;
00444 
00445         /** the BasicImage's pointer type
00446         */
00447     typedef PIXELTYPE *       pointer;
00448 
00449         /** the BasicImage's const pointer type
00450         */
00451     typedef PIXELTYPE const * const_pointer;
00452 
00453         /** the BasicImage's 1D random access iterator
00454             (note: lower case 'iterator' is a STL compatible 1D random
00455              access iterator, don't confuse with capitalized Iterator)
00456         */
00457     typedef PIXELTYPE * iterator;
00458 
00459         /** deprecated, use <TT>iterator</TT> instead
00460         */
00461     typedef PIXELTYPE * ScanOrderIterator;
00462 
00463         /** the BasicImage's 1D random access const iterator
00464             (note: lower case 'const_iterator' is a STL compatible 1D
00465             random access const iterator)
00466         */
00467     typedef PIXELTYPE const * const_iterator;
00468 
00469         /** deprecated, use <TT>const_iterator</TT> instead
00470         */
00471     typedef PIXELTYPE const * ConstScanOrderIterator;
00472 
00473         /** the BasicImage's 2D random access iterator ('traverser')
00474         */
00475     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
00476 
00477         /** deprecated, use <TT>traverser</TT> instead
00478         */
00479     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
00480 
00481         /** the BasicImage's 2D random access const iterator ('const traverser')
00482         */
00483     typedef
00484         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00485         const_traverser;
00486 
00487         /** deprecated, use <TT>const_traverser</TT> instead
00488         */
00489     typedef
00490         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00491         ConstIterator;
00492 
00493         /** the BasicImage's difference type (argument type of image[diff])
00494         */
00495     typedef Diff2D difference_type;
00496 
00497          /** the BasicImage's size type (result type of image.size())
00498         */
00499     typedef Size2D size_type;
00500 
00501        /** the BasicImage's default accessor
00502         */
00503     typedef typename
00504           IteratorTraits<traverser>::DefaultAccessor Accessor;
00505 
00506         /** the BasicImage's default const accessor
00507         */
00508     typedef typename
00509           IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
00510 
00511         /** the BasicImage's allocator (default: std::allocator<value_type>)
00512         */
00513     typedef Alloc allocator_type;
00514 
00515     typedef Alloc Allocator;
00516     typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator;
00517 
00518         /** construct image of size 0x0
00519         */
00520     BasicImage()
00521     : data_(0),
00522       width_(0),
00523       height_(0)
00524     {}
00525 
00526         /** construct image of size 0x0, use the specified allocator.
00527         */
00528     explicit BasicImage(Alloc const & alloc)
00529     : data_(0),
00530       width_(0),
00531       height_(0),
00532       allocator_(alloc),
00533       pallocator_(alloc)
00534     {}
00535 
00536         /** construct image of size width x height, use the specified allocator.
00537         */
00538     BasicImage(int width, int height, Alloc const & alloc = Alloc())
00539     : data_(0),
00540       width_(0),
00541       height_(0),
00542       allocator_(alloc),
00543       pallocator_(alloc)
00544     {
00545         vigra_precondition((width >= 0) && (height >= 0),
00546              "BasicImage::BasicImage(int width, int height): "
00547              "width and height must be >= 0.\n");
00548 
00549         resize(width, height, value_type());
00550     }
00551 
00552         /** construct image of size size.x x size.y, use the specified allocator.
00553         */
00554     explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc())
00555     : data_(0),
00556       width_(0),
00557       height_(0),
00558       allocator_(alloc),
00559       pallocator_(alloc)
00560     {
00561         vigra_precondition((size.x >= 0) && (size.y >= 0),
00562              "BasicImage::BasicImage(Diff2D size): "
00563              "size.x and size.y must be >= 0.\n");
00564 
00565         resize(size.x, size.y, value_type());
00566     }
00567 
00568         /** construct image of size width*height and initialize every
00569         pixel with the value \a d (use this constructor, if
00570         value_type doesn't have a default constructor). 
00571         Use the specified allocator.
00572         */
00573     BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc())
00574     : data_(0),
00575       width_(0),
00576       height_(0),
00577       allocator_(alloc),
00578       pallocator_(alloc)
00579     {
00580         vigra_precondition((width >= 0) && (height >= 0),
00581              "BasicImage::BasicImage(int width, int height, value_type const & ): "
00582              "width and height must be >= 0.\n");
00583 
00584         resize(width, height, d);
00585     }
00586 
00587         /** construct image of size size.x x size.y and initialize
00588         every pixel with given data (use this constructor, if
00589         value_type doesn't have a default constructor). Use the specified allocator.
00590         */
00591     explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc())
00592     : data_(0),
00593       width_(0),
00594       height_(0),
00595       allocator_(alloc),
00596       pallocator_(alloc)
00597     {
00598         vigra_precondition((size.x >= 0) && (size.y >= 0),
00599              "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
00600              "size.x and size.y must be >= 0.\n");
00601 
00602         resize(size.x, size.y, d);
00603     }
00604 
00605 
00606         /** construct image of size width*height and copy the data from the
00607             given C-style array \a d. Use the specified allocator.
00608         */
00609     BasicImage(int width, int height, const_pointer d, Alloc const & alloc = Alloc())
00610     : data_(0),
00611       width_(0),
00612       height_(0),
00613       allocator_(alloc),
00614       pallocator_(alloc)
00615     {
00616         vigra_precondition((width >= 0) && (height >= 0),
00617              "BasicImage::BasicImage(int width, int height, const_pointer ): "
00618              "width and height must be >= 0.\n");
00619 
00620         resizeCopy(width, height, d);
00621     }
00622 
00623         /** construct image of size size.x x size.y  and copy the data from the
00624             given C-style array. Use the specified allocator.
00625         */
00626     explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc())
00627     : data_(0),
00628       width_(0),
00629       height_(0),
00630       allocator_(alloc),
00631       pallocator_(alloc)
00632     {
00633         vigra_precondition((size.x >= 0) && (size.y >= 0),
00634              "BasicImage::BasicImage(Diff2D const & size, const_pointer): "
00635              "size.x and size.y must be >= 0.\n");
00636 
00637         resizeCopy(size.x, size.y, d);
00638     }
00639 
00640         /** copy rhs image
00641         */
00642     BasicImage(const BasicImage & rhs)
00643     : data_(0),
00644       width_(0),
00645       height_(0),
00646       allocator_(rhs.allocator_),
00647       pallocator_(rhs.pallocator_)
00648     {
00649         resizeCopy(rhs);
00650     }
00651 
00652         /** destructor
00653         */
00654     ~BasicImage()
00655     {
00656         deallocate();
00657     }
00658 
00659         /** copy rhs image (image is resized if necessary)
00660         */
00661     BasicImage & operator=(const BasicImage & rhs);
00662 
00663         /** \deprecated set Image with const value
00664         */
00665     BasicImage & operator=(value_type pixel);
00666 
00667         /** set Image with const value
00668         */
00669     BasicImage & init(value_type const & pixel);
00670 
00671         /** reset image to specified size (dimensions must not be negative)
00672             (old data are kept if new size matches old size)
00673         */
00674     void resize(int width, int height)
00675     {
00676         if(width != width_ || height != height_)
00677             resize(width, height, value_type());
00678     }
00679 
00680         /** reset image to specified size (dimensions must not be negative)
00681             (old data are kept if new size matches old size)
00682         */
00683     void resize(difference_type const & size)
00684     {
00685         if(size.x != width_ || size.y != height_)
00686         {
00687             resize(size.x, size.y, value_type());
00688         }
00689     }
00690 
00691         /** reset image to specified size and initialize it with
00692             given data (use this if value_type doesn't have a default
00693             constructor, dimensions must not be negative,
00694             old data are kept if new size matches old size)
00695         */
00696     void resize(int width, int height, value_type const & d);
00697 
00698         /** resize image to given size and initialize by copying data
00699             from the C-style arra \a data.
00700         */
00701     void resizeCopy(int width, int height, const_pointer data);
00702 
00703         /** resize image to size of other image and copy it's data
00704         */
00705     void resizeCopy(const BasicImage & rhs)
00706     {
00707         resizeCopy(rhs.width(), rhs.height(), rhs.data_);
00708     }
00709 
00710         /** swap the internal data with the rhs image in constant time
00711         */
00712     void swap( BasicImage & rhs );
00713 
00714         /** width of Image
00715         */
00716     int width() const
00717     {
00718         return width_;
00719     }
00720 
00721         /** height of Image
00722         */
00723     int height() const
00724     {
00725         return height_;
00726     }
00727 
00728         /** size of Image
00729         */
00730     size_type size() const
00731     {
00732         return size_type(width(), height());
00733     }
00734 
00735         /** test whether a given coordinate is inside the image
00736         */
00737     bool isInside(difference_type const & d) const
00738     {
00739         return d.x >= 0 && d.y >= 0 &&
00740                d.x < width() && d.y < height();
00741     }
00742 
00743         /** access pixel at given location. <br>
00744         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00745         */
00746     reference operator[](difference_type const & d)
00747     {
00748         return lines_[d.y][d.x];
00749     }
00750 
00751         /** read pixel at given location. <br>
00752         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00753         */
00754     const_reference operator[](difference_type const & d) const
00755     {
00756         return lines_[d.y][d.x];
00757     }
00758 
00759         /** access pixel at given location. <br>
00760         usage: <TT> value_type value = image(1,2) </TT>
00761         */
00762     reference operator()(int dx, int dy)
00763     {
00764         return lines_[dy][dx];
00765     }
00766 
00767         /** read pixel at given location. <br>
00768         usage: <TT> value_type value = image(1,2) </TT>
00769         */
00770     const_reference operator()(int dx, int dy) const
00771     {
00772         return lines_[dy][dx];
00773     }
00774 
00775         /** access pixel at given location.
00776             Note that the 'x' index is the trailing index. <br>
00777         usage: <TT> value_type value = image[2][1] </TT>
00778         */
00779     pointer operator[](int dy)
00780     {
00781         return lines_[dy];
00782     }
00783 
00784         /** read pixel at given location.
00785             Note that the 'x' index is the trailing index. <br>
00786         usage: <TT> value_type value = image[2][1] </TT>
00787         */
00788     const_pointer operator[](int dy) const
00789     {
00790         return lines_[dy];
00791     }
00792 
00793         /** init 2D random access iterator poining to upper left pixel
00794         */
00795     traverser upperLeft()
00796     {
00797         vigra_precondition(data_ != 0,
00798           "BasicImage::upperLeft(): image must have non-zero size.");
00799         return traverser(lines_);
00800     }
00801 
00802         /** init 2D random access iterator poining to
00803          pixel(width, height), i.e. one pixel right and below lower right
00804          corner of the image as is common in C/C++.
00805         */
00806     traverser lowerRight()
00807     {
00808         vigra_precondition(data_ != 0,
00809           "BasicImage::lowerRight(): image must have non-zero size.");
00810         return upperLeft() + size();
00811     }
00812 
00813         /** init 2D random access const iterator poining to upper left pixel
00814         */
00815     const_traverser upperLeft() const
00816     {
00817         vigra_precondition(data_ != 0,
00818           "BasicImage::upperLeft(): image must have non-zero size.");
00819         return const_traverser(const_cast<PIXELTYPE **>(lines_));
00820     }
00821 
00822         /** init 2D random access const iterator poining to
00823          pixel(width, height), i.e. one pixel right and below lower right
00824          corner of the image as is common in C/C++.
00825         */
00826     const_traverser lowerRight() const
00827     {
00828         vigra_precondition(data_ != 0,
00829           "BasicImage::lowerRight(): image must have non-zero size.");
00830         return upperLeft() + size();
00831     }
00832 
00833         /** init 1D random access iterator pointing to first pixel
00834         */
00835     iterator begin()
00836     {
00837         vigra_precondition(data_ != 0,
00838           "BasicImage::begin(): image must have non-zero size.");
00839         return data_;
00840     }
00841 
00842         /** init 1D random access iterator pointing past the end
00843         */
00844     iterator end()
00845     {
00846         vigra_precondition(data_ != 0,
00847           "BasicImage::end(): image must have non-zero size.");
00848         return data_ + width() * height();
00849     }
00850 
00851         /** init 1D random access const iterator pointing to first pixel
00852         */
00853     const_iterator begin() const
00854     {
00855         vigra_precondition(data_ != 0,
00856           "BasicImage::begin(): image must have non-zero size.");
00857         return data_;
00858     }
00859 
00860         /** init 1D random access const iterator pointing past the end
00861         */
00862     const_iterator end() const
00863     {
00864         vigra_precondition(data_ != 0,
00865           "BasicImage::end(): image must have non-zero size.");
00866         return data_ + width() * height();
00867     }
00868 
00869         /** return default accessor
00870         */
00871     Accessor accessor()
00872     {
00873         return Accessor();
00874     }
00875 
00876         /** return default const accessor
00877         */
00878     ConstAccessor accessor() const
00879     {
00880         return ConstAccessor();
00881     }
00882 
00883   private:
00884 
00885     void deallocate();
00886 
00887     value_type ** initLineStartArray(value_type * data, int width, int height);
00888 
00889     PIXELTYPE * data_;
00890     PIXELTYPE ** lines_;
00891     int width_, height_;
00892     Alloc allocator_;
00893     LineAllocator pallocator_;
00894 };
00895 
00896 template <class PIXELTYPE, class Alloc>
00897 BasicImage<PIXELTYPE, Alloc> &
00898 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage<PIXELTYPE, Alloc> & rhs)
00899 {
00900     if(this != &rhs)
00901     {
00902         if((width() != rhs.width()) ||
00903            (height() != rhs.height()))
00904         {
00905             resizeCopy(rhs);
00906         }
00907         else
00908         {
00909             ConstScanOrderIterator is = rhs.begin();
00910             ConstScanOrderIterator iend = rhs.end();
00911             ScanOrderIterator id = begin();
00912 
00913             for(; is != iend; ++is, ++id) *id = *is;
00914         }
00915     }
00916     return *this;
00917 }
00918 
00919 template <class PIXELTYPE, class Alloc>
00920 BasicImage<PIXELTYPE, Alloc> &
00921 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel)
00922 {
00923     ScanOrderIterator i = begin();
00924     ScanOrderIterator iend = end();
00925 
00926     for(; i != iend; ++i) *i = pixel;
00927 
00928     return *this;
00929 }
00930 
00931 template <class PIXELTYPE, class Alloc>
00932 BasicImage<PIXELTYPE, Alloc> &
00933 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel)
00934 {
00935     ScanOrderIterator i = begin();
00936     ScanOrderIterator iend = end();
00937 
00938     for(; i != iend; ++i) *i = pixel;
00939 
00940     return *this;
00941 }
00942 
00943 template <class PIXELTYPE, class Alloc>
00944 void
00945 BasicImage<PIXELTYPE, Alloc>::resize(int width, int height, value_type const & d)
00946 {
00947     vigra_precondition((width >= 0) && (height >= 0),
00948          "BasicImage::resize(int width, int height, value_type const &): "
00949          "width and height must be >= 0.\n");
00950 
00951     if (width_ != width || height_ != height)  // change size?
00952     {
00953         value_type * newdata = 0;
00954         value_type ** newlines = 0;
00955         if(width*height > 0)
00956         {
00957             if (width*height != width_*height_) // different sizes, must reallocate
00958             {
00959                 newdata = allocator_.allocate(width*height);
00960                 std::uninitialized_fill_n(newdata, width*height, d);
00961                 newlines = initLineStartArray(newdata, width, height);
00962                 deallocate();
00963             }
00964             else // need only to reshape
00965             {
00966                 newdata = data_;
00967                 std::fill_n(newdata, width*height, d);
00968                 newlines = initLineStartArray(newdata, width, height);
00969                 pallocator_.deallocate(lines_, height_);
00970             }
00971         }
00972         else
00973         {
00974             deallocate();
00975         }
00976 
00977         data_ = newdata;
00978         lines_ = newlines;
00979         width_ = width;
00980         height_ = height;
00981     }
00982     else if(width*height > 0) // keep size, re-init data
00983     {
00984         std::fill_n(data_, width*height, d);
00985     }
00986 }
00987 
00988 
00989 template <class PIXELTYPE, class Alloc>
00990 void
00991 BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data)
00992 {
00993     int newsize = width*height;
00994     if (width_ != width || height_ != height)  // change size?
00995     {
00996         value_type * newdata = 0;
00997         value_type ** newlines = 0;
00998         if(newsize > 0)
00999         {
01000             if (newsize != width_*height_) // different sizes, must reallocate
01001             {
01002                 newdata = allocator_.allocate(newsize);
01003                 std::uninitialized_copy(data, data + newsize, newdata);
01004                 newlines = initLineStartArray(newdata, width, height);
01005                 deallocate();
01006             }
01007             else // need only to reshape
01008             {
01009                 newdata = data_;
01010                 std::copy(data, data + newsize, newdata);
01011                 newlines = initLineStartArray(newdata, width, height);
01012                 pallocator_.deallocate(lines_, height_);
01013             }
01014         }
01015         else
01016         {
01017             deallocate();
01018         }
01019 
01020         data_ = newdata;
01021         lines_ = newlines;
01022         width_ = width;
01023         height_ = height;
01024     }
01025     else if(newsize > 0) // keep size, copy data
01026     {
01027         std::copy(data, data + newsize, data_);
01028     }
01029 }
01030 
01031 template <class PIXELTYPE, class Alloc>
01032 void
01033 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage<PIXELTYPE, Alloc>& rhs )
01034 {
01035   if (&rhs!=this)
01036   {
01037     std::swap( data_, rhs.data_ );
01038     std::swap( lines_, rhs.lines_ );
01039     std::swap( width_, rhs.width_ );
01040     std::swap( height_, rhs.height_ );
01041   }
01042 }
01043 
01044 template <class PIXELTYPE, class Alloc>
01045 void
01046 BasicImage<PIXELTYPE, Alloc>::deallocate()
01047 {
01048     if(data_)
01049     {
01050         ScanOrderIterator i = begin();
01051         ScanOrderIterator iend = end();
01052 
01053         for(; i != iend; ++i)   (*i).~PIXELTYPE();
01054 
01055         allocator_.deallocate(data_, width()*height());
01056         pallocator_.deallocate(lines_, height_);
01057     }
01058 }
01059 
01060 template <class PIXELTYPE, class Alloc>
01061 PIXELTYPE **
01062 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height)
01063 {
01064     value_type ** lines = pallocator_.allocate(height);
01065     for(int y=0; y<height; ++y)
01066          lines[y] = data + y*width;
01067     return lines;
01068 }
01069 
01070 /********************************************************/
01071 /*                                                      */
01072 /*              argument object factories               */
01073 /*                                                      */
01074 /********************************************************/
01075 
01076 template <class PixelType, class Accessor, class Alloc>
01077 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01078               typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01079 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a)
01080 {
01081     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01082                   typename BasicImage<PixelType, Alloc>::const_traverser,
01083           Accessor>(img.upperLeft(),
01084                     img.lowerRight(),
01085                     a);
01086 }
01087 
01088 template <class PixelType, class Accessor, class Alloc>
01089 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01090 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
01091 {
01092     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01093                 Accessor>(img.upperLeft(), a);
01094 }
01095 
01096 template <class PixelType, class Accessor, class Alloc>
01097 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
01098               typename BasicImage<PixelType, Alloc>::traverser, Accessor>
01099 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a)
01100 {
01101     return triple<typename BasicImage<PixelType, Alloc>::traverser,
01102                   typename BasicImage<PixelType, Alloc>::traverser,
01103           Accessor>(img.upperLeft(),
01104                     img.lowerRight(),
01105                     a);
01106 }
01107 
01108 template <class PixelType, class Accessor, class Alloc>
01109 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
01110 destImage(BasicImage<PixelType, Alloc> & img, Accessor a)
01111 {
01112     return pair<typename BasicImage<PixelType, Alloc>::traverser,
01113                 Accessor>(img.upperLeft(), a);
01114 }
01115 
01116 template <class PixelType, class Accessor, class Alloc>
01117 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01118 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
01119 {
01120     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01121                 Accessor>(img.upperLeft(), a);
01122 }
01123 
01124 /****************************************************************/
01125 
01126 template <class PixelType, class Alloc>
01127 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01128               typename BasicImage<PixelType, Alloc>::const_traverser,
01129               typename BasicImage<PixelType, Alloc>::ConstAccessor>
01130 srcImageRange(BasicImage<PixelType, Alloc> const & img)
01131 {
01132     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01133                   typename BasicImage<PixelType, Alloc>::const_traverser,
01134                   typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01135                                                                  img.lowerRight(),
01136                                                                  img.accessor());
01137 }
01138 
01139 template <class PixelType, class Alloc>
01140 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
01141              typename BasicImage<PixelType, Alloc>::ConstAccessor>
01142 srcImage(BasicImage<PixelType, Alloc> const & img)
01143 {
01144     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01145                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01146                                                                img.accessor());
01147 }
01148 
01149 template <class PixelType, class Alloc>
01150 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
01151                typename BasicImage<PixelType, Alloc>::traverser,
01152                typename BasicImage<PixelType, Alloc>::Accessor>
01153 destImageRange(BasicImage<PixelType, Alloc> & img)
01154 {
01155     return triple<typename BasicImage<PixelType, Alloc>::traverser,
01156                   typename BasicImage<PixelType, Alloc>::traverser,
01157                   typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
01158                                                             img.lowerRight(),
01159                                                             img.accessor());
01160 }
01161 
01162 template <class PixelType, class Alloc>
01163 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
01164              typename BasicImage<PixelType, Alloc>::Accessor>
01165 destImage(BasicImage<PixelType, Alloc> & img)
01166 {
01167     return pair<typename BasicImage<PixelType, Alloc>::traverser,
01168                 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
01169                                                           img.accessor());
01170 }
01171 
01172 template <class PixelType, class Alloc>
01173 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
01174              typename BasicImage<PixelType, Alloc>::ConstAccessor>
01175 maskImage(BasicImage<PixelType, Alloc> const & img)
01176 {
01177     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01178                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01179                                                                img.accessor());
01180 }
01181 
01182 } // namespace vigra
01183 
01184 #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.3 (18 Aug 2005)