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

| vigra/basicimage.hxx |
--- | --- | ---

    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)