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

vigra/basicimage.hxx |

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
    00004 /*                                                                      */
    00005 /*    This file is part of the VIGRA computer vision library.           */
    00006 /*    The VIGRA Website is                                              */
    00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
    00008 /*    Please direct questions, bug reports, and contributions to        */
    00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00010 /*        vigra@informatik.uni-hamburg.de                               */
    00011 /*                                                                      */
    00012 /*    Permission is hereby granted, free of charge, to any person       */
    00013 /*    obtaining a copy of this software and associated documentation    */
    00014 /*    files (the "Software"), to deal in the Software without           */
    00015 /*    restriction, including without limitation the rights to use,      */
    00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00017 /*    sell copies of the Software, and to permit persons to whom the    */
    00018 /*    Software is furnished to do so, subject to the following          */
    00019 /*    conditions:                                                       */
    00020 /*                                                                      */
    00021 /*    The above copyright notice and this permission notice shall be    */
    00022 /*    included in all copies or substantial portions of the             */
    00023 /*    Software.                                                         */
    00024 /*                                                                      */
    00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00033 /*                                                                      */
    00034 /************************************************************************/
    00035
    00036 #ifndef VIGRA_BASICIMAGE_HXX
    00037 #define VIGRA_BASICIMAGE_HXX
    00038
    00039 #include <memory>
    00040 #include <algorithm>
    00041 #include "utilities.hxx"
    00042 #include "iteratortraits.hxx"
    00043 #include "accessor.hxx"
    00044 #include "memory.hxx"
    00045
    00046 // Bounds checking Macro used if VIGRA_CHECK_BOUNDS is defined.
    00047 #ifdef VIGRA_CHECK_BOUNDS
    00048 #define VIGRA_ASSERT_INSIDE(diff) \
    00049   vigra_precondition(this->isInside(diff), "Index out of bounds")
    00050 #else
    00051 #define VIGRA_ASSERT_INSIDE(diff)
    00052 #endif
    00053
    00054 namespace vigra {
    00055
    00056 template <class IMAGEITERATOR>
    00057 class LineBasedColumnIteratorPolicy
    00058 {
    00059   public:
    00060     typedef IMAGEITERATOR                             ImageIterator;
    00061     typedef typename IMAGEITERATOR::LineStartIterator LineStartIterator;
    00062     typedef typename IMAGEITERATOR::value_type        value_type;
    00063     typedef typename IMAGEITERATOR::difference_type::MoveY
    00064                                                       difference_type;
    00065     typedef typename IMAGEITERATOR::reference         reference;
    00066     typedef typename IMAGEITERATOR::index_reference   index_reference;
    00067     typedef typename IMAGEITERATOR::pointer           pointer;
    00068     typedef std::random_access_iterator_tag           iterator_category;
    00069
    00070
    00071     struct BaseType
    00072     {
    00073         explicit BaseType(LineStartIterator c = LineStartIterator(),
    00074                           difference_type o = 0)
    00075         : line_start_(c), offset_(o)
    00076         {}
    00077
    00078         LineStartIterator line_start_;
    00079         difference_type offset_;
    00080     };
    00081
    00082     static void initialize(BaseType &) {}
    00083
    00084     static reference dereference(BaseType const & d)
    00085         { return const_cast<reference>(*(*d.line_start_ + d.offset_)); }
    00086
    00087     static index_reference dereference(BaseType const & d, difference_type n)
    00088     {
    00089         return const_cast<index_reference>(*(d.line_start_[n] + d.offset_));
    00090     }
    00091
    00092     static bool equal(BaseType const & d1, BaseType const & d2)
    00093         { return d1.line_start_ == d2.line_start_; }
    00094
    00095     static bool less(BaseType const & d1, BaseType const & d2)
    00096         { return d1.line_start_ < d2.line_start_; }
    00097
    00098     static difference_type difference(BaseType const & d1, BaseType const & d2)
    00099         { return d1.line_start_ - d2.line_start_; }
    00100
    00101     static void increment(BaseType & d)
    00102         { ++d.line_start_; }
    00103
    00104     static void decrement(BaseType & d)
    00105         { --d.line_start_; }
    00106
    00107     static void advance(BaseType & d, difference_type n)
    00108         { d.line_start_ += n; }
    00109 };
    00110
    00111 /********************************************************/
    00112 /*                                                      */
    00113 /*                    BasicImageIterator                */
    00114 /*                                                      */
    00115 /********************************************************/
    00116
    00117 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
    00118     See \ref vigra::ImageIterator for documentation.
    00119
    00120     <b>\#include</b> <<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>>
    00121     Namespace: vigra
    00122 */
    00123 template <class IMAGEITERATOR, class PIXELTYPE,
    00124           class REFERENCE, class POINTER, class LINESTARTITERATOR>
    00125 class BasicImageIteratorBase
    00126 {
    00127   public:
    00128     typedef BasicImageIteratorBase<IMAGEITERATOR,
    00129             PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type;
    00130
    00131     typedef LINESTARTITERATOR    LineStartIterator;
    00132     typedef PIXELTYPE            value_type;
    00133     typedef PIXELTYPE            PixelType;
    00134     typedef REFERENCE            reference;
    00135     typedef REFERENCE            index_reference;
    00136     typedef POINTER              pointer;
    00137     typedef Diff2D               difference_type;
    00138     typedef image_traverser_tag  iterator_category;
    00139     typedef POINTER              row_iterator;
    00140     typedef IteratorAdaptor<LineBasedColumnIteratorPolicy<IMAGEITERATOR> >
    00141                                  column_iterator;
    00142
    00143     typedef int                  MoveX;
    00144     typedef LINESTARTITERATOR    MoveY;
    00145
    00146     MoveX x;
    00147     MoveY y;
    00148
    00149     IMAGEITERATOR & operator+=(difference_type const & s)
    00150     {
    00151         x += s.x;
    00152         y += s.y;
    00153         return static_cast<IMAGEITERATOR &>(*this);
    00154     }
    00155
    00156     IMAGEITERATOR & operator-=(difference_type const & s)
    00157     {
    00158         x -= s.x;
    00159         y -= s.y;
    00160         return static_cast<IMAGEITERATOR &>(*this);
    00161     }
    00162
    00163     IMAGEITERATOR operator+(difference_type const & s) const
    00164     {
    00165         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
    00166
    00167         ret += s;
    00168
    00169         return ret;
    00170     }
    00171
    00172     IMAGEITERATOR operator-(difference_type const & s) const
    00173     {
    00174         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
    00175
    00176         ret -= s;
    00177
    00178         return ret;
    00179     }
    00180
    00181     difference_type operator-(BasicImageIteratorBase const & rhs) const
    00182     {
    00183         return difference_type(difference_type::MoveX(x - rhs.x),
    00184                                difference_type::MoveY(y - rhs.y));
    00185     }
    00186
    00187     bool operator==(BasicImageIteratorBase const & rhs) const
    00188     {
    00189         return (x == rhs.x) && (y == rhs.y);
    00190     }
    00191
    00192     bool operator!=(BasicImageIteratorBase const & rhs) const
    00193     {
    00194         return (x != rhs.x) || (y != rhs.y);
    00195     }
    00196
    00197     reference operator*() const
    00198     {
    00199         return *(*y + x );
    00200     }
    00201
    00202     pointer operator->() const
    00203     {
    00204         return *y + x;
    00205     }
    00206
    00207     index_reference operator[](difference_type const & d) const
    00208     {
    00209         return *(*(y + d.y) + x + d.x);
    00210     }
    00211
    00212     index_reference operator()(int dx, int dy) const
    00213     {
    00214         return *(*(y + dy) + x + dx);
    00215     }
    00216
    00217     pointer operator[](int dy) const
    00218     {
    00219         return y[dy] + x;
    00220     }
    00221
    00222     row_iterator rowIterator() const
    00223         { return *y + x; }
    00224
    00225     column_iterator columnIterator() const
    00226     {
    00227         typedef typename column_iterator::BaseType Iter;
    00228         return column_iterator(Iter(y, x));
    00229     }
    00230
    00231   protected:
    00232     BasicImageIteratorBase(LINESTARTITERATOR const & line)
    00233     : x(0),
    00234       y(line)
    00235     {}
    00236
    00237     BasicImageIteratorBase(int ix, LINESTARTITERATOR const & line)
    00238     : x(ix),
    00239       y(line)
    00240     {}
    00241
    00242     BasicImageIteratorBase()
    00243     : x(0),
    00244       y(0)
    00245     {}
    00246 };
    00247
    00248 /********************************************************/
    00249 /*                                                      */
    00250 /*                    BasicImageIterator                */
    00251 /*                                                      */
    00252 /********************************************************/
    00253
    00254 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
    00255     See \ref vigra::ImageIterator for documentation.
    00256
    00257     <b>\#include</b> <<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>>
    00258     Namespace: vigra
    00259 */
    00260 template <class PIXELTYPE, class ITERATOR>
    00261 class BasicImageIterator
    00262 : public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>,
    00263                             PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR>
    00264 {
    00265   public:
    00266
    00267     typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE,
    00268                                 PIXELTYPE &, PIXELTYPE *, ITERATOR> Base;
    00269
    00270
    00271     BasicImageIterator(ITERATOR line)
    00272     : Base(line)
    00273     {}
    00274
    00275     BasicImageIterator()
    00276     : Base()
    00277     {}
    00278 };
    00279
    00280 /********************************************************/
    00281 /*                                                      */
    00282 /*                ConstBasicImageIterator               */
    00283 /*                                                      */
    00284 /********************************************************/
    00285
    00286 /** Implementation of the standard const image iterator for \ref vigra::BasicImage.
    00287     See \ref vigra::ConstImageIterator for documentation.
    00288
    00289     <b>\#include</b> <<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>>
    00290     Namespace: vigra
    00291 */
    00292 template <class PIXELTYPE, class ITERATOR>
    00293 class ConstBasicImageIterator
    00294 : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>,
    00295                     PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR>
    00296 {
    00297   public:
    00298
    00299     typedef BasicImageIteratorBase<ConstBasicImageIterator,
    00300               PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> Base;
    00301
    00302
    00303     ConstBasicImageIterator(ITERATOR line)
    00304     : Base(line)
    00305     {}
    00306
    00307     ConstBasicImageIterator(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
    00308     : Base(rhs.x, rhs.y)
    00309     {}
    00310
    00311     ConstBasicImageIterator()
    00312     : Base()
    00313     {}
    00314
    00315     ConstBasicImageIterator &
    00316     operator=(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
    00317     {
    00318         Base::x = rhs.x;
    00319         Base::y = rhs.y;
    00320         return *this;
    00321     }
    00322
    00323 };
    00324
    00325 /********************************************************/
    00326 /*                                                      */
    00327 /*             definition of iterator traits            */
    00328 /*                                                      */
    00329 /********************************************************/
    00330
    00331
    00332 #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00333
    00334 template <class T>
    00335 struct IteratorTraits<BasicImageIterator<T, T**> >
    00336 : public IteratorTraitsBase<BasicImageIterator<T, T**> >
    00337 {
    00338     typedef BasicImageIterator<T, T**>                    mutable_iterator;
    00339     typedef ConstBasicImageIterator<T, T**>               const_iterator;
    00340     typedef typename AccessorTraits<T>::default_accessor  DefaultAccessor;
    00341     typedef DefaultAccessor                               default_accessor;
    00342     typedef VigraTrueType                                 hasConstantStrides;
    00343 };
    00344
    00345 template <class T>
    00346 struct IteratorTraits<ConstBasicImageIterator<T, T**> >
    00347 : public IteratorTraitsBase<ConstBasicImageIterator<T, T**> >
    00348 {
    00349     typedef BasicImageIterator<T, T**>                    mutable_iterator;
    00350     typedef ConstBasicImageIterator<T, T**>               const_iterator;
    00351     typedef typename AccessorTraits<T>::default_const_accessor  DefaultAccessor;
    00352     typedef DefaultAccessor                               default_accessor;
    00353     typedef VigraTrueType                                 hasConstantStrides;
    00354 };
    00355
    00356 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00357
    00358 #define VIGRA_DEFINE_ITERATORTRAITS(VALUETYPE) \
    00359     template <>  \
    00360     struct IteratorTraits<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
    00361     : public IteratorTraitsBase<BasicImageIterator<VALUETYPE, VALUETYPE **> > \
    00362     { \
    00363         typedef BasicImageIterator<VALUETYPE, VALUETYPE**>             mutable_iterator; \
    00364         typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**>        const_iterator; \
    00365         typedef typename AccessorTraits<VALUETYPE >::default_accessor  DefaultAccessor; \
    00366         typedef DefaultAccessor                               default_accessor; \
    00367         typedef VigraTrueType                                 hasConstantStrides; \
    00368     }; \
    00369     \
    00370     template <>  \
    00371     struct IteratorTraits<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
    00372     : public IteratorTraitsBase<ConstBasicImageIterator<VALUETYPE, VALUETYPE **> > \
    00373     { \
    00374         typedef BasicImageIterator<VALUETYPE, VALUETYPE**>             mutable_iterator; \
    00375         typedef ConstBasicImageIterator<VALUETYPE, VALUETYPE**>        const_iterator; \
    00376         typedef typename AccessorTraits<VALUETYPE >::default_const_accessor  DefaultAccessor; \
    00377         typedef DefaultAccessor                               default_accessor; \
    00378         typedef VigraTrueType                                 hasConstantStrides; \
    00379     };
    00380
    00381 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned char>)
    00382 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<short>)
    00383 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned short>)
    00384 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<int>)
    00385 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<unsigned int>)
    00386 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
    00387 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
    00388
    00389 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
    00390 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00391 #undef VIGRA_PIXELTYPE
    00392 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
    00393 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00394 #undef VIGRA_PIXELTYPE
    00395 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
    00396 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00397 #undef VIGRA_PIXELTYPE
    00398 #define VIGRA_PIXELTYPE TinyVector<short, 2>
    00399 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00400 #undef VIGRA_PIXELTYPE
    00401 #define VIGRA_PIXELTYPE TinyVector<short, 3>
    00402 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00403 #undef VIGRA_PIXELTYPE
    00404 #define VIGRA_PIXELTYPE TinyVector<short, 4>
    00405 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00406 #undef VIGRA_PIXELTYPE
    00407 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 2>
    00408 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00409 #undef VIGRA_PIXELTYPE
    00410 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 3>
    00411 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00412 #undef VIGRA_PIXELTYPE
    00413 #define VIGRA_PIXELTYPE TinyVector<unsigned short, 4>
    00414 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00415 #undef VIGRA_PIXELTYPE
    00416 #define VIGRA_PIXELTYPE TinyVector<int, 2>
    00417 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00418 #undef VIGRA_PIXELTYPE
    00419 #define VIGRA_PIXELTYPE TinyVector<int, 3>
    00420 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00421 #undef VIGRA_PIXELTYPE
    00422 #define VIGRA_PIXELTYPE TinyVector<int, 4>
    00423 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00424 #undef VIGRA_PIXELTYPE
    00425 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 2>
    00426 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00427 #undef VIGRA_PIXELTYPE
    00428 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 3>
    00429 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00430 #undef VIGRA_PIXELTYPE
    00431 #define VIGRA_PIXELTYPE TinyVector<unsigned int, 4>
    00432 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00433 #undef VIGRA_PIXELTYPE
    00434 #define VIGRA_PIXELTYPE TinyVector<float, 2>
    00435 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00436 #undef VIGRA_PIXELTYPE
    00437 #define VIGRA_PIXELTYPE TinyVector<float, 3>
    00438 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00439 #undef VIGRA_PIXELTYPE
    00440 #define VIGRA_PIXELTYPE TinyVector<float, 4>
    00441 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00442 #undef VIGRA_PIXELTYPE
    00443 #define VIGRA_PIXELTYPE TinyVector<double, 2>
    00444 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00445 #undef VIGRA_PIXELTYPE
    00446 #define VIGRA_PIXELTYPE TinyVector<double, 3>
    00447 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00448 #undef VIGRA_PIXELTYPE
    00449 #define VIGRA_PIXELTYPE TinyVector<double, 4>
    00450 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
    00451 #undef VIGRA_PIXELTYPE
    00452
    00453 #undef VIGRA_DEFINE_ITERATORTRAITS
    00454
    00455 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    00456
    00457 /********************************************************/
    00458 /*                                                      */
    00459 /*                     BasicImage                       */
    00460 /*                                                      */
    00461 /********************************************************/
    00462
    00463 /** \brief Fundamental class template for images.
    00464
    00465     A customized memory allocator can be specified as a templated argument
    00466     and passed in the constructor.
    00467
    00468     <b>\#include</b> <<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>>
    00469
    00470     Namespace: vigra
    00471 */
    00472 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
    00473 class BasicImage
    00474 {
    00475   public:
    00476
    00477         /** the BasicImage's pixel type
    00478         */
    00479     typedef PIXELTYPE value_type;
    00480
    00481         /** the BasicImage's pixel type
    00482         */
    00483     typedef PIXELTYPE PixelType;
    00484
    00485         /** the BasicImage's reference type (i.e. the
    00486             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
    00487         */
    00488     typedef PIXELTYPE &       reference;
    00489
    00490         /** the BasicImage's const reference type (i.e. the
    00491             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
    00492             when <TT>image</TT> is const)
    00493         */
    00494     typedef PIXELTYPE const & const_reference;
    00495
    00496         /** the BasicImage's pointer type
    00497         */
    00498     typedef PIXELTYPE *       pointer;
    00499
    00500         /** the BasicImage's const pointer type
    00501         */
    00502     typedef PIXELTYPE const * const_pointer;
    00503
    00504         /** the BasicImage's 1D random access iterator
    00505             (note: lower case 'iterator' is a STL compatible 1D random
    00506              access iterator, don't confuse with capitalized Iterator)
    00507         */
    00508     typedef PIXELTYPE * iterator;
    00509
    00510         /** deprecated, use <TT>iterator</TT> instead
    00511         */
    00512     typedef PIXELTYPE * ScanOrderIterator;
    00513
    00514         /** the BasicImage's 1D random access const iterator
    00515             (note: lower case 'const_iterator' is a STL compatible 1D
    00516             random access const iterator)
    00517         */
    00518     typedef PIXELTYPE const * const_iterator;
    00519
    00520         /** deprecated, use <TT>const_iterator</TT> instead
    00521         */
    00522     typedef PIXELTYPE const * ConstScanOrderIterator;
    00523
    00524         /** the BasicImage's 2D random access iterator ('traverser')
    00525         */
    00526     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
    00527
    00528         /** deprecated, use <TT>traverser</TT> instead
    00529         */
    00530     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
    00531
    00532         /** the BasicImage's 2D random access const iterator ('const traverser')
    00533         */
    00534     typedef
    00535         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
    00536         const_traverser;
    00537
    00538         /** deprecated, use <TT>const_traverser</TT> instead
    00539         */
    00540     typedef
    00541         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
    00542         ConstIterator;
    00543
    00544         /** the row iterator associated with the traverser
    00545         */
    00546     typedef typename traverser::row_iterator row_iterator;
    00547
    00548         /** the const row iterator associated with the const_traverser
    00549         */
    00550     typedef typename const_traverser::row_iterator const_row_iterator;
    00551
    00552         /** the column iterator associated with the traverser
    00553         */
    00554     typedef typename traverser::column_iterator column_iterator;
    00555
    00556         /** the const column iterator associated with the const_traverser
    00557         */
    00558     typedef typename const_traverser::column_iterator const_column_iterator;
    00559
    00560         /** the BasicImage's difference type (argument type of image[diff])
    00561         */
    00562     typedef Diff2D difference_type;
    00563
    00564          /** the BasicImage's size type (result type of image.size())
    00565         */
    00566     typedef Size2D size_type;
    00567
    00568        /** the BasicImage's default accessor
    00569         */
    00570     typedef typename
    00571           IteratorTraits<traverser>::DefaultAccessor Accessor;
    00572
    00573         /** the BasicImage's default const accessor
    00574         */
    00575     typedef typename
    00576           IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
    00577
    00578         /** the BasicImage's allocator (default: std::allocator<value_type>)
    00579         */
    00580     typedef Alloc allocator_type;
    00581
    00582     typedef Alloc Allocator;
    00583     typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator;
    00584
    00585         /** construct image of size 0x0
    00586         */
    00587     BasicImage()
    00588     : data_(0),
    00589       width_(0),
    00590       height_(0)
    00591     {}
    00592
    00593         /** construct image of size 0x0, use the specified allocator.
    00594         */
    00595     explicit BasicImage(Alloc const & alloc)
    00596     : data_(0),
    00597       width_(0),
    00598       height_(0),
    00599       allocator_(alloc),
    00600       pallocator_(alloc)
    00601     {}
    00602
    00603         /** construct image of size width x height, use the specified allocator.
    00604         */
    00605     BasicImage(int width, int height, 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): "
    00614              "width and height must be >= 0.\n");
    00615
    00616         resize(width, height, value_type());
    00617     }
    00618
    00619         /** construct image of size size.x x size.y, use the specified allocator.
    00620         */
    00621     explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc())
    00622     : data_(0),
    00623       width_(0),
    00624       height_(0),
    00625       allocator_(alloc),
    00626       pallocator_(alloc)
    00627     {
    00628         vigra_precondition((size.x >= 0) && (size.y >= 0),
    00629              "BasicImage::BasicImage(Diff2D size): "
    00630              "size.x and size.y must be >= 0.\n");
    00631
    00632         resize(size.x, size.y, value_type());
    00633     }
    00634
    00635         /** construct image of size width*height and initialize every
    00636         pixel with the value \a d (use this constructor, if
    00637         value_type doesn't have a default constructor).
    00638         Use the specified allocator.
    00639         */
    00640     BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc())
    00641     : data_(0),
    00642       width_(0),
    00643       height_(0),
    00644       allocator_(alloc),
    00645       pallocator_(alloc)
    00646     {
    00647         vigra_precondition((width >= 0) && (height >= 0),
    00648              "BasicImage::BasicImage(int width, int height, value_type const & ): "
    00649              "width and height must be >= 0.\n");
    00650
    00651         resize(width, height, d);
    00652     }
    00653
    00654         /** construct image of size width*height and try to skip initialization
    00655             of the memory (see BasicImage::resize for details).
    00656             Use the specified allocator.
    00657         */
    00658     BasicImage(int width, int height, SkipInitializationTag, Alloc const & alloc = Alloc())
    00659     : data_(0),
    00660       width_(0),
    00661       height_(0),
    00662       allocator_(alloc),
    00663       pallocator_(alloc)
    00664     {
    00665         vigra_precondition((width >= 0) && (height >= 0),
    00666              "BasicImage::BasicImage(int width, int height, value_type const & ): "
    00667              "width and height must be >= 0.\n");
    00668
    00669         resize(width, height, SkipInitialization);
    00670     }
    00671
    00672         /** construct image of size size.x x size.y and initialize
    00673         every pixel with given data (use this constructor, if
    00674         value_type doesn't have a default constructor). Use the specified allocator.
    00675         */
    00676     explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc())
    00677     : data_(0),
    00678       width_(0),
    00679       height_(0),
    00680       allocator_(alloc),
    00681       pallocator_(alloc)
    00682     {
    00683         vigra_precondition((size.x >= 0) && (size.y >= 0),
    00684              "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
    00685              "size.x and size.y must be >= 0.\n");
    00686
    00687         resize(size.x, size.y, d);
    00688     }
    00689
    00690         /** construct image of size size.x x size.y and try to skip initialization
    00691             of the memory (see BasicImage::resize for details). Use the specified allocator.
    00692         */
    00693     explicit BasicImage(difference_type const & size, SkipInitializationTag, Alloc const & alloc = Alloc())
    00694     : data_(0),
    00695       width_(0),
    00696       height_(0),
    00697       allocator_(alloc),
    00698       pallocator_(alloc)
    00699     {
    00700         vigra_precondition((size.x >= 0) && (size.y >= 0),
    00701              "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
    00702              "size.x and size.y must be >= 0.\n");
    00703
    00704         resize(size.x, size.y, SkipInitialization);
    00705     }
    00706
    00707
    00708         /** construct image of size width*height and copy the data from the
    00709             given C-style array \a d. Use the specified allocator.
    00710         */
    00711     BasicImage(int width, int height, const_pointer d, Alloc const & alloc = Alloc())
    00712     : data_(0),
    00713       width_(0),
    00714       height_(0),
    00715       allocator_(alloc),
    00716       pallocator_(alloc)
    00717     {
    00718         vigra_precondition((width >= 0) && (height >= 0),
    00719              "BasicImage::BasicImage(int width, int height, const_pointer ): "
    00720              "width and height must be >= 0.\n");
    00721
    00722         resizeCopy(width, height, d);
    00723     }
    00724
    00725         /** construct image of size size.x x size.y  and copy the data from the
    00726             given C-style array. Use the specified allocator.
    00727         */
    00728     explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc())
    00729     : data_(0),
    00730       width_(0),
    00731       height_(0),
    00732       allocator_(alloc),
    00733       pallocator_(alloc)
    00734     {
    00735         vigra_precondition((size.x >= 0) && (size.y >= 0),
    00736              "BasicImage::BasicImage(Diff2D const & size, const_pointer): "
    00737              "size.x and size.y must be >= 0.\n");
    00738
    00739         resizeCopy(size.x, size.y, d);
    00740     }
    00741
    00742         /** copy rhs image
    00743         */
    00744     BasicImage(const BasicImage & rhs)
    00745     : data_(0),
    00746       width_(0),
    00747       height_(0),
    00748       allocator_(rhs.allocator_),
    00749       pallocator_(rhs.pallocator_)
    00750     {
    00751         resizeCopy(rhs);
    00752     }
    00753
    00754         /** destructor
    00755         */
    00756     ~BasicImage()
    00757     {
    00758         deallocate();
    00759     }
    00760
    00761         /** copy rhs image (image is resized if necessary)
    00762         */
    00763     BasicImage & operator=(const BasicImage & rhs);
    00764
    00765         /** \deprecated set Image with const value
    00766         */
    00767     BasicImage & operator=(value_type pixel);
    00768
    00769         /** set Image with const value
    00770         */
    00771     BasicImage & init(value_type const & pixel);
    00772
    00773         /** reset image to specified size (dimensions must not be negative)
    00774             (old data are kept if new size matches old size)
    00775         */
    00776     void resize(int width, int height)
    00777     {
    00778         if(width != width_ || height != height_)
    00779             resize(width, height, value_type());
    00780     }
    00781
    00782         /** reset image to specified size (dimensions must not be negative)
    00783             (old data are kept if new size matches old size)
    00784         */
    00785     void resize(difference_type const & size)
    00786     {
    00787         if(size.x != width_ || size.y != height_)
    00788         {
    00789             resize(size.x, size.y, value_type());
    00790         }
    00791     }
    00792
    00793         /** reset image to specified size and initialize it with
    00794             given data (use this if value_type doesn't have a default
    00795             constructor, dimensions must not be negative,
    00796             old data are kept if new size matches old size)
    00797         */
    00798     void resize(int width, int height, value_type const & d)
    00799     {
    00800         resizeImpl(width, height, d, false);
    00801     }
    00802
    00803         /** reset image to specified size and skip initialization
    00804             if possible (use this if <tt>value_type</tt> is a built-in type
    00805             or <tt>TinyVector&lt;builtin&gt&</tt> and the data is
    00806             immediately overridden afterwards). If <tt>value_type</tt> requires
    00807             initialization, <tt>SkipInitialization</tt> is ignored.
    00808
    00809             Usage:
    00810             \code
    00811             image.resize(new_width, new_height, SkipInitialization);
    00812             \endcode
    00813         */
    00814     void resize(int width, int height, SkipInitializationTag)
    00815     {
    00816         resizeImpl(width, height, NumericTraits<value_type>::zero(),
    00817                    CanSkipInitialization<value_type>::value);
    00818     }
    00819
    00820         /** resize image to given size and initialize by copying data
    00821             from the C-style arra \a data.
    00822         */
    00823     void resizeCopy(int width, int height, const_pointer data);
    00824
    00825         /** resize image to size of other image and copy it's data
    00826         */
    00827     void resizeCopy(const BasicImage & rhs)
    00828     {
    00829         resizeCopy(rhs.width(), rhs.height(), rhs.data_);
    00830     }
    00831
    00832         /** swap the internal data with the rhs image in constant time
    00833         */
    00834     void swap( BasicImage & rhs );
    00835
    00836         /** width of Image
    00837         */
    00838     int width() const
    00839     {
    00840         return width_;
    00841     }
    00842
    00843         /** height of Image
    00844         */
    00845     int height() const
    00846     {
    00847         return height_;
    00848     }
    00849
    00850         /** size of Image
    00851         */
    00852     size_type size() const
    00853     {
    00854         return size_type(width(), height());
    00855     }
    00856
    00857         /** test whether a given coordinate is inside the image
    00858         */
    00859     bool isInside(difference_type const & d) const
    00860     {
    00861         return d.x >= 0 && d.y >= 0 &&
    00862                d.x < width() && d.y < height();
    00863     }
    00864
    00865         /** access pixel at given location. <br>
    00866         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
    00867         */
    00868     reference operator[](difference_type const & d)
    00869     {
    00870         VIGRA_ASSERT_INSIDE(d);
    00871         return lines_[d.y][d.x];
    00872     }
    00873
    00874         /** read pixel at given location. <br>
    00875         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
    00876         */
    00877     const_reference operator[](difference_type const & d) const
    00878     {
    00879          VIGRA_ASSERT_INSIDE(d);
    00880         return lines_[d.y][d.x];
    00881     }
    00882
    00883         /** access pixel at given location. <br>
    00884         usage: <TT> value_type value = image(1,2) </TT>
    00885         */
    00886     reference operator()(int dx, int dy)
    00887     {
    00888         VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
    00889         return lines_[dy][dx];
    00890     }
    00891
    00892         /** read pixel at given location. <br>
    00893         usage: <TT> value_type value = image(1,2) </TT>
    00894         */
    00895     const_reference operator()(int dx, int dy) const
    00896     {
    00897         VIGRA_ASSERT_INSIDE(difference_type(dx,dy));
    00898         return lines_[dy][dx];
    00899     }
    00900
    00901         /** access pixel at given location.
    00902             Note that the 'x' index is the trailing index. <br>
    00903         usage: <TT> value_type value = image[2][1] </TT>
    00904         */
    00905     pointer operator[](int dy)
    00906     {
    00907         VIGRA_ASSERT_INSIDE(difference_type(0,dy));
    00908         return lines_[dy];
    00909     }
    00910
    00911         /** read pixel at given location.
    00912             Note that the 'x' index is the trailing index. <br>
    00913         usage: <TT> value_type value = image[2][1] </TT>
    00914         */
    00915     const_pointer operator[](int dy) const
    00916     {
    00917         VIGRA_ASSERT_INSIDE(difference_type(0,dy));
    00918         return lines_[dy];
    00919     }
    00920
    00921         /** init 2D random access iterator poining to upper left pixel
    00922         */
    00923     traverser upperLeft()
    00924     {
    00925         vigra_precondition(data_ != 0,
    00926           "BasicImage::upperLeft(): image must have non-zero size.");
    00927         return traverser(lines_);
    00928     }
    00929
    00930         /** init 2D random access iterator poining to
    00931          pixel(width, height), i.e. one pixel right and below lower right
    00932          corner of the image as is common in C/C++.
    00933         */
    00934     traverser lowerRight()
    00935     {
    00936         vigra_precondition(data_ != 0,
    00937           "BasicImage::lowerRight(): image must have non-zero size.");
    00938         return upperLeft() + size();
    00939     }
    00940
    00941         /** init 2D random access const iterator poining to upper left pixel
    00942         */
    00943     const_traverser upperLeft() const
    00944     {
    00945         vigra_precondition(data_ != 0,
    00946           "BasicImage::upperLeft(): image must have non-zero size.");
    00947         return const_traverser(const_cast<PIXELTYPE **>(lines_));
    00948     }
    00949
    00950         /** init 2D random access const iterator poining to
    00951          pixel(width, height), i.e. one pixel right and below lower right
    00952          corner of the image as is common in C/C++.
    00953         */
    00954     const_traverser lowerRight() const
    00955     {
    00956         vigra_precondition(data_ != 0,
    00957           "BasicImage::lowerRight(): image must have non-zero size.");
    00958         return upperLeft() + size();
    00959     }
    00960
    00961         /** init 1D random access iterator pointing to first pixel
    00962         */
    00963     iterator begin()
    00964     {
    00965         vigra_precondition(data_ != 0,
    00966           "BasicImage::begin(): image must have non-zero size.");
    00967         return data_;
    00968     }
    00969
    00970         /** init 1D random access iterator pointing past the end
    00971         */
    00972     iterator end()
    00973     {
    00974         vigra_precondition(data_ != 0,
    00975           "BasicImage::end(): image must have non-zero size.");
    00976         return data_ + width() * height();
    00977     }
    00978
    00979         /** init 1D random access const iterator pointing to first pixel
    00980         */
    00981     const_iterator begin() const
    00982     {
    00983         vigra_precondition(data_ != 0,
    00984           "BasicImage::begin(): image must have non-zero size.");
    00985         return data_;
    00986     }
    00987
    00988         /** init 1D random access const iterator pointing past the end
    00989         */
    00990     const_iterator end() const
    00991     {
    00992         vigra_precondition(data_ != 0,
    00993           "BasicImage::end(): image must have non-zero size.");
    00994         return data_ + width() * height();
    00995     }
    00996
    00997         /** init 1D random access iterator pointing to first pixel of row \a y
    00998         */
    00999     row_iterator rowBegin(int y)
    01000     {
    01001         return lines_[y];
    01002     }
    01003
    01004         /** init 1D random access iterator pointing past the end of row \a y
    01005         */
    01006     row_iterator rowEnd(int y)
    01007     {
    01008         return rowBegin(y) + width();
    01009     }
    01010
    01011         /** init 1D random access const iterator pointing to first pixel of row \a y
    01012         */
    01013     const_row_iterator rowBegin(int y) const
    01014     {
    01015         return lines_[y];
    01016     }
    01017
    01018         /** init 1D random access const iterator pointing past the end of row \a y
    01019         */
    01020     const_row_iterator rowEnd(int y) const
    01021     {
    01022         return rowBegin(y) + width();
    01023     }
    01024
    01025         /** init 1D random access iterator pointing to first pixel of column \a x
    01026         */
    01027     column_iterator columnBegin(int x)
    01028     {
    01029         typedef typename column_iterator::BaseType Iter;
    01030         return column_iterator(Iter(lines_, x));
    01031     }
    01032
    01033         /** init 1D random access iterator pointing past the end of column \a x
    01034         */
    01035     column_iterator columnEnd(int x)
    01036     {
    01037         return columnBegin(x) + height();
    01038     }
    01039
    01040         /** init 1D random access const iterator pointing to first pixel of column \a x
    01041         */
    01042     const_column_iterator columnBegin(int x) const
    01043     {
    01044         typedef typename const_column_iterator::BaseType Iter;
    01045         return const_column_iterator(Iter(lines_, x));
    01046     }
    01047
    01048         /** init 1D random access const iterator pointing past the end of column \a x
    01049         */
    01050     const_column_iterator columnEnd(int x) const
    01051     {
    01052         return columnBegin(x) + height();
    01053     }
    01054
    01055         /** get a pointer to the internal data
    01056         */
    01057     const_pointer data() const
    01058     {
    01059         return data_;
    01060     }
    01061
    01062         /** return default accessor
    01063         */
    01064     Accessor accessor()
    01065     {
    01066         return Accessor();
    01067     }
    01068
    01069         /** return default const accessor
    01070         */
    01071     ConstAccessor accessor() const
    01072     {
    01073         return ConstAccessor();
    01074     }
    01075
    01076   private:
    01077
    01078     void deallocate();
    01079     void resizeImpl(int width, int height, value_type const & d, bool skipInit);
    01080
    01081
    01082     value_type ** initLineStartArray(value_type * data, int width, int height);
    01083
    01084     PIXELTYPE * data_;
    01085     PIXELTYPE ** lines_;
    01086     int width_, height_;
    01087     Alloc allocator_;
    01088     LineAllocator pallocator_;
    01089 };
    01090
    01091 template <class PIXELTYPE, class Alloc>
    01092 BasicImage<PIXELTYPE, Alloc> &
    01093 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage<PIXELTYPE, Alloc> & rhs)
    01094 {
    01095     if(this != &rhs)
    01096     {
    01097         if((width() != rhs.width()) ||
    01098            (height() != rhs.height()))
    01099         {
    01100             resizeCopy(rhs);
    01101         }
    01102         else
    01103         {
    01104             ConstScanOrderIterator is = rhs.begin();
    01105             ConstScanOrderIterator iend = rhs.end();
    01106             ScanOrderIterator id = begin();
    01107
    01108             for(; is != iend; ++is, ++id) *id = *is;
    01109         }
    01110     }
    01111     return *this;
    01112 }
    01113
    01114 template <class PIXELTYPE, class Alloc>
    01115 BasicImage<PIXELTYPE, Alloc> &
    01116 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel)
    01117 {
    01118     ScanOrderIterator i = begin();
    01119     ScanOrderIterator iend = end();
    01120
    01121     for(; i != iend; ++i) *i = pixel;
    01122
    01123     return *this;
    01124 }
    01125
    01126 template <class PIXELTYPE, class Alloc>
    01127 BasicImage<PIXELTYPE, Alloc> &
    01128 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel)
    01129 {
    01130     ScanOrderIterator i = begin();
    01131     ScanOrderIterator iend = end();
    01132
    01133     for(; i != iend; ++i) *i = pixel;
    01134
    01135     return *this;
    01136 }
    01137
    01138 template <class PIXELTYPE, class Alloc>
    01139 void
    01140 BasicImage<PIXELTYPE, Alloc>::resizeImpl(int width, int height, value_type const & d, bool skipInit)
    01141 {
    01142     vigra_precondition((width >= 0) && (height >= 0),
    01143          "BasicImage::resize(int width, int height, value_type const &): "
    01144          "width and height must be >= 0.\n");
    01145     vigra_precondition(width * height >= 0,
    01146          "BasicImage::resize(int width, int height, value_type const &): "
    01147          "width * height too large (integer overflow -> negative).\n");
    01148
    01149     if (width_ != width || height_ != height)  // change size?
    01150     {
    01151         value_type * newdata = 0;
    01152         value_type ** newlines = 0;
    01153         if(width*height > 0)
    01154         {
    01155             if (width*height != width_*height_) // different sizes, must reallocate
    01156             {
    01157                 newdata = allocator_.allocate(typename Alloc::size_type(width*height));
    01158                 if(!skipInit)
    01159                     std::uninitialized_fill_n(newdata, width*height, d);
    01160                 newlines = initLineStartArray(newdata, width, height);
    01161                 deallocate();
    01162             }
    01163             else // need only to reshape
    01164             {
    01165                 newdata = data_;
    01166                 if(!skipInit)
    01167                     std::fill_n(newdata, width*height, d);
    01168                 newlines = initLineStartArray(newdata, width, height);
    01169                 pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
    01170             }
    01171         }
    01172         else
    01173         {
    01174             deallocate();
    01175         }
    01176
    01177         data_ = newdata;
    01178         lines_ = newlines;
    01179         width_ = width;
    01180         height_ = height;
    01181     }
    01182     else if(width*height > 0 && !skipInit) // keep size, re-init data
    01183     {
    01184         std::fill_n(data_, width*height, d);
    01185     }
    01186 }
    01187
    01188
    01189 template <class PIXELTYPE, class Alloc>
    01190 void
    01191 BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data)
    01192 {
    01193     int newsize = width*height;
    01194     if (width_ != width || height_ != height)  // change size?
    01195     {
    01196         value_type * newdata = 0;
    01197         value_type ** newlines = 0;
    01198         if(newsize > 0)
    01199         {
    01200             if (newsize != width_*height_) // different sizes, must reallocate
    01201             {
    01202                 newdata = allocator_.allocate(typename Alloc::size_type(newsize));
    01203                 std::uninitialized_copy(data, data + newsize, newdata);
    01204                 newlines = initLineStartArray(newdata, width, height);
    01205                 deallocate();
    01206             }
    01207             else // need only to reshape
    01208             {
    01209                 newdata = data_;
    01210                 std::copy(data, data + newsize, newdata);
    01211                 newlines = initLineStartArray(newdata, width, height);
    01212                 pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
    01213             }
    01214         }
    01215         else
    01216         {
    01217             deallocate();
    01218         }
    01219
    01220         data_ = newdata;
    01221         lines_ = newlines;
    01222         width_ = width;
    01223         height_ = height;
    01224     }
    01225     else if(newsize > 0) // keep size, copy data
    01226     {
    01227         std::copy(data, data + newsize, data_);
    01228     }
    01229 }
    01230
    01231 template <class PIXELTYPE, class Alloc>
    01232 void
    01233 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage<PIXELTYPE, Alloc>& rhs )
    01234 {
    01235   if (&rhs!=this)
    01236   {
    01237     std::swap( data_, rhs.data_ );
    01238     std::swap( lines_, rhs.lines_ );
    01239     std::swap( width_, rhs.width_ );
    01240     std::swap( height_, rhs.height_ );
    01241   }
    01242 }
    01243
    01244 template <class PIXELTYPE, class Alloc>
    01245 void
    01246 BasicImage<PIXELTYPE, Alloc>::deallocate()
    01247 {
    01248     if(data_)
    01249     {
    01250         ScanOrderIterator i = begin();
    01251         ScanOrderIterator iend = end();
    01252
    01253         for(; i != iend; ++i)   (*i).~PIXELTYPE();
    01254
    01255         allocator_.deallocate(data_, typename Alloc::size_type(width()*height()));
    01256         pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
    01257     }
    01258 }
    01259
    01260 template <class PIXELTYPE, class Alloc>
    01261 PIXELTYPE **
    01262 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height)
    01263 {
    01264     value_type ** lines = pallocator_.allocate(typename Alloc::size_type(height));
    01265     for(int y=0; y<height; ++y)
    01266          lines[y] = data + y*width;
    01267     return lines;
    01268 }
    01269
    01270 /********************************************************/
    01271 /*                                                      */
    01272 /*              argument object factories               */
    01273 /*                                                      */
    01274 /********************************************************/
    01275
    01276 template <class PixelType, class Accessor, class Alloc>
    01277 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01278               typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
    01279 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a)
    01280 {
    01281     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01282                   typename BasicImage<PixelType, Alloc>::const_traverser,
    01283           Accessor>(img.upperLeft(),
    01284                     img.lowerRight(),
    01285                     a);
    01286 }
    01287
    01288 template <class PixelType, class Accessor, class Alloc>
    01289 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01290               typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
    01291 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi, Accessor a)
    01292 {
    01293     vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
    01294                        roi.right() <= img.width() && roi.bottom() <= img.height(),
    01295                        "srcImageRange(): ROI rectangle outside image.");
    01296     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01297                   typename BasicImage<PixelType, Alloc>::const_traverser,
    01298           Accessor>(img.upperLeft() + roi.upperLeft(),
    01299                     img.upperLeft() + roi.lowerRight(),
    01300                     a);
    01301 }
    01302
    01303 template <class PixelType, class Accessor, class Alloc>
    01304 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
    01305 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
    01306 {
    01307     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01308                 Accessor>(img.upperLeft(), a);
    01309 }
    01310
    01311 template <class PixelType, class Accessor, class Alloc>
    01312 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
    01313 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
    01314 {
    01315     vigra_precondition(img.isInside(ul),
    01316                        "srcImage(): ROI rectangle outside image.");
    01317     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01318                 Accessor>(img.upperLeft() + ul, a);
    01319 }
    01320
    01321 template <class PixelType, class Accessor, class Alloc>
    01322 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
    01323               typename BasicImage<PixelType, Alloc>::traverser, Accessor>
    01324 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a)
    01325 {
    01326     return triple<typename BasicImage<PixelType, Alloc>::traverser,
    01327                   typename BasicImage<PixelType, Alloc>::traverser,
    01328           Accessor>(img.upperLeft(),
    01329                     img.lowerRight(),
    01330                     a);
    01331 }
    01332
    01333 template <class PixelType, class Accessor, class Alloc>
    01334 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
    01335               typename BasicImage<PixelType, Alloc>::traverser, Accessor>
    01336 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi, Accessor a)
    01337 {
    01338     vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
    01339                        roi.right() <= img.width() && roi.bottom() <= img.height(),
    01340                        "destImageRange(): ROI rectangle outside image.");
    01341     return triple<typename BasicImage<PixelType, Alloc>::traverser,
    01342                   typename BasicImage<PixelType, Alloc>::traverser,
    01343           Accessor>(img.upperLeft() + roi.upperLeft(),
    01344                     img.upperLeft() + roi.lowerRight(),
    01345                     a);
    01346 }
    01347
    01348 template <class PixelType, class Accessor, class Alloc>
    01349 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
    01350 destImage(BasicImage<PixelType, Alloc> & img, Accessor a)
    01351 {
    01352     return pair<typename BasicImage<PixelType, Alloc>::traverser,
    01353                 Accessor>(img.upperLeft(), a);
    01354 }
    01355
    01356 template <class PixelType, class Accessor, class Alloc>
    01357 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
    01358 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul, Accessor a)
    01359 {
    01360     vigra_precondition(img.isInside(ul),
    01361                        "destImage(): ROI rectangle outside image.");
    01362     return pair<typename BasicImage<PixelType, Alloc>::traverser,
    01363                 Accessor>(img.upperLeft() + ul, a);
    01364 }
    01365
    01366 template <class PixelType, class Accessor, class Alloc>
    01367 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
    01368 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
    01369 {
    01370     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01371                 Accessor>(img.upperLeft(), a);
    01372 }
    01373
    01374 template <class PixelType, class Accessor, class Alloc>
    01375 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
    01376 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul, Accessor a)
    01377 {
    01378     vigra_precondition(img.isInside(ul),
    01379                        "maskImage(): ROI rectangle outside image.");
    01380     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01381                 Accessor>(img.upperLeft() + ul, a);
    01382 }
    01383
    01384 /****************************************************************/
    01385
    01386 template <class PixelType, class Alloc>
    01387 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01388               typename BasicImage<PixelType, Alloc>::const_traverser,
    01389               typename BasicImage<PixelType, Alloc>::ConstAccessor>
    01390 srcImageRange(BasicImage<PixelType, Alloc> const & img)
    01391 {
    01392     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01393                   typename BasicImage<PixelType, Alloc>::const_traverser,
    01394                   typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
    01395                                                                         img.lowerRight(),
    01396                                                                         img.accessor());
    01397 }
    01398
    01399 template <class PixelType, class Alloc>
    01400 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01401               typename BasicImage<PixelType, Alloc>::const_traverser,
    01402               typename BasicImage<PixelType, Alloc>::ConstAccessor>
    01403 srcImageRange(BasicImage<PixelType, Alloc> const & img, Rect2D const & roi)
    01404 {
    01405     vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
    01406                        roi.right() <= img.width() && roi.bottom() <= img.height(),
    01407                        "srcImageRange(): ROI rectangle outside image.");
    01408     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
    01409                   typename BasicImage<PixelType, Alloc>::const_traverser,
    01410                   typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + roi.upperLeft(),
    01411                                                                         img.upperLeft() + roi.lowerRight(),
    01412                                                                         img.accessor());
    01413 }
    01414
    01415 template <class PixelType, class Alloc>
    01416 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
    01417              typename BasicImage<PixelType, Alloc>::ConstAccessor>
    01418 srcImage(BasicImage<PixelType, Alloc> const & img)
    01419 {
    01420     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01421                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
    01422                                                                       img.accessor());
    01423 }
    01424
    01425 template <class PixelType, class Alloc>
    01426 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
    01427              typename BasicImage<PixelType, Alloc>::ConstAccessor>
    01428 srcImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
    01429 {
    01430     vigra_precondition(img.isInside(ul),
    01431                        "srcImage(): ROI rectangle outside image.");
    01432     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01433                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
    01434                                                                       img.accessor());
    01435 }
    01436
    01437 template <class PixelType, class Alloc>
    01438 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
    01439                typename BasicImage<PixelType, Alloc>::traverser,
    01440                typename BasicImage<PixelType, Alloc>::Accessor>
    01441 destImageRange(BasicImage<PixelType, Alloc> & img)
    01442 {
    01443     return triple<typename BasicImage<PixelType, Alloc>::traverser,
    01444                   typename BasicImage<PixelType, Alloc>::traverser,
    01445                   typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
    01446                                                                    img.lowerRight(),
    01447                                                                    img.accessor());
    01448 }
    01449
    01450 template <class PixelType, class Alloc>
    01451 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
    01452                typename BasicImage<PixelType, Alloc>::traverser,
    01453                typename BasicImage<PixelType, Alloc>::Accessor>
    01454 destImageRange(BasicImage<PixelType, Alloc> & img, Rect2D const & roi)
    01455 {
    01456     vigra_precondition(roi.left() >= 0 && roi.top() >= 0 &&
    01457                        roi.right() <= img.width() && roi.bottom() <= img.height(),
    01458                        "destImageRange(): ROI rectangle outside image.");
    01459     return triple<typename BasicImage<PixelType, Alloc>::traverser,
    01460                   typename BasicImage<PixelType, Alloc>::traverser,
    01461                   typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + roi.upperLeft(),
    01462                                                                    img.upperLeft() + roi.lowerRight(),
    01463                                                                    img.accessor());
    01464 }
    01465
    01466 template <class PixelType, class Alloc>
    01467 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
    01468              typename BasicImage<PixelType, Alloc>::Accessor>
    01469 destImage(BasicImage<PixelType, Alloc> & img)
    01470 {
    01471     return pair<typename BasicImage<PixelType, Alloc>::traverser,
    01472                 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
    01473                                                           img.accessor());
    01474 }
    01475
    01476 template <class PixelType, class Alloc>
    01477 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
    01478              typename BasicImage<PixelType, Alloc>::Accessor>
    01479 destImage(BasicImage<PixelType, Alloc> & img, Point2D const & ul)
    01480 {
    01481     vigra_precondition(img.isInside(ul),
    01482                        "destImage(): ROI rectangle outside image.");
    01483     return pair<typename BasicImage<PixelType, Alloc>::traverser,
    01484                 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft() + ul,
    01485                                                                  img.accessor());
    01486 }
    01487
    01488 template <class PixelType, class Alloc>
    01489 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
    01490              typename BasicImage<PixelType, Alloc>::ConstAccessor>
    01491 maskImage(BasicImage<PixelType, Alloc> const & img)
    01492 {
    01493     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01494                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
    01495                                                                       img.accessor());
    01496 }
    01497
    01498 template <class PixelType, class Alloc>
    01499 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
    01500              typename BasicImage<PixelType, Alloc>::ConstAccessor>
    01501 maskImage(BasicImage<PixelType, Alloc> const & img, Point2D const & ul)
    01502 {
    01503     vigra_precondition(img.isInside(ul),
    01504                        "maskImage(): ROI rectangle outside image.");
    01505     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
    01506                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft() + ul,
    01507                                                                       img.accessor());
    01508 }
    01509
    01510 } // namespace vigra
    01511 #undef VIGRA_ASSERT_INSIDE
    01512 #endif // VIGRA_BASICIMAGE_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.7.1 (3 Dec 2010)