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

vigra/basicimage.hxx VIGRA

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> <vigra/basicimage.hxx>
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> <vigra/basicimage.hxx>
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> <vigra/basicimage.hxx>
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> <vigra/basicimage.hxx>
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 array \a data.
00822         */
00823     void resizeCopy(int width, int height, const_pointer data);
00824 
00825         /** resize image to size of other image and copy its 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 pointing 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 pointing 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 pointing 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 pointing 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 & 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 & 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.9.0 (Tue Nov 6 2012)