[ 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.2.0, Aug 07 2003 )                                    */
00008 /*    You may use, modify, and distribute this software according       */
00009 /*    to the terms stated in the LICENSE file included in               */
00010 /*    the VIGRA distribution.                                           */
00011 /*                                                                      */
00012 /*    The VIGRA Website is                                              */
00013 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00014 /*    Please direct questions, bug reports, and contributions to        */
00015 /*        koethe@informatik.uni-hamburg.de                              */
00016 /*                                                                      */
00017 /*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
00018 /*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
00019 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
00020 /*                                                                      */
00021 /************************************************************************/
00022 
00023 
00024 #ifndef VIGRA_BASICIMAGE_HXX
00025 #define VIGRA_BASICIMAGE_HXX
00026 
00027 
00028 #include <new>
00029 #include <memory>
00030 #include <algorithm>
00031 #include "vigra/utilities.hxx"
00032 
00033 namespace vigra {
00034 
00035 template <class IMAGEITERATOR>
00036 class LineBasedColumnIteratorPolicy
00037 {
00038   public:
00039     typedef IMAGEITERATOR                             ImageIterator;
00040     typedef typename IMAGEITERATOR::LineStartIterator LineStartIterator;
00041     typedef typename IMAGEITERATOR::value_type        value_type;
00042     typedef typename IMAGEITERATOR::difference_type::MoveY
00043                                                       difference_type;
00044     typedef typename IMAGEITERATOR::reference         reference;
00045     typedef typename IMAGEITERATOR::index_reference   index_reference;
00046     typedef typename IMAGEITERATOR::pointer           pointer;
00047     typedef std::random_access_iterator_tag           iterator_category;
00048 
00049 
00050     struct BaseType
00051     {
00052         explicit BaseType(LineStartIterator c = LineStartIterator(),
00053                           difference_type o = 0)
00054         : line_start_(c), offset_(o)
00055         {}
00056 
00057         LineStartIterator line_start_;
00058         difference_type offset_;
00059     };
00060 
00061     static void initialize(BaseType &) {}
00062 
00063     static reference dereference(BaseType const & d)
00064         { return const_cast<reference>(*(*d.line_start_ + d.offset_)); }
00065 
00066     static index_reference dereference(BaseType const & d, difference_type n)
00067     {
00068         return const_cast<index_reference>(*(d.line_start_[n] + d.offset_));
00069     }
00070 
00071     static bool equal(BaseType const & d1, BaseType const & d2)
00072         { return d1.line_start_ == d2.line_start_; }
00073 
00074     static bool less(BaseType const & d1, BaseType const & d2)
00075         { return d1.line_start_ < d2.line_start_; }
00076 
00077     static difference_type difference(BaseType const & d1, BaseType const & d2)
00078         { return d1.line_start_ - d2.line_start_; }
00079 
00080     static void increment(BaseType & d)
00081         { ++d.line_start_; }
00082 
00083     static void decrement(BaseType & d)
00084         { --d.line_start_; }
00085 
00086     static void advance(BaseType & d, difference_type n)
00087         { d.line_start_ += n; }
00088 };
00089 
00090 /********************************************************/
00091 /*                                                      */
00092 /*                    BasicImageIterator                */
00093 /*                                                      */
00094 /********************************************************/
00095 
00096 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
00097     See \ref vigra::ImageIterator for documentation.
00098 
00099     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00100     Namespace: vigra
00101 */
00102 template <class IMAGEITERATOR, class PIXELTYPE,
00103           class REFERENCE, class POINTER, class LINESTARTITERATOR>
00104 class BasicImageIteratorBase
00105 {
00106   public:
00107     typedef BasicImageIteratorBase<IMAGEITERATOR,
00108             PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type;
00109 
00110     typedef LINESTARTITERATOR    LineStartIterator;
00111     typedef PIXELTYPE            value_type;
00112     typedef PIXELTYPE            PixelType;
00113     typedef REFERENCE            reference;
00114     typedef REFERENCE            index_reference;
00115     typedef POINTER              pointer;
00116     typedef Diff2D               difference_type;
00117     typedef image_traverser_tag  iterator_category;
00118     typedef POINTER              row_iterator;
00119     typedef IteratorAdaptor<LineBasedColumnIteratorPolicy<IMAGEITERATOR> >
00120                                  column_iterator;
00121 
00122     typedef int                  MoveX;
00123     typedef LINESTARTITERATOR    MoveY;
00124 
00125     MoveX x;
00126     MoveY y;
00127 
00128     IMAGEITERATOR & operator+=(difference_type const & s)
00129     {
00130         x += s.x;
00131         y += s.y;
00132         return static_cast<IMAGEITERATOR &>(*this);
00133     }
00134 
00135     IMAGEITERATOR & operator-=(difference_type const & s)
00136     {
00137         x -= s.x;
00138         y -= s.y;
00139         return static_cast<IMAGEITERATOR &>(*this);
00140     }
00141 
00142     IMAGEITERATOR operator+(difference_type const & s) const
00143     {
00144         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
00145 
00146         ret += s;
00147 
00148         return ret;
00149     }
00150 
00151     IMAGEITERATOR operator-(difference_type const & s) const
00152     {
00153         IMAGEITERATOR ret(static_cast<IMAGEITERATOR const &>(*this));
00154 
00155         ret -= s;
00156 
00157         return ret;
00158     }
00159 
00160     difference_type operator-(BasicImageIteratorBase const & rhs) const
00161     {
00162         return difference_type(x - rhs.x, y - rhs.y);
00163     }
00164 
00165     bool operator==(BasicImageIteratorBase const & rhs) const
00166     {
00167         return (x == rhs.x) && (y == rhs.y);
00168     }
00169 
00170     bool operator!=(BasicImageIteratorBase const & rhs) const
00171     {
00172         return (x != rhs.x) || (y != rhs.y);
00173     }
00174 
00175     reference operator*() const
00176     {
00177         return *(*y + x );
00178     }
00179 
00180     pointer operator->() const
00181     {
00182         return *y + x;
00183     }
00184 
00185     index_reference operator[](difference_type const & d) const
00186     {
00187         return *(*(y + d.y) + x + d.x);
00188     }
00189 
00190     index_reference operator()(int dx, int dy) const
00191     {
00192         return *(*(y + dy) + x + dx);
00193     }
00194 
00195     pointer operator[](int dy) const
00196     {
00197         return y[dy] + x;
00198     }
00199 
00200     row_iterator rowIterator() const
00201         { return *y + x; }
00202 
00203     column_iterator columnIterator() const
00204     {
00205         typedef typename column_iterator::BaseType Iter;
00206         return column_iterator(Iter(y, x));
00207     }
00208 
00209   protected:
00210     BasicImageIteratorBase(LINESTARTITERATOR const & line)
00211     : x(0),
00212       y(line)
00213     {}
00214 
00215     BasicImageIteratorBase(int ix, LINESTARTITERATOR const & line)
00216     : x(ix),
00217       y(line)
00218     {}
00219 
00220     BasicImageIteratorBase()
00221     : x(0),
00222       y(0)
00223     {}
00224 };
00225 
00226 /********************************************************/
00227 /*                                                      */
00228 /*                    BasicImageIterator                */
00229 /*                                                      */
00230 /********************************************************/
00231 
00232 /** Implementation of the standard image iterator for \ref vigra::BasicImage.
00233     See \ref vigra::ImageIterator for documentation.
00234 
00235     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00236     Namespace: vigra
00237 */
00238 template <class PIXELTYPE, class ITERATOR>
00239 class BasicImageIterator
00240 : public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>,
00241                             PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR>
00242 {
00243   public:
00244 
00245     typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE,
00246                                 PIXELTYPE &, PIXELTYPE *, ITERATOR> Base;
00247 
00248 
00249     BasicImageIterator(ITERATOR line)
00250     : Base(line)
00251     {}
00252 
00253     BasicImageIterator()
00254     : Base()
00255     {}
00256 };
00257 
00258 /********************************************************/
00259 /*                                                      */
00260 /*                ConstBasicImageIterator               */
00261 /*                                                      */
00262 /********************************************************/
00263 
00264 /** Implementation of the standard const image iterator for \ref vigra::BasicImage.
00265     See \ref vigra::ConstImageIterator for documentation.
00266 
00267     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00268     Namespace: vigra
00269 */
00270 template <class PIXELTYPE, class ITERATOR>
00271 class ConstBasicImageIterator
00272 : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR>,
00273                     PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR>
00274 {
00275   public:
00276 
00277     typedef BasicImageIteratorBase<ConstBasicImageIterator,
00278               PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERATOR> Base;
00279 
00280 
00281     ConstBasicImageIterator(ITERATOR line)
00282     : Base(line)
00283     {}
00284 
00285     ConstBasicImageIterator(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
00286     : Base(rhs.x, rhs.y)
00287     {}
00288 
00289     ConstBasicImageIterator()
00290     : Base()
00291     {}
00292 
00293     ConstBasicImageIterator &
00294     operator=(BasicImageIterator<PIXELTYPE, ITERATOR> const & rhs)
00295     {
00296         x = rhs.x;
00297         y = rhs.y;
00298         return *this;
00299     }
00300 
00301 };
00302 
00303 template <class T> struct IteratorTraits;
00304 
00305 /********************************************************/
00306 /*                                                      */
00307 /*                     BasicImage                       */
00308 /*                                                      */
00309 /********************************************************/
00310 
00311 /** \brief Fundamental class template for images .
00312 
00313     <b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimage.hxx</a>"
00314 
00315     Namespace: vigra
00316 */
00317 template <class PIXELTYPE>
00318 class BasicImage
00319 {
00320   public:
00321 
00322         /** the BasicImage's pixel type
00323         */
00324     typedef PIXELTYPE value_type;
00325 
00326         /** the BasicImage's pixel type
00327         */
00328     typedef PIXELTYPE PixelType;
00329 
00330         /** the BasicImage's reference type (i.e. the
00331             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>)
00332         */
00333     typedef PIXELTYPE &       reference;
00334 
00335         /** the BasicImage's const reference type (i.e. the
00336             return type of <TT>image[diff]</TT> and <TT>image(dx,dy)</TT>
00337             when <TT>image</TT> is const)
00338         */
00339     typedef PIXELTYPE const & const_reference;
00340 
00341         /** the BasicImage's pointer type
00342         */
00343     typedef PIXELTYPE *       pointer;
00344 
00345         /** the BasicImage's const pointer type
00346         */
00347     typedef PIXELTYPE const * const_pointer;
00348 
00349         /** the BasicImage's 1D random access iterator
00350             (note: lower case 'iterator' is a STL compatible 1D random
00351              access iterator, don't confuse with capitalized Iterator)
00352         */
00353     typedef PIXELTYPE * iterator;
00354 
00355         /** deprecated, use <TT>iterator</TT> instead
00356         */
00357     typedef PIXELTYPE * ScanOrderIterator;
00358 
00359         /** the BasicImage's 1D random access const iterator
00360             (note: lower case 'const_iterator' is a STL compatible 1D
00361             random access const iterator)
00362         */
00363     typedef PIXELTYPE const * const_iterator;
00364 
00365         /** deprecated, use <TT>const_iterator</TT> instead
00366         */
00367     typedef PIXELTYPE const * ConstScanOrderIterator;
00368 
00369         /** the BasicImage's 2D random access iterator ('traverser')
00370         */
00371     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> traverser;
00372 
00373         /** deprecated, use <TT>traverser</TT> instead
00374         */
00375     typedef BasicImageIterator<PIXELTYPE, PIXELTYPE **> Iterator;
00376 
00377         /** the BasicImage's 2D random access const iterator ('const traverser')
00378         */
00379     typedef
00380         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00381         const_traverser;
00382 
00383         /** deprecated, use <TT>const_traverser</TT> instead
00384         */
00385     typedef
00386         ConstBasicImageIterator<PIXELTYPE, PIXELTYPE **>
00387         ConstIterator;
00388 
00389         /** the BasicImage's difference type (argument type of image[diff])
00390         */
00391     typedef Diff2D difference_type;
00392 
00393          /** the BasicImage's size type (result type of image.size())
00394         */
00395     typedef Size2D size_type;
00396 
00397        /** the BasicImage's default accessor
00398         */
00399     typedef typename
00400           IteratorTraits<traverser>::DefaultAccessor Accessor;
00401 
00402         /** the BasicImage's default const accessor
00403         */
00404     typedef typename
00405           IteratorTraits<const_traverser>::DefaultAccessor ConstAccessor;
00406 
00407     struct Allocator
00408     {
00409         static value_type * allocate(int n) {
00410                   return (value_type *)::operator new(n*sizeof(value_type)); }
00411         static void deallocate(value_type * p) {
00412                  ::operator delete(p); }
00413     };
00414 
00415         /** construct image of size 0x0
00416         */
00417     BasicImage()
00418     : data_(0),
00419       width_(0),
00420       height_(0)
00421     {}
00422 
00423         /** construct image of size width x height
00424         */
00425     BasicImage(int width, int height)
00426     : data_(0),
00427       width_(0),
00428       height_(0)
00429     {
00430         vigra_precondition((width >= 0) && (height >= 0),
00431              "BasicImage::BasicImage(int width, int height): "
00432              "width and height must be >= 0.\n");
00433 
00434         resize(width, height, value_type());
00435     }
00436 
00437         /** construct image of size size.x x size.y
00438         */
00439     explicit BasicImage(difference_type const & size)
00440     : data_(0),
00441       width_(0),
00442       height_(0)
00443     {
00444         vigra_precondition((size.x >= 0) && (size.y >= 0),
00445              "BasicImage::BasicImage(Diff2D size): "
00446              "size.x and size.y must be >= 0.\n");
00447 
00448         resize(size.x, size.y, value_type());
00449     }
00450 
00451         /** construct image of size width*height and initialize every
00452         pixel with given data (use this constructor, if
00453         value_type doesn't have a default constructor)
00454         */
00455     BasicImage(int width, int height, value_type const & d)
00456     : data_(0),
00457       width_(0),
00458       height_(0)
00459     {
00460         vigra_precondition((width >= 0) && (height >= 0),
00461              "BasicImage::BasicImage(int width, int height, value_type const & ): "
00462              "width and height must be >= 0.\n");
00463 
00464         resize(width, height, d);
00465     }
00466 
00467         /** copy rhs image
00468         */
00469     BasicImage(const BasicImage & rhs)
00470     : data_(0),
00471       width_(0),
00472       height_(0)
00473     {
00474         resizeCopy(rhs);
00475     }
00476 
00477         /** destructor
00478         */
00479     ~BasicImage()
00480     {
00481         deallocate();
00482     }
00483 
00484         /** copy rhs image (image is resized if necessary)
00485         */
00486     BasicImage & operator=(const BasicImage & rhs);
00487 
00488         /** \deprecated set Image with const value
00489         */
00490     BasicImage & operator=(value_type pixel);
00491 
00492         /** set Image with const value
00493         */
00494     BasicImage & init(value_type const & pixel);
00495 
00496         /** reset image to specified size (dimensions must not be negative)
00497         (old data are destroyed)
00498         */
00499     void resize(int width, int height)
00500     {
00501         resize(width, height, value_type());
00502     }
00503 
00504         /** reset image to specified size (dimensions must not be negative)
00505         (old data are destroyed)
00506         */
00507     void resize(difference_type const & size)
00508     {
00509         resize(size.x, size.y, value_type());
00510     }
00511 
00512         /** reset image to specified size and initialize it with
00513             given data (use this if value_type doesn't have a default
00514             constructor, dimensions must not be negative, old data are destroyed)
00515         */
00516     void resize(int width, int height, value_type const & d);
00517 
00518 
00519         /** resize image to size of other image and copy it's data
00520         */
00521     void resizeCopy(const BasicImage & rhs);
00522 
00523         /** swap the internal data with the rhs image in constant time
00524         */
00525     void swap( BasicImage<PIXELTYPE>& rhs );
00526 
00527         /** width of Image
00528         */
00529     int width() const
00530     {
00531         return width_;
00532     }
00533 
00534         /** height of Image
00535         */
00536     int height() const
00537     {
00538         return height_;
00539     }
00540 
00541         /** size of Image
00542         */
00543     size_type size() const
00544     {
00545         return size_type(width(), height());
00546     }
00547 
00548         /** test whether a given coordinate is inside the image
00549         */
00550     bool isInside(difference_type const & d) const
00551     {
00552         return d.x >= 0 && d.y >= 0 &&
00553                d.x < width() && d.y < height();
00554     }
00555 
00556         /** access pixel at given location. <br>
00557         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00558         */
00559     reference operator[](difference_type const & d)
00560     {
00561         return lines_[d.y][d.x];
00562     }
00563 
00564         /** read pixel at given location. <br>
00565         usage: <TT> value_type value = image[Diff2D(1,2)] </TT>
00566         */
00567     const_reference operator[](difference_type const & d) const
00568     {
00569         return lines_[d.y][d.x];
00570     }
00571 
00572         /** access pixel at given location. <br>
00573         usage: <TT> value_type value = image(1,2) </TT>
00574         */
00575     reference operator()(int dx, int dy)
00576     {
00577         return lines_[dy][dx];
00578     }
00579 
00580         /** read pixel at given location. <br>
00581         usage: <TT> value_type value = image(1,2) </TT>
00582         */
00583     const_reference operator()(int dx, int dy) const
00584     {
00585         return lines_[dy][dx];
00586     }
00587 
00588         /** access pixel at given location.
00589             Note that the 'x' index is the trailing index. <br>
00590         usage: <TT> value_type value = image[2][1] </TT>
00591         */
00592     pointer operator[](int dy)
00593     {
00594         return lines_[dy];
00595     }
00596 
00597         /** read pixel at given location.
00598             Note that the 'x' index is the trailing index. <br>
00599         usage: <TT> value_type value = image[2][1] </TT>
00600         */
00601     const_pointer operator[](int dy) const
00602     {
00603         return lines_[dy];
00604     }
00605 
00606         /** init 2D random access iterator poining to upper left pixel
00607         */
00608     traverser upperLeft()
00609     {
00610         vigra_precondition(data_ != 0,
00611           "basicImage::upperLeft(): image must have non-zero size.");
00612         return traverser(lines_);
00613     }
00614 
00615         /** init 2D random access iterator poining to
00616          pixel(width, height), i.e. one pixel right and below lower right
00617          corner of the image as is common in C/C++.
00618         */
00619     traverser lowerRight()
00620     {
00621         vigra_precondition(data_ != 0,
00622           "basicImage::lowerRight(): image must have non-zero size.");
00623         return upperLeft() + size();
00624     }
00625 
00626         /** init 2D random access const iterator poining to upper left pixel
00627         */
00628     const_traverser upperLeft() const
00629     {
00630         vigra_precondition(data_ != 0,
00631           "basicImage::upperLeft(): image must have non-zero size.");
00632         return const_traverser(const_cast<PIXELTYPE **>(lines_));
00633     }
00634 
00635         /** init 2D random access const iterator poining to
00636          pixel(width, height), i.e. one pixel right and below lower right
00637          corner of the image as is common in C/C++.
00638         */
00639     const_traverser lowerRight() const
00640     {
00641         vigra_precondition(data_ != 0,
00642           "basicImage::lowerRight(): image must have non-zero size.");
00643         return upperLeft() + size();
00644     }
00645 
00646         /** init 1D random access iterator pointing to first pixel
00647         */
00648     iterator begin()
00649     {
00650         vigra_precondition(data_ != 0,
00651           "basicImage::begin(): image must have non-zero size.");
00652         return data_;
00653     }
00654 
00655         /** init 1D random access iterator pointing past the end
00656         */
00657     iterator end()
00658     {
00659         vigra_precondition(data_ != 0,
00660           "basicImage::end(): image must have non-zero size.");
00661         return data_ + width() * height();
00662     }
00663 
00664         /** init 1D random access const iterator pointing to first pixel
00665         */
00666     const_iterator begin() const
00667     {
00668         vigra_precondition(data_ != 0,
00669           "basicImage::begin(): image must have non-zero size.");
00670         return data_;
00671     }
00672 
00673         /** init 1D random access const iterator pointing past the end
00674         */
00675     const_iterator end() const
00676     {
00677         vigra_precondition(data_ != 0,
00678           "basicImage::end(): image must have non-zero size.");
00679         return data_ + width() * height();
00680     }
00681 
00682         /** return default accessor
00683         */
00684     Accessor accessor()
00685     {
00686         return Accessor();
00687     }
00688 
00689         /** return default const accessor
00690         */
00691     ConstAccessor accessor() const
00692     {
00693         return ConstAccessor();
00694     }
00695 
00696   private:
00697 
00698     void deallocate();
00699 
00700     static value_type ** initLineStartArray(value_type * data, int width, int height);
00701 
00702     PIXELTYPE * data_;
00703     PIXELTYPE ** lines_;
00704     int width_, height_;
00705 };
00706 
00707 template <class PIXELTYPE>
00708 BasicImage<PIXELTYPE> &
00709 BasicImage<PIXELTYPE>::operator=(const BasicImage<PIXELTYPE> & rhs)
00710 {
00711     if(this != &rhs)
00712     {
00713         if((width() != rhs.width()) ||
00714            (height() != rhs.height()))
00715         {
00716             resizeCopy(rhs);
00717         }
00718         else
00719         {
00720             ConstScanOrderIterator is = rhs.begin();
00721             ConstScanOrderIterator iend = rhs.end();
00722             ScanOrderIterator id = begin();
00723 
00724             for(; is != iend; ++is, ++id) *id = *is;
00725         }
00726     }
00727     return *this;
00728 }
00729 
00730 template <class PIXELTYPE>
00731 BasicImage<PIXELTYPE> &
00732 BasicImage<PIXELTYPE>::operator=(value_type pixel)
00733 {
00734     ScanOrderIterator i = begin();
00735     ScanOrderIterator iend = end();
00736 
00737     for(; i != iend; ++i) *i = pixel;
00738 
00739     return *this;
00740 }
00741 
00742 template <class PIXELTYPE>
00743 BasicImage<PIXELTYPE> &
00744 BasicImage<PIXELTYPE>::init(value_type const & pixel)
00745 {
00746     ScanOrderIterator i = begin();
00747     ScanOrderIterator iend = end();
00748 
00749     for(; i != iend; ++i) *i = pixel;
00750 
00751     return *this;
00752 }
00753 
00754 template <class PIXELTYPE>
00755 void
00756 BasicImage<PIXELTYPE>::resize(int width, int height, value_type const & d)
00757 {
00758     vigra_precondition((width >= 0) && (height >= 0),
00759          "BasicImage::resize(int width, int height, value_type const &): "
00760          "width and height must be >= 0.\n");
00761 
00762     value_type * newdata = 0;
00763     value_type ** newlines = 0;
00764     if(width*height > 0)
00765     {
00766         newdata = Allocator::allocate(width*height);
00767 
00768         std::uninitialized_fill_n(newdata, width*height, d);
00769 
00770         newlines = initLineStartArray(newdata, width, height);
00771     }
00772 
00773     deallocate();
00774     data_ = newdata;
00775     lines_ = newlines;
00776     width_ = width;
00777     height_ = height;
00778 }
00779 
00780 
00781 template <class PIXELTYPE>
00782 void
00783 BasicImage<PIXELTYPE>::resizeCopy(const BasicImage & rhs)
00784 {
00785     value_type * newdata = 0;
00786     value_type ** newlines = 0;
00787     if(rhs.width()*rhs.height() > 0)
00788     {
00789         newdata = Allocator::allocate(rhs.width()*rhs.height());
00790 
00791         std::uninitialized_copy(rhs.begin(), rhs.end(), newdata);
00792 
00793         newlines =
00794            initLineStartArray(newdata, rhs.width(), rhs.height());
00795     }
00796 
00797     deallocate();
00798     data_ = newdata;
00799     lines_ = newlines;
00800     width_ = rhs.width();
00801     height_ = rhs.height();
00802 }
00803 
00804 template <class PIXELTYPE>
00805 void
00806 BasicImage<PIXELTYPE>::swap( BasicImage<PIXELTYPE>& rhs )
00807 {
00808   if (&rhs!=this)
00809   {
00810     std::swap( data_, rhs.data_ );
00811     std::swap( lines_, rhs.lines_ );
00812     std::swap( width_, rhs.width_ );
00813     std::swap( height_, rhs.height_ );
00814   }
00815 }
00816 
00817 template <class PIXELTYPE>
00818 void
00819 BasicImage<PIXELTYPE>::deallocate()
00820 {
00821     if(data_)
00822     {
00823         ScanOrderIterator i = begin();
00824         ScanOrderIterator iend = end();
00825 
00826         for(; i != iend; ++i)   (*i).~PIXELTYPE();
00827 
00828         Allocator::deallocate(data_);
00829         delete[] lines_;
00830     }
00831 }
00832 
00833 template <class PIXELTYPE>
00834 PIXELTYPE **
00835 BasicImage<PIXELTYPE>::initLineStartArray(value_type * data, int width, int height)
00836 {
00837     value_type ** lines = new PIXELTYPE*[height];
00838     for(int y=0; y<height; ++y)
00839          lines[y] = data + y*width;
00840     return lines;
00841 }
00842 
00843 /********************************************************/
00844 /*                                                      */
00845 /*              argument object factories               */
00846 /*                                                      */
00847 /********************************************************/
00848 
00849 template <class PixelType, class Accessor>
00850 inline triple<typename BasicImage<PixelType>::const_traverser, 
00851               typename BasicImage<PixelType>::const_traverser, Accessor>
00852 srcImageRange(BasicImage<PixelType> const & img, Accessor a)
00853 {
00854     return triple<typename BasicImage<PixelType>::const_traverser, 
00855                   typename BasicImage<PixelType>::const_traverser, 
00856           Accessor>(img.upperLeft(),
00857                     img.lowerRight(),
00858                     a);
00859 }
00860 
00861 template <class PixelType, class Accessor>
00862 inline pair<typename BasicImage<PixelType>::const_traverser, Accessor>
00863 srcImage(BasicImage<PixelType> const & img, Accessor a)
00864 {
00865     return pair<typename BasicImage<PixelType>::const_traverser, 
00866                 Accessor>(img.upperLeft(), a);
00867 }
00868 
00869 template <class PixelType, class Accessor>
00870 inline triple<typename BasicImage<PixelType>::traverser, 
00871               typename BasicImage<PixelType>::traverser, Accessor>
00872 destImageRange(BasicImage<PixelType> & img, Accessor a)
00873 {
00874     return triple<typename BasicImage<PixelType>::traverser, 
00875                   typename BasicImage<PixelType>::traverser, 
00876           Accessor>(img.upperLeft(),
00877                     img.lowerRight(),
00878                     a);
00879 }
00880 
00881 template <class PixelType, class Accessor>
00882 inline pair<typename BasicImage<PixelType>::traverser, Accessor>
00883 destImage(BasicImage<PixelType> & img, Accessor a)
00884 {
00885     return pair<typename BasicImage<PixelType>::traverser, 
00886                 Accessor>(img.upperLeft(), a);
00887 }
00888 
00889 template <class PixelType, class Accessor>
00890 inline pair<typename BasicImage<PixelType>::const_traverser, Accessor>
00891 maskImage(BasicImage<PixelType> const & img, Accessor a)
00892 {
00893     return pair<typename BasicImage<PixelType>::const_traverser, 
00894                 Accessor>(img.upperLeft(), a);
00895 }
00896 
00897 /****************************************************************/
00898 
00899 template <class PixelType>
00900 inline triple<typename BasicImage<PixelType>::const_traverser, 
00901               typename BasicImage<PixelType>::const_traverser, 
00902               typename BasicImage<PixelType>::ConstAccessor>
00903 srcImageRange(BasicImage<PixelType> const & img)
00904 {
00905     return triple<typename BasicImage<PixelType>::const_traverser, 
00906                   typename BasicImage<PixelType>::const_traverser, 
00907                   typename BasicImage<PixelType>::ConstAccessor>(img.upperLeft(),
00908                                                                  img.lowerRight(),
00909                                                                  img.accessor());
00910 }
00911 
00912 template <class PixelType>
00913 inline pair< typename BasicImage<PixelType>::const_traverser, 
00914              typename BasicImage<PixelType>::ConstAccessor>
00915 srcImage(BasicImage<PixelType> const & img)
00916 {
00917     return pair<typename BasicImage<PixelType>::const_traverser, 
00918                 typename BasicImage<PixelType>::ConstAccessor>(img.upperLeft(), 
00919                                                                img.accessor());
00920 }
00921 
00922 template <class PixelType>
00923 inline triple< typename BasicImage<PixelType>::traverser, 
00924                typename BasicImage<PixelType>::traverser, 
00925                typename BasicImage<PixelType>::Accessor>
00926 destImageRange(BasicImage<PixelType> & img)
00927 {
00928     return triple<typename BasicImage<PixelType>::traverser, 
00929                   typename BasicImage<PixelType>::traverser, 
00930                   typename BasicImage<PixelType>::Accessor>(img.upperLeft(),
00931                                                             img.lowerRight(),
00932                                                             img.accessor());
00933 }
00934 
00935 template <class PixelType>
00936 inline pair< typename BasicImage<PixelType>::traverser, 
00937              typename BasicImage<PixelType>::Accessor>
00938 destImage(BasicImage<PixelType> & img)
00939 {
00940     return pair<typename BasicImage<PixelType>::traverser, 
00941                 typename BasicImage<PixelType>::Accessor>(img.upperLeft(), 
00942                                                           img.accessor());
00943 }
00944 
00945 template <class PixelType>
00946 inline pair< typename BasicImage<PixelType>::const_traverser, 
00947              typename BasicImage<PixelType>::ConstAccessor>
00948 maskImage(BasicImage<PixelType> const & img)
00949 {
00950     return pair<typename BasicImage<PixelType>::const_traverser, 
00951                 typename BasicImage<PixelType>::ConstAccessor>(img.upperLeft(), 
00952                                                                img.accessor());
00953 }
00954 
00955 } // namespace vigra
00956 
00957 #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.2.0 (7 Aug 2003)