[ 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.4.0, Dec 21 2005 )                                    */
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 "vigra/utilities.hxx"
00044 #include "vigra/iteratortraits.hxx"
00045 #include "vigra/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<int>)
00376 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<float>)
00377 VIGRA_DEFINE_ITERATORTRAITS(RGBValue<double>)
00378 
00379 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 2>
00380 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00381 #undef VIGRA_PIXELTYPE
00382 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 3>
00383 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00384 #undef VIGRA_PIXELTYPE
00385 #define VIGRA_PIXELTYPE TinyVector<unsigned char, 4>
00386 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00387 #undef VIGRA_PIXELTYPE
00388 #define VIGRA_PIXELTYPE TinyVector<short, 2>
00389 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00390 #undef VIGRA_PIXELTYPE
00391 #define VIGRA_PIXELTYPE TinyVector<short, 3>
00392 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00393 #undef VIGRA_PIXELTYPE
00394 #define VIGRA_PIXELTYPE TinyVector<short, 4>
00395 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00396 #undef VIGRA_PIXELTYPE
00397 #define VIGRA_PIXELTYPE TinyVector<int, 2>
00398 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00399 #undef VIGRA_PIXELTYPE
00400 #define VIGRA_PIXELTYPE TinyVector<int, 3>
00401 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00402 #undef VIGRA_PIXELTYPE
00403 #define VIGRA_PIXELTYPE TinyVector<int, 4>
00404 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00405 #undef VIGRA_PIXELTYPE
00406 #define VIGRA_PIXELTYPE TinyVector<float, 2>
00407 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00408 #undef VIGRA_PIXELTYPE
00409 #define VIGRA_PIXELTYPE TinyVector<float, 3>
00410 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00411 #undef VIGRA_PIXELTYPE
00412 #define VIGRA_PIXELTYPE TinyVector<float, 4>
00413 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00414 #undef VIGRA_PIXELTYPE
00415 #define VIGRA_PIXELTYPE TinyVector<double, 2>
00416 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00417 #undef VIGRA_PIXELTYPE
00418 #define VIGRA_PIXELTYPE TinyVector<double, 3>
00419 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00420 #undef VIGRA_PIXELTYPE
00421 #define VIGRA_PIXELTYPE TinyVector<double, 4>
00422 VIGRA_DEFINE_ITERATORTRAITS(VIGRA_PIXELTYPE)
00423 #undef VIGRA_PIXELTYPE
00424 
00425 #undef VIGRA_DEFINE_ITERATORTRAITS
00426 
00427 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
00428 
00429 /********************************************************/
00430 /*                                                      */
00431 /*                     BasicImage                       */
00432 /*                                                      */
00433 /********************************************************/
00434 
00435 /** \brief Fundamental class template for images.
00436 
00437     A customized memory allocator can be specified as a templated argument
00438     ans passed in the constructor.
00439 
00440     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00441 
00442     Namespace: vigra
00443 */
00444 template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
00445 class BasicImage
00446 {
00447   public:
00448 
00449         /** the BasicImage's pixel type
00450         */
00451     typedef PIXELTYPE value_type;
00452 
00453         /** the BasicImage's pixel type
00454         */
00455     typedef PIXELTYPE PixelType;
00456 
00457         /** the BasicImage's reference type (i.e. the
00458             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
00459         */
00460     typedef PIXELTYPE &       reference;
00461 
00462         /** the BasicImage's const reference type (i.e. the
00463             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
00464             when <TT>image</TT> is const)
00465         */
00466     typedef PIXELTYPE const & const_reference;
00467 
00468         /** the BasicImage's pointer type
00469         */
00470     typedef PIXELTYPE *       pointer;
00471 
00472         /** the BasicImage's const pointer type
00473         */
00474     typedef PIXELTYPE const * const_pointer;
00475 
00476         /** the BasicImage's 1D random access iterator
00477             (note: lower case 'iterator' is a STL compatible 1D random
00478              access iterator, don't confuse with capitalized Iterator)
00479         */
00480     typedef PIXELTYPE * iterator;
00481 
00482         /** deprecated, use <TT>iterator</TT> instead
00483         */
00484     typedef PIXELTYPE * ScanOrderIterator;
00485 
00486         /** the BasicImage's 1D random access const iterator
00487             (note: lower case 'const_iterator' is a STL compatible 1D
00488             random access const iterator)
00489         */
00490     typedef PIXELTYPE const * const_iterator;
00491 
00492         /** deprecated, use <TT>const_iterator</TT> instead
00493         */
00494     typedef PIXELTYPE const * ConstScanOrderIterator;
00495 
00496         /** the BasicImage's 2D random access iterator ('traverser')
00497         */
00498     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
00499 
00500         /** deprecated, use <TT>traverser</TT> instead
00501         */
00502     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
00503 
00504         /** the BasicImage's 2D random access const iterator ('const traverser')
00505         */
00506     typedef
00507         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00508         const_traverser;
00509 
00510         /** deprecated, use <TT>const_traverser</TT> instead
00511         */
00512     typedef
00513         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00514         ConstIterator;
00515 
00516         /** the row iterator associated with the traverser
00517         */
00518     typedef typename traverser::row_iterator row_iterator;
00519 
00520         /** the const row iterator associated with the const_traverser
00521         */
00522     typedef typename const_traverser::row_iterator const_row_iterator;
00523 
00524         /** the column iterator associated with the traverser
00525         */
00526     typedef typename traverser::column_iterator column_iterator;
00527 
00528         /** the const column iterator associated with the const_traverser
00529         */
00530     typedef typename const_traverser::column_iterator const_column_iterator;
00531 
00532         /** the BasicImage's difference type (argument type of image[diff])
00533         */
00534     typedef Diff2D difference_type;
00535 
00536          /** the BasicImage's size type (result type of image.size())
00537         */
00538     typedef Size2D size_type;
00539 
00540        /** the BasicImage's default accessor
00541         */
00542     typedef typename
00543           IteratorTraits<traverser>::DefaultAccessor Accessor;
00544 
00545         /** the BasicImage's default const accessor
00546         */
00547     typedef typename
00548           IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
00549 
00550         /** the BasicImage's allocator (default: std::allocator<value_type>)
00551         */
00552     typedef Alloc allocator_type;
00553 
00554     typedef Alloc Allocator;
00555     typedef typename Alloc::template rebind<PIXELTYPE *>::other LineAllocator;
00556 
00557         /** construct image of size 0x0
00558         */
00559     BasicImage()
00560     : data_(0),
00561       width_(0),
00562       height_(0)
00563     {}
00564 
00565         /** construct image of size 0x0, use the specified allocator.
00566         */
00567     explicit BasicImage(Alloc const & alloc)
00568     : data_(0),
00569       width_(0),
00570       height_(0),
00571       allocator_(alloc),
00572       pallocator_(alloc)
00573     {}
00574 
00575         /** construct image of size width x height, use the specified allocator.
00576         */
00577     BasicImage(int width, int height, Alloc const & alloc = Alloc())
00578     : data_(0),
00579       width_(0),
00580       height_(0),
00581       allocator_(alloc),
00582       pallocator_(alloc)
00583     {
00584         vigra_precondition((width >= 0) && (height >= 0),
00585              "BasicImage::BasicImage(int width, int height): "
00586              "width and height must be >= 0.\n");
00587 
00588         resize(width, height, value_type());
00589     }
00590 
00591         /** construct image of size size.x x size.y, use the specified allocator.
00592         */
00593     explicit BasicImage(difference_type const & size, Alloc const & alloc = Alloc())
00594     : data_(0),
00595       width_(0),
00596       height_(0),
00597       allocator_(alloc),
00598       pallocator_(alloc)
00599     {
00600         vigra_precondition((size.x >= 0) && (size.y >= 0),
00601              "BasicImage::BasicImage(Diff2D size): "
00602              "size.x and size.y must be >= 0.\n");
00603 
00604         resize(size.x, size.y, value_type());
00605     }
00606 
00607         /** construct image of size width*height and initialize every
00608         pixel with the value \a d (use this constructor, if
00609         value_type doesn't have a default constructor). 
00610         Use the specified allocator.
00611         */
00612     BasicImage(int width, int height, value_type const & d, Alloc const & alloc = Alloc())
00613     : data_(0),
00614       width_(0),
00615       height_(0),
00616       allocator_(alloc),
00617       pallocator_(alloc)
00618     {
00619         vigra_precondition((width >= 0) && (height >= 0),
00620              "BasicImage::BasicImage(int width, int height, value_type const & ): "
00621              "width and height must be >= 0.\n");
00622 
00623         resize(width, height, d);
00624     }
00625 
00626         /** construct image of size size.x x size.y and initialize
00627         every pixel with given data (use this constructor, if
00628         value_type doesn't have a default constructor). Use the specified allocator.
00629         */
00630     explicit BasicImage(difference_type const & size, value_type const & d, Alloc const & alloc = Alloc())
00631     : data_(0),
00632       width_(0),
00633       height_(0),
00634       allocator_(alloc),
00635       pallocator_(alloc)
00636     {
00637         vigra_precondition((size.x >= 0) && (size.y >= 0),
00638              "BasicImage::BasicImage(Diff2D const & size, value_type const & v): "
00639              "size.x and size.y must be >= 0.\n");
00640 
00641         resize(size.x, size.y, d);
00642     }
00643 
00644 
00645         /** construct image of size width*height and copy the data from the
00646             given C-style array \a d. Use the specified allocator.
00647         */
00648     BasicImage(int width, int height, const_pointer d, Alloc const & alloc = Alloc())
00649     : data_(0),
00650       width_(0),
00651       height_(0),
00652       allocator_(alloc),
00653       pallocator_(alloc)
00654     {
00655         vigra_precondition((width >= 0) && (height >= 0),
00656              "BasicImage::BasicImage(int width, int height, const_pointer ): "
00657              "width and height must be >= 0.\n");
00658 
00659         resizeCopy(width, height, d);
00660     }
00661 
00662         /** construct image of size size.x x size.y  and copy the data from the
00663             given C-style array. Use the specified allocator.
00664         */
00665     explicit BasicImage(difference_type const & size, const_pointer d, Alloc const & alloc = Alloc())
00666     : data_(0),
00667       width_(0),
00668       height_(0),
00669       allocator_(alloc),
00670       pallocator_(alloc)
00671     {
00672         vigra_precondition((size.x >= 0) && (size.y >= 0),
00673              "BasicImage::BasicImage(Diff2D const & size, const_pointer): "
00674              "size.x and size.y must be >= 0.\n");
00675 
00676         resizeCopy(size.x, size.y, d);
00677     }
00678 
00679         /** copy rhs image
00680         */
00681     BasicImage(const BasicImage & rhs)
00682     : data_(0),
00683       width_(0),
00684       height_(0),
00685       allocator_(rhs.allocator_),
00686       pallocator_(rhs.pallocator_)
00687     {
00688         resizeCopy(rhs);
00689     }
00690 
00691         /** destructor
00692         */
00693     ~BasicImage()
00694     {
00695         deallocate();
00696     }
00697 
00698         /** copy rhs image (image is resized if necessary)
00699         */
00700     BasicImage & operator=(const BasicImage & rhs);
00701 
00702         /** \deprecated set Image with const value
00703         */
00704     BasicImage & operator=(value_type pixel);
00705 
00706         /** set Image with const value
00707         */
00708     BasicImage & init(value_type const & pixel);
00709 
00710         /** reset image to specified size (dimensions must not be negative)
00711             (old data are kept if new size matches old size)
00712         */
00713     void resize(int width, int height)
00714     {
00715         if(width != width_ || height != height_)
00716             resize(width, height, value_type());
00717     }
00718 
00719         /** reset image to specified size (dimensions must not be negative)
00720             (old data are kept if new size matches old size)
00721         */
00722     void resize(difference_type const & size)
00723     {
00724         if(size.x != width_ || size.y != height_)
00725         {
00726             resize(size.x, size.y, value_type());
00727         }
00728     }
00729 
00730         /** reset image to specified size and initialize it with
00731             given data (use this if value_type doesn't have a default
00732             constructor, dimensions must not be negative,
00733             old data are kept if new size matches old size)
00734         */
00735     void resize(int width, int height, value_type const & d);
00736 
00737         /** resize image to given size and initialize by copying data
00738             from the C-style arra \a data.
00739         */
00740     void resizeCopy(int width, int height, const_pointer data);
00741 
00742         /** resize image to size of other image and copy it's data
00743         */
00744     void resizeCopy(const BasicImage & rhs)
00745     {
00746         resizeCopy(rhs.width(), rhs.height(), rhs.data_);
00747     }
00748 
00749         /** swap the internal data with the rhs image in constant time
00750         */
00751     void swap( BasicImage & rhs );
00752 
00753         /** width of Image
00754         */
00755     int width() const
00756     {
00757         return width_;
00758     }
00759 
00760         /** height of Image
00761         */
00762     int height() const
00763     {
00764         return height_;
00765     }
00766 
00767         /** size of Image
00768         */
00769     size_type size() const
00770     {
00771         return size_type(width(), height());
00772     }
00773 
00774         /** test whether a given coordinate is inside the image
00775         */
00776     bool isInside(difference_type const & d) const
00777     {
00778         return d.x >= 0 && d.y >= 0 &&
00779                d.x < width() && d.y < height();
00780     }
00781 
00782         /** access pixel at given location. <br>
00783         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00784         */
00785     reference operator[](difference_type const & d)
00786     {
00787         return lines_[d.y][d.x];
00788     }
00789 
00790         /** read pixel at given location. <br>
00791         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00792         */
00793     const_reference operator[](difference_type const & d) const
00794     {
00795         return lines_[d.y][d.x];
00796     }
00797 
00798         /** access pixel at given location. <br>
00799         usage: <TT> value_type value = image(1,2) </TT>
00800         */
00801     reference operator()(int dx, int dy)
00802     {
00803         return lines_[dy][dx];
00804     }
00805 
00806         /** read pixel at given location. <br>
00807         usage: <TT> value_type value = image(1,2) </TT>
00808         */
00809     const_reference operator()(int dx, int dy) const
00810     {
00811         return lines_[dy][dx];
00812     }
00813 
00814         /** access pixel at given location.
00815             Note that the 'x' index is the trailing index. <br>
00816         usage: <TT> value_type value = image[2][1] </TT>
00817         */
00818     pointer operator[](int dy)
00819     {
00820         return lines_[dy];
00821     }
00822 
00823         /** read pixel at given location.
00824             Note that the 'x' index is the trailing index. <br>
00825         usage: <TT> value_type value = image[2][1] </TT>
00826         */
00827     const_pointer operator[](int dy) const
00828     {
00829         return lines_[dy];
00830     }
00831 
00832         /** init 2D random access iterator poining to upper left pixel
00833         */
00834     traverser upperLeft()
00835     {
00836         vigra_precondition(data_ != 0,
00837           "BasicImage::upperLeft(): image must have non-zero size.");
00838         return traverser(lines_);
00839     }
00840 
00841         /** init 2D random access iterator poining to
00842          pixel(width, height), i.e. one pixel right and below lower right
00843          corner of the image as is common in C/C++.
00844         */
00845     traverser lowerRight()
00846     {
00847         vigra_precondition(data_ != 0,
00848           "BasicImage::lowerRight(): image must have non-zero size.");
00849         return upperLeft() + size();
00850     }
00851 
00852         /** init 2D random access const iterator poining to upper left pixel
00853         */
00854     const_traverser upperLeft() const
00855     {
00856         vigra_precondition(data_ != 0,
00857           "BasicImage::upperLeft(): image must have non-zero size.");
00858         return const_traverser(const_cast<PIXELTYPE **>(lines_));
00859     }
00860 
00861         /** init 2D random access const 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     const_traverser lowerRight() const
00866     {
00867         vigra_precondition(data_ != 0,
00868           "BasicImage::lowerRight(): image must have non-zero size.");
00869         return upperLeft() + size();
00870     }
00871 
00872         /** init 1D random access iterator pointing to first pixel
00873         */
00874     iterator begin()
00875     {
00876         vigra_precondition(data_ != 0,
00877           "BasicImage::begin(): image must have non-zero size.");
00878         return data_;
00879     }
00880 
00881         /** init 1D random access iterator pointing past the end
00882         */
00883     iterator end()
00884     {
00885         vigra_precondition(data_ != 0,
00886           "BasicImage::end(): image must have non-zero size.");
00887         return data_ + width() * height();
00888     }
00889 
00890         /** init 1D random access const iterator pointing to first pixel
00891         */
00892     const_iterator begin() const
00893     {
00894         vigra_precondition(data_ != 0,
00895           "BasicImage::begin(): image must have non-zero size.");
00896         return data_;
00897     }
00898 
00899         /** init 1D random access const iterator pointing past the end
00900         */
00901     const_iterator end() const
00902     {
00903         vigra_precondition(data_ != 0,
00904           "BasicImage::end(): image must have non-zero size.");
00905         return data_ + width() * height();
00906     }
00907 
00908         /** init 1D random access iterator pointing to first pixel of row \a y
00909         */
00910     row_iterator rowBegin(int y)
00911     {
00912         return lines_[y];
00913     }
00914 
00915         /** init 1D random access iterator pointing past the end of row \a y
00916         */
00917     row_iterator rowEnd(int y)
00918     {
00919         return rowBegin(y) + width();
00920     }
00921 
00922         /** init 1D random access const iterator pointing to first pixel of row \a y
00923         */
00924     const_row_iterator rowBegin(int y) const
00925     {
00926         return lines_[y];
00927     }
00928 
00929         /** init 1D random access const iterator pointing past the end of row \a y
00930         */
00931     const_row_iterator rowEnd(int y) const
00932     {
00933         return rowBegin(y) + width();
00934     }
00935 
00936         /** init 1D random access iterator pointing to first pixel of column \a x
00937         */
00938     column_iterator columnBegin(int x)
00939     {
00940         typedef typename column_iterator::BaseType Iter;
00941         return column_iterator(Iter(lines_, x));
00942     }
00943 
00944         /** init 1D random access iterator pointing past the end of column \a x
00945         */
00946     column_iterator columnEnd(int x)
00947     {
00948         return columnBegin(x) + height();
00949     }
00950 
00951         /** init 1D random access const iterator pointing to first pixel of column \a x
00952         */
00953     const_column_iterator columnBegin(int x) const 
00954     {
00955         typedef typename const_column_iterator::BaseType Iter;
00956         return const_column_iterator(Iter(lines_, x));
00957     }
00958 
00959         /** init 1D random access const iterator pointing past the end of column \a x
00960         */
00961     const_column_iterator columnEnd(int x) const 
00962     {
00963         return columnBegin(x) + height();
00964     }
00965 
00966         /** get a pointer to the internal data
00967         */
00968     const_pointer data() const
00969     {
00970         return data_;
00971     }
00972 
00973         /** return default accessor
00974         */
00975     Accessor accessor()
00976     {
00977         return Accessor();
00978     }
00979 
00980         /** return default const accessor
00981         */
00982     ConstAccessor accessor() const
00983     {
00984         return ConstAccessor();
00985     }
00986 
00987   private:
00988 
00989     void deallocate();
00990 
00991     value_type ** initLineStartArray(value_type * data, int width, int height);
00992 
00993     PIXELTYPE * data_;
00994     PIXELTYPE ** lines_;
00995     int width_, height_;
00996     Alloc allocator_;
00997     LineAllocator pallocator_;
00998 };
00999 
01000 template <class PIXELTYPE, class Alloc>
01001 BasicImage<PIXELTYPE, Alloc> &
01002 BasicImage<PIXELTYPE, Alloc>::operator=(const BasicImage<PIXELTYPE, Alloc> & rhs)
01003 {
01004     if(this != &rhs)
01005     {
01006         if((width() != rhs.width()) ||
01007            (height() != rhs.height()))
01008         {
01009             resizeCopy(rhs);
01010         }
01011         else
01012         {
01013             ConstScanOrderIterator is = rhs.begin();
01014             ConstScanOrderIterator iend = rhs.end();
01015             ScanOrderIterator id = begin();
01016 
01017             for(; is != iend; ++is, ++id) *id = *is;
01018         }
01019     }
01020     return *this;
01021 }
01022 
01023 template <class PIXELTYPE, class Alloc>
01024 BasicImage<PIXELTYPE, Alloc> &
01025 BasicImage<PIXELTYPE, Alloc>::operator=(value_type pixel)
01026 {
01027     ScanOrderIterator i = begin();
01028     ScanOrderIterator iend = end();
01029 
01030     for(; i != iend; ++i) *i = pixel;
01031 
01032     return *this;
01033 }
01034 
01035 template <class PIXELTYPE, class Alloc>
01036 BasicImage<PIXELTYPE, Alloc> &
01037 BasicImage<PIXELTYPE, Alloc>::init(value_type const & pixel)
01038 {
01039     ScanOrderIterator i = begin();
01040     ScanOrderIterator iend = end();
01041 
01042     for(; i != iend; ++i) *i = pixel;
01043 
01044     return *this;
01045 }
01046 
01047 template <class PIXELTYPE, class Alloc>
01048 void
01049 BasicImage<PIXELTYPE, Alloc>::resize(int width, int height, value_type const & d)
01050 {
01051     vigra_precondition((width >= 0) && (height >= 0),
01052          "BasicImage::resize(int width, int height, value_type const &): "
01053          "width and height must be >= 0.\n");
01054 
01055     if (width_ != width || height_ != height)  // change size?
01056     {
01057         value_type * newdata = 0;
01058         value_type ** newlines = 0;
01059         if(width*height > 0)
01060         {
01061             if (width*height != width_*height_) // different sizes, must reallocate
01062             {
01063                 newdata = allocator_.allocate(width*height);
01064                 std::uninitialized_fill_n(newdata, width*height, d);
01065                 newlines = initLineStartArray(newdata, width, height);
01066                 deallocate();
01067             }
01068             else // need only to reshape
01069             {
01070                 newdata = data_;
01071                 std::fill_n(newdata, width*height, d);
01072                 newlines = initLineStartArray(newdata, width, height);
01073                 pallocator_.deallocate(lines_, height_);
01074             }
01075         }
01076         else
01077         {
01078             deallocate();
01079         }
01080 
01081         data_ = newdata;
01082         lines_ = newlines;
01083         width_ = width;
01084         height_ = height;
01085     }
01086     else if(width*height > 0) // keep size, re-init data
01087     {
01088         std::fill_n(data_, width*height, d);
01089     }
01090 }
01091 
01092 
01093 template <class PIXELTYPE, class Alloc>
01094 void
01095 BasicImage<PIXELTYPE, Alloc>::resizeCopy(int width, int height, const_pointer data)
01096 {
01097     int newsize = width*height;
01098     if (width_ != width || height_ != height)  // change size?
01099     {
01100         value_type * newdata = 0;
01101         value_type ** newlines = 0;
01102         if(newsize > 0)
01103         {
01104             if (newsize != width_*height_) // different sizes, must reallocate
01105             {
01106                 newdata = allocator_.allocate(newsize);
01107                 std::uninitialized_copy(data, data + newsize, newdata);
01108                 newlines = initLineStartArray(newdata, width, height);
01109                 deallocate();
01110             }
01111             else // need only to reshape
01112             {
01113                 newdata = data_;
01114                 std::copy(data, data + newsize, newdata);
01115                 newlines = initLineStartArray(newdata, width, height);
01116                 pallocator_.deallocate(lines_, height_);
01117             }
01118         }
01119         else
01120         {
01121             deallocate();
01122         }
01123 
01124         data_ = newdata;
01125         lines_ = newlines;
01126         width_ = width;
01127         height_ = height;
01128     }
01129     else if(newsize > 0) // keep size, copy data
01130     {
01131         std::copy(data, data + newsize, data_);
01132     }
01133 }
01134 
01135 template <class PIXELTYPE, class Alloc>
01136 void
01137 BasicImage<PIXELTYPE, Alloc>::swap( BasicImage<PIXELTYPE, Alloc>& rhs )
01138 {
01139   if (&rhs!=this)
01140   {
01141     std::swap( data_, rhs.data_ );
01142     std::swap( lines_, rhs.lines_ );
01143     std::swap( width_, rhs.width_ );
01144     std::swap( height_, rhs.height_ );
01145   }
01146 }
01147 
01148 template <class PIXELTYPE, class Alloc>
01149 void
01150 BasicImage<PIXELTYPE, Alloc>::deallocate()
01151 {
01152     if(data_)
01153     {
01154         ScanOrderIterator i = begin();
01155         ScanOrderIterator iend = end();
01156 
01157         for(; i != iend; ++i)   (*i).~PIXELTYPE();
01158 
01159         allocator_.deallocate(data_, width()*height());
01160         pallocator_.deallocate(lines_, height_);
01161     }
01162 }
01163 
01164 template <class PIXELTYPE, class Alloc>
01165 PIXELTYPE **
01166 BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int width, int height)
01167 {
01168     value_type ** lines = pallocator_.allocate(height);
01169     for(int y=0; y<height; ++y)
01170          lines[y] = data + y*width;
01171     return lines;
01172 }
01173 
01174 /********************************************************/
01175 /*                                                      */
01176 /*              argument object factories               */
01177 /*                                                      */
01178 /********************************************************/
01179 
01180 template <class PixelType, class Accessor, class Alloc>
01181 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01182               typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01183 srcImageRange(BasicImage<PixelType, Alloc> const & img, Accessor a)
01184 {
01185     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01186                   typename BasicImage<PixelType, Alloc>::const_traverser,
01187           Accessor>(img.upperLeft(),
01188                     img.lowerRight(),
01189                     a);
01190 }
01191 
01192 template <class PixelType, class Accessor, class Alloc>
01193 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01194 srcImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
01195 {
01196     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01197                 Accessor>(img.upperLeft(), a);
01198 }
01199 
01200 template <class PixelType, class Accessor, class Alloc>
01201 inline triple<typename BasicImage<PixelType, Alloc>::traverser,
01202               typename BasicImage<PixelType, Alloc>::traverser, Accessor>
01203 destImageRange(BasicImage<PixelType, Alloc> & img, Accessor a)
01204 {
01205     return triple<typename BasicImage<PixelType, Alloc>::traverser,
01206                   typename BasicImage<PixelType, Alloc>::traverser,
01207           Accessor>(img.upperLeft(),
01208                     img.lowerRight(),
01209                     a);
01210 }
01211 
01212 template <class PixelType, class Accessor, class Alloc>
01213 inline pair<typename BasicImage<PixelType, Alloc>::traverser, Accessor>
01214 destImage(BasicImage<PixelType, Alloc> & img, Accessor a)
01215 {
01216     return pair<typename BasicImage<PixelType, Alloc>::traverser,
01217                 Accessor>(img.upperLeft(), a);
01218 }
01219 
01220 template <class PixelType, class Accessor, class Alloc>
01221 inline pair<typename BasicImage<PixelType, Alloc>::const_traverser, Accessor>
01222 maskImage(BasicImage<PixelType, Alloc> const & img, Accessor a)
01223 {
01224     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01225                 Accessor>(img.upperLeft(), a);
01226 }
01227 
01228 /****************************************************************/
01229 
01230 template <class PixelType, class Alloc>
01231 inline triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01232               typename BasicImage<PixelType, Alloc>::const_traverser,
01233               typename BasicImage<PixelType, Alloc>::ConstAccessor>
01234 srcImageRange(BasicImage<PixelType, Alloc> const & img)
01235 {
01236     return triple<typename BasicImage<PixelType, Alloc>::const_traverser,
01237                   typename BasicImage<PixelType, Alloc>::const_traverser,
01238                   typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01239                                                                  img.lowerRight(),
01240                                                                  img.accessor());
01241 }
01242 
01243 template <class PixelType, class Alloc>
01244 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
01245              typename BasicImage<PixelType, Alloc>::ConstAccessor>
01246 srcImage(BasicImage<PixelType, Alloc> const & img)
01247 {
01248     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01249                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01250                                                                img.accessor());
01251 }
01252 
01253 template <class PixelType, class Alloc>
01254 inline triple< typename BasicImage<PixelType, Alloc>::traverser,
01255                typename BasicImage<PixelType, Alloc>::traverser,
01256                typename BasicImage<PixelType, Alloc>::Accessor>
01257 destImageRange(BasicImage<PixelType, Alloc> & img)
01258 {
01259     return triple<typename BasicImage<PixelType, Alloc>::traverser,
01260                   typename BasicImage<PixelType, Alloc>::traverser,
01261                   typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
01262                                                             img.lowerRight(),
01263                                                             img.accessor());
01264 }
01265 
01266 template <class PixelType, class Alloc>
01267 inline pair< typename BasicImage<PixelType, Alloc>::traverser,
01268              typename BasicImage<PixelType, Alloc>::Accessor>
01269 destImage(BasicImage<PixelType, Alloc> & img)
01270 {
01271     return pair<typename BasicImage<PixelType, Alloc>::traverser,
01272                 typename BasicImage<PixelType, Alloc>::Accessor>(img.upperLeft(),
01273                                                           img.accessor());
01274 }
01275 
01276 template <class PixelType, class Alloc>
01277 inline pair< typename BasicImage<PixelType, Alloc>::const_traverser,
01278              typename BasicImage<PixelType, Alloc>::ConstAccessor>
01279 maskImage(BasicImage<PixelType, Alloc> const & img)
01280 {
01281     return pair<typename BasicImage<PixelType, Alloc>::const_traverser,
01282                 typename BasicImage<PixelType, Alloc>::ConstAccessor>(img.upperLeft(),
01283                                                                img.accessor());
01284 }
01285 
01286 } // namespace vigra
01287 
01288 #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.4.0 (21 Dec 2005)