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

details vigra/basicimage.hxx VIGRA

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

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

html generated using doxygen and Python
VIGRA 1.5.0 (7 Dec 2006)