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

vigra/basicimage.hxx

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