| edgedetection.hxx | | edgedetection.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_EDGEDETECTION_HXX | | #ifndef VIGRA_EDGEDETECTION_HXX | |
| #define VIGRA_EDGEDETECTION_HXX | | #define VIGRA_EDGEDETECTION_HXX | |
| | | | |
| #include <vector> | | #include <vector> | |
|
| | | #include <queue> | |
| #include <cmath> // sqrt(), abs() | | #include <cmath> // sqrt(), abs() | |
| #include "vigra/utilities.hxx" | | #include "vigra/utilities.hxx" | |
| #include "vigra/numerictraits.hxx" | | #include "vigra/numerictraits.hxx" | |
| #include "vigra/stdimage.hxx" | | #include "vigra/stdimage.hxx" | |
| #include "vigra/stdimagefunctions.hxx" | | #include "vigra/stdimagefunctions.hxx" | |
| #include "vigra/recursiveconvolution.hxx" | | #include "vigra/recursiveconvolution.hxx" | |
| #include "vigra/separableconvolution.hxx" | | #include "vigra/separableconvolution.hxx" | |
| #include "vigra/labelimage.hxx" | | #include "vigra/labelimage.hxx" | |
|
| | | #include "vigra/mathutil.hxx" | |
| | | #include "vigra/pixelneighborhood.hxx" | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| /** \addtogroup EdgeDetection Edge Detection | | /** \addtogroup EdgeDetection Edge Detection | |
| Edge detectors based on first and second derivatives, | | Edge detectors based on first and second derivatives, | |
| and related post-processing. | | and related post-processing. | |
| */ | | */ | |
| //@{ | | //@{ | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| skipping to change at line 1409 | | skipping to change at line 1427 | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* cannyEdgeImage */ | | /* cannyEdgeImage */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Detect and mark edges in an edge image using Canny's algorithm. | | /** \brief Detect and mark edges in an edge image using Canny's algorithm. | |
| | | | |
| This operator first calls \ref cannyEdgelList() to generate an | | This operator first calls \ref cannyEdgelList() to generate an | |
|
| edgel list for the given image. Than it scans this list and selects edg
els | | edgel list for the given image. Then it scans this list and selects edg
els | |
| whose strength is above the given <TT>gradient_threshold</TT>. For each
of these | | whose strength is above the given <TT>gradient_threshold</TT>. For each
of these | |
| edgels, the edgel's location is rounded to the nearest pixel, and that | | edgels, the edgel's location is rounded to the nearest pixel, and that | |
| pixel marked with the given <TT>edge_marker</TT>. | | pixel marked with the given <TT>edge_marker</TT>. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| | | | |
| skipping to change at line 1514 | | skipping to change at line 1532 | |
| inline void cannyEdgeImage( | | inline void cannyEdgeImage( | |
| triple<SrcIterator, SrcIterator, SrcAccessor> src, | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| double scale, GradValue gradient_threshold, DestValue edge_marke
r) | | double scale, GradValue gradient_threshold, DestValue edge_marke
r) | |
| { | | { | |
| cannyEdgeImage(src.first, src.second, src.third, | | cannyEdgeImage(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
| scale, gradient_threshold, edge_marker); | | scale, gradient_threshold, edge_marker); | |
| } | | } | |
| | | | |
|
| | | /********************************************************/ | |
| | | | |
| | | namespace detail { | |
| | | | |
| | | template <class DestIterator> | |
| | | int neighborhoodConfiguration(DestIterator dul) | |
| | | { | |
| | | int v = 0; | |
| | | NeighborhoodCirculator<DestIterator, EightNeighborCode> c(dul, EightNei | |
| | | ghborCode::SouthEast); | |
| | | for(int i=0; i<8; ++i, --c) | |
| | | { | |
| | | v = (v << 1) | ((*c != 0) ? 1 : 0); | |
| | | } | |
| | | | |
| | | return v; | |
| | | } | |
| | | | |
| | | template <class GradValue> | |
| | | struct SimplePoint | |
| | | { | |
| | | Diff2D point; | |
| | | GradValue grad; | |
| | | | |
| | | SimplePoint(Diff2D const & p, GradValue g) | |
| | | : point(p), grad(g) | |
| | | {} | |
| | | | |
| | | bool operator<(SimplePoint const & o) const | |
| | | { | |
| | | return grad < o.grad; | |
| | | } | |
| | | }; | |
| | | | |
| | | } // namespace detail | |
| | | | |
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* cannyEdgeImageWithThinning */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | /** \brief Detect and mark edges in an edge image using Canny's algorithm. | |
| | | | |
| | | This operator first calls \ref cannyEdgeImage() to generate an | |
| | | edge image. The resulting edge pixels are then subjected to topological | |
| | | thinning | |
| | | so that the remaining edge pixels can be linked into edgel chains with | |
| | | a provable, | |
| | | non-heuristic algorithm. Optionally, the outermost pixels are marked as | |
| | | edge pixels | |
| | | as well when <tt>addBorder</tt> is true. | |
| | | | |
| | | <b> Declarations:</b> | |
| | | | |
| | | pass arguments explicitly: | |
| | | \code | |
| | | namespace vigra { | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class GradValue, class DestValue> | |
| | | void cannyEdgeImageWithThinning( | |
| | | SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, | |
| | | double scale, GradValue gradient_threshold, | |
| | | DestValue edge_marker, bool addBorder = true); | |
| | | } | |
| | | \endcode | |
| | | | |
| | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| | | \code | |
| | | namespace vigra { | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class GradValue, class DestValue> | |
| | | void cannyEdgeImageWithThinning( | |
| | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | double scale, GradValue gradient_threshold, | |
| | | DestValue edge_marker, bool addBorder = true); | |
| | | } | |
| | | \endcode | |
| | | | |
| | | <b> Usage:</b> | |
| | | | |
| | | <b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/edgede | |
| | | tection.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | | |
| | | \code | |
| | | vigra::BImage src(w,h), edges(w,h); | |
| | | | |
| | | // empty edge image | |
| | | edges = 0; | |
| | | ... | |
| | | | |
| | | // find edges at scale 0.8 with gradient larger than 4.0, mark with 1, | |
| | | annd add border | |
| | | vigra::cannyEdgeImageWithThinning(srcImageRange(src), destImage(edges), | |
| | | 0.8, 4.0, 1, true); | |
| | | \endcode | |
| | | | |
| | | <b> Required Interface:</b> | |
| | | | |
| | | see also: \ref cannyEdgelList(). | |
| | | | |
| | | \code | |
| | | DestImageIterator dest_upperleft; | |
| | | DestAccessor dest_accessor; | |
| | | DestValue edge_marker; | |
| | | | |
| | | dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1)); | |
| | | \endcode | |
| | | | |
| | | <b> Preconditions:</b> | |
| | | | |
| | | \code | |
| | | scale > 0 | |
| | | gradient_threshold > 0 | |
| | | \endcode | |
| | | */ | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class GradValue, class DestValue> | |
| | | void cannyEdgeImageWithThinning( | |
| | | SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, | |
| | | double scale, GradValue gradient_threshold, | |
| | | DestValue edge_marker, bool addBorder) | |
| | | { | |
| | | int w = slr.x - sul.x; | |
| | | int h = slr.y - sul.y; | |
| | | | |
| | | BImage edgeImage(w, h, BImage::value_type(0)); | |
| | | BImage::traverser eul = edgeImage.upperLeft(); | |
| | | BImage::Accessor ea = edgeImage.accessor(); | |
| | | if(addBorder) | |
| | | initImageBorder(destImageRange(edgeImage), 1, 1); | |
| | | cannyEdgeImage(sul, slr, sa, eul, ea, | |
| | | scale, gradient_threshold, 1); | |
| | | | |
| | | static bool isSimplePoint[256] = { | |
| | | 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, | |
| | | 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, | |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, | |
| | | 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, | |
| | | 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, | |
| | | 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, | |
| | | 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, | |
| | | 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, | |
| | | 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, | |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| | | 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, | |
| | | 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, | |
| | | 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, | |
| | | 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, | |
| | | 1, 0, 1, 0 }; | |
| | | | |
| | | eul += Diff2D(1,1); | |
| | | sul += Diff2D(1,1); | |
| | | int w2 = w-2; | |
| | | int h2 = h-2; | |
| | | | |
| | | typedef detail::SimplePoint<GradValue> SP; | |
| | | std::priority_queue<SP, std::vector<SP> > pqueue; | |
| | | | |
| | | Diff2D p(0,0); | |
| | | for(; p.y < h2; ++p.y) | |
| | | { | |
| | | for(p.x = 0; p.x < w2; ++p.x) | |
| | | { | |
| | | BImage::traverser e = eul + p; | |
| | | if(*e == 0) | |
| | | continue; | |
| | | int v = detail::neighborhoodConfiguration(e); | |
| | | if(isSimplePoint[v]) | |
| | | { | |
| | | pqueue.push(SP(p, norm(sa(sul+p)))); | |
| | | *e = 2; // remember that it is already in queue | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | static const Diff2D dist[] = { Diff2D(-1,0), Diff2D(0,-1), | |
| | | Diff2D(1,0), Diff2D(0,1) }; | |
| | | | |
| | | while(pqueue.size()) | |
| | | { | |
| | | p = pqueue.top().point; | |
| | | pqueue.pop(); | |
| | | | |
| | | BImage::traverser e = eul + p; | |
| | | int v = detail::neighborhoodConfiguration(e); | |
| | | if(!isSimplePoint[v]) | |
| | | continue; // point may no longer be simple because its neighbor | |
| | | s changed | |
| | | | |
| | | *e = 0; // delete simple point | |
| | | | |
| | | for(int i=0; i<4; ++i) | |
| | | { | |
| | | Diff2D pneu = p + dist[i]; | |
| | | if(pneu.x == -1 || pneu.y == -1 || pneu.x == w2 || pneu.y == h2 | |
| | | ) | |
| | | continue; // do not remove points at the border | |
| | | | |
| | | BImage::traverser eneu = eul + pneu; | |
| | | if(*eneu == 1) // point is boundary and not yet in the queue | |
| | | { | |
| | | int v = detail::neighborhoodConfiguration(eneu); | |
| | | if(isSimplePoint[v]) | |
| | | { | |
| | | pqueue.push(SP(pneu, norm(sa(sul+pneu)))); | |
| | | *eneu = 2; // remember that it is already in queue | |
| | | } | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | initImageIf(destIterRange(dul, dul+Diff2D(w,h), da), | |
| | | maskImage(edgeImage), edge_marker); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class GradValue, class DestValue> | |
| | | inline void cannyEdgeImageWithThinning( | |
| | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | double scale, GradValue gradient_threshold, | |
| | | DestValue edge_marker, bool addBorder) | |
| | | { | |
| | | cannyEdgeImageWithThinning(src.first, src.second, src.third, | |
| | | dest.first, dest.second, | |
| | | scale, gradient_threshold, edge_marker, addB | |
| | | order); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class GradValue, class DestValue> | |
| | | inline void cannyEdgeImageWithThinning( | |
| | | SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, | |
| | | double scale, GradValue gradient_threshold, DestValue edge_marke | |
| | | r) | |
| | | { | |
| | | cannyEdgeImageWithThinning(sul, slr, sa, | |
| | | dul, da, | |
| | | scale, gradient_threshold, edge_marker, true | |
| | | ); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class GradValue, class DestValue> | |
| | | inline void cannyEdgeImageWithThinning( | |
| | | triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | double scale, GradValue gradient_threshold, DestValue edge_marke | |
| | | r) | |
| | | { | |
| | | cannyEdgeImageWithThinning(src.first, src.second, src.third, | |
| | | dest.first, dest.second, | |
| | | scale, gradient_threshold, edge_marker, true | |
| | | ); | |
| | | } | |
| | | | |
| //@} | | //@} | |
| | | | |
| /** \page CrackEdgeImage Crack Edge Image | | /** \page CrackEdgeImage Crack Edge Image | |
| | | | |
| Crack edges are marked <i>between</i> the pixels of an image. | | Crack edges are marked <i>between</i> the pixels of an image. | |
| A Crack Edge Image is an image that represents these edges. In order | | A Crack Edge Image is an image that represents these edges. In order | |
| to accomodate the cracks, the Crack Edge Image must be twice as large | | to accomodate the cracks, the Crack Edge Image must be twice as large | |
| as the original image (precisely (2*w - 1) by (2*h - 1)). A Crack Edge Imag
e | | as the original image (precisely (2*w - 1) by (2*h - 1)). A Crack Edge Imag
e | |
| can easily be derived from a binary image or from the signs of the | | can easily be derived from a binary image or from the signs of the | |
| response of a Laplacean filter. Consider the following sketch, where | | response of a Laplacean filter. Consider the following sketch, where | |
| | | | |
End of changes. 7 change blocks. |
| 10 lines changed or deleted | | 296 lines changed or added | |
|
| fixedpoint.hxx | | fixedpoint.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 2004-2005 by Ullrich Koethe */ | | /* Copyright 2004-2005 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_FIXEDPOINT_HXX | | #ifndef VIGRA_FIXEDPOINT_HXX | |
| #define VIGRA_FIXEDPOINT_HXX | | #define VIGRA_FIXEDPOINT_HXX | |
| | | | |
| #include "vigra/mathutil.hxx" | | #include "vigra/mathutil.hxx" | |
| #include "vigra/static_assert.hxx" | | #include "vigra/static_assert.hxx" | |
| #include "vigra/error.hxx" | | #include "vigra/error.hxx" | |
| #include "vigra/numerictraits.hxx" | | #include "vigra/numerictraits.hxx" | |
| | | | |
| skipping to change at line 50 | | skipping to change at line 65 | |
| { | | { | |
| public: | | public: | |
| typedef Error_FixedPointTraits_not_specialized_for_this_case PlusType; | | typedef Error_FixedPointTraits_not_specialized_for_this_case PlusType; | |
| typedef Error_FixedPointTraits_not_specialized_for_this_case MinusType; | | typedef Error_FixedPointTraits_not_specialized_for_this_case MinusType; | |
| typedef Error_FixedPointTraits_not_specialized_for_this_case Multiplies
Type; | | typedef Error_FixedPointTraits_not_specialized_for_this_case Multiplies
Type; | |
| // typedef Error_FixedPointTraits_not_specialized_for_this_case DividesT
ype; | | // typedef Error_FixedPointTraits_not_specialized_for_this_case DividesT
ype; | |
| }; | | }; | |
| | | | |
| // return type policy: | | // return type policy: | |
| // * try to allocate enough bits to represent the biggest possible resu
lt | | // * try to allocate enough bits to represent the biggest possible resu
lt | |
|
| // * in case of ass/subtract: if all bits of the internal int are used
up, | | // * in case of add/subtract: if all bits of the internal int are used
up, | |
| // keep the representation | | // keep the representation | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| class FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2
, FracBits2> > | | class FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2
, FracBits2> > | |
| { | | { | |
| enum { MaxIntBits = (IntBits1 < IntBits2) ? IntBits2 : IntBits1, | | enum { MaxIntBits = (IntBits1 < IntBits2) ? IntBits2 : IntBits1, | |
| MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1, | | MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1, | |
| PlusMinusIntBits = (MaxIntBits + 1 + MaxFracBits < 32) ? | | PlusMinusIntBits = (MaxIntBits + 1 + MaxFracBits < 32) ? | |
|
| MaxIntBits + 1 : MaxIntBits}; | | MaxIntBits + 1 : MaxIntBits, | |
| | | MultipliesFracBits = (IntBits1 + IntBits2 < 31) | |
| | | ? (FracBits1 + FracBits2) > (31 - IntBi | |
| | | ts1 - IntBits2) | |
| | | ? 31 - IntBits1 - IntBits2 | |
| | | : FracBits1 + FracBits2 | |
| | | : 0 | |
| | | }; | |
| public: | | public: | |
| typedef FixedPoint<PlusMinusIntBits, MaxFracBits> PlusTyp
e; | | typedef FixedPoint<PlusMinusIntBits, MaxFracBits> PlusTyp
e; | |
| typedef FixedPoint<PlusMinusIntBits, MaxFracBits> MinusTy
pe; | | typedef FixedPoint<PlusMinusIntBits, MaxFracBits> MinusTy
pe; | |
|
| typedef FixedPoint<IntBits1 + IntBits2, FracBits1 + FracBits2> Multipl
iesType; | | typedef FixedPoint<IntBits1 + IntBits2, MultipliesFracBits> Multiplies
Type; | |
| // typedef FixedPoint<IntBits1 + FracBits2, FracBits1 + IntBits2> Divid
esType; | | // typedef FixedPoint<IntBits1 + FracBits2, FracBits1 + IntBits2> Divid
esType; | |
| }; | | }; | |
| | | | |
|
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | struct SquareRootTraits<FixedPoint<IntBits, FracBits> > | |
| | | { | |
| | | enum { SRTotalBits = (IntBits + FracBits + 1) / 2, | |
| | | SRIntBits = (IntBits + 1) / 2, | |
| | | SRFracBits = SRTotalBits - SRIntBits | |
| | | }; | |
| | | public: | |
| | | typedef FixedPoint<IntBits, FracBits> Type; | |
| | | typedef FixedPoint<SRIntBits, SRFracBits> SquareRootResult; | |
| | | typedef Type SquareRootArgument; | |
| | | }; | |
| | | | |
| | | #ifndef DOXYGEN | |
| | | | |
| template <int N> | | template <int N> | |
| struct FixedPoint_overflow_error__More_than_31_bits_requested | | struct FixedPoint_overflow_error__More_than_31_bits_requested | |
| : staticAssert::AssertBool<(N < 32)> | | : staticAssert::AssertBool<(N < 32)> | |
| {}; | | {}; | |
| | | | |
|
| | | #endif /* DOXYGEN */ | |
| | | | |
| template <bool Predicate> | | template <bool Predicate> | |
| struct FixedPoint_assignment_error__Target_object_has_too_few_integer_bits | | struct FixedPoint_assignment_error__Target_object_has_too_few_integer_bits | |
| : staticAssert::AssertBool<Predicate> | | : staticAssert::AssertBool<Predicate> | |
| {}; | | {}; | |
| | | | |
| enum FixedPointNoShift { FPNoShift }; | | enum FixedPointNoShift { FPNoShift }; | |
| | | | |
| namespace detail { | | namespace detail { | |
| | | | |
| template <bool MustRound> | | template <bool MustRound> | |
| | | | |
| skipping to change at line 129 | | skipping to change at line 167 | |
| int shiftl = l >> diffl; | | int shiftl = l >> diffl; | |
| int shiftr = r >> diffr; | | int shiftr = r >> diffr; | |
| | | | |
| return shiftl * shiftr + (((l & maskl) * shiftr) >> diffl) + | | return shiftl * shiftr + (((l & maskl) * shiftr) >> diffl) + | |
| (((r & maskr) * shiftl) >> diffr); | | (((r & maskr) * shiftl) >> diffr); | |
| } | | } | |
| }; | | }; | |
| | | | |
| } // namespace detail | | } // namespace detail | |
| | | | |
|
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* FixedPoint */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | /** Template for fixed point arithmetic. | |
| | | | |
| | | Fixed point arithmetic is used when computations with fractional accura | |
| | | cy | |
| | | must be made at the highest speed possible (e.g. in the inner loop | |
| | | of a volume rendering routine). The speed-up relative to floating | |
| | | point arithmetic can be dramatic, especially when one can avoid | |
| | | conversions between integer anfloating point numbers (these are | |
| | | very expensive because integer and floating point arithmetic | |
| | | resides in different pipelines). | |
| | | | |
| | | The template wraps an <tt>int</tt> and uses <tt>IntBits</tt> to | |
| | | represent the integral part of a number, and <tt>FractionalBits</tt> | |
| | | for the fractional part, where <tt>IntBits + FractionalBits < 32</tt | |
| | | >. | |
| | | (The 32rd bit is reserved because FixedPoint is a signed type). | |
| | | These numbers will be automatically allocated in an intelligent way | |
| | | in the result of an arithmetic operation. For example, when two | |
| | | fixed point numbers are multiplied, the required number of integer | |
| | | bits in the result is the sum of the number of integer bits of the | |
| | | arguments, but only when so many bits are avaiable. This is figured out | |
| | | by means of FixedPointTraits, and a compile-time error is raised | |
| | | when no suitable representation can be found. The idea is that the righ | |
| | | t | |
| | | thing happens automatically as often as possible. | |
| | | | |
| | | <tt>FixedPoint</tt> implements the required interface of an | |
| | | \ref AlgebraicRing and the required numeric and | |
| | | promotion traits. In addition, it supports functions <tt>add</tt>, | |
| | | <tt>sub</tt>, and <tt>mul</tt>, where a particular layout of the result | |
| | | can | |
| | | be enforced. | |
| | | | |
| | | <tt>unsigned char, signed char, unsigned short, signed short, int</tt> | |
| | | can be | |
| | | transformed into a FixedPoint with appropriate layout by means of the f | |
| | | actory | |
| | | function <tt>fixedPoint()</tt>. | |
| | | | |
| | | <b>See also:</b> | |
| | | <ul> | |
| | | <li> \ref FixedPointOperations | |
| | | <li> \ref FixedPointTraits | |
| | | </ul> | |
| | | | |
| | | <b>\#include</b> "<a href="fixedpoint_8hxx-source.html">vigra/fixedpoin | |
| | | t.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| template <unsigned IntBits, unsigned FractionalBits> | | template <unsigned IntBits, unsigned FractionalBits> | |
| class FixedPoint | | class FixedPoint | |
| { | | { | |
| public: | | public: | |
| enum { | | enum { | |
| INT_BITS = IntBits, | | INT_BITS = IntBits, | |
| FRACTIONAL_BITS = FractionalBits, | | FRACTIONAL_BITS = FractionalBits, | |
| TOTAL_BITS = IntBits + FractionalBits, | | TOTAL_BITS = IntBits + FractionalBits, | |
| MAX = (int)(((unsigned)1 << TOTAL_BITS) - 1), | | MAX = (int)(((unsigned)1 << TOTAL_BITS) - 1), | |
| ONE = 1 << FractionalBits, | | ONE = 1 << FractionalBits, | |
| ONE_HALF = ONE >> 1, | | ONE_HALF = ONE >> 1, | |
| FRACTIONAL_MASK = ONE - 1, | | FRACTIONAL_MASK = ONE - 1, | |
| INT_MASK = MAX ^ FRACTIONAL_MASK | | INT_MASK = MAX ^ FRACTIONAL_MASK | |
| }; | | }; | |
| | | | |
|
| int value; | | Int32 value; | |
| | | | |
| FixedPoint() | | FixedPoint() | |
|
| {} | | { | |
| | | VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_r | |
| | | equested<(IntBits + FractionalBits)>)); | |
| | | } | |
| | | | |
|
| /** | | /** Construct from an int (fractional part will become zero). | |
| */ | | */ | |
| explicit FixedPoint(int v) | | explicit FixedPoint(int v) | |
| : value(v << FractionalBits) | | : value(v << FractionalBits) | |
| { | | { | |
| VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_r
equested<(IntBits + FractionalBits)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_r
equested<(IntBits + FractionalBits)>)); | |
| } | | } | |
| | | | |
|
| /** | | /** Construct from an int by a bitwise copy. This is normally only
used internally. | |
| */ | | */ | |
| FixedPoint(int v, FixedPointNoShift) | | FixedPoint(int v, FixedPointNoShift) | |
| : value(v) | | : value(v) | |
| { | | { | |
| VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_r
equested<(IntBits + FractionalBits)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_r
equested<(IntBits + FractionalBits)>)); | |
| } | | } | |
| | | | |
|
| | | /** Construct from an double and round the fractional part to | |
| | | <tt>FractionalBits</tt> accuracy. A PreconditionViolation excep | |
| | | tion is raised when | |
| | | the integer part is too small to represent the number. | |
| | | */ | |
| explicit FixedPoint(double rhs) | | explicit FixedPoint(double rhs) | |
| : value((int)round(rhs * ONE)) | | : value((int)round(rhs * ONE)) | |
| { | | { | |
|
| | | VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_r
equested<(IntBits + FractionalBits)>)); | |
| vigra_precondition(abs(rhs * ONE) <= (double)MAX, | | vigra_precondition(abs(rhs * ONE) <= (double)MAX, | |
| "FixedPoint(double rhs): Too few integer bits to convert rhs.")
; | | "FixedPoint(double rhs): Too few integer bits to convert rhs.")
; | |
| } | | } | |
| | | | |
|
| | | /** Copy constructor. | |
| | | */ | |
| FixedPoint(const FixedPoint &other) | | FixedPoint(const FixedPoint &other) | |
| : value(other.value) | | : value(other.value) | |
| {} | | {} | |
| | | | |
|
| | | /** Construct from a FixedPoint with different layout. It rounds as | |
| | | appropriate and raises | |
| | | a compile-time error when the target type has too few integer b | |
| | | its. | |
| | | */ | |
| template <unsigned Int2, unsigned Frac2> | | template <unsigned Int2, unsigned Frac2> | |
| FixedPoint(const FixedPoint<Int2, Frac2> &other) | | FixedPoint(const FixedPoint<Int2, Frac2> &other) | |
| : value(detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template e
xec<Frac2 - FractionalBits>(other.value)) | | : value(detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template e
xec<Frac2 - FractionalBits>(other.value)) | |
| { | | { | |
|
| | | VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_r
equested<(IntBits + FractionalBits)>)); | |
| VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | |
| } | | } | |
| | | | |
|
| | | /** Assignment from int. The fractional part will become zero. | |
| | | A PreconditionViolation exception is raised when | |
| | | the integer part is too small to represent the number. | |
| | | */ | |
| FixedPoint &operator=(int rhs) | | FixedPoint &operator=(int rhs) | |
| { | | { | |
| vigra_precondition(abs(rhs) < (1 << IntBits), | | vigra_precondition(abs(rhs) < (1 << IntBits), | |
| "FixedPoint::operator=(int rhs): Too few integer bits to repres
ent rhs."); | | "FixedPoint::operator=(int rhs): Too few integer bits to repres
ent rhs."); | |
| value = rhs << FractionalBits; | | value = rhs << FractionalBits; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | /** Assignment form double. The fractional part is rounded, and a | |
| | | PreconditionViolation exception is raised when | |
| | | the integer part is too small to represent the number. | |
| | | */ | |
| FixedPoint &operator=(double rhs) | | FixedPoint &operator=(double rhs) | |
| { | | { | |
| vigra_precondition(abs(rhs) <= ((1 << IntBits) - 1), | | vigra_precondition(abs(rhs) <= ((1 << IntBits) - 1), | |
| "FixedPoint::operator=(double rhs): Too few integer bits to con
vert rhs."); | | "FixedPoint::operator=(double rhs): Too few integer bits to con
vert rhs."); | |
| value = (int)round(rhs * ONE); | | value = (int)round(rhs * ONE); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | /** Copy assignment. | |
| | | */ | |
| FixedPoint & operator=(const FixedPoint &other) | | FixedPoint & operator=(const FixedPoint &other) | |
| { | | { | |
| value = other.value; | | value = other.value; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | /** Assignment from a FixedPoint with different layout. It rounds a | |
| | | s appropriate and raises | |
| | | a compile-time error when the target type has too few integer b | |
| | | its. | |
| | | */ | |
| template <unsigned Int2, unsigned Frac2> | | template <unsigned Int2, unsigned Frac2> | |
| FixedPoint & operator=(const FixedPoint<Int2, Frac2> &other) | | FixedPoint & operator=(const FixedPoint<Int2, Frac2> &other) | |
| { | | { | |
| VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | |
| value = detail::FPAssignWithRound<(Frac2 > FractionalBits)>::templa
te exec<Frac2 - FractionalBits>(other.value); | | value = detail::FPAssignWithRound<(Frac2 > FractionalBits)>::templa
te exec<Frac2 - FractionalBits>(other.value); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| operator double() const | | /** Negation. | |
| { | | */ | |
| return (double)value / ONE; | | | |
| } | | | |
| | | | |
| FixedPoint operator-() const | | FixedPoint operator-() const | |
| { | | { | |
| return FixedPoint(-value, FPNoShift); | | return FixedPoint(-value, FPNoShift); | |
| } | | } | |
| | | | |
|
| | | /** Pre-increment. | |
| | | */ | |
| FixedPoint & operator++() | | FixedPoint & operator++() | |
| { | | { | |
| value += ONE; | | value += ONE; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | /** Post-increment. | |
| | | */ | |
| FixedPoint operator++(int) | | FixedPoint operator++(int) | |
| { | | { | |
| FixedPoint old(*this); | | FixedPoint old(*this); | |
| value += ONE; | | value += ONE; | |
| return old; | | return old; | |
| } | | } | |
| | | | |
|
| | | /** Pre-decrement. | |
| | | */ | |
| FixedPoint & operator--() | | FixedPoint & operator--() | |
| { | | { | |
| value -= ONE; | | value -= ONE; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | /** Post-decrement. | |
| | | */ | |
| FixedPoint operator--(int) | | FixedPoint operator--(int) | |
| { | | { | |
| FixedPoint old(*this); | | FixedPoint old(*this); | |
| value -= ONE; | | value -= ONE; | |
| return old; | | return old; | |
| } | | } | |
| | | | |
|
| | | /** Add-assignment from a FixedPoint with different layout. It roun | |
| | | ds as appropriate and raises | |
| | | a compile-time error when the target type has too few integer b | |
| | | its. | |
| | | */ | |
| template <unsigned Int2, unsigned Frac2> | | template <unsigned Int2, unsigned Frac2> | |
| FixedPoint & operator+=(const FixedPoint<Int2, Frac2> &other) | | FixedPoint & operator+=(const FixedPoint<Int2, Frac2> &other) | |
| { | | { | |
| VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | |
| value += detail::FPAssignWithRound<(Frac2 > FractionalBits)>::templ
ate exec<Frac2 - FractionalBits>(other.value); | | value += detail::FPAssignWithRound<(Frac2 > FractionalBits)>::templ
ate exec<Frac2 - FractionalBits>(other.value); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | /** Subtract-assignment from a FixedPoint with different layout. It | |
| | | rounds as appropriate and raises | |
| | | a compile-time error when the target type has too few integer b | |
| | | its. | |
| | | */ | |
| template <unsigned Int2, unsigned Frac2> | | template <unsigned Int2, unsigned Frac2> | |
| FixedPoint & operator-=(const FixedPoint<Int2, Frac2> &other) | | FixedPoint & operator-=(const FixedPoint<Int2, Frac2> &other) | |
| { | | { | |
| VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | |
| value -= detail::FPAssignWithRound<(Frac2 > FractionalBits)>::templ
ate exec<Frac2 - FractionalBits>(other.value); | | value -= detail::FPAssignWithRound<(Frac2 > FractionalBits)>::templ
ate exec<Frac2 - FractionalBits>(other.value); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
|
| | | /** Multiply-assignment from a FixedPoint with different layout. It | |
| | | rounds as appropriate and raises | |
| | | a compile-time error when the target type has too few integer b | |
| | | its. | |
| | | */ | |
| template <unsigned Int2, unsigned Frac2> | | template <unsigned Int2, unsigned Frac2> | |
| FixedPoint & operator*=(const FixedPoint<Int2, Frac2> &other) | | FixedPoint & operator*=(const FixedPoint<Int2, Frac2> &other) | |
| { | | { | |
| VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has
_too_few_integer_bits<(IntBits >= Int2)>)); | |
| value = detail::FPMulImplementation<(Frac2 > 0)>::template exec<Fra
c2>(value, other.value); | | value = detail::FPMulImplementation<(Frac2 > 0)>::template exec<Fra
c2>(value, other.value); | |
| return *this; | | return *this; | |
| } | | } | |
| }; | | }; | |
| | | | |
| #define VIGRA_FIXED_POINT_FACTORY(T, INTBITS) \ | | #define VIGRA_FIXED_POINT_FACTORY(T, INTBITS) \ | |
| | | | |
| skipping to change at line 288 | | skipping to change at line 414 | |
| } | | } | |
| | | | |
| VIGRA_FIXED_POINT_FACTORY(unsigned char, 8) | | VIGRA_FIXED_POINT_FACTORY(unsigned char, 8) | |
| VIGRA_FIXED_POINT_FACTORY(signed char, 7) | | VIGRA_FIXED_POINT_FACTORY(signed char, 7) | |
| VIGRA_FIXED_POINT_FACTORY(unsigned short, 16) | | VIGRA_FIXED_POINT_FACTORY(unsigned short, 16) | |
| VIGRA_FIXED_POINT_FACTORY(signed short, 15) | | VIGRA_FIXED_POINT_FACTORY(signed short, 15) | |
| VIGRA_FIXED_POINT_FACTORY(int, 31) | | VIGRA_FIXED_POINT_FACTORY(int, 31) | |
| | | | |
| #undef VIGRA_FIXED_POINT_FACTORY | | #undef VIGRA_FIXED_POINT_FACTORY | |
| | | | |
|
| | | template <class T> | |
| | | struct FixedPointCast; | |
| | | | |
| | | #define VIGRA_FIXED_POINT_CAST(type) \ | |
| | | template <> \ | |
| | | struct FixedPointCast<type> \ | |
| | | { \ | |
| | | template <unsigned IntBits, unsigned FracBits> \ | |
| | | static type cast(FixedPoint<IntBits, FracBits> v) \ | |
| | | { \ | |
| | | return round(v); \ | |
| | | } \ | |
| | | }; | |
| | | | |
| | | VIGRA_FIXED_POINT_CAST(Int8); | |
| | | VIGRA_FIXED_POINT_CAST(UInt8); | |
| | | VIGRA_FIXED_POINT_CAST(Int16); | |
| | | VIGRA_FIXED_POINT_CAST(UInt16); | |
| | | VIGRA_FIXED_POINT_CAST(Int32); | |
| | | VIGRA_FIXED_POINT_CAST(UInt32); | |
| | | | |
| | | #undef VIGRA_FIXED_POINT_CAST | |
| | | | |
| | | template <> | |
| | | struct FixedPointCast<float> | |
| | | { | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | static float cast(FixedPoint<IntBits, FracBits> v) | |
| | | { | |
| | | return (float)v.value / FixedPoint<IntBits, FracBits>::ONE; | |
| | | } | |
| | | }; | |
| | | | |
| | | template <> | |
| | | struct FixedPointCast<double> | |
| | | { | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | static double cast(FixedPoint<IntBits, FracBits> v) | |
| | | { | |
| | | return (double)v.value / FixedPoint<IntBits, FracBits>::ONE; | |
| | | } | |
| | | }; | |
| | | | |
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* FixedPointOperations */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | /** \addtogroup FixedPointOperations Functions for FixedPoint | |
| | | | |
| | | \brief <b>\#include</b> "<a href="fixedpoint_8hxx-source.html">vigr | |
| | | a/fixedpoint.hxx</a>"<br> | |
| | | | |
| | | These functions fulfill the requirements of an \ref AlgebraicRing. | |
| | | | |
| | | Namespace: vigra | |
| | | <p> | |
| | | | |
| | | */ | |
| | | //@{ | |
| | | | |
| | | /** Convert a FixedPoint to a built-in type. | |
| | | If the target is integral, the value is rounded.<br> | |
| | | Usage: | |
| | | \code | |
| | | FixedPoint<16,15> fp(...); | |
| | | | |
| | | double d = fixed_point_cast<double>(fp); | |
| | | \endcode | |
| | | */ | |
| | | template <class TARGET, unsigned IntBits, unsigned FracBits> | |
| | | TARGET fixed_point_cast(FixedPoint<IntBits, FracBits> v) | |
| | | { | |
| | | return FixedPointCast<TARGET>::cast(v); | |
| | | } | |
| | | | |
| | | /// equal | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| bool operator==(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | | bool operator==(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return (l.value << (MaxFracBits - FracBits1)) == (r.value << (MaxFracBi
ts - FracBits2)); | | return (l.value << (MaxFracBits - FracBits1)) == (r.value << (MaxFracBi
ts - FracBits2)); | |
| } | | } | |
| | | | |
|
| | | /// not equal | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| bool operator!=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | | bool operator!=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return (l.value << (MaxFracBits - FracBits1)) != (r.value << (MaxFracBi
ts - FracBits2)); | | return (l.value << (MaxFracBits - FracBits1)) != (r.value << (MaxFracBi
ts - FracBits2)); | |
| } | | } | |
| | | | |
|
| | | /// less than | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| bool operator<(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Frac
Bits2> r) | | bool operator<(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Frac
Bits2> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return (l.value << (MaxFracBits - FracBits1)) < (r.value << (MaxFracBit
s - FracBits2)); | | return (l.value << (MaxFracBits - FracBits1)) < (r.value << (MaxFracBit
s - FracBits2)); | |
| } | | } | |
| | | | |
|
| | | /// less or equal | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| bool operator<=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | | bool operator<=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return (l.value << (MaxFracBits - FracBits1)) <= (r.value << (MaxFracBi
ts - FracBits2)); | | return (l.value << (MaxFracBits - FracBits1)) <= (r.value << (MaxFracBi
ts - FracBits2)); | |
| } | | } | |
| | | | |
|
| | | /// greater | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| bool operator>(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Frac
Bits2> r) | | bool operator>(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Frac
Bits2> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return (l.value << (MaxFracBits - FracBits1)) > (r.value << (MaxFracBit
s - FracBits2)); | | return (l.value << (MaxFracBits - FracBits1)) > (r.value << (MaxFracBit
s - FracBits2)); | |
| } | | } | |
| | | | |
|
| | | /// greater or equal | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| bool operator>=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | | bool operator>=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, Fra
cBits2> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return (l.value << (MaxFracBits - FracBits1)) >= (r.value << (MaxFracBi
ts - FracBits2)); | | return (l.value << (MaxFracBits - FracBits1)) >= (r.value << (MaxFracBi
ts - FracBits2)); | |
| } | | } | |
| | | | |
|
| | | /// addition with automatic determination of the appropriate result typ
e. | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBi
ts2, FracBits2> >::PlusType | | typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBi
ts2, FracBits2> >::PlusType | |
| operator+(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2
> r) | | operator+(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2
> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return typename | | return typename | |
| FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBit
s2, FracBits2> >:: | | FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBit
s2, FracBits2> >:: | |
| PlusType((l.value << (MaxFracBits - FracBits1)) + (r.value << (MaxF
racBits - FracBits2)), FPNoShift); | | PlusType((l.value << (MaxFracBits - FracBits1)) + (r.value << (MaxF
racBits - FracBits2)), FPNoShift); | |
| } | | } | |
| | | | |
|
| | | /// addition with enforced result type. | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2, | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2, | |
| unsigned IntBits3, unsigned FracBits3> | | unsigned IntBits3, unsigned FracBits3> | |
| inline void | | inline void | |
| add(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r, | | add(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r, | |
| FixedPoint<IntBits3, FracBits3> & result) | | FixedPoint<IntBits3, FracBits3> & result) | |
| { | | { | |
| result = l + r; | | result = l + r; | |
| } | | } | |
| | | | |
|
| | | /// subtraction with automatic determination of the appropriate result
type. | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBi
ts2, FracBits2> >::MinusType | | typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBi
ts2, FracBits2> >::MinusType | |
| operator-(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2
> r) | | operator-(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2
> r) | |
| { | | { | |
| enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | | enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 }; | |
| return typename | | return typename | |
| FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBit
s2, FracBits2> >:: | | FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBit
s2, FracBits2> >:: | |
| MinusType((l.value << (MaxFracBits - FracBits1)) - (r.value << (Max
FracBits - FracBits2)), FPNoShift); | | MinusType((l.value << (MaxFracBits - FracBits1)) - (r.value << (Max
FracBits - FracBits2)), FPNoShift); | |
| } | | } | |
| | | | |
|
| | | /// subtraction with enforced result type. | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2, | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2, | |
| unsigned IntBits3, unsigned FracBits3> | | unsigned IntBits3, unsigned FracBits3> | |
| inline void | | inline void | |
| sub(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r, | | sub(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r, | |
| FixedPoint<IntBits3, FracBits3> & result) | | FixedPoint<IntBits3, FracBits3> & result) | |
| { | | { | |
| result = l - r; | | result = l - r; | |
| } | | } | |
| | | | |
|
| | | /// multiplication with automatic determination of the appropriate resu
lt type. | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| inline | | inline | |
| typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBi
ts2, FracBits2> >::MultipliesType | | typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBi
ts2, FracBits2> >::MultipliesType | |
| operator*(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2
> r) | | operator*(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2
> r) | |
| { | | { | |
|
| return typename | | typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<I | |
| FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBit | | ntBits2, FracBits2> >:: | |
| s2, FracBits2> >:: | | MultipliesType res; | |
| MultipliesType(l.value * r.value, FPNoShift); | | mul(l, r, res); | |
| | | return res; | |
| } | | } | |
| | | | |
|
| | | /// multiplication with enforced result type. | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2, | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2, | |
| unsigned IntBits3, unsigned FracBits3> | | unsigned IntBits3, unsigned FracBits3> | |
| inline void | | inline void | |
| mul(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r, | | mul(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r, | |
| FixedPoint<IntBits3, FracBits3> & result) | | FixedPoint<IntBits3, FracBits3> & result) | |
| { | | { | |
| VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too
_few_integer_bits<(IntBits1 + IntBits2 <= IntBits3)>)); | | VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too
_few_integer_bits<(IntBits1 + IntBits2 <= IntBits3)>)); | |
| enum { diff = FracBits1 + FracBits2 - FracBits3 }; | | enum { diff = FracBits1 + FracBits2 - FracBits3 }; | |
| result.value = detail::FPMulImplementation<(diff > 0)>::template exec<d
iff>(l.value, r.value); | | result.value = detail::FPMulImplementation<(diff > 0)>::template exec<d
iff>(l.value, r.value); | |
| } | | } | |
| | | | |
|
| | | /// square root. | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | inline typename SquareRootTraits<FixedPoint<IntBits, FracBits> >::SquareRoo | |
| | | tResult | |
| | | sqrt(FixedPoint<IntBits, FracBits> v) | |
| | | { | |
| | | return typename SquareRootTraits<FixedPoint<IntBits, FracBits> >::Squar | |
| | | eRootResult(sqrti(v.value), FPNoShift); | |
| | | } | |
| | | | |
| | | /// absolute value. | |
| template <unsigned IntBits, unsigned FracBits> | | template <unsigned IntBits, unsigned FracBits> | |
| inline FixedPoint<IntBits, FracBits> | | inline FixedPoint<IntBits, FracBits> | |
| abs(FixedPoint<IntBits, FracBits> v) | | abs(FixedPoint<IntBits, FracBits> v) | |
| { | | { | |
| return FixedPoint<IntBits, FracBits>(abs(v.value), FPNoShift); | | return FixedPoint<IntBits, FracBits>(abs(v.value), FPNoShift); | |
| } | | } | |
| | | | |
|
| | | /// squared norm (same as v*v). | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | inline | |
| | | typename FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntBits | |
| | | , FracBits> >::MultipliesType | |
| | | squaredNorm(FixedPoint<IntBits, FracBits> v) | |
| | | { | |
| | | return v*v; | |
| | | } | |
| | | | |
| | | /// norm (same as abs). | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | inline | |
| | | FixedPoint<IntBits, FracBits> | |
| | | norm(FixedPoint<IntBits, FracBits> const & v) | |
| | | { | |
| | | return abs(v); | |
| | | } | |
| | | | |
| | | /// fractional part. | |
| template <unsigned IntBits, unsigned FracBits> | | template <unsigned IntBits, unsigned FracBits> | |
| inline FixedPoint<0, FracBits> | | inline FixedPoint<0, FracBits> | |
| frac(FixedPoint<IntBits, FracBits> v) | | frac(FixedPoint<IntBits, FracBits> v) | |
| { | | { | |
| return FixedPoint<0, FracBits>(v.value & FixedPoint<IntBits, FracBits>:
:FRACTIONAL_MASK, FPNoShift); | | return FixedPoint<0, FracBits>(v.value & FixedPoint<IntBits, FracBits>:
:FRACTIONAL_MASK, FPNoShift); | |
| } | | } | |
| | | | |
|
| | | /// dual fractional part: <tt>1 - frac(v)</tt>. | |
| template <unsigned IntBits, unsigned FracBits> | | template <unsigned IntBits, unsigned FracBits> | |
| inline FixedPoint<0, FracBits> | | inline FixedPoint<0, FracBits> | |
| dual_frac(FixedPoint<IntBits, FracBits> v) | | dual_frac(FixedPoint<IntBits, FracBits> v) | |
| { | | { | |
| return FixedPoint<0, FracBits>(FixedPoint<0, FracBits>::ONE - | | return FixedPoint<0, FracBits>(FixedPoint<0, FracBits>::ONE - | |
| (v.value & FixedPoint<IntBits, FracBits>
::FRACTIONAL_MASK), FPNoShift); | | (v.value & FixedPoint<IntBits, FracBits>
::FRACTIONAL_MASK), FPNoShift); | |
| } | | } | |
| | | | |
|
| | | /// rounding down. | |
| template <unsigned IntBits, unsigned FracBits> | | template <unsigned IntBits, unsigned FracBits> | |
| inline int | | inline int | |
| floor(FixedPoint<IntBits, FracBits> v) | | floor(FixedPoint<IntBits, FracBits> v) | |
| { | | { | |
| return(v.value >> FracBits); | | return(v.value >> FracBits); | |
| } | | } | |
| | | | |
|
| | | /// rounding up. | |
| template <unsigned IntBits, unsigned FracBits> | | template <unsigned IntBits, unsigned FracBits> | |
| inline int | | inline int | |
| ceil(FixedPoint<IntBits, FracBits> v) | | ceil(FixedPoint<IntBits, FracBits> v) | |
| { | | { | |
| return((v.value + FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK) >> Fr
acBits); | | return((v.value + FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK) >> Fr
acBits); | |
| } | | } | |
| | | | |
|
| | | /// rounding to the nearest integer. | |
| template <unsigned IntBits, unsigned FracBits> | | template <unsigned IntBits, unsigned FracBits> | |
| inline int | | inline int | |
| round(FixedPoint<IntBits, FracBits> v) | | round(FixedPoint<IntBits, FracBits> v) | |
| { | | { | |
| return((v.value + FixedPoint<IntBits, FracBits>::ONE_HALF) >> FracBits)
; | | return((v.value + FixedPoint<IntBits, FracBits>::ONE_HALF) >> FracBits)
; | |
| } | | } | |
| | | | |
|
| | | //@} | |
| | | | |
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* FixedPoint-Traits */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | /** \page FixedPointTraits Numeric and Promote Traits of FixedPoint | |
| | | | |
| | | The numeric and promote traits for FixedPoint follow | |
| | | the general specifications for \ref NumericPromotionTraits and | |
| | | \ref AlgebraicRing. They are implemented in terms of the traits of the | |
| | | basic types by | |
| | | partial template specialization: | |
| | | | |
| | | \code | |
| | | | |
| | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, uns | |
| | | igned FracBits2> | |
| | | class FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntB | |
| | | its2, FracBits2> > | |
| | | { | |
| | | typedef FixedPoint<PlusMinusIntBits, MaxFracBits> Plu | |
| | | sType; | |
| | | typedef FixedPoint<PlusMinusIntBits, MaxFracBits> Min | |
| | | usType; | |
| | | typedef FixedPoint<IntBits1 + IntBits2, FracBits1 + FracBits2> Mul | |
| | | tipliesType; | |
| | | }; | |
| | | | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | struct NumericTraits<FixedPoint<IntBits, FracBits> > | |
| | | { | |
| | | typedef FixedPoint<IntBits, FracBits> Type; | |
| | | // Promote undefined because it depends on the layout, use Fixe | |
| | | dPointTraits | |
| | | // RealPromote in AlgebraicRing -- multiplication with double i | |
| | | s not supported. | |
| | | // ComplexPromote in AlgebraicRing -- multiplication with doubl | |
| | | e is not supported. | |
| | | typedef Type ValueType; | |
| | | | |
| | | typedef VigraFalseType isIntegral; | |
| | | typedef VigraTrueType isScalar; | |
| | | typedef VigraTrueType isSigned; | |
| | | typedef VigraTrueType isOrdered; | |
| | | typedef VigraFalseType isComplex; | |
| | | | |
| | | ... // etc. | |
| | | }; | |
| | | | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | struct SquareRootTraits<FixedPoint<IntBits, FracBits> > | |
| | | { | |
| | | typedef FixedPoint<IntBits, FracBits> Type; | |
| | | typedef FixedPoint<SRIntBits, SRFracBits> SquareRootResult; | |
| | | typedef Type SquareRootArgument; | |
| | | }; | |
| | | | |
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | struct NormTraits<FixedPoint<IntBits, FracBits> > | |
| | | { | |
| | | typedef FixedPoint<IntBits, FracBits> Type; | |
| | | typedef typename | |
| | | FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntB | |
| | | its, FracBits> >::MultipliesType | |
| | | SquaredNormType; | |
| | | typedef Type NormType; | |
| | | }; | |
| | | | |
| | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, uns | |
| | | igned FracBits2> | |
| | | struct PromoteTraits<FixedPoint<IntBits1, FracBits1>, | |
| | | FixedPoint<IntBits2, FracBits2> > | |
| | | { | |
| | | typedef typename | |
| | | FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<In | |
| | | tBits2, FracBits2> >::PlusType | |
| | | Promote; | |
| | | }; | |
| | | \endcode | |
| | | | |
| | | <b>\#include</b> "<a href="fixedpoint_8hxx-source.html">vigra/fixedpoin | |
| | | t.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | | |
| | | */ | |
| template <unsigned IntBits, unsigned FracBits> | | template <unsigned IntBits, unsigned FracBits> | |
| struct NumericTraits<FixedPoint<IntBits, FracBits> > | | struct NumericTraits<FixedPoint<IntBits, FracBits> > | |
| { | | { | |
| typedef FixedPoint<IntBits, FracBits> Type; | | typedef FixedPoint<IntBits, FracBits> Type; | |
| //typedef FixedPoint<IntBits, FracBits> Promote; | | //typedef FixedPoint<IntBits, FracBits> Promote; | |
| //typedef FixedPoint<IntBits, FracBits> RealPromote; | | //typedef FixedPoint<IntBits, FracBits> RealPromote; | |
| //typedef std::complex<RealPromote> ComplexPromote; | | //typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
|
| //typedef VigraFalseType isIntegral; | | typedef VigraFalseType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static Type zero() { return Type(0, FPNoShift); } | | static Type zero() { return Type(0, FPNoShift); } | |
| static Type one() { return Type(Type::ONE, FPNoShift); } | | static Type one() { return Type(Type::ONE, FPNoShift); } | |
| static Type nonZero() { return one(); } | | static Type nonZero() { return one(); } | |
| static Type epsilon() { return Type(1, FPNoShift); } | | static Type epsilon() { return Type(1, FPNoShift); } | |
| static Type smallestPositive() { return Type(1, FPNoShift); } | | static Type smallestPositive() { return Type(1, FPNoShift); } | |
| static Type max() { return Type( Type::MAX, FPNoShift); } | | static Type max() { return Type( Type::MAX, FPNoShift); } | |
| static Type min() { return -max(); } | | static Type min() { return -max(); } | |
| }; | | }; | |
| | | | |
|
| | | template <unsigned IntBits, unsigned FracBits> | |
| | | struct NormTraits<FixedPoint<IntBits, FracBits> > | |
| | | { | |
| | | typedef FixedPoint<IntBits, FracBits> Type; | |
| | | typedef typename | |
| | | FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntBits, | |
| | | FracBits> >::MultipliesType | |
| | | SquaredNormType; | |
| | | typedef Type NormType; | |
| | | }; | |
| | | | |
| template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | | template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigne
d FracBits2> | |
| struct PromoteTraits<FixedPoint<IntBits1, FracBits1>, | | struct PromoteTraits<FixedPoint<IntBits1, FracBits1>, | |
| FixedPoint<IntBits2, FracBits2> > | | FixedPoint<IntBits2, FracBits2> > | |
| { | | { | |
| typedef typename | | typedef typename | |
| FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBit
s2, FracBits2> >::PlusType | | FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBit
s2, FracBits2> >::PlusType | |
| Promote; | | Promote; | |
| }; | | }; | |
| | | | |
| } // namespace vigra | | } // namespace vigra | |
| | | | |
End of changes. 53 change blocks. |
| 26 lines changed or deleted | | 397 lines changed or added | |
|
| impex.hxx | | impex.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 2001-2002 by Gunnar Kedenburg */ | | /* Copyright 2001-2002 by Gunnar Kedenburg */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| /*! | | /*! | |
| \file impex.hxx | | \file impex.hxx | |
| \brief image import and export functions | | \brief image import and export functions | |
| | | | |
| this file provides the declarations and implementations of importImage() | | this file provides the declarations and implementations of importImage() | |
| and exportImage(). the matching implementation for the given datatype is | | and exportImage(). the matching implementation for the given datatype is | |
| selected by template metacode. | | selected by template metacode. | |
| */ | | */ | |
| | | | |
| #ifndef VIGRA_IMPEX_HXX | | #ifndef VIGRA_IMPEX_HXX | |
| #define VIGRA_IMPEX_HXX | | #define VIGRA_IMPEX_HXX | |
| | | | |
| #if defined(_MSC_VER) | | #if defined(_MSC_VER) | |
| #pragma warning (disable: 4267) | | #pragma warning (disable: 4267) | |
| #endif | | #endif | |
| | | | |
|
| | | #include "vigra/sized_int.hxx" | |
| #include "vigra/stdimage.hxx" | | #include "vigra/stdimage.hxx" | |
| #include "vigra/tinyvector.hxx" | | #include "vigra/tinyvector.hxx" | |
| #include "vigra/imageinfo.hxx" | | #include "vigra/imageinfo.hxx" | |
| #include "vigra/numerictraits.hxx" | | #include "vigra/numerictraits.hxx" | |
| #include "vigra/codec.hxx" | | #include "vigra/codec.hxx" | |
| #include "vigra/accessor.hxx" | | #include "vigra/accessor.hxx" | |
| #include "vigra/inspectimage.hxx" | | #include "vigra/inspectimage.hxx" | |
| #include "vigra/transformimage.hxx" | | #include "vigra/transformimage.hxx" | |
| #include "vigra/copyimage.hxx" | | #include "vigra/copyimage.hxx" | |
| #include "vigra/multi_array.hxx" | | #include "vigra/multi_array.hxx" | |
| | | | |
| skipping to change at line 179 | | skipping to change at line 195 | |
| \param iter image iterator referencing the upper left pixel
of the destination image | | \param iter image iterator referencing the upper left pixel
of the destination image | |
| \param a image accessor for the destination image | | \param a image accessor for the destination image | |
| */ | | */ | |
| template< class ImageIterator, class Accessor > | | template< class ImageIterator, class Accessor > | |
| void importVectorImage( const ImageImportInfo & info, ImageIterator ite
r, Accessor a ) | | void importVectorImage( const ImageImportInfo & info, ImageIterator ite
r, Accessor a ) | |
| { | | { | |
| std::auto_ptr<Decoder> dec = decoder(info); | | std::auto_ptr<Decoder> dec = decoder(info); | |
| std::string pixeltype = dec->getPixelType(); | | std::string pixeltype = dec->getPixelType(); | |
| | | | |
| if ( pixeltype == "UINT8" ) | | if ( pixeltype == "UINT8" ) | |
|
| read_bands( dec.get(), iter, a, (unsigned char)0 ); | | read_bands( dec.get(), iter, a, (UInt8)0 ); | |
| else if ( pixeltype == "INT16" ) | | else if ( pixeltype == "INT16" ) | |
|
| read_bands( dec.get(), iter, a, short() ); | | read_bands( dec.get(), iter, a, Int16() ); | |
| else if ( pixeltype == "INT32" ) | | else if ( pixeltype == "INT32" ) | |
|
| read_bands( dec.get(), iter, a, int() ); | | read_bands( dec.get(), iter, a, Int32() ); | |
| else if ( pixeltype == "FLOAT" ) | | else if ( pixeltype == "FLOAT" ) | |
| read_bands( dec.get(), iter, a, float() ); | | read_bands( dec.get(), iter, a, float() ); | |
| else if ( pixeltype == "DOUBLE" ) | | else if ( pixeltype == "DOUBLE" ) | |
| read_bands( dec.get(), iter, a, double() ); | | read_bands( dec.get(), iter, a, double() ); | |
| else | | else | |
| vigra_precondition( false, "invalid pixeltype" ); | | vigra_precondition( false, "invalid pixeltype" ); | |
| | | | |
| // close the decoder | | // close the decoder | |
| dec->close(); | | dec->close(); | |
| } | | } | |
| | | | |
| skipping to change at line 223 | | skipping to change at line 239 | |
| \param iter image iterator referencing the upper left pixel
of the destination image | | \param iter image iterator referencing the upper left pixel
of the destination image | |
| \param a image accessor for the destination image | | \param a image accessor for the destination image | |
| */ | | */ | |
| template < class ImageIterator, class Accessor > | | template < class ImageIterator, class Accessor > | |
| void importScalarImage( const ImageImportInfo & info, ImageIterator ite
r, Accessor a ) | | void importScalarImage( const ImageImportInfo & info, ImageIterator ite
r, Accessor a ) | |
| { | | { | |
| std::auto_ptr<Decoder> dec = decoder(info); | | std::auto_ptr<Decoder> dec = decoder(info); | |
| std::string pixeltype = dec->getPixelType(); | | std::string pixeltype = dec->getPixelType(); | |
| | | | |
| if ( pixeltype == "UINT8" ) | | if ( pixeltype == "UINT8" ) | |
|
| read_band( dec.get(), iter, a, (unsigned char)0 ); | | read_band( dec.get(), iter, a, (UInt8)0 ); | |
| else if ( pixeltype == "INT16" ) | | else if ( pixeltype == "INT16" ) | |
|
| read_band( dec.get(), iter, a, short() ); | | read_band( dec.get(), iter, a, Int16() ); | |
| else if ( pixeltype == "INT32" ) | | else if ( pixeltype == "INT32" ) | |
|
| read_band( dec.get(), iter, a, int() ); | | read_band( dec.get(), iter, a, Int32() ); | |
| else if ( pixeltype == "FLOAT" ) | | else if ( pixeltype == "FLOAT" ) | |
| read_band( dec.get(), iter, a, float() ); | | read_band( dec.get(), iter, a, float() ); | |
| else if ( pixeltype == "DOUBLE" ) | | else if ( pixeltype == "DOUBLE" ) | |
| read_band( dec.get(), iter, a, double() ); | | read_band( dec.get(), iter, a, double() ); | |
| else | | else | |
| vigra_precondition( false, "invalid pixeltype" ); | | vigra_precondition( false, "invalid pixeltype" ); | |
| | | | |
| // close the decoder | | // close the decoder | |
| dec->close(); | | dec->close(); | |
| } | | } | |
| | | | |
| skipping to change at line 669 | | skipping to change at line 685 | |
| const ImageExportInfo & info, VigraFalseType /*not sc
alar */) | | const ImageExportInfo & info, VigraFalseType /*not sc
alar */) | |
| { | | { | |
| typedef typename SrcAccessor::value_type AccessorValueType; | | typedef typename SrcAccessor::value_type AccessorValueType; | |
| typedef typename AccessorValueType::value_type SrcValueType; | | typedef typename AccessorValueType::value_type SrcValueType; | |
| std::string pixeltype = info.getPixelType(); | | std::string pixeltype = info.getPixelType(); | |
| std::auto_ptr<Encoder> enc = encoder(info); | | std::auto_ptr<Encoder> enc = encoder(info); | |
| bool downcast = negotiatePixelType(enc->getFileType(), | | bool downcast = negotiatePixelType(enc->getFileType(), | |
| TypeAsString<SrcValueType>::result(), pixeltype); | | TypeAsString<SrcValueType>::result(), pixeltype); | |
| enc->setPixelType(pixeltype); | | enc->setPixelType(pixeltype); | |
| if(pixeltype == "UINT8") | | if(pixeltype == "UINT8") | |
|
| detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
(unsigned char)0); | | detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
(UInt8)0); | |
| else if(pixeltype == "INT16") | | else if(pixeltype == "INT16") | |
|
| detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
short()); | | detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
Int16()); | |
| else if(pixeltype == "INT32") | | else if(pixeltype == "INT32") | |
|
| detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
int()); | | detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
Int32()); | |
| else if(pixeltype == "FLOAT") | | else if(pixeltype == "FLOAT") | |
| detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
float()); | | detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
float()); | |
| else if(pixeltype == "DOUBLE") | | else if(pixeltype == "DOUBLE") | |
| detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
double()); | | detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
double()); | |
| enc->close(); | | enc->close(); | |
| } | | } | |
| | | | |
| template < class SrcIterator, class SrcAccessor > | | template < class SrcIterator, class SrcAccessor > | |
| void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget, | | void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget, | |
| const ImageExportInfo & info, VigraTrueType /*scalar*
/ ) | | const ImageExportInfo & info, VigraTrueType /*scalar*
/ ) | |
| { | | { | |
| typedef typename SrcAccessor::value_type SrcValueType; | | typedef typename SrcAccessor::value_type SrcValueType; | |
| std::string pixeltype = info.getPixelType(); | | std::string pixeltype = info.getPixelType(); | |
| std::auto_ptr<Encoder> enc = encoder(info); | | std::auto_ptr<Encoder> enc = encoder(info); | |
| bool downcast = negotiatePixelType(enc->getFileType(), | | bool downcast = negotiatePixelType(enc->getFileType(), | |
| TypeAsString<SrcValueType>::result(), pixeltype)
; | | TypeAsString<SrcValueType>::result(), pixeltype)
; | |
| enc->setPixelType(pixeltype); | | enc->setPixelType(pixeltype); | |
| if(pixeltype == "UINT8") | | if(pixeltype == "UINT8") | |
|
| detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
(unsigned char)0); | | detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
(UInt8)0); | |
| else if(pixeltype == "INT16") | | else if(pixeltype == "INT16") | |
|
| detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
short()); | | detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
Int16()); | |
| else if(pixeltype == "INT32") | | else if(pixeltype == "INT32") | |
|
| detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
int()); | | detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
Int32()); | |
| else if(pixeltype == "FLOAT") | | else if(pixeltype == "FLOAT") | |
| detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
float()); | | detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
float()); | |
| else if(pixeltype == "DOUBLE") | | else if(pixeltype == "DOUBLE") | |
| detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
double()); | | detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
double()); | |
| enc->close(); | | enc->close(); | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* exportImage */ | | /* exportImage */ | |
| | | | |
End of changes. 16 change blocks. |
| 21 lines changed or deleted | | 37 lines changed or added | |
|
| localminmax.hxx | | localminmax.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_LOCALMINMAX_HXX | | #ifndef VIGRA_LOCALMINMAX_HXX | |
| #define VIGRA_LOCALMINMAX_HXX | | #define VIGRA_LOCALMINMAX_HXX | |
| | | | |
| #include <vector> | | #include <vector> | |
|
| | | #include <functional> | |
| #include "vigra/utilities.hxx" | | #include "vigra/utilities.hxx" | |
| #include "vigra/stdimage.hxx" | | #include "vigra/stdimage.hxx" | |
| #include "vigra/initimage.hxx" | | #include "vigra/initimage.hxx" | |
| #include "vigra/labelimage.hxx" | | #include "vigra/labelimage.hxx" | |
|
| | | #include "vigra/pixelneighborhood.hxx" | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| /** \addtogroup LocalMinMax Local Minima and Maxima | | /** \addtogroup LocalMinMax Local Minima and Maxima | |
| | | | |
| Detect local minima and maxima of the gray level, | | Detect local minima and maxima of the gray level, | |
| including extremal plateaus larger than 1 pixel | | including extremal plateaus larger than 1 pixel | |
| */ | | */ | |
| //@{ | | //@{ | |
| | | | |
|
| | | namespace detail { | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class DestValue, class Neighborhood, | |
| | | class Compare> | |
| | | void | |
| | | localMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, | |
| | | DestValue marker, Neighborhood neighborhood, | |
| | | Compare compare) | |
| | | { | |
| | | int w = slr.x - sul.x - 2; | |
| | | int h = slr.y - sul.y - 2; | |
| | | | |
| | | int i,x,y; | |
| | | | |
| | | sul += Diff2D(1,1); | |
| | | dul += Diff2D(1,1); | |
| | | | |
| | | for(y=0; y<h; ++y, ++sul.y, ++dul.y) | |
| | | { | |
| | | SrcIterator sx = sul; | |
| | | DestIterator dx = dul; | |
| | | | |
| | | for(x=0; x<w; ++x, ++sx.x, ++dx.x) | |
| | | { | |
| | | typename SrcAccessor::value_type v = sa(sx); | |
| | | NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx); | |
| | | for(i = 0; i < Neighborhood::DirectionCount; ++i, ++sc) | |
| | | { | |
| | | if(!compare(v, sa(sc))) | |
| | | break; | |
| | | } | |
| | | | |
| | | if(i == Neighborhood::DirectionCount) | |
| | | da.set(marker, dx); | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | } // namespace detail | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* localMinima */ | | /* localMinima */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Find local minima in an image. | | /** \brief Find local minima in an image. | |
| | | | |
| The minima are found only when the have a size of one pixel. | | The minima are found only when the have a size of one pixel. | |
| Use \ref extendedLocalMinima() to find minimal plateaus. Minima are | | Use \ref extendedLocalMinima() to find minimal plateaus. Minima are | |
| marked in the destination image with the given marker value | | marked in the destination image with the given marker value | |
| (default is 1), all other destination pixels remain unchanged. | | (default is 1), all other destination pixels remain unchanged. | |
| <TT>SrcAccessor::value_type</TT> must be less-comparable. | | <TT>SrcAccessor::value_type</TT> must be less-comparable. | |
| A pixel at the image border will never be marked as minimum. | | A pixel at the image border will never be marked as minimum. | |
|
| | | Pass \ref vigra::EightNeighborCode or \ref vigra::FourNeighborCode | |
| | | to determine the neighborhood where pixel values are compared. | |
| The function uses accessors. | | The function uses accessors. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode> | |
| void | | void | |
| localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
|
| DestIterator dul, DestAccessor da, | | DestIterator dul, DestAccessor da, | |
| DestValue marker = NumericTraits<DestValue>::one()) | | DestValue marker = NumericTraits<DestValue>::one(), | |
| | | Neighborhood neighborhood = EightNeighborCode()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode> | |
| void | | void | |
| localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| DestValue marker = NumericTraits<DestValue>::one()) | | DestValue marker = NumericTraits<DestValue>::one(), | |
| | | Neighborhood neighborhood = EightNeighborCode()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | | <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| vigra::BImage src(w,h), minima(w,h); | | vigra::BImage src(w,h), minima(w,h); | |
| | | | |
| skipping to change at line 118 | | skipping to change at line 184 | |
| SrcAccessor::value_type u = src_accessor(src_upperleft); | | SrcAccessor::value_type u = src_accessor(src_upperleft); | |
| | | | |
| u < u | | u < u | |
| | | | |
| DestValue marker; | | DestValue marker; | |
| dest_accessor.set(marker, dest_upperleft); | | dest_accessor.set(marker, dest_upperleft); | |
| \endcode | | \endcode | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, | |
| void | | class DestValue, class Neighborhood> | |
| | | inline void | |
| localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
|
| DestIterator dul, DestAccessor da, DestValue marker) | | DestIterator dul, DestAccessor da, | |
| | | DestValue marker, Neighborhood neighborhood) | |
| { | | { | |
|
| int w = slr.x - sul.x - 2; | | detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, | |
| int h = slr.y - sul.y - 2; | | std::less<typename SrcAccessor::value_type>()); | |
| | | } | |
| static const Diff2D dist[] = { | | | |
| Diff2D( 1, 0), Diff2D( 1, -1), Diff2D( 0, -1), Diff2D( -1, -1), | | | |
| Diff2D( -1, 0), Diff2D( -1, 1), Diff2D( 0, 1), Diff2D( 1, 1)}; | | | |
| | | | |
| int i,x,y; | | | |
| | | | |
| sul += Diff2D(1,1); | | | |
| dul += Diff2D(1,1); | | | |
| | | | |
| for(y=0; y<h; ++y, ++sul.y, ++dul.y) | | | |
| { | | | |
| SrcIterator sx = sul; | | | |
| DestIterator dx = dul; | | | |
| | | | |
| for(x=0; x<w; ++x, ++sx.x, ++dx.x) | | | |
| { | | | |
| for(i=0; i<8; ++i) | | | |
| { | | | |
| if(!(sa(sx) < sa(sx, dist[i]))) break; | | | |
| } | | | |
| | | | |
|
| if(i == 8) da.set(marker, dx); | | template <class SrcIterator, class SrcAccessor, | |
| } | | class DestIterator, class DestAccessor, class DestValue> | |
| } | | inline void | |
| | | localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, | |
| | | DestValue marker) | |
| | | { | |
| | | localMinima(sul, slr, sa, dul, da, marker, EightNeighborCode()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| DestIterator dul, DestAccessor da) | | DestIterator dul, DestAccessor da) | |
| { | | { | |
| localMinima(sul, slr, sa, dul, da, | | localMinima(sul, slr, sa, dul, da, | |
|
| NumericTraits<typename DestAccessor::value_type>::one()); | | NumericTraits<typename DestAccessor::value_type>::one(), | |
| | | EightNeighborCode()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class DestValue, class Neighborhood> | |
| | | inline void | |
| | | localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | DestValue marker, Neighborhood neighborhood) | |
| | | { | |
| | | localMinima(src.first, src.second, src.third, | |
| | | dest.first, dest.second, marker, neighborhood); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, class DestValue> | |
| inline void | | inline void | |
| localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
|
| DestValue marker) | | DestValue marker) | |
| { | | { | |
| localMinima(src.first, src.second, src.third, | | localMinima(src.first, src.second, src.third, | |
|
| dest.first, dest.second, marker); | | dest.first, dest.second, marker, EightNeighborCode()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest) | | pair<DestIterator, DestAccessor> dest) | |
| { | | { | |
| localMinima(src.first, src.second, src.third, | | localMinima(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
|
| NumericTraits<typename DestAccessor::value_type>::one()); | | NumericTraits<typename DestAccessor::value_type>::one(), | |
| | | EightNeighborCode()); | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* localMaxima */ | | /* localMaxima */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Find local maxima in an image. | | /** \brief Find local maxima in an image. | |
| | | | |
| | | | |
| skipping to change at line 206 | | skipping to change at line 273 | |
| <TT>SrcAccessor::value_type</TT> must be less-comparable. | | <TT>SrcAccessor::value_type</TT> must be less-comparable. | |
| A pixel at the image border will never be marked as maximum. | | A pixel at the image border will never be marked as maximum. | |
| The function uses accessors. | | The function uses accessors. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode> | |
| void | | void | |
| localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
|
| DestIterator dul, DestAccessor da, | | DestIterator dul, DestAccessor da, | |
| DestValue marker = NumericTraits<DestValue>::one()) | | DestValue marker = NumericTraits<DestValue>::one(), | |
| | | Neighborhood neighborhood = EightNeighborCode()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode> | |
| void | | void | |
| localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| DestValue marker = NumericTraits<DestValue>::one()) | | DestValue marker = NumericTraits<DestValue>::one(), | |
| | | Neighborhood neighborhood = EightNeighborCode()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | | <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
| vigra::BImage src(w,h), maxima(w,h); | | vigra::BImage src(w,h), maxima(w,h); | |
| | | | |
| skipping to change at line 261 | | skipping to change at line 332 | |
| SrcAccessor::value_type u = src_accessor(src_upperleft); | | SrcAccessor::value_type u = src_accessor(src_upperleft); | |
| | | | |
| u < u | | u < u | |
| | | | |
| DestValue marker; | | DestValue marker; | |
| dest_accessor.set(marker, dest_upperleft); | | dest_accessor.set(marker, dest_upperleft); | |
| \endcode | | \endcode | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, | |
| void | | class DestValue, class Neighborhood> | |
| | | inline void | |
| localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
|
| DestIterator dul, DestAccessor da, DestValue marker) | | DestIterator dul, DestAccessor da, | |
| | | DestValue marker, Neighborhood neighborhood) | |
| { | | { | |
|
| int w = slr.x - sul.x - 2; | | detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, | |
| int h = slr.y - sul.y - 2; | | std::greater<typename SrcAccessor::value_type>()); | |
| | | } | |
| static const Diff2D dist[] = { | | | |
| Diff2D( 1, 0), Diff2D( 1, -1), Diff2D( 0, -1), Diff2D( -1, -1), | | | |
| Diff2D( -1, 0), Diff2D( -1, 1), Diff2D( 0, 1), Diff2D( 1, 1)}; | | | |
| | | | |
| int i,x,y; | | | |
| | | | |
| sul += Diff2D(1,1); | | | |
| dul += Diff2D(1,1); | | | |
| | | | |
| for(y=0; y<h; ++y, ++sul.y, ++dul.y) | | | |
| { | | | |
| SrcIterator sx = sul; | | | |
| DestIterator dx = dul; | | | |
| | | | |
| for(x=0; x<w; ++x, ++sx.x, ++dx.x) | | | |
| { | | | |
| for(i=0; i<8; ++i) | | | |
| { | | | |
| if(!(sa(sx, dist[i]) < sa(sx))) break; | | | |
| } | | | |
| | | | |
|
| if(i == 8) da.set(marker, dx); | | template <class SrcIterator, class SrcAccessor, | |
| } | | class DestIterator, class DestAccessor, class DestValue> | |
| } | | inline void | |
| | | localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, | |
| | | DestValue marker) | |
| | | { | |
| | | localMaxima(sul, slr, sa, dul, da, marker, EightNeighborCode()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| DestIterator dul, DestAccessor da) | | DestIterator dul, DestAccessor da) | |
| { | | { | |
| localMaxima(sul, slr, sa, dul, da, | | localMaxima(sul, slr, sa, dul, da, | |
|
| NumericTraits<typename DestAccessor::value_type>::one()); | | NumericTraits<typename DestAccessor::value_type>::one(), | |
| | | EightNeighborCode()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, | |
| | | class DestValue, class Neighborhood> | |
| | | inline void | |
| | | localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | DestValue marker, Neighborhood neighborhood) | |
| | | { | |
| | | localMaxima(src.first, src.second, src.third, | |
| | | dest.first, dest.second, marker, neighborhood); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, class DestValue> | |
| inline void | | inline void | |
| localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
|
| DestValue marker) | | DestValue marker) | |
| { | | { | |
| localMaxima(src.first, src.second, src.third, | | localMaxima(src.first, src.second, src.third, | |
|
| dest.first, dest.second, marker); | | dest.first, dest.second, marker, EightNeighborCode()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest) | | pair<DestIterator, DestAccessor> dest) | |
| { | | { | |
| localMaxima(src.first, src.second, src.third, | | localMaxima(src.first, src.second, src.third, | |
| dest.first, dest.second, | | dest.first, dest.second, | |
|
| NumericTraits<typename DestAccessor::value_type>::one()); | | NumericTraits<typename DestAccessor::value_type>::one(), | |
| | | EightNeighborCode()); | |
| } | | } | |
| | | | |
|
| | | namespace detail { | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, class DestValue, | |
| | | class Neighborhood, class Compare, class Equal> | |
| | | void | |
| | | extendedLocalMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, DestValue marker, | |
| | | Neighborhood neighborhood, Compare compare, Equal equal) | |
| | | { | |
| | | typedef typename SrcAccessor::value_type SrcType; | |
| | | | |
| | | int w = slr.x - sul.x; | |
| | | int h = slr.y - sul.y; | |
| | | | |
| | | int i,x,y; | |
| | | | |
| | | BasicImage<int> labels(w,h); | |
| | | | |
| | | int number_of_regions = | |
| | | labelImage(sul, slr, sa, labels.upperLeft(), labels.accessor(), | |
| | | (Neighborhood::DirectionCount == 8), equal); | |
| | | | |
| | | // assume that a region is a extremum until the opposite is proved | |
| | | std::vector<unsigned char> isExtremum(number_of_regions+1, 1); | |
| | | | |
| | | BasicImage<int>::traverser ly = labels.upperLeft(); | |
| | | | |
| | | for(y=0; y<h; ++y, ++sul.y, ++ly.y) | |
| | | { | |
| | | SrcIterator sx = sul; | |
| | | BasicImage<int>::traverser lx(ly); | |
| | | | |
| | | for(x=0; x<w; ++x, ++sx.x, ++lx.x) | |
| | | { | |
| | | int lab = *lx; | |
| | | if(x == 0 || y == 0 || x == w-1 || y == h-1) | |
| | | { | |
| | | // mark all regions that touch the image border as non-extr | |
| | | emum | |
| | | isExtremum[lab] = 0; | |
| | | continue; | |
| | | } | |
| | | | |
| | | SrcType v = sa(sx); | |
| | | NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx); | |
| | | NeighborhoodCirculator<BasicImage<int>::traverser, Neighborhood | |
| | | > lc(lx); | |
| | | for(i=0; i<Neighborhood::DirectionCount; ++i, ++sc, ++lc) | |
| | | { | |
| | | if(lab != *lc && compare(sa(sc),v)) | |
| | | isExtremum[lab] = 0; | |
| | | } | |
| | | | |
| | | } | |
| | | } | |
| | | | |
| | | ly = labels.upperLeft(); | |
| | | for(y=0; y<h; ++y, ++dul.y, ++ly.y) | |
| | | { | |
| | | DestIterator xd = dul; | |
| | | BasicImage<int>::Iterator lx(ly); | |
| | | | |
| | | for(x=0; x<w; ++x, ++xd.x, ++lx.x) | |
| | | { | |
| | | if(isExtremum[*lx]) | |
| | | da.set(marker, xd); | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | } // namespace detail | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* extendedLocalMinima */ | | /* extendedLocalMinima */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Find local minimal regions in an image. | | /** \brief Find local minimal regions in an image. | |
| | | | |
| This function finds regions of uniform pixel value | | This function finds regions of uniform pixel value | |
|
| whose neighboring regions are all have larger values | | whose neighboring regions are all have smaller values | |
| (minimal plateaus of arbitrary size). Minimal regions are | | (minimal plateaus of arbitrary size). By default, the pixels | |
| | | in a plateau have exactly identical values. By passing an <tt>EqualityF | |
| | | unctor</tt> | |
| | | with tolerance, one can allow for plateaus that are not quite constant | |
| | | (this is often necessary with float pixel values). Pass | |
| | | \ref vigra::EightNeighborCode or \ref vigra::FourNeighborCode | |
| | | to determine the neighborhood where pixel values are compared. | |
| | | | |
| | | Minimal regions are | |
| marked in the destination image with the given marker value | | marked in the destination image with the given marker value | |
| (default is 1), all other destination pixels remain unchanged. | | (default is 1), all other destination pixels remain unchanged. | |
| <TT>SrcAccessor::value_type</TT> must be equality-comparable and | | <TT>SrcAccessor::value_type</TT> must be equality-comparable and | |
| less-comparable. | | less-comparable. | |
|
| A pixel at the image border will never be marked as minimum or | | A pixel or region touching the image border will never be marked as min
imum or | |
| minimal plateau. | | minimal plateau. | |
| The function uses accessors. | | The function uses accessors. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode, | |
| | | class EqualityFunctor = std::equal_to<typename SrcAssesso | |
| | | r::value_type> > | |
| void | | void | |
| extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor s
a, | | extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor s
a, | |
|
| DestIterator dul, DestAccessor da, | | DestIterator dul, DestAccessor da, | |
| DestValue marker = NumericTraits<DestValue>::one | | DestValue marker = NumericTraits<DestValue>::on | |
| ()) | | e(), | |
| | | Neighborhood neighborhood = EightNeighborCode() | |
| | | , | |
| | | EqualityFunctor equal = EqualityFunctor()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode, | |
| | | class EqualityFunctor = std::equal_to<typename SrcAssesso | |
| | | r::value_type> > | |
| void | | void | |
| extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> s
rc, | | extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> s
rc, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| DestValue marker = NumericTraits<DestValue>::one | | DestValue marker = NumericTraits<DestValue>::on | |
| ()) | | e(), | |
| | | Neighborhood neighborhood = EightNeighborCode() | |
| | | , | |
| | | EqualityFunctor equal = EqualityFunctor()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | | <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
|
| | | | |
| | | // optional: define an equality functor | |
| | | template <class T> | |
| | | struct EqualWithToleranceFunctor | |
| | | { | |
| | | EqualWithToleranceFunctor(T tolerance) | |
| | | : t(tolerance) | |
| | | {} | |
| | | | |
| | | bool operator()(T l, T r) const | |
| | | { | |
| | | return vigra::abs(l-r) <= t; | |
| | | } | |
| | | | |
| | | T t; | |
| | | }; | |
| | | | |
| vigra::BImage src(w,h), minima(w,h); | | vigra::BImage src(w,h), minima(w,h); | |
| | | | |
| // init destiniation image | | // init destiniation image | |
|
| minima = 0; | | minima.init(0); | |
| | | | |
| vigra::extendedLocalMinima(srcImageRange(src), destImage(minima)); | | vigra::extendedLocalMinima(srcImageRange(src), destImage(minima)); | |
|
| | | | |
| | | // allow plateaus with tolerance | |
| | | minima.init(0); | |
| | | vigra::extendedLocalMinima(srcImageRange(src), destImage(minima), 1.0, | |
| | | EqualWithToleranceFunctor<unsigned char>(1)) | |
| | | ; | |
| \endcode | | \endcode | |
| | | | |
| <b> Required Interface:</b> | | <b> Required Interface:</b> | |
| | | | |
| \code | | \code | |
| SrcImageIterator src_upperleft, src_lowerright; | | SrcImageIterator src_upperleft, src_lowerright; | |
| DestImageIterator dest_upperleft; | | DestImageIterator dest_upperleft; | |
| | | | |
| SrcAccessor src_accessor; | | SrcAccessor src_accessor; | |
| DestAccessor dest_accessor; | | DestAccessor dest_accessor; | |
| | | | |
| SrcAccessor::value_type u = src_accessor(src_upperleft); | | SrcAccessor::value_type u = src_accessor(src_upperleft); | |
| | | | |
|
| | | EqualityFunctor equal; | |
| u == u | | u == u | |
|
| | | equal(u, u); | |
| u < u | | u < u | |
| | | | |
| DestValue marker; | | DestValue marker; | |
| dest_accessor.set(marker, dest_upperleft); | | dest_accessor.set(marker, dest_upperleft); | |
| \endcode | | \endcode | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, class DestValue, | |
| void | | class Neighborhood, class EqualityFunctor> | |
| | | inline void | |
| extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
|
| DestIterator dul, DestAccessor da, DestValue marker) | | DestIterator dul, DestAccessor da, DestValue marker, | |
| | | Neighborhood neighborhood, EqualityFunctor equal) | |
| { | | { | |
|
| int w = slr.x - sul.x; | | typedef typename SrcAccessor::value_type SrcType; | |
| int h = slr.y - sul.y; | | | |
| | | | |
| static const Diff2D dist[] = { | | | |
| Diff2D( 1, 0), Diff2D( 1, -1), Diff2D( 0, -1), Diff2D( -1, -1), | | | |
| Diff2D( -1, 0), Diff2D( -1, 1), Diff2D( 0, 1), Diff2D( 1, 1), | | | |
| Diff2D( 1, 0), Diff2D( 1, -1), Diff2D( 0, -1), Diff2D( -1, -1)}; | | | |
| | | | |
| int i,x,y; | | | |
| | | | |
| BasicImage<int> labels(w,h); | | | |
| | | | |
| labels = 0; | | | |
| | | | |
| int number_of_regions = | | | |
| labelImage(sul, slr, sa, labels.upperLeft(), labels.accessor(), tru | | | |
| e); | | | |
| | | | |
| std::vector<unsigned char> processed(number_of_regions+1, (unsigned cha | | | |
| r)0); | | | |
| | | | |
| SrcIterator ys = sul + Diff2D(1,1); | | | |
| BasicImage<int>::Iterator lul = labels.upperLeft(); | | | |
| BasicImage<int>::Iterator ly = lul + Diff2D(1,1); | | | |
| | | | |
| initImage(lul, lul+Diff2D(1,h), labels.accessor(), 0); | | | |
| | | | |
| for(y=1; y<h-1; ++y, ++ys.y, ++ly.y) | | | |
| { | | | |
| SrcIterator sx = ys; | | | |
| BasicImage<int>::Iterator lx(ly); | | | |
| | | | |
| for(x=1; x<w-1; ++x, ++sx.x, ++lx.x) | | | |
| { | | | |
| int lab = *lx; | | | |
| typename SrcAccessor::value_type v = sa(sx); | | | |
| | | | |
| if(processed[lab]) continue; | | | |
| | | | |
| processed[lab] = 1; // assume minimum until opposite is proved | | | |
| | | | |
| int is_plateau = 0; | | | |
| | | | |
| for(i=11; i>3; --i) | | | |
| { | | | |
| if(lx[dist[i]] == lab) | | | |
| { | | | |
| is_plateau = i; | | | |
| } | | | |
| else if(sa(sx, dist[i]) < v) | | | |
| { | | | |
| break; | | | |
| } | | | |
| } | | | |
| | | | |
| if(i > 3) | | | |
| { | | | |
| processed[lab] = 2; // not a minimum | | | |
| continue; | | | |
| } | | | |
| | | | |
| if(!is_plateau) continue; // is a minimum | | | |
| | | | |
| if((x == 1) && (is_plateau == 4) && | | | |
| (lx[dist[3]] == lab)) is_plateau = 3; | | | |
| | | | |
| // is a plateau - do contour-following | | | |
| int xa = x; | | | |
| int ya = y; | | | |
| int first_dir = is_plateau & 7; | | | |
| int dir = first_dir; | | | |
| int xc = xa; | | | |
| int yc = ya; | | | |
| | | | |
| do | | | |
| { | | | |
| xc = xc + dist[dir].x; | | | |
| yc = yc + dist[dir].y; | | | |
| | | | |
| dir = (dir + 6) & 7; | | | |
| | | | |
| for (; true; dir = (dir + 1) & 7) | | | |
| { | | | |
| int xn = xc + dist[dir].x; | | | |
| int yn = yc + dist[dir].y; | | | |
| Diff2D dn(xn, yn); | | | |
| | | | |
|
| if((xn >= 0) && (xn < w) && (yn >= 0) && (yn < h)) | | detail::extendedLocalMinMax(sul, slr, sa, dul, da, | |
| { | | marker, neighborhood, | |
| if(lul[dn] == lab) break; | | std::less<SrcType>(), equal); | |
| | | } | |
| | | | |
|
| if(dir & 1) continue; | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, class DestValue, | |
| | | class Neighborhood> | |
| | | inline void | |
| | | extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, DestValue marker, | |
| | | Neighborhood neighborhood) | |
| | | { | |
| | | typedef typename SrcAccessor::value_type SrcType; | |
| | | | |
|
| if(sa(sul, dn) < v) | | extendedLocalMinima(sul, slr, sa, dul, da, | |
| { | | marker, neighborhood, std::equal_to<SrcType>()); | |
| processed[lab] = 2; // current region not a mini | | } | |
| mum | | | |
| } | | | |
| else | | | |
| { | | | |
| processed[lul[dn]] = 2; // other region not | | | |
| // a minimum | | | |
| } | | | |
| } | | | |
| } | | | |
| } | | | |
| while((xc != xa) || (yc != ya) || (dir != first_dir)); | | | |
| } | | | |
| } | | | |
| | | | |
|
| for(y=0; y<h; ++y, ++dul.y, ++lul.y) | | template <class SrcIterator, class SrcAccessor, | |
| { | | class DestIterator, class DestAccessor, class DestValue> | |
| DestIterator xd = dul; | | inline void | |
| BasicImage<int>::Iterator lx(lul); | | extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, DestValue marker) | |
| | | { | |
| | | typedef typename SrcAccessor::value_type SrcType; | |
| | | | |
|
| for(x=0; x<w; ++x, ++xd.x, ++lx.x) | | extendedLocalMinima(sul, slr, sa, dul, da, | |
| { | | marker, EightNeighborCode()); | |
| if(processed[*lx] == 1) da.set(marker, xd); | | | |
| } | | | |
| } | | | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| DestIterator dul, DestAccessor da) | | DestIterator dul, DestAccessor da) | |
| { | | { | |
| extendedLocalMinima(sul, slr, sa, dul, da, | | extendedLocalMinima(sul, slr, sa, dul, da, | |
| NumericTraits<typename DestAccessor::value_type>::one()); | | NumericTraits<typename DestAccessor::value_type>::one()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| | | class DestIterator, class DestAccessor, class DestValue, | |
| | | class Neighborhood, class EqualityFunctor> | |
| | | inline void | |
| | | extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | DestValue marker, Neighborhood neighborhood, | |
| | | EqualityFunctor equal) | |
| | | { | |
| | | extendedLocalMinima(src.first, src.second, src.third, | |
| | | dest.first, dest.second, marker, neighborhood, equal); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, class DestValue, | |
| | | class Neighborhood> | |
| | | inline void | |
| | | extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | DestValue marker, Neighborhood neighborhood) | |
| | | { | |
| | | extendedLocalMinima(src.first, src.second, src.third, | |
| | | dest.first, dest.second, marker, neighborhood); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, class DestValue> | |
| inline void | | inline void | |
| extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
|
| DestValue marker) | | DestValue marker) | |
| { | | { | |
| extendedLocalMinima(src.first, src.second, src.third, | | extendedLocalMinima(src.first, src.second, src.third, | |
|
| dest.first, dest.second, marker); | | dest.first, dest.second, marker); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest) | | pair<DestIterator, DestAccessor> dest) | |
| { | | { | |
| extendedLocalMinima(src.first, src.second, src.third, | | extendedLocalMinima(src.first, src.second, src.third, | |
|
| dest.first, dest.second, | | dest.first, dest.second); | |
| NumericTraits<typename DestAccessor::value_type>::one()); | | | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* extendedLocalMaxima */ | | /* extendedLocalMaxima */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Find local maximal regions in an image. | | /** \brief Find local maximal regions in an image. | |
| | | | |
| This function finds regions of uniform pixel value | | This function finds regions of uniform pixel value | |
| whose neighboring regions are all have smaller values | | whose neighboring regions are all have smaller values | |
|
| (maximal plateaus of arbitrary size). Maximal regions are | | (maximal plateaus of arbitrary size). By default, the pixels | |
| | | in a plateau have exactly identical values. By passing an <tt>EqualityF | |
| | | unctor</tt> | |
| | | with tolerance, one can allow for plateaus that are not quite constant | |
| | | (this is often necessary with float pixel values). Pass | |
| | | \ref vigra::EightNeighborCode or \ref vigra::FourNeighborCode | |
| | | to determine the neighborhood where pixel values are compared. | |
| | | | |
| | | Maximal regions are | |
| marked in the destination image with the given marker value | | marked in the destination image with the given marker value | |
| (default is 1), all other destination pixels remain unchanged. | | (default is 1), all other destination pixels remain unchanged. | |
| <TT>SrcAccessor::value_type</TT> must be equality-comparable and | | <TT>SrcAccessor::value_type</TT> must be equality-comparable and | |
| less-comparable. | | less-comparable. | |
|
| A pixel at the image border will never be marked as maximum or | | A pixel or region touching the image border will never be marked as max
imum or | |
| maximal plateau. | | maximal plateau. | |
| The function uses accessors. | | The function uses accessors. | |
| | | | |
| <b> Declarations:</b> | | <b> Declarations:</b> | |
| | | | |
| pass arguments explicitly: | | pass arguments explicitly: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode, | |
| | | class EqualityFunctor = std::equal_to<typename SrcAssesso | |
| | | r::value_type> > | |
| void | | void | |
| extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor s
a, | | extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor s
a, | |
|
| DestIterator dul, DestAccessor da, | | DestIterator dul, DestAccessor da, | |
| DestValue marker = NumericTraits<DestValue>::one | | DestValue marker = NumericTraits<DestValue>::on | |
| ()) | | e(), | |
| | | Neighborhood neighborhood = EightNeighborCode() | |
| | | , | |
| | | EqualityFunctor equal = EqualityFunctor()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| use argument objects in conjunction with \ref ArgumentObjectFactories: | | use argument objects in conjunction with \ref ArgumentObjectFactories: | |
| \code | | \code | |
| namespace vigra { | | namespace vigra { | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class DestValue = DestAccessor::value_type> | | class DestValue = DestAccessor::value_type, | |
| | | class Neighborhood = EightNeighborCode, | |
| | | class EqualityFunctor = std::equal_to<typename SrcAssesso | |
| | | r::value_type> > | |
| void | | void | |
| extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> s
rc, | | extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> s
rc, | |
|
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
| DestValue marker = NumericTraits<DestValue>::one | | DestValue marker = NumericTraits<DestValue>::on | |
| ()) | | e(), | |
| | | Neighborhood neighborhood = EightNeighborCode() | |
| | | , | |
| | | EqualityFunctor equal = EqualityFunctor()) | |
| } | | } | |
| \endcode | | \endcode | |
| | | | |
| <b> Usage:</b> | | <b> Usage:</b> | |
| | | | |
| <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | | <b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca
lminmax.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| \code | | \code | |
|
| | | | |
| | | // optional: define an equality functor | |
| | | template <class T> | |
| | | struct EqualWithToleranceFunctor | |
| | | { | |
| | | EqualWithToleranceFunctor(T tolerance) | |
| | | : t(tolerance) | |
| | | {} | |
| | | | |
| | | bool operator()(T l, T r) const | |
| | | { | |
| | | return vigra::abs(l-r) <= t; | |
| | | } | |
| | | | |
| | | T t; | |
| | | }; | |
| | | | |
| vigra::BImage src(w,h), maxima(w,h); | | vigra::BImage src(w,h), maxima(w,h); | |
| | | | |
| // init destiniation image | | // init destiniation image | |
|
| maxima = 0; | | maxima.init(0); | |
| | | | |
| vigra::extendedLocalMaxima(srcImageRange(src), destImage(maxima)); | | vigra::extendedLocalMaxima(srcImageRange(src), destImage(maxima)); | |
|
| | | | |
| | | // allow plateaus with tolerance | |
| | | maxima.init(0); | |
| | | vigra::extendedLocalMaxima(srcImageRange(src), destImage(maxima), 1.0, | |
| | | EqualWithToleranceFunctor<unsigned char>(1)) | |
| | | ; | |
| \endcode | | \endcode | |
| | | | |
| <b> Required Interface:</b> | | <b> Required Interface:</b> | |
| | | | |
| \code | | \code | |
| SrcImageIterator src_upperleft, src_lowerright; | | SrcImageIterator src_upperleft, src_lowerright; | |
| DestImageIterator dest_upperleft; | | DestImageIterator dest_upperleft; | |
| | | | |
| SrcAccessor src_accessor; | | SrcAccessor src_accessor; | |
| DestAccessor dest_accessor; | | DestAccessor dest_accessor; | |
| | | | |
| SrcAccessor::value_type u = src_accessor(src_upperleft); | | SrcAccessor::value_type u = src_accessor(src_upperleft); | |
| | | | |
|
| | | EqualityFunctor equal; | |
| u == u | | u == u | |
|
| | | equal(u, u); | |
| u < u | | u < u | |
| | | | |
| DestValue marker; | | DestValue marker; | |
| dest_accessor.set(marker, dest_upperleft); | | dest_accessor.set(marker, dest_upperleft); | |
| \endcode | | \endcode | |
| | | | |
| */ | | */ | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, class DestValue, | |
| void | | class Neighborhood, class EqualityFunctor> | |
| | | inline void | |
| extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
|
| DestIterator dul, DestAccessor da, DestValue marker) | | DestIterator dul, DestAccessor da, DestValue marker, | |
| | | Neighborhood neighborhood, EqualityFunctor equal) | |
| { | | { | |
|
| int w = slr.x - sul.x; | | typedef typename SrcAccessor::value_type SrcType; | |
| int h = slr.y - sul.y; | | | |
| | | | |
| static const Diff2D dist[] = { | | | |
| Diff2D( 1, 0), Diff2D( 1, -1), Diff2D( 0, -1), Diff2D( -1, -1), | | | |
| Diff2D( -1, 0), Diff2D( -1, 1), Diff2D( 0, 1), Diff2D( 1, 1), | | | |
| Diff2D( 1, 0), Diff2D( 1, -1), Diff2D( 0, -1), Diff2D( -1, -1)}; | | | |
| | | | |
| int i,x,y; | | | |
| | | | |
| BasicImage<int> labels(w,h); | | | |
| | | | |
| int number_of_regions = | | | |
| labelImage(sul, slr, sa, labels.upperLeft(), labels.accessor(), tru | | | |
| e); | | | |
| | | | |
| std::vector<unsigned char> processed(number_of_regions+1, (unsigned cha | | | |
| r)0); | | | |
| | | | |
| SrcIterator ys = sul + Diff2D(1,1); | | | |
| BasicImage<int>::Iterator lul = labels.upperLeft(); | | | |
| BasicImage<int>::Iterator ly = lul + Diff2D(1,1); | | | |
| | | | |
| lul(0,1) = 0; | | | |
| | | | |
| for(y=1; y<h-1; ++y, ++ys.y, ++ly.y) | | | |
| { | | | |
| SrcIterator sx = ys; | | | |
| BasicImage<int>::Iterator lx(ly); | | | |
| | | | |
| for(x=1; x<w-1; ++x, ++sx.x, ++lx.x) | | | |
| { | | | |
| int lab = *lx; | | | |
| typename SrcAccessor::value_type v = sa(sx); | | | |
| | | | |
| if(processed[lab]) continue; | | | |
| | | | |
| processed[lab] = 1; // assume maximum until opposite is proved | | | |
| | | | |
| int is_plateau = 0; | | | |
| | | | |
| for(i=11; i>3; --i) | | | |
| { | | | |
| if(lx[dist[i]] == lab) | | | |
| { | | | |
| is_plateau = i; | | | |
| } | | | |
| else if(v < sa(sx, dist[i])) | | | |
| { | | | |
| break; | | | |
| } | | | |
| } | | | |
| | | | |
| if(i > 3) | | | |
| { | | | |
| processed[lab] = 2; // not a maximum | | | |
| continue; | | | |
| } | | | |
| | | | |
| if(!is_plateau) continue; // is a maximum | | | |
| | | | |
| if((x == 1) && (is_plateau == 4) && | | | |
| (lx[dist[3]] == lab)) is_plateau = 3; | | | |
| | | | |
| // is a plateau - do contour-following | | | |
| int xa = x; | | | |
| int ya = y; | | | |
| int first_dir = is_plateau & 7; | | | |
| int dir = first_dir; | | | |
| int xc = xa; | | | |
| int yc = ya; | | | |
| | | | |
| do | | | |
| { | | | |
| xc = xc + dist[dir].x; | | | |
| yc = yc + dist[dir].y; | | | |
| | | | |
| dir = (dir + 6) & 7; | | | |
| | | | |
| for (; true; dir = (dir + 1) & 7) | | | |
| { | | | |
| int xn = xc + dist[dir].x; | | | |
| int yn = yc + dist[dir].y; | | | |
| Diff2D dn(xn, yn); | | | |
| | | | |
|
| if((xn >= 0) && (xn < w) && (yn >= 0) && (yn < h)) | | detail::extendedLocalMinMax(sul, slr, sa, dul, da, | |
| { | | marker, neighborhood, | |
| if(lul[dn] == lab) break; | | std::greater<SrcType>(), equal); | |
| | | } | |
| | | | |
|
| if(dir & 1) continue; | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, class DestValue, | |
| | | class Neighborhood> | |
| | | inline void | |
| | | extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, DestValue marker, | |
| | | Neighborhood neighborhood) | |
| | | { | |
| | | typedef typename SrcAccessor::value_type SrcType; | |
| | | | |
|
| if(v < sa(sul, dn)) | | extendedLocalMaxima(sul, slr, sa, dul, da, | |
| { | | marker, neighborhood, std::equal_to<SrcType>()); | |
| processed[lab] = 2; // current region not a maxi | | } | |
| mum | | | |
| } | | | |
| else | | | |
| { | | | |
| processed[lul[dn]] = 2; // other region not | | | |
| // a maximum | | | |
| } | | | |
| } | | | |
| } | | | |
| } | | | |
| while((xc != xa) || (yc != ya) || (dir != first_dir)); | | | |
| } | | | |
| } | | | |
| | | | |
|
| for(y=0; y<h; ++y, ++dul.y, ++lul.y) | | template <class SrcIterator, class SrcAccessor, | |
| { | | class DestIterator, class DestAccessor, class DestValue> | |
| DestIterator xd = dul; | | inline void | |
| BasicImage<int>::Iterator lx(lul); | | extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| | | DestIterator dul, DestAccessor da, DestValue marker) | |
| | | { | |
| | | typedef typename SrcAccessor::value_type SrcType; | |
| | | | |
|
| for(x=0; x<w; ++x, ++xd.x, ++lx.x) | | extendedLocalMaxima(sul, slr, sa, dul, da, | |
| { | | marker, EightNeighborCode()); | |
| if(processed[*lx] == 1) da.set(marker, xd); | | | |
| } | | | |
| } | | | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | | extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, | |
| DestIterator dul, DestAccessor da) | | DestIterator dul, DestAccessor da) | |
| { | | { | |
| extendedLocalMaxima(sul, slr, sa, dul, da, | | extendedLocalMaxima(sul, slr, sa, dul, da, | |
| NumericTraits<typename DestAccessor::value_type>::one()); | | NumericTraits<typename DestAccessor::value_type>::one()); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
|
| | | class DestIterator, class DestAccessor, class DestValue, | |
| | | class Neighborhood, class EqualityFunctor> | |
| | | inline void | |
| | | extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | DestValue marker, Neighborhood neighborhood, | |
| | | EqualityFunctor equal) | |
| | | { | |
| | | extendedLocalMaxima(src.first, src.second, src.third, | |
| | | dest.first, dest.second, marker, neighborhood, equal); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| | | class DestIterator, class DestAccessor, class DestValue, | |
| | | class Neighborhood> | |
| | | inline void | |
| | | extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| | | pair<DestIterator, DestAccessor> dest, | |
| | | DestValue marker, Neighborhood neighborhood) | |
| | | { | |
| | | extendedLocalMaxima(src.first, src.second, src.third, | |
| | | dest.first, dest.second, marker, neighborhood); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, class DestValue> | | class DestIterator, class DestAccessor, class DestValue> | |
| inline void | | inline void | |
| extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest, | | pair<DestIterator, DestAccessor> dest, | |
|
| DestValue marker) | | DestValue marker) | |
| { | | { | |
| extendedLocalMaxima(src.first, src.second, src.third, | | extendedLocalMaxima(src.first, src.second, src.third, | |
|
| dest.first, dest.second, marker); | | dest.first, dest.second, marker); | |
| } | | } | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor> | | class DestIterator, class DestAccessor> | |
| inline void | | inline void | |
| extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | | extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, | |
| pair<DestIterator, DestAccessor> dest) | | pair<DestIterator, DestAccessor> dest) | |
| { | | { | |
| extendedLocalMaxima(src.first, src.second, src.third, | | extendedLocalMaxima(src.first, src.second, src.third, | |
|
| dest.first, dest.second, | | dest.first, dest.second); | |
| NumericTraits<typename DestAccessor::value_type>::one()); | | | |
| } | | } | |
| | | | |
| //@} | | //@} | |
| | | | |
| } // namespace vigra | | } // namespace vigra | |
| | | | |
| #endif // VIGRA_LOCALMINMAX_HXX | | #endif // VIGRA_LOCALMINMAX_HXX | |
| | | | |
End of changes. 78 change blocks. |
| 360 lines changed or deleted | | 471 lines changed or added | |
|
| mathutil.hxx | | mathutil.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2005 by Ullrich Koethe */ | | /* Copyright 1998-2005 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_MATHUTIL_HXX | | #ifndef VIGRA_MATHUTIL_HXX | |
| #define VIGRA_MATHUTIL_HXX | | #define VIGRA_MATHUTIL_HXX | |
| | | | |
| #include <cmath> | | #include <cmath> | |
| #include <cstdlib> | | #include <cstdlib> | |
| #include "vigra/config.hxx" | | #include "vigra/config.hxx" | |
|
| | | #include "vigra/sized_int.hxx" | |
| #include "vigra/numerictraits.hxx" | | #include "vigra/numerictraits.hxx" | |
| | | | |
| /*! \page MathConstants Mathematical Constants | | /*! \page MathConstants Mathematical Constants | |
| | | | |
| <TT>M_PI, M_SQRT2</TT> | | <TT>M_PI, M_SQRT2</TT> | |
| | | | |
| <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathutil.hx
x</a>" | | <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathutil.hx
x</a>" | |
| | | | |
| Since <TT>M_PI</TT> and <TT>M_SQRT2</TT> are not officially standardize
d, | | Since <TT>M_PI</TT> and <TT>M_SQRT2</TT> are not officially standardize
d, | |
| we provide definitions here for those compilers that don't support them
. | | we provide definitions here for those compilers that don't support them
. | |
| | | | |
| skipping to change at line 163 | | skipping to change at line 179 | |
| <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti
l.hxx</a>"<br> | | <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti
l.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| inline | | inline | |
| typename NumericTraits<T>::Promote sq(T t) | | typename NumericTraits<T>::Promote sq(T t) | |
| { | | { | |
| return t*t; | | return t*t; | |
| } | | } | |
| | | | |
|
| | | namespace detail { | |
| | | | |
| | | template <class T> | |
| | | class IntSquareRoot | |
| | | { | |
| | | public: | |
| | | static int sqq_table[]; | |
| | | static UInt32 exec(UInt32 v); | |
| | | }; | |
| | | | |
| | | template <class T> | |
| | | int IntSquareRoot<T>::sqq_table[] = { | |
| | | 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55 | |
| | | , 57, | |
| | | 59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81 | |
| | | , 83, | |
| | | 84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101 | |
| | | , 102, | |
| | | 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117 | |
| | | , 118, | |
| | | 119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131 | |
| | | , 132, | |
| | | 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144 | |
| | | , 145, | |
| | | 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156 | |
| | | , 157, | |
| | | 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167 | |
| | | , 168, | |
| | | 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178 | |
| | | , 178, | |
| | | 179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187 | |
| | | , 188, | |
| | | 189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197 | |
| | | , 197, | |
| | | 198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206 | |
| | | , 206, | |
| | | 207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214 | |
| | | , 215, | |
| | | 215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222 | |
| | | , 223, | |
| | | 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230 | |
| | | , 231, | |
| | | 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238 | |
| | | , 238, | |
| | | 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245 | |
| | | , 246, | |
| | | 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252 | |
| | | , 253, | |
| | | 253, 254, 254, 255 | |
| | | }; | |
| | | | |
| | | template <class T> | |
| | | UInt32 IntSquareRoot<T>::exec(UInt32 x) | |
| | | { | |
| | | unsigned long xn; | |
| | | if (x >= 0x10000) | |
| | | if (x >= 0x1000000) | |
| | | if (x >= 0x10000000) | |
| | | if (x >= 0x40000000) { | |
| | | if (x >= (UInt32)65535*(UInt32)65535) | |
| | | return 65535; | |
| | | xn = sqq_table[x>>24] << 8; | |
| | | } else | |
| | | xn = sqq_table[x>>22] << 7; | |
| | | else | |
| | | if (x >= 0x4000000) | |
| | | xn = sqq_table[x>>20] << 6; | |
| | | else | |
| | | xn = sqq_table[x>>18] << 5; | |
| | | else { | |
| | | if (x >= 0x100000) | |
| | | if (x >= 0x400000) | |
| | | xn = sqq_table[x>>16] << 4; | |
| | | else | |
| | | xn = sqq_table[x>>14] << 3; | |
| | | else | |
| | | if (x >= 0x40000) | |
| | | xn = sqq_table[x>>12] << 2; | |
| | | else | |
| | | xn = sqq_table[x>>10] << 1; | |
| | | | |
| | | goto nr1; | |
| | | } | |
| | | else | |
| | | if (x >= 0x100) { | |
| | | if (x >= 0x1000) | |
| | | if (x >= 0x4000) | |
| | | xn = (sqq_table[x>>8] >> 0) + 1; | |
| | | else | |
| | | xn = (sqq_table[x>>6] >> 1) + 1; | |
| | | else | |
| | | if (x >= 0x400) | |
| | | xn = (sqq_table[x>>4] >> 2) + 1; | |
| | | else | |
| | | xn = (sqq_table[x>>2] >> 3) + 1; | |
| | | | |
| | | goto adj; | |
| | | } else | |
| | | return sqq_table[x] >> 4; | |
| | | | |
| | | /* Run two iterations of the standard convergence formula */ | |
| | | | |
| | | xn = (xn + 1 + x / xn) / 2; | |
| | | nr1: | |
| | | xn = (xn + 1 + x / xn) / 2; | |
| | | adj: | |
| | | | |
| | | if (xn * xn > x) /* Correct rounding if necessary */ | |
| | | xn--; | |
| | | | |
| | | return xn; | |
| | | } | |
| | | | |
| | | } // namespace detail | |
| | | | |
| | | using VIGRA_CSTD::sqrt; | |
| | | | |
| | | /*! Signed integer square root. | |
| | | | |
| | | <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti | |
| | | l.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | inline Int32 sqrti(Int32 v) | |
| | | { | |
| | | if(v < 0) | |
| | | throw std::domain_error("sqrti(Int32): negative argument."); | |
| | | return (Int32)detail::IntSquareRoot<UInt32>::exec((UInt32)v); | |
| | | } | |
| | | | |
| | | /*! Unsigned integer square root. | |
| | | | |
| | | <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti | |
| | | l.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | inline UInt32 sqrti(UInt32 v) | |
| | | { | |
| | | return detail::IntSquareRoot<UInt32>::exec(v); | |
| | | } | |
| | | | |
| #ifdef VIGRA_NO_HYPOT | | #ifdef VIGRA_NO_HYPOT | |
| /*! Compute the Euclidean distance (length of the hypothenuse of a righ
t-angled triangle). | | /*! Compute the Euclidean distance (length of the hypothenuse of a righ
t-angled triangle). | |
| | | | |
| The hypot() function returns the sqrt(a*a + b*b). | | The hypot() function returns the sqrt(a*a + b*b). | |
| It is implemented in a way that minimizes round-off error. | | It is implemented in a way that minimizes round-off error. | |
| | | | |
| <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti
l.hxx</a>"<br> | | <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti
l.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| | | | |
| skipping to change at line 272 | | skipping to change at line 409 | |
| For scalar types: implemented as <tt>abs(t)</tt><br> | | For scalar types: implemented as <tt>abs(t)</tt><br> | |
| otherwise: implemented as <tt>sqrt(squaredNorm(t))</tt>. | | otherwise: implemented as <tt>sqrt(squaredNorm(t))</tt>. | |
| | | | |
| <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti
l.hxx</a>"<br> | | <b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti
l.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| template <class T> | | template <class T> | |
| inline typename NormTraits<T>::NormType | | inline typename NormTraits<T>::NormType | |
| norm(T const & t) | | norm(T const & t) | |
| { | | { | |
|
| return VIGRA_CSTD::sqrt(static_cast<typename NormTraits<T>::NormType>(s | | typedef typename NormTraits<T>::SquaredNormType SNT; | |
| quaredNorm(t))); | | return sqrt(static_cast<typename SquareRootTraits<SNT>::SquareRootArgum | |
| | | ent>(squaredNorm(t))); | |
| } | | } | |
| | | | |
| namespace detail { | | namespace detail { | |
| | | | |
| // both f1 and f2 are unsigned here | | // both f1 and f2 are unsigned here | |
| template<class FPT> | | template<class FPT> | |
| inline | | inline | |
| FPT safeFloatDivision( FPT f1, FPT f2 ) | | FPT safeFloatDivision( FPT f1, FPT f2 ) | |
| { | | { | |
| return f2 < NumericTraits<FPT>::one() && f1 > f2 * NumericTraits<FPT>:
:max() | | return f2 < NumericTraits<FPT>::one() && f1 > f2 * NumericTraits<FPT>:
:max() | |
| | | | |
End of changes. 6 change blocks. |
| 11 lines changed or deleted | | 169 lines changed or added | |
|
| multi_array.hxx | | multi_array.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 2003 by Gunnar Kedenburg */ | | /* Copyright 2003 by Gunnar Kedenburg */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* ( Version 1.3.0, Sep 10 2004 ) */ | | /* ( Version 1.3.0, Sep 10 2004 ) */ | |
|
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_MULTI_ARRAY_HXX | | #ifndef VIGRA_MULTI_ARRAY_HXX | |
| #define VIGRA_MULTI_ARRAY_HXX | | #define VIGRA_MULTI_ARRAY_HXX | |
| | | | |
| #include <memory> | | #include <memory> | |
| #include <algorithm> | | #include <algorithm> | |
| #include "vigra/accessor.hxx" | | #include "vigra/accessor.hxx" | |
| #include "vigra/tinyvector.hxx" | | #include "vigra/tinyvector.hxx" | |
| #include "vigra/rgbvalue.hxx" | | #include "vigra/rgbvalue.hxx" | |
| #include "vigra/basicimageview.hxx" | | #include "vigra/basicimageview.hxx" | |
| #include "vigra/imageiterator.hxx" | | #include "vigra/imageiterator.hxx" | |
| #include "vigra/numerictraits.hxx" | | #include "vigra/numerictraits.hxx" | |
| #include "vigra/multi_iterator.hxx" | | #include "vigra/multi_iterator.hxx" | |
| #include "vigra/metaprogramming.hxx" | | #include "vigra/metaprogramming.hxx" | |
|
| | | #include "vigra/mathutil.hxx" | |
| | | | |
| namespace vigra | | namespace vigra | |
| { | | { | |
| | | | |
| namespace detail | | namespace detail | |
| { | | { | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* defaultStride */ | | /* defaultStride */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /* generates the stride for a gapless shape. | | /* generates the stride for a gapless shape. | |
| | | | |
| Namespace: vigra::detail | | Namespace: vigra::detail | |
| */ | | */ | |
| template <unsigned int N> | | template <unsigned int N> | |
|
| TinyVector <int, N> defaultStride(const TinyVector <int, N> &shape) | | TinyVector <ptrdiff_t, N> defaultStride(const TinyVector <ptrdiff_t, N> &sh
ape) | |
| { | | { | |
|
| TinyVector <int, N> ret; | | TinyVector <ptrdiff_t, N> ret; | |
| ret [0] = 1; | | ret [0] = 1; | |
| for (unsigned int i = 1; i < N; ++i) | | for (unsigned int i = 1; i < N; ++i) | |
| ret [i] = ret [i-1] * shape [i-1]; | | ret [i] = ret [i-1] * shape [i-1]; | |
| return ret; | | return ret; | |
| } | | } | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* MaybeStrided */ | | /* MaybeStrided */ | |
| /* */ | | /* */ | |
| | | | |
| skipping to change at line 335 | | skipping to change at line 351 | |
| typedef const value_type &const_reference; | | typedef const value_type &const_reference; | |
| | | | |
| /** pointer type | | /** pointer type | |
| */ | | */ | |
| typedef value_type *pointer; | | typedef value_type *pointer; | |
| | | | |
| /** const pointer type | | /** const pointer type | |
| */ | | */ | |
| typedef const value_type *const_pointer; | | typedef const value_type *const_pointer; | |
| | | | |
|
| /** size type | | /** difference type (used for offsetting) | |
| */ | | */ | |
|
| typedef TinyVector <int, actual_dimension> size_type; | | typedef TinyVector <ptrdiff_t, actual_dimension> difference_type; | |
| | | | |
|
| /** difference type (used for offsetting) | | /** size type | |
| */ | | */ | |
|
| typedef TinyVector <int, actual_dimension> difference_type; | | typedef difference_type size_type; | |
| | | | |
| /** traverser (MultiIterator) type | | /** traverser (MultiIterator) type | |
| */ | | */ | |
| typedef typename detail::MultiIteratorChooser < | | typedef typename detail::MultiIteratorChooser < | |
| C>::template Traverser <actual_dimension, T, T &, T *>::type traver
ser; | | C>::template Traverser <actual_dimension, T, T &, T *>::type traver
ser; | |
| | | | |
| /** const traverser (MultiIterator) type | | /** const traverser (MultiIterator) type | |
| */ | | */ | |
| typedef typename detail::MultiIteratorChooser < | | typedef typename detail::MultiIteratorChooser < | |
| C>::template Traverser <actual_dimension, T, T const &, T const *>:
:type const_traverser; | | C>::template Traverser <actual_dimension, T, T const &, T const *>:
:type const_traverser; | |
| | | | |
| skipping to change at line 367 | | skipping to change at line 383 | |
| /** the matrix type associated with this array. | | /** the matrix type associated with this array. | |
| */ | | */ | |
| typedef MultiArray <N, T> matrix_type; | | typedef MultiArray <N, T> matrix_type; | |
| | | | |
| /** the squared norm type (return type of array.squaredNorm()). | | /** the squared norm type (return type of array.squaredNorm()). | |
| */ | | */ | |
| typedef typename NormTraits<T>::SquaredNormType SquaredNormType; | | typedef typename NormTraits<T>::SquaredNormType SquaredNormType; | |
| | | | |
| /** the norm type (return type of array.norm()). | | /** the norm type (return type of array.norm()). | |
| */ | | */ | |
|
| typedef typename NumericTraits<SquaredNormType>::RealPromote NormType; | | typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No
rmType; | |
| | | | |
| protected: | | protected: | |
| | | | |
|
| | | static const typename difference_type::value_type diff_zero = 0; | |
| | | | |
| /** the shape of the image pointed to is stored here. | | /** the shape of the image pointed to is stored here. | |
|
| */ | | */ | |
| difference_type m_shape; | | difference_type m_shape; | |
| | | | |
| /** the strides (offset of a sample to the next) for every dimensio
n | | /** the strides (offset of a sample to the next) for every dimensio
n | |
| are stored here. | | are stored here. | |
| */ | | */ | |
| difference_type m_stride; | | difference_type m_stride; | |
| | | | |
| /** pointer to the image. | | /** pointer to the image. | |
| */ | | */ | |
| pointer m_ptr; | | pointer m_ptr; | |
| | | | |
| public: | | public: | |
| | | | |
| /** default constructor: create an empty image of size 0. | | /** default constructor: create an empty image of size 0. | |
| */ | | */ | |
| MultiArrayView () | | MultiArrayView () | |
|
| : m_shape (0), m_stride (0), m_ptr (0) | | : m_shape (diff_zero), m_stride (diff_zero), m_ptr (0) | |
| {} | | {} | |
| | | | |
| /** construct from shape and pointer | | /** construct from shape and pointer | |
| */ | | */ | |
| MultiArrayView (const difference_type &shape, pointer ptr); | | MultiArrayView (const difference_type &shape, pointer ptr); | |
| | | | |
| /** construct from shape, strides (offset of a sample to the next) | | /** construct from shape, strides (offset of a sample to the next) | |
| for every dimension) and pointer | | for every dimension) and pointer | |
| */ | | */ | |
| MultiArrayView (const difference_type &shape, | | MultiArrayView (const difference_type &shape, | |
| | | | |
| skipping to change at line 502 | | skipping to change at line 520 | |
| /** Copy the data of the right-hand array (array shapes must match)
. | | /** Copy the data of the right-hand array (array shapes must match)
. | |
| */ | | */ | |
| template <class U, class CN> | | template <class U, class CN> | |
| void copy(const MultiArrayView <N, U, CN>& rhs); | | void copy(const MultiArrayView <N, U, CN>& rhs); | |
| | | | |
| /** bind the M outmost dimensions to certain indices. | | /** bind the M outmost dimensions to certain indices. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
| max { 1, N-M } | | max { 1, N-M } | |
| */ | | */ | |
| template <unsigned int M> | | template <unsigned int M> | |
|
| MultiArrayView <N-M, T, C> bindOuter (const TinyVector <int, M> &d) con
st; | | MultiArrayView <N-M, T, C> bindOuter (const TinyVector <ptrdiff_t, M> &
d) const; | |
| | | | |
| /** bind the M innermost dimensions to certain indices. | | /** bind the M innermost dimensions to certain indices. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
| max { 1, N-M } | | max { 1, N-M } | |
| */ | | */ | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-M, T, StridedArrayTag> | | MultiArrayView <N-M, T, StridedArrayTag> | |
|
| bindInner (const TinyVector <int, M> &d) const; | | bindInner (const TinyVector <ptrdiff_t, M> &d) const; | |
| | | | |
| /** bind dimension M to index d. | | /** bind dimension M to index d. | |
| this reduces the dimensionality of the image to | | this reduces the dimensionality of the image to | |
| max { 1, N-1 } | | max { 1, N-1 } | |
| */ | | */ | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | | MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | |
| bind (int d) const; | | bind (int d) const; | |
| | | | |
| /** bind the outmost dimension to a certain index. | | /** bind the outmost dimension to a certain index. | |
| | | | |
| skipping to change at line 618 | | skipping to change at line 636 | |
| return m_stride; | | return m_stride; | |
| } | | } | |
| | | | |
| /** return the array's stride at a certain dimension. | | /** return the array's stride at a certain dimension. | |
| */ | | */ | |
| int stride (int n) const | | int stride (int n) const | |
| { | | { | |
| return m_stride [n]; | | return m_stride [n]; | |
| } | | } | |
| | | | |
|
| | | /** check whether the given point is in the array range. | |
| | | */ | |
| | | bool isInside (difference_type const & p) const | |
| | | { | |
| | | for(int d=0; d<actual_dimension; ++d) | |
| | | if(p[d] < 0 || p[d] >= shape(d)) | |
| | | return false; | |
| | | return true; | |
| | | } | |
| | | | |
| /** return the squared norm of the array (sum of squares of the arr
ay elements). | | /** return the squared norm of the array (sum of squares of the arr
ay elements). | |
| */ | | */ | |
| SquaredNormType squaredNorm() const | | SquaredNormType squaredNorm() const | |
| { | | { | |
| SquaredNormType res = NumericTraits<SquaredNormType>::zero(); | | SquaredNormType res = NumericTraits<SquaredNormType>::zero(); | |
| detail::squaredNormOfMultiArray(traverser_begin(), shape(), res, Me
taInt<actual_dimension-1>()); | | detail::squaredNormOfMultiArray(traverser_begin(), shape(), res, Me
taInt<actual_dimension-1>()); | |
| return res; | | return res; | |
| } | | } | |
| | | | |
| /** return the norm of the array (equals <tt>sqrt(array.squaredNorm
())</tt>). | | /** return the norm of the array (equals <tt>sqrt(array.squaredNorm
())</tt>). | |
| */ | | */ | |
| NormType norm() const | | NormType norm() const | |
| { | | { | |
|
| return VIGRA_CSTD::sqrt(static_cast<NormType>(this->squaredNorm()))
; | | return sqrt(static_cast<typename SquareRootTraits<SquaredNormType>:
:SquareRootArgument>(this->squaredNorm())); | |
| } | | } | |
| | | | |
| /** return the pointer to the image data | | /** return the pointer to the image data | |
| */ | | */ | |
| pointer data () const | | pointer data () const | |
| { | | { | |
| return m_ptr; | | return m_ptr; | |
| } | | } | |
| | | | |
| /** returns the N-dimensional MultiIterator pointing | | /** returns the N-dimensional MultiIterator pointing | |
| | | | |
| skipping to change at line 722 | | skipping to change at line 750 | |
| if(this == &rhs) | | if(this == &rhs) | |
| return; | | return; | |
| vigra_precondition (shape () == rhs.shape (), | | vigra_precondition (shape () == rhs.shape (), | |
| "MultiArrayView::copy(): shape mismatch."); | | "MultiArrayView::copy(): shape mismatch."); | |
| detail::copyMultiArrayData(rhs.traverser_begin(), shape(), traverser_be
gin(), MetaInt<actual_dimension-1>()); | | detail::copyMultiArrayData(rhs.traverser_begin(), shape(), traverser_be
gin(), MetaInt<actual_dimension-1>()); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class C> | | template <unsigned int N, class T, class C> | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-M, T, C> | | MultiArrayView <N-M, T, C> | |
|
| MultiArrayView <N, T, C>::bindOuter (const TinyVector <int, M> &d) const | | MultiArrayView <N, T, C>::bindOuter (const TinyVector <ptrdiff_t, M> &d) co
nst | |
| { | | { | |
|
| TinyVector <int, M> stride; | | TinyVector <ptrdiff_t, M> stride; | |
| stride.init (m_stride.begin () + N-M, m_stride.end ()); | | stride.init (m_stride.begin () + N-M, m_stride.end ()); | |
| pointer ptr = m_ptr + dot (d, stride); | | pointer ptr = m_ptr + dot (d, stride); | |
| static const int NNew = (N-M == 0) ? 1 : N-M; | | static const int NNew = (N-M == 0) ? 1 : N-M; | |
|
| TinyVector <int, NNew> inner_shape, inner_stride; | | TinyVector <ptrdiff_t, NNew> inner_shape, inner_stride; | |
| if (N-M == 0) | | if (N-M == 0) | |
| { | | { | |
| inner_shape [0] = 1; | | inner_shape [0] = 1; | |
| inner_stride [0] = 0; | | inner_stride [0] = 0; | |
| } | | } | |
| else | | else | |
| { | | { | |
| inner_shape.init (m_shape.begin (), m_shape.end () - M); | | inner_shape.init (m_shape.begin (), m_shape.end () - M); | |
| inner_stride.init (m_stride.begin (), m_stride.end () - M); | | inner_stride.init (m_stride.begin (), m_stride.end () - M); | |
| } | | } | |
| return MultiArrayView <N-M, T, C> (inner_shape, inner_stride, ptr); | | return MultiArrayView <N-M, T, C> (inner_shape, inner_stride, ptr); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class C> | | template <unsigned int N, class T, class C> | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N - M, T, StridedArrayTag> | | MultiArrayView <N - M, T, StridedArrayTag> | |
|
| MultiArrayView <N, T, C>::bindInner (const TinyVector <int, M> &d) const | | MultiArrayView <N, T, C>::bindInner (const TinyVector <ptrdiff_t, M> &d) co
nst | |
| { | | { | |
|
| TinyVector <int, M> stride; | | TinyVector <ptrdiff_t, M> stride; | |
| stride.init (m_stride.begin (), m_stride.end () - N + M); | | stride.init (m_stride.begin (), m_stride.end () - N + M); | |
| pointer ptr = m_ptr + dot (d, stride); | | pointer ptr = m_ptr + dot (d, stride); | |
| static const int NNew = (N-M == 0) ? 1 : N-M; | | static const int NNew = (N-M == 0) ? 1 : N-M; | |
|
| TinyVector <int, NNew> outer_shape, outer_stride; | | TinyVector <ptrdiff_t, NNew> outer_shape, outer_stride; | |
| if (N-M == 0) | | if (N-M == 0) | |
| { | | { | |
| outer_shape [0] = 1; | | outer_shape [0] = 1; | |
| outer_stride [0] = 0; | | outer_stride [0] = 0; | |
| } | | } | |
| else | | else | |
| { | | { | |
| outer_shape.init (m_shape.begin () + M, m_shape.end ()); | | outer_shape.init (m_shape.begin () + M, m_shape.end ()); | |
| outer_stride.init (m_stride.begin () + M, m_stride.end ()); | | outer_stride.init (m_stride.begin () + M, m_stride.end ()); | |
| } | | } | |
| return MultiArrayView <N-M, T, StridedArrayTag> | | return MultiArrayView <N-M, T, StridedArrayTag> | |
| (outer_shape, outer_stride, ptr); | | (outer_shape, outer_stride, ptr); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class C> | | template <unsigned int N, class T, class C> | |
| template <unsigned int M> | | template <unsigned int M> | |
| MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | | MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > | |
| MultiArrayView <N, T, C>::bind (int d) const | | MultiArrayView <N, T, C>::bind (int d) const | |
| { | | { | |
| static const int NNew = (N-1 == 0) ? 1 : N-1; | | static const int NNew = (N-1 == 0) ? 1 : N-1; | |
|
| TinyVector <int, NNew> shape, stride; | | TinyVector <ptrdiff_t, NNew> shape, stride; | |
| // the remaining dimensions are 0..n-1,n+1..N-1 | | // the remaining dimensions are 0..n-1,n+1..N-1 | |
| if (N-1 == 0) | | if (N-1 == 0) | |
| { | | { | |
| shape[0] = 1; | | shape[0] = 1; | |
| stride[0] = 0; | | stride[0] = 0; | |
| } | | } | |
| else | | else | |
| { | | { | |
| std::copy (m_shape.begin (), m_shape.begin () + M, shape.begin ()); | | std::copy (m_shape.begin (), m_shape.begin () + M, shape.begin ()); | |
| std::copy (m_shape.begin () + M+1, m_shape.end (), | | std::copy (m_shape.begin () + M+1, m_shape.end (), | |
| | | | |
| skipping to change at line 797 | | skipping to change at line 825 | |
| } | | } | |
| return MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type> | | return MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type> | |
| (shape, stride, m_ptr + d * m_stride[M]); | | (shape, stride, m_ptr + d * m_stride[M]); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class C> | | template <unsigned int N, class T, class C> | |
| MultiArrayView <N - 1, T, C> | | MultiArrayView <N - 1, T, C> | |
| MultiArrayView <N, T, C>::bindOuter (int d) const | | MultiArrayView <N, T, C>::bindOuter (int d) const | |
| { | | { | |
| static const int NNew = (N-1 == 0) ? 1 : N-1; | | static const int NNew = (N-1 == 0) ? 1 : N-1; | |
|
| TinyVector <int, NNew> inner_shape, inner_stride; | | TinyVector <ptrdiff_t, NNew> inner_shape, inner_stride; | |
| if (N-1 == 0) | | if (N-1 == 0) | |
| { | | { | |
| inner_shape [0] = 1; | | inner_shape [0] = 1; | |
| inner_stride [0] = 0; | | inner_stride [0] = 0; | |
| } | | } | |
| else | | else | |
| { | | { | |
| inner_shape.init (m_shape.begin (), m_shape.end () - 1); | | inner_shape.init (m_shape.begin (), m_shape.end () - 1); | |
| inner_stride.init (m_stride.begin (), m_stride.end () - 1); | | inner_stride.init (m_stride.begin (), m_stride.end () - 1); | |
| } | | } | |
| return MultiArrayView <N-1, T, C> (inner_shape, inner_stride, | | return MultiArrayView <N-1, T, C> (inner_shape, inner_stride, | |
| m_ptr + d * m_stride [N-1]); | | m_ptr + d * m_stride [N-1]); | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class C> | | template <unsigned int N, class T, class C> | |
| MultiArrayView <N - 1, T, StridedArrayTag> | | MultiArrayView <N - 1, T, StridedArrayTag> | |
| MultiArrayView <N, T, C>::bindInner (int d) const | | MultiArrayView <N, T, C>::bindInner (int d) const | |
| { | | { | |
| static const int NNew = (N-1 == 0) ? 1 : N-1; | | static const int NNew = (N-1 == 0) ? 1 : N-1; | |
|
| TinyVector <int, NNew> outer_shape, outer_stride; | | TinyVector <ptrdiff_t, NNew> outer_shape, outer_stride; | |
| if (N-1 == 0) | | if (N-1 == 0) | |
| { | | { | |
| outer_shape [0] = 1; | | outer_shape [0] = 1; | |
| outer_stride [0] = 0; | | outer_stride [0] = 0; | |
| } | | } | |
| else | | else | |
| { | | { | |
| outer_shape.init (m_shape.begin () + 1, m_shape.end ()); | | outer_shape.init (m_shape.begin () + 1, m_shape.end ()); | |
| outer_stride.init (m_stride.begin () + 1, m_stride.end ()); | | outer_stride.init (m_stride.begin () + 1, m_stride.end ()); | |
| } | | } | |
| | | | |
| skipping to change at line 840 | | skipping to change at line 868 | |
| } | | } | |
| | | | |
| template <unsigned int N, class T, class C> | | template <unsigned int N, class T, class C> | |
| MultiArrayView <N - 1, T, StridedArrayTag> | | MultiArrayView <N - 1, T, StridedArrayTag> | |
| MultiArrayView <N, T, C>::bindAt (int n, int d) const | | MultiArrayView <N, T, C>::bindAt (int n, int d) const | |
| { | | { | |
| vigra_precondition ( | | vigra_precondition ( | |
| n < static_cast <int> (N), | | n < static_cast <int> (N), | |
| "MultiArrayView <N, T, C>::bindAt(): dimension out of range."); | | "MultiArrayView <N, T, C>::bindAt(): dimension out of range."); | |
| static const int NNew = (N-1 == 0) ? 1 : N-1; | | static const int NNew = (N-1 == 0) ? 1 : N-1; | |
|
| TinyVector <int, NNew> shape, stride; | | TinyVector <ptrdiff_t, NNew> shape, stride; | |
| // the remaining dimensions are 0..n-1,n+1..N-1 | | // the remaining dimensions are 0..n-1,n+1..N-1 | |
| if (N-1 == 0) | | if (N-1 == 0) | |
| { | | { | |
| shape [0] = 1; | | shape [0] = 1; | |
| stride [0] = 0; | | stride [0] = 0; | |
| } | | } | |
| else | | else | |
| { | | { | |
| std::copy (m_shape.begin (), m_shape.begin () + n, shape.begin ()); | | std::copy (m_shape.begin (), m_shape.begin () + n, shape.begin ()); | |
| std::copy (m_shape.begin () + n+1, m_shape.end (), | | std::copy (m_shape.begin () + n+1, m_shape.end (), | |
| | | | |
| skipping to change at line 993 | | skipping to change at line 1021 | |
| /** the squared norm type (return type of squaredNorm(array)). | | /** the squared norm type (return type of squaredNorm(array)). | |
| */ | | */ | |
| typedef typename view_type::SquaredNormType SquaredNormType; | | typedef typename view_type::SquaredNormType SquaredNormType; | |
| | | | |
| /** the norm type (return type of norm(array)). | | /** the norm type (return type of norm(array)). | |
| */ | | */ | |
| typedef typename view_type::NormType NormType; | | typedef typename view_type::NormType NormType; | |
| | | | |
| protected: | | protected: | |
| | | | |
|
| | | static const typename difference_type::value_type diff_zero = 0; | |
| | | | |
| /** the allocator used to allocate the memory | | /** the allocator used to allocate the memory | |
| */ | | */ | |
| allocator_type m_alloc; | | allocator_type m_alloc; | |
| | | | |
| /** allocate memory for s pixels, write its address into the given | | /** allocate memory for s pixels, write its address into the given | |
| pointer and initialize the pixels with init. | | pointer and initialize the pixels with init. | |
| */ | | */ | |
| void allocate (pointer &ptr, std::size_t s, const_reference init); | | void allocate (pointer &ptr, std::size_t s, const_reference init); | |
| | | | |
| /** allocate memory for s pixels, write its address into the given | | /** allocate memory for s pixels, write its address into the given | |
| | | | |
| skipping to change at line 1136 | | skipping to change at line 1166 | |
| /** get the allocator. | | /** get the allocator. | |
| */ | | */ | |
| allocator_type const & allocator () const | | allocator_type const & allocator () const | |
| { | | { | |
| return m_alloc; | | return m_alloc; | |
| } | | } | |
| }; | | }; | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray () | | MultiArray <N, T, A>::MultiArray () | |
|
| : MultiArrayView <N, T> (difference_type (0), difference_type (0), 0) | | : MultiArrayView <N, T> (difference_type (diff_zero), | |
| | | difference_type (diff_zero), 0) | |
| {} | | {} | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray (allocator_type const & alloc) | | MultiArray <N, T, A>::MultiArray (allocator_type const & alloc) | |
|
| : MultiArrayView <N, T> (difference_type (0), difference_type (0), 0), | | : MultiArrayView <N, T> (difference_type (diff_zero), | |
| | | difference_type (diff_zero), 0), | |
| m_alloc(alloc) | | m_alloc(alloc) | |
| {} | | {} | |
| | | | |
| template <unsigned int N, class T, class A> | | template <unsigned int N, class T, class A> | |
| MultiArray <N, T, A>::MultiArray (const difference_type &shape, | | MultiArray <N, T, A>::MultiArray (const difference_type &shape, | |
| allocator_type const & alloc) | | allocator_type const & alloc) | |
| : MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N
,T>::actual_dimension> (shape), 0), | | : MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N
,T>::actual_dimension> (shape), 0), | |
| m_alloc(alloc) | | m_alloc(alloc) | |
| { | | { | |
| if (N == 0) | | if (N == 0) | |
| | | | |
End of changes. 32 change blocks. |
| 33 lines changed or deleted | | 65 lines changed or added | |
|
| numerictraits.hxx | | numerictraits.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_NUMERICTRAITS_HXX | | #ifndef VIGRA_NUMERICTRAITS_HXX | |
| #define VIGRA_NUMERICTRAITS_HXX | | #define VIGRA_NUMERICTRAITS_HXX | |
| | | | |
| #include <limits.h> | | #include <limits.h> | |
| #include <cfloat> | | #include <cfloat> | |
| #include <complex> | | #include <complex> | |
| #include "vigra/metaprogramming.hxx" | | #include "vigra/metaprogramming.hxx" | |
|
| | | #include "vigra/sized_int.hxx" | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* NumericTraits */ | | /* NumericTraits */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \page NumericPromotionTraits Numeric and Promotion Traits | | /** \page NumericPromotionTraits Numeric and Promotion Traits | |
| | | | |
| Meta-information about arithmetic types. | | Meta-information about arithmetic types. | |
| | | | |
| skipping to change at line 51 | | skipping to change at line 67 | |
| <DL> | | <DL> | |
| <DT> | | <DT> | |
| <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | | <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | |
| \ref NumericTraits | | \ref NumericTraits | |
| <DD><em>Unary traits for promotion, conversion, creation of arithmetic
objects</em> | | <DD><em>Unary traits for promotion, conversion, creation of arithmetic
objects</em> | |
| <DT> | | <DT> | |
| <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | | <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | |
| \ref PromoteTraits | | \ref PromoteTraits | |
| <DD><em>Binary traits for promotion of arithmetic objects</em> | | <DD><em>Binary traits for promotion of arithmetic objects</em> | |
| <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | | <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | |
|
| | | \ref SquareRootTraits | |
| | | <DD><em>Unary traits for the calculation of the square root of arithmet | |
| | | ic objects</em> | |
| | | <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | |
| \ref NormTraits | | \ref NormTraits | |
| <DD><em>Unary traits for the calculation of the norm and squared norm o
f arithmetic objects</em> | | <DD><em>Unary traits for the calculation of the norm and squared norm o
f arithmetic objects</em> | |
| </DL> | | </DL> | |
| | | | |
| These traits classes contain information that is used by generic | | These traits classes contain information that is used by generic | |
| algorithms and data structures to determine intermediate and result | | algorithms and data structures to determine intermediate and result | |
| types of numerical calculations, to convert between different | | types of numerical calculations, to convert between different | |
| representations of arithmetic types, and to create certain important | | representations of arithmetic types, and to create certain important | |
| constants of each type. Thus, algorithms and data structures | | constants of each type. Thus, algorithms and data structures | |
| operating that need arithmetic operations can be made more | | operating that need arithmetic operations can be made more | |
| | | | |
| skipping to change at line 277 | | skipping to change at line 296 | |
| </td></tr> | | </td></tr> | |
| <tr><td> | | <tr><td> | |
| <b> <TT>typedef ... isScalar;</TT></b> | | <b> <TT>typedef ... isScalar;</TT></b> | |
| </td><td> | | </td><td> | |
| VigraTrueType if <TT>ArithmeticType</TT> is a scalar type, | | VigraTrueType if <TT>ArithmeticType</TT> is a scalar type, | |
| VigraFalseType otherwise | | VigraFalseType otherwise | |
| | | | |
| </td></tr> | | </td></tr> | |
| <tr><td> | | <tr><td> | |
| <tr><td> | | <tr><td> | |
|
| | | <b> <TT>typedef ... isSigned;</TT></b> | |
| | | </td><td> | |
| | | VigraTrueType if <TT>ArithmeticType</TT> is a signed type, | |
| | | VigraFalseType otherwise | |
| | | | |
| | | </td></tr> | |
| | | <tr><td> | |
| | | <tr><td> | |
| <b> <TT>typedef ... isOrdered;</TT></b> | | <b> <TT>typedef ... isOrdered;</TT></b> | |
| </td><td> | | </td><td> | |
| VigraTrueType if <TT>ArithmeticType</TT> supports operator<(), | | VigraTrueType if <TT>ArithmeticType</TT> supports operator<(), | |
| VigraFalseType otherwise | | VigraFalseType otherwise | |
| | | | |
| </td></tr> | | </td></tr> | |
| <tr><td> | | <tr><td> | |
| <b> <TT>typedef ... isComplex;</TT></b> | | <b> <TT>typedef ... isComplex;</TT></b> | |
| </td><td> | | </td><td> | |
| VigraTrueType if <TT>ArithmeticType</TT> is a complex number, | | VigraTrueType if <TT>ArithmeticType</TT> is a complex number, | |
| | | | |
| skipping to change at line 362 | | skipping to change at line 389 | |
| convert to <TT>Promote</TT> type | | convert to <TT>Promote</TT> type | |
| </td></tr> | | </td></tr> | |
| </table> | | </table> | |
| | | | |
| PromoteTraits for the built-in types are defined in <b>\#include</b> | | PromoteTraits for the built-in types are defined in <b>\#include</b> | |
| "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | | "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| | | | |
|
| | | /** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticTyp | |
| | | e> | |
| | | | |
| | | Unary traits for the calculation of the square root of arithmetic objec | |
| | | ts. | |
| | | | |
| | | <b>\#include</b> | |
| | | "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | |
| | | | |
| | | This traits class is used to determine appropriate argument and result | |
| | | types | |
| | | for the function sqrt(). These traits are typically used like this: | |
| | | | |
| | | \code | |
| | | ArithmeticType t = ...; | |
| | | SquareRootTraits<ArithmeticType>::SquareRootResult r = | |
| | | sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t); | |
| | | \endcode | |
| | | | |
| | | This approach avoids 'ambigouos overload errors' when taking the square | |
| | | root of | |
| | | an integer type. It also takes care of determining the proper result of | |
| | | the | |
| | | sqrt() function of \ref vigra::FixedPoint and of the norm() function, w | |
| | | hen | |
| | | it is implemented via sqrt(squaredNorm(x)). | |
| | | The following members are defined in <b> <TT>SquareRootTraits<Arithmeti | |
| | | cType></TT></b>: | |
| | | | |
| | | <table> | |
| | | <tr><td> | |
| | | <b> <TT>typedef ArithmeticType Type;</TT></b> | |
| | | </td><td> | |
| | | the type itself | |
| | | </td></tr> | |
| | | <tr><td> | |
| | | <b> <TT>typedef ... SquareRootArgument;</TT></b> | |
| | | </td><td> | |
| | | required argument type for srqt(), i.e. <tt>sqrt((SquareRootArg | |
| | | ument)x)</tt> | |
| | | </td></tr> | |
| | | <tr><td> | |
| | | <b> <TT>typedef ... SquareRootResult;</TT></b> | |
| | | </td><td> | |
| | | result of <tt>sqrt((SquareRootArgument)x)</tt> | |
| | | </td></tr> | |
| | | </table> | |
| | | | |
| | | NormTraits for the built-in types are defined in <b>\#include</b> | |
| | | "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | |
| | | | |
| | | Namespace: vigra | |
| | | */ | |
| | | | |
| /** \page NormTraits template<> struct NormTraits<ArithmeticType> | | /** \page NormTraits template<> struct NormTraits<ArithmeticType> | |
| | | | |
| Unary traits for the calculation of the norm and squared norm of arithm
etic objects. | | Unary traits for the calculation of the norm and squared norm of arithm
etic objects. | |
| | | | |
| <b>\#include</b> | | <b>\#include</b> | |
| "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | | "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | |
| | | | |
| This traits class is used to determine appropriate result types | | This traits class is used to determine appropriate result types | |
| for the functions norm() and squaredNorm(). These functions are always | | for the functions norm() and squaredNorm(). These functions are always | |
| declared like this (where <tt>ArithmeticType</tt> is a type thats suppo
rts a norm): | | declared like this (where <tt>ArithmeticType</tt> is a type thats suppo
rts a norm): | |
| | | | |
| skipping to change at line 395 | | skipping to change at line 468 | |
| </td></tr> | | </td></tr> | |
| <tr><td> | | <tr><td> | |
| <b> <TT>typedef ... SquaredNormType;</TT></b> | | <b> <TT>typedef ... SquaredNormType;</TT></b> | |
| </td><td> | | </td><td> | |
| result of <tt>squaredNorm(ArithmeticType)</tt> | | result of <tt>squaredNorm(ArithmeticType)</tt> | |
| </td></tr> | | </td></tr> | |
| <tr><td> | | <tr><td> | |
| <b> <TT>typedef ... NormType;</TT></b> | | <b> <TT>typedef ... NormType;</TT></b> | |
| </td><td> | | </td><td> | |
| result of <tt>norm(ArithmeticType)</tt><br> | | result of <tt>norm(ArithmeticType)</tt><br> | |
|
| Usually equal to <tt>NumericTraits<SquaredNormType>::Real
Promote | | Usually equal to <tt>SquareRootTraits<SquaredNormType>::S
quareRootResult | |
| </td></tr> | | </td></tr> | |
| </table> | | </table> | |
| | | | |
| NormTraits for the built-in types are defined in <b>\#include</b> | | NormTraits for the built-in types are defined in <b>\#include</b> | |
| "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | | "<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| struct Error_NumericTraits_not_specialized_for_this_case { }; | | struct Error_NumericTraits_not_specialized_for_this_case { }; | |
|
| | | struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_u
nsigned_char { }; | |
| | | | |
| template<class A> | | template<class A> | |
| struct NumericTraits | | struct NumericTraits | |
| { | | { | |
| typedef Error_NumericTraits_not_specialized_for_this_case Type; | | typedef Error_NumericTraits_not_specialized_for_this_case Type; | |
| typedef Error_NumericTraits_not_specialized_for_this_case Promote; | | typedef Error_NumericTraits_not_specialized_for_this_case Promote; | |
| typedef Error_NumericTraits_not_specialized_for_this_case RealPromote; | | typedef Error_NumericTraits_not_specialized_for_this_case RealPromote; | |
| typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromot
e; | | typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromot
e; | |
| typedef Error_NumericTraits_not_specialized_for_this_case ValueType; | | typedef Error_NumericTraits_not_specialized_for_this_case ValueType; | |
| | | | |
| typedef Error_NumericTraits_not_specialized_for_this_case isScalar; | | typedef Error_NumericTraits_not_specialized_for_this_case isScalar; | |
| typedef Error_NumericTraits_not_specialized_for_this_case isIntegral; | | typedef Error_NumericTraits_not_specialized_for_this_case isIntegral; | |
|
| | | typedef Error_NumericTraits_not_specialized_for_this_case isSigned; | |
| typedef Error_NumericTraits_not_specialized_for_this_case isOrdered; | | typedef Error_NumericTraits_not_specialized_for_this_case isOrdered; | |
| typedef Error_NumericTraits_not_specialized_for_this_case isComplex; | | typedef Error_NumericTraits_not_specialized_for_this_case isComplex; | |
| }; | | }; | |
| | | | |
|
| | | template<> | |
| | | struct NumericTraits<char> | |
| | | { | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char Type; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char Promote; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char RealPromote; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char ComplexPromote; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char ValueType; | |
| | | | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char isScalar; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char isIntegral; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char isSigned; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char isOrdered; | |
| | | typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char | |
| | | _or_unsigned_char isComplex; | |
| | | }; | |
| | | | |
| #ifndef NO_BOOL | | #ifndef NO_BOOL | |
| template<> | | template<> | |
| struct NumericTraits<bool> | | struct NumericTraits<bool> | |
| { | | { | |
| typedef bool Type; | | typedef bool Type; | |
| typedef int Promote; | | typedef int Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraFalseType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static bool zero() { return false; } | | static bool zero() { return false; } | |
| static bool one() { return true; } | | static bool one() { return true; } | |
| static bool nonZero() { return true; } | | static bool nonZero() { return true; } | |
| static bool min() { return false; } | | static bool min() { return false; } | |
| static bool max() { return true; } | | static bool max() { return true; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 474 | | skipping to change at line 566 | |
| struct NumericTraits<signed char> | | struct NumericTraits<signed char> | |
| { | | { | |
| typedef signed char Type; | | typedef signed char Type; | |
| typedef int Promote; | | typedef int Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static signed char zero() { return 0; } | | static signed char zero() { return 0; } | |
| static signed char one() { return 1; } | | static signed char one() { return 1; } | |
| static signed char nonZero() { return 1; } | | static signed char nonZero() { return 1; } | |
| static signed char min() { return SCHAR_MIN; } | | static signed char min() { return SCHAR_MIN; } | |
| static signed char max() { return SCHAR_MAX; } | | static signed char max() { return SCHAR_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 517 | | skipping to change at line 610 | |
| struct NumericTraits<unsigned char> | | struct NumericTraits<unsigned char> | |
| { | | { | |
| typedef unsigned char Type; | | typedef unsigned char Type; | |
| typedef int Promote; | | typedef int Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraFalseType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static unsigned char zero() { return 0; } | | static unsigned char zero() { return 0; } | |
| static unsigned char one() { return 1; } | | static unsigned char one() { return 1; } | |
| static unsigned char nonZero() { return 1; } | | static unsigned char nonZero() { return 1; } | |
| static unsigned char min() { return 0; } | | static unsigned char min() { return 0; } | |
| static unsigned char max() { return UCHAR_MAX; } | | static unsigned char max() { return UCHAR_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 558 | | skipping to change at line 652 | |
| struct NumericTraits<short int> | | struct NumericTraits<short int> | |
| { | | { | |
| typedef short int Type; | | typedef short int Type; | |
| typedef int Promote; | | typedef int Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static short int zero() { return 0; } | | static short int zero() { return 0; } | |
| static short int one() { return 1; } | | static short int one() { return 1; } | |
| static short int nonZero() { return 1; } | | static short int nonZero() { return 1; } | |
| static short int min() { return SHRT_MIN; } | | static short int min() { return SHRT_MIN; } | |
| static short int max() { return SHRT_MAX; } | | static short int max() { return SHRT_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 602 | | skipping to change at line 697 | |
| struct NumericTraits<short unsigned int> | | struct NumericTraits<short unsigned int> | |
| { | | { | |
| typedef short unsigned int Type; | | typedef short unsigned int Type; | |
| typedef int Promote; | | typedef int Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraFalseType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static short unsigned int zero() { return 0; } | | static short unsigned int zero() { return 0; } | |
| static short unsigned int one() { return 1; } | | static short unsigned int one() { return 1; } | |
| static short unsigned int nonZero() { return 1; } | | static short unsigned int nonZero() { return 1; } | |
| static short unsigned int min() { return 0; } | | static short unsigned int min() { return 0; } | |
| static short unsigned int max() { return USHRT_MAX; } | | static short unsigned int max() { return USHRT_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 643 | | skipping to change at line 739 | |
| struct NumericTraits<int> | | struct NumericTraits<int> | |
| { | | { | |
| typedef int Type; | | typedef int Type; | |
| typedef int Promote; | | typedef int Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static int zero() { return 0; } | | static int zero() { return 0; } | |
| static int one() { return 1; } | | static int one() { return 1; } | |
| static int nonZero() { return 1; } | | static int nonZero() { return 1; } | |
| static int min() { return INT_MIN; } | | static int min() { return INT_MIN; } | |
| static int max() { return INT_MAX; } | | static int max() { return INT_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 684 | | skipping to change at line 781 | |
| struct NumericTraits<unsigned int> | | struct NumericTraits<unsigned int> | |
| { | | { | |
| typedef unsigned int Type; | | typedef unsigned int Type; | |
| typedef unsigned int Promote; | | typedef unsigned int Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraFalseType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static unsigned int zero() { return 0; } | | static unsigned int zero() { return 0; } | |
| static unsigned int one() { return 1; } | | static unsigned int one() { return 1; } | |
| static unsigned int nonZero() { return 1; } | | static unsigned int nonZero() { return 1; } | |
| static unsigned int min() { return 0; } | | static unsigned int min() { return 0; } | |
| static unsigned int max() { return UINT_MAX; } | | static unsigned int max() { return UINT_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 723 | | skipping to change at line 821 | |
| struct NumericTraits<long> | | struct NumericTraits<long> | |
| { | | { | |
| typedef long Type; | | typedef long Type; | |
| typedef long Promote; | | typedef long Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static long zero() { return 0; } | | static long zero() { return 0; } | |
| static long one() { return 1; } | | static long one() { return 1; } | |
| static long nonZero() { return 1; } | | static long nonZero() { return 1; } | |
| static long min() { return LONG_MIN; } | | static long min() { return LONG_MIN; } | |
| static long max() { return LONG_MAX; } | | static long max() { return LONG_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 764 | | skipping to change at line 863 | |
| struct NumericTraits<unsigned long> | | struct NumericTraits<unsigned long> | |
| { | | { | |
| typedef unsigned long Type; | | typedef unsigned long Type; | |
| typedef unsigned long Promote; | | typedef unsigned long Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraTrueType isIntegral; | | typedef VigraTrueType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraFalseType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static unsigned long zero() { return 0; } | | static unsigned long zero() { return 0; } | |
| static unsigned long one() { return 1; } | | static unsigned long one() { return 1; } | |
| static unsigned long nonZero() { return 1; } | | static unsigned long nonZero() { return 1; } | |
| static unsigned long min() { return 0; } | | static unsigned long min() { return 0; } | |
| static unsigned long max() { return ULONG_MAX; } | | static unsigned long max() { return ULONG_MAX; } | |
| | | | |
| #ifdef NO_INLINE_STATIC_CONST_DEFINITION | | #ifdef NO_INLINE_STATIC_CONST_DEFINITION | |
| | | | |
| skipping to change at line 803 | | skipping to change at line 903 | |
| struct NumericTraits<float> | | struct NumericTraits<float> | |
| { | | { | |
| typedef float Type; | | typedef float Type; | |
| typedef float Promote; | | typedef float Promote; | |
| typedef float RealPromote; | | typedef float RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraFalseType isIntegral; | | typedef VigraFalseType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static float zero() { return 0.0; } | | static float zero() { return 0.0; } | |
| static float one() { return 1.0; } | | static float one() { return 1.0; } | |
| static float nonZero() { return 1.0; } | | static float nonZero() { return 1.0; } | |
| static float epsilon() { return FLT_EPSILON; } | | static float epsilon() { return FLT_EPSILON; } | |
| static float smallestPositive() { return FLT_MIN; } | | static float smallestPositive() { return FLT_MIN; } | |
| static float min() { return -FLT_MAX; } | | static float min() { return -FLT_MAX; } | |
| static float max() { return FLT_MAX; } | | static float max() { return FLT_MAX; } | |
| | | | |
| skipping to change at line 831 | | skipping to change at line 932 | |
| struct NumericTraits<double> | | struct NumericTraits<double> | |
| { | | { | |
| typedef double Type; | | typedef double Type; | |
| typedef double Promote; | | typedef double Promote; | |
| typedef double RealPromote; | | typedef double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraFalseType isIntegral; | | typedef VigraFalseType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static double zero() { return 0.0; } | | static double zero() { return 0.0; } | |
| static double one() { return 1.0; } | | static double one() { return 1.0; } | |
| static double nonZero() { return 1.0; } | | static double nonZero() { return 1.0; } | |
| static double epsilon() { return DBL_EPSILON; } | | static double epsilon() { return DBL_EPSILON; } | |
| static double smallestPositive() { return DBL_MIN; } | | static double smallestPositive() { return DBL_MIN; } | |
| static double min() { return -DBL_MAX; } | | static double min() { return -DBL_MAX; } | |
| static double max() { return DBL_MAX; } | | static double max() { return DBL_MAX; } | |
| | | | |
| skipping to change at line 859 | | skipping to change at line 961 | |
| struct NumericTraits<long double> | | struct NumericTraits<long double> | |
| { | | { | |
| typedef long double Type; | | typedef long double Type; | |
| typedef long double Promote; | | typedef long double Promote; | |
| typedef long double RealPromote; | | typedef long double RealPromote; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef Type ValueType; | | typedef Type ValueType; | |
| | | | |
| typedef VigraFalseType isIntegral; | | typedef VigraFalseType isIntegral; | |
| typedef VigraTrueType isScalar; | | typedef VigraTrueType isScalar; | |
|
| | | typedef VigraTrueType isSigned; | |
| typedef VigraTrueType isOrdered; | | typedef VigraTrueType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static long double zero() { return 0.0; } | | static long double zero() { return 0.0; } | |
| static long double one() { return 1.0; } | | static long double one() { return 1.0; } | |
| static long double nonZero() { return 1.0; } | | static long double nonZero() { return 1.0; } | |
| static long double epsilon() { return LDBL_EPSILON; } | | static long double epsilon() { return LDBL_EPSILON; } | |
| static long double smallestPositive() { return LDBL_MIN; } | | static long double smallestPositive() { return LDBL_MIN; } | |
| static long double min() { return -LDBL_MAX; } | | static long double min() { return -LDBL_MAX; } | |
| static long double max() { return LDBL_MAX; } | | static long double max() { return LDBL_MAX; } | |
| | | | |
| skipping to change at line 889 | | skipping to change at line 992 | |
| struct NumericTraits<std::complex<T> > | | struct NumericTraits<std::complex<T> > | |
| { | | { | |
| typedef std::complex<T> Type; | | typedef std::complex<T> Type; | |
| typedef std::complex<typename NumericTraits<T>::Promote> Promote; | | typedef std::complex<typename NumericTraits<T>::Promote> Promote; | |
| typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromot
e; | | typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromot
e; | |
| typedef std::complex<RealPromote> ComplexPromote; | | typedef std::complex<RealPromote> ComplexPromote; | |
| typedef T ValueType; | | typedef T ValueType; | |
| | | | |
| typedef VigraFalseType isIntegral; | | typedef VigraFalseType isIntegral; | |
| typedef VigraFalseType isScalar; | | typedef VigraFalseType isScalar; | |
|
| | | typedef typename NumericTraits<T>::isSigned isSigned; | |
| typedef VigraFalseType isOrdered; | | typedef VigraFalseType isOrdered; | |
| typedef VigraTrueType isComplex; | | typedef VigraTrueType isComplex; | |
| | | | |
| static Type zero() { return Type(0.0); } | | static Type zero() { return Type(0.0); } | |
| static Type one() { return Type(1.0); } | | static Type one() { return Type(1.0); } | |
| static Type nonZero() { return one(); } | | static Type nonZero() { return one(); } | |
| static Type epsilon() { return Type(NumericTraits<T>::epsilon()); } | | static Type epsilon() { return Type(NumericTraits<T>::epsilon()); } | |
| static Type smallestPositive() { return Type(NumericTraits<T>::smallest
Positive()); } | | static Type smallestPositive() { return Type(NumericTraits<T>::smallest
Positive()); } | |
| | | | |
| static Promote toPromote(Type const & v) { return v; } | | static Promote toPromote(Type const & v) { return v; } | |
| static Type fromPromote(Promote const & v) { return v; } | | static Type fromPromote(Promote const & v) { return v; } | |
| static Type fromRealPromote(RealPromote v) { return Type(v); } | | static Type fromRealPromote(RealPromote v) { return Type(v); } | |
| }; | | }; | |
| | | | |
| #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION | | #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
|
| | | /* SquareRootTraits */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | template<class T> | |
| | | struct SquareRootTraits | |
| | | { | |
| | | typedef T Type; | |
| | | typedef typename NumericTraits<T>::RealPromote SquareRoot | |
| | | Result; | |
| | | typedef typename NumericTraits<T>::RealPromote SquareRoot | |
| | | Argument; | |
| | | }; | |
| | | | |
| | | /********************************************************/ | |
| | | /* */ | |
| /* NormTraits */ | | /* NormTraits */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| struct Error_NormTraits_not_specialized_for_this_case { }; | | struct Error_NormTraits_not_specialized_for_this_case { }; | |
| | | | |
|
| template<class A> | | template<class T> | |
| struct NormTraits | | struct NormTraits | |
| { | | { | |
|
| typedef Error_NormTraits_not_specialized_for_this_case Type; | | typedef T Ty | |
| typedef Error_NormTraits_not_specialized_for_this_case SquaredNormType; | | pe; | |
| typedef Error_NormTraits_not_specialized_for_this_case NormType; | | typedef typename T::SquaredNormType Sq | |
| | | uaredNormType; | |
| | | typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No | |
| | | rmType; | |
| }; | | }; | |
| | | | |
| #define VIGRA_DEFINE_NORM_TRAITS(T) \ | | #define VIGRA_DEFINE_NORM_TRAITS(T) \ | |
| template <> struct NormTraits<T> { \ | | template <> struct NormTraits<T> { \ | |
| typedef T Type; \ | | typedef T Type; \ | |
| typedef NumericTraits<T>::Promote SquaredNormType; \ | | typedef NumericTraits<T>::Promote SquaredNormType; \ | |
| typedef T NormType; \ | | typedef T NormType; \ | |
| }; | | }; | |
| | | | |
| VIGRA_DEFINE_NORM_TRAITS(bool) | | VIGRA_DEFINE_NORM_TRAITS(bool) | |
| | | | |
| skipping to change at line 948 | | skipping to change at line 1066 | |
| VIGRA_DEFINE_NORM_TRAITS(double) | | VIGRA_DEFINE_NORM_TRAITS(double) | |
| VIGRA_DEFINE_NORM_TRAITS(long double) | | VIGRA_DEFINE_NORM_TRAITS(long double) | |
| | | | |
| #undef VIGRA_DEFINE_NORM_TRAITS | | #undef VIGRA_DEFINE_NORM_TRAITS | |
| | | | |
| #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION | | #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION | |
| | | | |
| template<class T> | | template<class T> | |
| struct NormTraits<std::complex<T> > | | struct NormTraits<std::complex<T> > | |
| { | | { | |
|
| typedef std::complex<T> Type; | | typedef std::complex<T> Ty | |
| typedef typename NormTraits<T>::SquaredNormType SquaredNor | | pe; | |
| mType; | | typedef typename NormTraits<T>::SquaredNormType Sq | |
| typedef typename NumericTraits<SquaredNormType>::RealPromote NormType; | | uaredNormType; | |
| | | typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No | |
| | | rmType; | |
| }; | | }; | |
| | | | |
| #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION | | #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* PromoteTraits */ | | /* PromoteTraits */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| struct Error_PromoteTraits_not_specialized_for_this_case { }; | | struct Error_PromoteTraits_not_specialized_for_this_case { }; | |
| | | | |
| template<class A, class B> | | template<class A, class B> | |
| struct PromoteTraits | | struct PromoteTraits | |
| { | | { | |
| typedef Error_PromoteTraits_not_specialized_for_this_case Promote; | | typedef Error_PromoteTraits_not_specialized_for_this_case Promote; | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, char> | | struct PromoteTraits<signed char, signed char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, unsigned char> | | struct PromoteTraits<signed char, unsigned char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, short int> | | struct PromoteTraits<signed char, short int> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(short int v) { return v; } | | static Promote toPromote(short int v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, short unsigned int> | | struct PromoteTraits<signed char, short unsigned int> | |
| { | | { | |
| typedef unsigned int Promote; | | typedef unsigned int Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(short unsigned int v) { return v; } | | static Promote toPromote(short unsigned int v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, int> | | struct PromoteTraits<signed char, int> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(int v) { return v; } | | static Promote toPromote(int v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, unsigned int> | | struct PromoteTraits<signed char, unsigned int> | |
| { | | { | |
| typedef unsigned int Promote; | | typedef unsigned int Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(unsigned int v) { return v; } | | static Promote toPromote(unsigned int v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, long> | | struct PromoteTraits<signed char, long> | |
| { | | { | |
| typedef long Promote; | | typedef long Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(long v) { return v; } | | static Promote toPromote(long v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, unsigned long> | | struct PromoteTraits<signed char, unsigned long> | |
| { | | { | |
| typedef unsigned long Promote; | | typedef unsigned long Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(unsigned long v) { return v; } | | static Promote toPromote(unsigned long v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, float> | | struct PromoteTraits<signed char, float> | |
| { | | { | |
| typedef float Promote; | | typedef float Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(float v) { return v; } | | static Promote toPromote(float v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, double> | | struct PromoteTraits<signed char, double> | |
| { | | { | |
| typedef double Promote; | | typedef double Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(double v) { return v; } | | static Promote toPromote(double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<char, long double> | | struct PromoteTraits<signed char, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<unsigned char, char> | | struct PromoteTraits<unsigned char, signed char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<unsigned char, unsigned char> | | struct PromoteTraits<unsigned char, unsigned char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| | | | |
| skipping to change at line 1144 | | skipping to change at line 1262 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<unsigned char, long double> | | struct PromoteTraits<unsigned char, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<short int, char> | | struct PromoteTraits<short int, signed char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
| static Promote toPromote(short int v) { return v; } | | static Promote toPromote(short int v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<short int, unsigned char> | | struct PromoteTraits<short int, unsigned char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
| static Promote toPromote(short int v) { return v; } | | static Promote toPromote(short int v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1231 | | skipping to change at line 1349 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<short int, long double> | | struct PromoteTraits<short int, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(short int v) { return v; } | | static Promote toPromote(short int v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<short unsigned int, char> | | struct PromoteTraits<short unsigned int, signed char> | |
| { | | { | |
| typedef unsigned int Promote; | | typedef unsigned int Promote; | |
| static Promote toPromote(short unsigned int v) { return v; } | | static Promote toPromote(short unsigned int v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<short unsigned int, unsigned char> | | struct PromoteTraits<short unsigned int, unsigned char> | |
| { | | { | |
| typedef unsigned int Promote; | | typedef unsigned int Promote; | |
| static Promote toPromote(short unsigned int v) { return v; } | | static Promote toPromote(short unsigned int v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1318 | | skipping to change at line 1436 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<short unsigned int, long double> | | struct PromoteTraits<short unsigned int, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(short unsigned int v) { return v; } | | static Promote toPromote(short unsigned int v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<int, char> | | struct PromoteTraits<int, signed char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
| static Promote toPromote(int v) { return v; } | | static Promote toPromote(int v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<int, unsigned char> | | struct PromoteTraits<int, unsigned char> | |
| { | | { | |
| typedef int Promote; | | typedef int Promote; | |
| static Promote toPromote(int v) { return v; } | | static Promote toPromote(int v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1405 | | skipping to change at line 1523 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<int, long double> | | struct PromoteTraits<int, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(int v) { return v; } | | static Promote toPromote(int v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<unsigned int, char> | | struct PromoteTraits<unsigned int, signed char> | |
| { | | { | |
| typedef unsigned int Promote; | | typedef unsigned int Promote; | |
| static Promote toPromote(unsigned int v) { return v; } | | static Promote toPromote(unsigned int v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<unsigned int, unsigned char> | | struct PromoteTraits<unsigned int, unsigned char> | |
| { | | { | |
| typedef unsigned int Promote; | | typedef unsigned int Promote; | |
| static Promote toPromote(unsigned int v) { return v; } | | static Promote toPromote(unsigned int v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1492 | | skipping to change at line 1610 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<unsigned int, long double> | | struct PromoteTraits<unsigned int, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(unsigned int v) { return v; } | | static Promote toPromote(unsigned int v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<long, char> | | struct PromoteTraits<long, signed char> | |
| { | | { | |
| typedef long Promote; | | typedef long Promote; | |
| static Promote toPromote(long v) { return v; } | | static Promote toPromote(long v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<long, unsigned char> | | struct PromoteTraits<long, unsigned char> | |
| { | | { | |
| typedef long Promote; | | typedef long Promote; | |
| static Promote toPromote(long v) { return v; } | | static Promote toPromote(long v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1579 | | skipping to change at line 1697 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<long, long double> | | struct PromoteTraits<long, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(long v) { return v; } | | static Promote toPromote(long v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<unsigned long, char> | | struct PromoteTraits<unsigned long, signed char> | |
| { | | { | |
| typedef unsigned long Promote; | | typedef unsigned long Promote; | |
| static Promote toPromote(unsigned long v) { return v; } | | static Promote toPromote(unsigned long v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<unsigned long, unsigned char> | | struct PromoteTraits<unsigned long, unsigned char> | |
| { | | { | |
| typedef unsigned long Promote; | | typedef unsigned long Promote; | |
| static Promote toPromote(unsigned long v) { return v; } | | static Promote toPromote(unsigned long v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1666 | | skipping to change at line 1784 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<unsigned long, long double> | | struct PromoteTraits<unsigned long, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(unsigned long v) { return v; } | | static Promote toPromote(unsigned long v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<float, char> | | struct PromoteTraits<float, signed char> | |
| { | | { | |
| typedef float Promote; | | typedef float Promote; | |
| static Promote toPromote(float v) { return v; } | | static Promote toPromote(float v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<float, unsigned char> | | struct PromoteTraits<float, unsigned char> | |
| { | | { | |
| typedef float Promote; | | typedef float Promote; | |
| static Promote toPromote(float v) { return v; } | | static Promote toPromote(float v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1753 | | skipping to change at line 1871 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<float, long double> | | struct PromoteTraits<float, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(float v) { return v; } | | static Promote toPromote(float v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<double, char> | | struct PromoteTraits<double, signed char> | |
| { | | { | |
| typedef double Promote; | | typedef double Promote; | |
| static Promote toPromote(double v) { return v; } | | static Promote toPromote(double v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<double, unsigned char> | | struct PromoteTraits<double, unsigned char> | |
| { | | { | |
| typedef double Promote; | | typedef double Promote; | |
| static Promote toPromote(double v) { return v; } | | static Promote toPromote(double v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 1840 | | skipping to change at line 1958 | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<double, long double> | | struct PromoteTraits<double, long double> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(double v) { return v; } | | static Promote toPromote(double v) { return v; } | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
|
| struct PromoteTraits<long double, char> | | struct PromoteTraits<long double, signed char> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
|
| static Promote toPromote(char v) { return v; } | | static Promote toPromote(signed char v) { return v; } | |
| }; | | }; | |
| | | | |
| template<> | | template<> | |
| struct PromoteTraits<long double, unsigned char> | | struct PromoteTraits<long double, unsigned char> | |
| { | | { | |
| typedef long double Promote; | | typedef long double Promote; | |
| static Promote toPromote(long double v) { return v; } | | static Promote toPromote(long double v) { return v; } | |
| static Promote toPromote(unsigned char v) { return v; } | | static Promote toPromote(unsigned char v) { return v; } | |
| }; | | }; | |
| | | | |
| | | | |
End of changes. 70 change blocks. |
| 60 lines changed or deleted | | 204 lines changed or added | |
|
| pixelneighborhood.hxx | | pixelneighborhood.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
|
| /* Copyright 1998-2002 by Hans Meine, Ullrich Koethe */ | | /* Copyright 1998-2005 by Hans Meine, Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_PIXELNEIGHBORHOOD_HXX | | #ifndef VIGRA_PIXELNEIGHBORHOOD_HXX | |
| #define VIGRA_PIXELNEIGHBORHOOD_HXX | | #define VIGRA_PIXELNEIGHBORHOOD_HXX | |
| | | | |
| #include <vigra/utilities.hxx> | | #include <vigra/utilities.hxx> | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| | | | |
| skipping to change at line 42 | | skipping to change at line 57 | |
| 4- and 8-neighborhood definitions and circulators. | | 4- and 8-neighborhood definitions and circulators. | |
| | | | |
| <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | | <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | |
| | | | |
| <b>See also:</b> \ref vigra::NeighborhoodCirculator | | <b>See also:</b> \ref vigra::NeighborhoodCirculator | |
| */ | | */ | |
| //@{ | | //@{ | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
|
| | | /* AtImageBorder */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | /** \brief Encode whether a point is near the image border. | |
| | | | |
| | | This enum is used with \ref isAtImageBorder() and | |
| | | \ref vigra::RestrictedNeighborhoodCirculator. | |
| | | | |
| | | <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi | |
| | | xelneighborhood.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | enum AtImageBorder | |
| | | { | |
| | | NotAtBorder = 0, ///< | |
| | | RightBorder = 1, ///< | |
| | | LeftBorder = 2, ///< | |
| | | TopBorder = 4, ///< | |
| | | BottomBorder = 8, ///< | |
| | | TopRightBorder = TopBorder | RightBorder, ///< | |
| | | TopLeftBorder = TopBorder | LeftBorder, ///< | |
| | | BottomLeftBorder = BottomBorder | LeftBorder, ///< | |
| | | BottomRightBorder = BottomBorder | RightBorder ///< | |
| | | }; | |
| | | | |
| | | /** \brief Find out whether a point is at the image border. | |
| | | | |
| | | This function checks if \a x == 0 or \a x == \a width - 1 and | |
| | | \a y == 0 or \a y == \a height - 1 and returns the appropriate value | |
| | | of \ref vigra::AtImageBorder, or zero when the point is not at te image | |
| | | border. | |
| | | The behavior of the function is undefined if (x,y) is not inside the im | |
| | | age. | |
| | | | |
| | | <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi | |
| | | xelneighborhood.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | inline AtImageBorder isAtImageBorder(int x, int y, int width, int height) | |
| | | { | |
| | | return static_cast<AtImageBorder>((x == 0 | |
| | | ? LeftBorder | |
| | | : x == width-1 | |
| | | ? RightBorder | |
| | | : NotAtBorder) | | |
| | | (y == 0 | |
| | | ? TopBorder | |
| | | : y == height-1 | |
| | | ? BottomBorder | |
| | | : NotAtBorder)); | |
| | | } | |
| | | | |
| | | /********************************************************/ | |
| | | /* */ | |
| /* FourNeighborhood */ | | /* FourNeighborhood */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** Utilities for 4-neighborhood. */ | | /** Utilities for 4-neighborhood. */ | |
| namespace FourNeighborhood | | namespace FourNeighborhood | |
| { | | { | |
| | | | |
| /** \brief Encapsulation of direction management for 4-neighborhood. | | /** \brief Encapsulation of direction management for 4-neighborhood. | |
| | | | |
| | | | |
| skipping to change at line 83 | | skipping to change at line 149 | |
| | | | |
| If you want to pass 4-neighborhood codes as a template parameter, use | | If you want to pass 4-neighborhood codes as a template parameter, use | |
| the class FourNeighborhood::NeighborCode. | | the class FourNeighborhood::NeighborCode. | |
| | | | |
| <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | | <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | |
| Namespace: vigra::FourNeighborhood | | Namespace: vigra::FourNeighborhood | |
| */ | | */ | |
| class NeighborCode | | class NeighborCode | |
| { | | { | |
| public: | | public: | |
|
| /** Freeman direction codes for 4-neighborhood. | | /** Freeman direction codes for the 4-neighborhood. | |
| East = 0, North = 1 etc. | | <tt>East = 0</tt>, <tt>North = 1</tt> etc. | |
| DirectionCount may be used for portable loop termination condit | | <tt>DirectionCount</tt> may be used for portable loop terminati | |
| ions. | | on conditions. | |
| | | <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and | |
| | | last (inclusive) | |
| | | neighbors in the causal neighborhood, i.e. in the set of neighb | |
| | | ors that have | |
| | | already been visited when the image is traversed in scan order. | |
| | | <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the op | |
| | | posite. | |
| */ | | */ | |
| enum Direction { | | enum Direction { | |
|
| Error = -1, ///< | | Error = -1, ///< | |
| East = 0, ///< | | East = 0, ///< | |
| North, ///< | | North, ///< | |
| West, ///< | | West, ///< | |
| South, ///< | | South, ///< | |
| DirectionCount ///< | | DirectionCount, ///< | |
| | | CausalFirst = North, ///< | |
| | | CausalLast = West, ///< | |
| | | AntiCausalFirst = South, ///< | |
| | | AntiCausalLast = East ///< | |
| | | }; | |
| | | | |
| | | static unsigned int directionBit(Direction d) | |
| | | { | |
| | | static unsigned int b[] = {1 << (East + 1), | |
| | | 1 << (North + 1), | |
| | | 1 << (West + 1), | |
| | | 1 << (South + 1)}; | |
| | | return b[d]; | |
| }; | | }; | |
| | | | |
|
| | | /** The number of valid neighbors if the current center is at the i | |
| | | mage border. | |
| | | */ | |
| | | static unsigned int nearBorderDirectionCount(AtImageBorder b) | |
| | | { | |
| | | static unsigned int c[] = { 4, 3, 3, 0, 3, 2, 2, 0, 3, 2, 2}; | |
| | | return c[b]; | |
| | | } | |
| | | | |
| | | /** The valid direction codes when the center is at the image borde | |
| | | r. | |
| | | \a index must be in the range <tt>0...nearBorderDirectionCount( | |
| | | b)-1</tt>. | |
| | | */ | |
| | | static Direction nearBorderDirections(AtImageBorder b, int index) | |
| | | { | |
| | | static Direction c[11][4] = { | |
| | | { East, North, West, South}, | |
| | | { North, West, South, Error}, | |
| | | { East, North, South, Error}, | |
| | | { Error, Error, Error, Error}, | |
| | | { East, West, South, Error}, | |
| | | { West, South, Error, Error}, | |
| | | { East, South, Error, Error}, | |
| | | { Error, Error, Error, Error}, | |
| | | { East, North, West, Error}, | |
| | | { North, West, Error, Error}, | |
| | | { East, North, Error, Error} | |
| | | }; | |
| | | return c[b][index]; | |
| | | } | |
| | | | |
| /** Transform direction code into corresponding Diff2D offset. | | /** Transform direction code into corresponding Diff2D offset. | |
| (note: there is no bounds checking on the code you pass.) | | (note: there is no bounds checking on the code you pass.) | |
| */ | | */ | |
| static Diff2D const & diff(Direction code) | | static Diff2D const & diff(Direction code) | |
| { | | { | |
| static Diff2D d[] = { | | static Diff2D d[] = { | |
| Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1) | | Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1) | |
| }; | | }; | |
| return d[code]; | | return d[code]; | |
| } | | } | |
| | | | |
| skipping to change at line 208 | | skipping to change at line 320 | |
| /** Export NeighborCode::Direction into the scope of namespace FourNeig
hborhood. | | /** Export NeighborCode::Direction into the scope of namespace FourNeig
hborhood. | |
| */ | | */ | |
| typedef NeighborCode::Direction Direction; | | typedef NeighborCode::Direction Direction; | |
| | | | |
| static const Direction East = NeighborCode::East; /**<
Export NeighborCode::East to namespace FourNeighborhood */ | | static const Direction East = NeighborCode::East; /**<
Export NeighborCode::East to namespace FourNeighborhood */ | |
| static const Direction North = NeighborCode::North; /**<
Export NeighborCode::North to namespace FourNeighborhood */ | | static const Direction North = NeighborCode::North; /**<
Export NeighborCode::North to namespace FourNeighborhood */ | |
| static const Direction West = NeighborCode::West; /**<
Export NeighborCode::West to namespace FourNeighborhood */ | | static const Direction West = NeighborCode::West; /**<
Export NeighborCode::West to namespace FourNeighborhood */ | |
| static const Direction South = NeighborCode::South; /**<
Export NeighborCode::South to namespace FourNeighborhood */ | | static const Direction South = NeighborCode::South; /**<
Export NeighborCode::South to namespace FourNeighborhood */ | |
| static const Direction DirectionCount = NeighborCode::DirectionCount; /**<
Export NeighborCode::DirectionCount to namespace FourNeighborhood */ | | static const Direction DirectionCount = NeighborCode::DirectionCount; /**<
Export NeighborCode::DirectionCount to namespace FourNeighborhood */ | |
| | | | |
|
| | | inline Diff2D const & east() { return NeighborCode::diff(East); } | |
| | | /**< Offset to the east neighbor */ | |
| | | inline Diff2D const & north() { return NeighborCode::diff(North); } | |
| | | /**< Offset to the north neighbor */ | |
| | | inline Diff2D const & west() { return NeighborCode::diff(West); } | |
| | | /**< Offset to the west neighbor */ | |
| | | inline Diff2D const & south() { return NeighborCode::diff(South); } | |
| | | /**< Offset to the south neighbor */ | |
| | | | |
| } // namespace FourNeighborhood | | } // namespace FourNeighborhood | |
| | | | |
| /** Export \ref vigra::FourNeighborhood::NeighborCode into the scope of
namespace vigra. | | /** Export \ref vigra::FourNeighborhood::NeighborCode into the scope of
namespace vigra. | |
| */ | | */ | |
| typedef FourNeighborhood::NeighborCode FourNeighborCode; | | typedef FourNeighborhood::NeighborCode FourNeighborCode; | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* EightNeighborhood */ | | /* EightNeighborhood */ | |
| /* */ | | /* */ | |
| | | | |
| skipping to change at line 257 | | skipping to change at line 374 | |
| If you want to pass 8-neighborhood codes as a template parameter, use | | If you want to pass 8-neighborhood codes as a template parameter, use | |
| the class EightNeighborhood::NeighborCode. | | the class EightNeighborhood::NeighborCode. | |
| | | | |
| <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | | <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | |
| Namespace: vigra::EightNeighborhood | | Namespace: vigra::EightNeighborhood | |
| */ | | */ | |
| class NeighborCode | | class NeighborCode | |
| { | | { | |
| public: | | public: | |
| /** Freeman direction codes for the 8-neighborhood. | | /** Freeman direction codes for the 8-neighborhood. | |
|
| East = 0, NorthEast = 1 etc. | | <tt>East = 0</tt>, <tt>North = 1</tt> etc. | |
| DirectionCount may be used for portable loop termination condit | | <tt>DirectionCount</tt> may be used for portable loop terminati | |
| ions. | | on conditions. | |
| | | <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and | |
| | | last (inclusive) | |
| | | neighbors in the causal neighborhood, i.e. in the set of neighb | |
| | | ors that have | |
| | | already been visited when the image is traversed in scan order. | |
| | | <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the op | |
| | | posite. | |
| */ | | */ | |
| enum Direction { | | enum Direction { | |
| Error = -1, ///< | | Error = -1, ///< | |
| East = 0, ///< | | East = 0, ///< | |
| NorthEast, ///< | | NorthEast, ///< | |
| North, ///< | | North, ///< | |
| NorthWest, ///< | | NorthWest, ///< | |
| West, ///< | | West, ///< | |
| SouthWest, ///< | | SouthWest, ///< | |
| South, ///< | | South, ///< | |
| SouthEast, ///< | | SouthEast, ///< | |
|
| DirectionCount ///< | | DirectionCount, ///< | |
| | | CausalFirst = NorthEast, ///< | |
| | | CausalLast = West, ///< | |
| | | AntiCausalFirst = SouthWest, ///< | |
| | | AntiCausalLast = East ///< | |
| | | }; | |
| | | | |
| | | static unsigned int directionBit(Direction d) | |
| | | { | |
| | | static unsigned int b[] = {1 << (East + 1), | |
| | | 1 << (NorthEast + 1), | |
| | | 1 << (North + 1), | |
| | | 1 << (NorthWest + 1), | |
| | | 1 << (West + 1), | |
| | | 1 << (SouthWest + 1), | |
| | | 1 << (South + 1), | |
| | | 1 << (SouthEast + 1)}; | |
| | | return b[d]; | |
| }; | | }; | |
| | | | |
|
| | | /** The number of valid neighbors if the current center is at the i | |
| | | mage border. | |
| | | */ | |
| | | static unsigned int nearBorderDirectionCount(AtImageBorder b) | |
| | | { | |
| | | static unsigned int c[] = { 8, 5, 5, 0, 5, 3, 3, 0, 5, 3, 3}; | |
| | | return c[b]; | |
| | | } | |
| | | | |
| | | /** The valid direction codes when the center is at the image borde | |
| | | r. | |
| | | \a index must be in the range <tt>0...nearBorderDirectionCount( | |
| | | b)-1</tt>. | |
| | | */ | |
| | | static Direction nearBorderDirections(AtImageBorder b, int index) | |
| | | { | |
| | | static Direction c[11][8] = { | |
| | | { East, NorthEast, North, NorthWest, West, SouthWest, South | |
| | | , SouthEast}, | |
| | | { North, NorthWest, West, SouthWest, South, Error, Error, E | |
| | | rror}, | |
| | | { East, NorthEast, North, South, SouthEast, Error, Error, E | |
| | | rror}, | |
| | | { Error, Error, Error, Error, Error, Error, Error, Error}, | |
| | | { East, West, SouthWest, South, SouthEast, Error, Error, Er | |
| | | ror}, | |
| | | { West, SouthWest, South, Error, Error, Error, Error, Error | |
| | | }, | |
| | | { East, South, SouthEast, Error, Error, Error, Error, Error | |
| | | }, | |
| | | { Error, Error, Error, Error, Error, Error, Error, Error}, | |
| | | { East, NorthEast, North, NorthWest, West, Error, Error, Er | |
| | | ror}, | |
| | | { North, NorthWest, West, Error, Error, Error, Error, Error | |
| | | }, | |
| | | { East, NorthEast, North, Error, Error, Error, Error, Error | |
| | | } | |
| | | }; | |
| | | return c[b][index]; | |
| | | } | |
| | | | |
| /** Transform direction code into corresponding Diff2D offset. | | /** Transform direction code into corresponding Diff2D offset. | |
| (note: there is no bounds checking on the code you pass.) | | (note: there is no bounds checking on the code you pass.) | |
| */ | | */ | |
| static Diff2D const & diff(Direction code) | | static Diff2D const & diff(Direction code) | |
| { | | { | |
| static Diff2D d[] = { | | static Diff2D d[] = { | |
| Diff2D(1, 0), Diff2D(1, -1), Diff2D(0, -1), Diff2D(-1, -1), | | Diff2D(1, 0), Diff2D(1, -1), Diff2D(0, -1), Diff2D(-1, -1), | |
| Diff2D(-1, 0), Diff2D(-1, 1), Diff2D(0, 1), Diff2D(1, 1) | | Diff2D(-1, 0), Diff2D(-1, 1), Diff2D(0, 1), Diff2D(1, 1) | |
| }; | | }; | |
| return d[code]; | | return d[code]; | |
| | | | |
| skipping to change at line 430 | | skipping to change at line 597 | |
| static const Direction East = NeighborCode::East; /**< Ex
port NeighborCode::East to namespace EightNeighborhood */ | | static const Direction East = NeighborCode::East; /**< Ex
port NeighborCode::East to namespace EightNeighborhood */ | |
| static const Direction NorthEast = NeighborCode::NorthEast; /**< Ex
port NeighborCode::NorthEast to namespace EightNeighborhood */ | | static const Direction NorthEast = NeighborCode::NorthEast; /**< Ex
port NeighborCode::NorthEast to namespace EightNeighborhood */ | |
| static const Direction North = NeighborCode::North; /**< Ex
port NeighborCode::North to namespace EightNeighborhood */ | | static const Direction North = NeighborCode::North; /**< Ex
port NeighborCode::North to namespace EightNeighborhood */ | |
| static const Direction NorthWest = NeighborCode::NorthWest; /**< Ex
port NeighborCode::NorthWest to namespace EightNeighborhood */ | | static const Direction NorthWest = NeighborCode::NorthWest; /**< Ex
port NeighborCode::NorthWest to namespace EightNeighborhood */ | |
| static const Direction West = NeighborCode::West; /**< Ex
port NeighborCode::West to namespace EightNeighborhood */ | | static const Direction West = NeighborCode::West; /**< Ex
port NeighborCode::West to namespace EightNeighborhood */ | |
| static const Direction SouthWest = NeighborCode::SouthWest; /**< Ex
port NeighborCode::SouthWest to namespace EightNeighborhood */ | | static const Direction SouthWest = NeighborCode::SouthWest; /**< Ex
port NeighborCode::SouthWest to namespace EightNeighborhood */ | |
| static const Direction South = NeighborCode::South; /**< Ex
port NeighborCode::South to namespace EightNeighborhood */ | | static const Direction South = NeighborCode::South; /**< Ex
port NeighborCode::South to namespace EightNeighborhood */ | |
| static const Direction SouthEast = NeighborCode::SouthEast; /**< Ex
port NeighborCode::SouthEast to namespace EightNeighborhood */ | | static const Direction SouthEast = NeighborCode::SouthEast; /**< Ex
port NeighborCode::SouthEast to namespace EightNeighborhood */ | |
| static const Direction DirectionCount = NeighborCode::DirectionCount; /**
< Export NeighborCode::DirectionCount to namespace EightNeighborhood */ | | static const Direction DirectionCount = NeighborCode::DirectionCount; /**
< Export NeighborCode::DirectionCount to namespace EightNeighborhood */ | |
| | | | |
|
| | | inline Diff2D const & east() { return NeighborCode::diff(East); } | |
| | | /**< Offset to the east neighbor */ | |
| | | inline Diff2D const & northEast() { return NeighborCode::diff(NorthEast); | |
| | | } /**< Offset to the northEast neighbor */ | |
| | | inline Diff2D const & north() { return NeighborCode::diff(North); } | |
| | | /**< Offset to the north neighbor */ | |
| | | inline Diff2D const & northWest() { return NeighborCode::diff(NorthWest); | |
| | | } /**< Offset to the northWest neighbor */ | |
| | | inline Diff2D const & west() { return NeighborCode::diff(West); } | |
| | | /**< Offset to the west neighbor */ | |
| | | inline Diff2D const & southWest() { return NeighborCode::diff(SouthWest); | |
| | | } /**< Offset to the southWest neighbor */ | |
| | | inline Diff2D const & south() { return NeighborCode::diff(South); } | |
| | | /**< Offset to the south neighbor */ | |
| | | inline Diff2D const & southEast() { return NeighborCode::diff(SouthEast); | |
| | | } /**< Offset to the southEast neighbor */ | |
| | | | |
| } // namespace EightNeighborhood | | } // namespace EightNeighborhood | |
| | | | |
| /** Export \ref vigra::EightNeighborhood::NeighborCode into the scope o
f namespace vigra. | | /** Export \ref vigra::EightNeighborhood::NeighborCode into the scope o
f namespace vigra. | |
| */ | | */ | |
| typedef EightNeighborhood::NeighborCode EightNeighborCode; | | typedef EightNeighborhood::NeighborCode EightNeighborCode; | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* NeighborOffsetCirculator */ | | /* NeighborOffsetCirculator */ | |
| /* */ | | /* */ | |
| | | | |
| skipping to change at line 590 | | skipping to change at line 766 | |
| direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::Nor
th) % NEIGHBORCODE::DirectionCount); | | direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::Nor
th) % NEIGHBORCODE::DirectionCount); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** Move to the opposite direction of the current direction. | | /** Move to the opposite direction of the current direction. | |
| This is equivalent to <tt>four_circulator += 2</tt> and | | This is equivalent to <tt>four_circulator += 2</tt> and | |
| <tt>eight_circulator += 4</tt> respectively. | | <tt>eight_circulator += 4</tt> respectively. | |
| */ | | */ | |
| NeighborOffsetCirculator & turnRound() | | NeighborOffsetCirculator & turnRound() | |
| { | | { | |
|
| direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::Wes
t) % NEIGHBORCODE::DirectionCount); | | direction_ = opposite(); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** Move to the given direction. | | /** Move to the given direction. | |
| */ | | */ | |
| NeighborOffsetCirculator & turnTo(Direction d) | | NeighborOffsetCirculator & turnTo(Direction d) | |
| { | | { | |
| direction_ = d; | | direction_ = d; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 689 | | skipping to change at line 865 | |
| return NEIGHBORCODE::isDiagonal(direction_); | | return NEIGHBORCODE::isDiagonal(direction_); | |
| } | | } | |
| | | | |
| /** Get current direction. | | /** Get current direction. | |
| */ | | */ | |
| Direction direction() const | | Direction direction() const | |
| { | | { | |
| return direction_; | | return direction_; | |
| } | | } | |
| | | | |
|
| | | /** Get current direction bit. | |
| | | */ | |
| | | unsigned int directionBit() const | |
| | | { | |
| | | return NEIGHBORCODE::directionBit(direction_); | |
| | | } | |
| | | | |
| | | /** Get opposite of current direction. | |
| | | */ | |
| | | Direction opposite() const | |
| | | { | |
| | | return static_cast<Direction>((direction_ + NEIGHBORCODE::West) % N | |
| | | EIGHBORCODE::DirectionCount); | |
| | | } | |
| | | | |
| | | /** Get opposite bit of current direction. | |
| | | */ | |
| | | unsigned int oppositeDirectionBit() const | |
| | | { | |
| | | return NEIGHBORCODE::directionBit(opposite()); | |
| | | } | |
| | | | |
| /** Get direction code at offset of current direction. | | /** Get direction code at offset of current direction. | |
| */ | | */ | |
| Direction direction(difference_type offset) const | | Direction direction(difference_type offset) const | |
| { | | { | |
| int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount; | | int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount; | |
| if(result < 0) | | if(result < 0) | |
| result += NEIGHBORCODE::DirectionCount; | | result += NEIGHBORCODE::DirectionCount; | |
| return static_cast<Direction>(result); | | return static_cast<Direction>(result); | |
| } | | } | |
| }; | | }; | |
| | | | |
| skipping to change at line 723 | | skipping to change at line 920 | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* NeighborhoodCirculator */ | | /* NeighborhoodCirculator */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Circulator that walks around a given location in a given image. | | /** \brief Circulator that walks around a given location in a given image. | |
| | | | |
| The template parameters define the kind of neighborhood used and the un
derlying | | The template parameters define the kind of neighborhood used and the un
derlying | |
|
| image, e.g. | | image. The access functions return the value of the current neighbor pi | |
| | | xel. | |
| \code | | Use <tt>center()</tt> to access the center pixel of the neighborhood. | |
| NeighborhoodCirculator<BImage::traverser, EightNeighborCode> eight_circ | | The center can be changed by calling <tt>moveCenterToNeighbor()</tt> | |
| ulator(image.upperLeft()+Diff2D(2,2)); | | or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot | |
| NeighborhoodCirculator<BImage::traverser, FourNeighborCode> four_circu | | when the center is at the image border. You must then use | |
| lator(image.upperLeft()+Diff2D(2,2)); | | \ref vigra::RestrictedNeighborhoodCirculator | |
| \endcode | | | |
| | | | |
|
| The access functions return the value of the current neighbor pixel. Us | | <b>Usage:</b><br> | |
| e <tt>center()</tt> to | | | |
| access the center pixel of the neighborhood. The center can be changed | | | |
| by calling | | | |
| <tt>moveCenterToNeighbor()</tt> or <tt>swapCenterNeighbor()</tt>. | | | |
| | | | |
| <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | | <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi
xelneighborhood.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
|
| | | | |
| | | \code | |
| | | BImage::traverser upperleft(...), lowerright(...); | |
| | | | |
| | | int width = lowerright.x - upperleft.x; | |
| | | int height = lowerright.y - upperleft.y; | |
| | | | |
| | | ++upperleft.y; // avoide image border | |
| | | for(int y=1; y<height-1; ++y, ++upperleft.y) | |
| | | { | |
| | | BImage::traverser ix = upperleft + Diff2D(1,0); | |
| | | for(int x=1; x<width-1; ++x, ++ix.x) | |
| | | { | |
| | | // analyse all neighbors of a pixel (use FourNeighborCode | |
| | | // instead of EightNeighborCode for 4-neighborhood): | |
| | | NeighborhoodCirculator<BImage::traverser, EightNeighborCode> | |
| | | circulator(ix), | |
| | | end(circulator); | |
| | | do | |
| | | { | |
| | | analysisFunc(*circulator, ...); // do sth. with current nei | |
| | | ghbor | |
| | | } | |
| | | while(++circulator != end); // compare with start/end circulato | |
| | | r | |
| | | } | |
| | | } | |
| | | \endcode | |
| */ | | */ | |
| template <class IMAGEITERATOR, class NEIGHBORCODE> | | template <class IMAGEITERATOR, class NEIGHBORCODE> | |
| class NeighborhoodCirculator : private IMAGEITERATOR | | class NeighborhoodCirculator : private IMAGEITERATOR | |
| { | | { | |
| typedef NeighborOffsetCirculator<NEIGHBORCODE> NEIGHBOROFFSETCIRCULATOR
; | | typedef NeighborOffsetCirculator<NEIGHBORCODE> NEIGHBOROFFSETCIRCULATOR
; | |
| | | | |
| public: | | public: | |
| /** type of the underlying image iterator | | /** type of the underlying image iterator | |
| */ | | */ | |
| typedef IMAGEITERATOR base_type; | | typedef IMAGEITERATOR base_type; | |
| | | | |
| skipping to change at line 973 | | skipping to change at line 1194 | |
| { | | { | |
| return (base_type)*this - neighborCode_.diff(); | | return (base_type)*this - neighborCode_.diff(); | |
| } | | } | |
| | | | |
| /** Get the current direction. */ | | /** Get the current direction. */ | |
| Direction direction() const | | Direction direction() const | |
| { | | { | |
| return neighborCode_.direction(); | | return neighborCode_.direction(); | |
| } | | } | |
| | | | |
|
| | | /** Get the current direction bit. */ | |
| | | unsigned int directionBit() const | |
| | | { | |
| | | return neighborCode_.directionBit(); | |
| | | } | |
| | | | |
| /** Get the difference vector (Diff2D) from the center to the curre
nt neighbor. */ | | /** Get the difference vector (Diff2D) from the center to the curre
nt neighbor. */ | |
| Diff2D const & diff() const | | Diff2D const & diff() const | |
| { | | { | |
| return neighborCode_.diff(); | | return neighborCode_.diff(); | |
| } | | } | |
| | | | |
| /** Is the current neighbor a diagonal neighbor? */ | | /** Is the current neighbor a diagonal neighbor? */ | |
| bool isDiagonal() const | | bool isDiagonal() const | |
| { | | { | |
| return neighborCode_.isDiagonal(); | | return neighborCode_.isDiagonal(); | |
| } | | } | |
| | | | |
| private: | | private: | |
| NEIGHBOROFFSETCIRCULATOR neighborCode_; | | NEIGHBOROFFSETCIRCULATOR neighborCode_; | |
| }; | | }; | |
| | | | |
|
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* RestrictedNeighborhoodCirculator */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | /** \brief Circulator that walks around a given location in a given image, | |
| | | unsing a restricted neighborhood. | |
| | | | |
| | | This circulator behaves essentially like \ref vigra::NeighborhoodCircul | |
| | | ator, | |
| | | but can also be used near the image border, where some of the neighbor | |
| | | points | |
| | | would be outside the image und must not be accessed. | |
| | | The template parameters define the kind of neighborhood used (four or e | |
| | | ight) | |
| | | and the underlying image, whereas the required neighbirhood restriction | |
| | | is | |
| | | given by the last constructur argument. This below for typical usage. | |
| | | | |
| | | The access functions return the value of the current neighbor pixel. Us | |
| | | e <tt>center()</tt> to | |
| | | access the center pixel of the neighborhood. | |
| | | | |
| | | <b>Usage:</b><br> | |
| | | | |
| | | <b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi | |
| | | xelneighborhood.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | | |
| | | \code | |
| | | BImage::traverser upperleft(...), lowerright(...); | |
| | | | |
| | | int width = lowerright.x - upperleft.x; | |
| | | int height = lowerright.y - upperleft.y; | |
| | | | |
| | | for(int y=0; y<height; ++y, ++upperleft.y) | |
| | | { | |
| | | BImage::traverser ix = upperleft; | |
| | | for(int x=0; x<width; ++x, ++ix.x) | |
| | | { | |
| | | // use FourNeighborCode instead of EightNeighborCode for 4-neig | |
| | | hborhood | |
| | | RestrictedNeighborhoodCirculator<BImage::traverser, EightNeighb | |
| | | orCode> | |
| | | circulator(ix, isAtImageBorder(x, y, width, heig | |
| | | ht)), | |
| | | end(circulator); | |
| | | do | |
| | | { | |
| | | ... // do something with the circulator | |
| | | } | |
| | | while(++circulator != end); // out-of-range pixels will be auto | |
| | | matically skipped | |
| | | } | |
| | | } | |
| | | \endcode | |
| | | */ | |
| | | template <class IMAGEITERATOR, class NEIGHBORCODE> | |
| | | class RestrictedNeighborhoodCirculator | |
| | | : private NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE> | |
| | | { | |
| | | typedef NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE> BaseType; | |
| | | | |
| | | public: | |
| | | /** type of the underlying image iterator | |
| | | */ | |
| | | typedef IMAGEITERATOR base_type; | |
| | | | |
| | | /** type of the used neighbor code | |
| | | */ | |
| | | typedef NEIGHBORCODE NeighborCode; | |
| | | | |
| | | /** the circulator's value type | |
| | | */ | |
| | | typedef typename BaseType::value_type value_type; | |
| | | | |
| | | /** type of the direction code | |
| | | */ | |
| | | typedef typename BaseType::Direction Direction; | |
| | | | |
| | | /** the circulator's reference type (return type of <TT>*circ</TT>) | |
| | | */ | |
| | | typedef typename BaseType::reference reference; | |
| | | | |
| | | /** the circulator's index reference type (return type of <TT>circ[ | |
| | | n]</TT>) | |
| | | */ | |
| | | typedef typename BaseType::index_reference index_reference; | |
| | | | |
| | | /** the circulator's pointer type (return type of <TT>operator-></T | |
| | | T>) | |
| | | */ | |
| | | typedef typename BaseType::pointer pointer; | |
| | | | |
| | | /** the circulator's difference type (argument type of <TT>circ[dif | |
| | | f]</TT>) | |
| | | */ | |
| | | typedef typename BaseType::difference_type difference_type; | |
| | | | |
| | | /** the circulator tag (random_access_circulator_tag) | |
| | | */ | |
| | | typedef typename BaseType::iterator_category iterator_category; | |
| | | | |
| | | /** Construct circulator with given <tt>center</tt> pixel, using th | |
| | | e restricted | |
| | | neighborhood given by \a atBorder. | |
| | | */ | |
| | | RestrictedNeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEIT | |
| | | ERATOR(), | |
| | | AtImageBorder atBorder = NotAtBorder) | |
| | | : BaseType(center, NEIGHBORCODE::nearBorderDirections(atBorder, 0)) | |
| | | , | |
| | | whichBorder_(atBorder), | |
| | | count_(NEIGHBORCODE::nearBorderDirectionCount(atBorder)), | |
| | | current_(0) | |
| | | {} | |
| | | | |
| | | /** pre-increment */ | |
| | | RestrictedNeighborhoodCirculator & operator++() | |
| | | { | |
| | | return operator+=(1); | |
| | | } | |
| | | | |
| | | /** pre-decrement */ | |
| | | RestrictedNeighborhoodCirculator operator++(int) | |
| | | { | |
| | | RestrictedNeighborhoodCirculator ret(*this); | |
| | | operator++(); | |
| | | return ret; | |
| | | } | |
| | | | |
| | | /** post-increment */ | |
| | | RestrictedNeighborhoodCirculator & operator--() | |
| | | { | |
| | | return operator+=(-1); | |
| | | } | |
| | | | |
| | | /** post-decrement */ | |
| | | RestrictedNeighborhoodCirculator operator--(int) | |
| | | { | |
| | | RestrictedNeighborhoodCirculator ret(*this); | |
| | | operator--(); | |
| | | return ret; | |
| | | } | |
| | | | |
| | | /** add-assignment */ | |
| | | RestrictedNeighborhoodCirculator & operator+=(difference_type d) | |
| | | { | |
| | | current_ = static_cast<Direction>((current_ + count_ + d) % count_) | |
| | | ; | |
| | | BaseType::turnTo(NEIGHBORCODE::nearBorderDirections(whichBorder_, c | |
| | | urrent_)); | |
| | | return *this; | |
| | | } | |
| | | | |
| | | /** subtract-assignment */ | |
| | | RestrictedNeighborhoodCirculator & operator-=(difference_type d) | |
| | | { | |
| | | return operator+=(-d); | |
| | | } | |
| | | | |
| | | /** addition */ | |
| | | RestrictedNeighborhoodCirculator operator+(difference_type d) const | |
| | | { | |
| | | RestrictedNeighborhoodCirculator result(*this); | |
| | | result+= d; | |
| | | return result; | |
| | | } | |
| | | | |
| | | /** subtraction */ | |
| | | RestrictedNeighborhoodCirculator operator-(difference_type d) const | |
| | | { | |
| | | RestrictedNeighborhoodCirculator result(*this); | |
| | | result-= d; | |
| | | return result; | |
| | | } | |
| | | | |
| | | /** equality */ | |
| | | bool operator==(RestrictedNeighborhoodCirculator const & rhs) const | |
| | | { | |
| | | return current_ == rhs.current_; | |
| | | } | |
| | | | |
| | | /** inequality */ | |
| | | bool operator!=(RestrictedNeighborhoodCirculator const & rhs) const | |
| | | { | |
| | | return current_ != rhs.current_; | |
| | | } | |
| | | | |
| | | /** subtraction */ | |
| | | difference_type operator-(RestrictedNeighborhoodCirculator const & rhs) | |
| | | const | |
| | | { | |
| | | return (current_ - rhs.current_) % count_; | |
| | | } | |
| | | | |
| | | /** dereference */ | |
| | | reference operator*() const | |
| | | { | |
| | | return BaseType::operator*(); | |
| | | } | |
| | | | |
| | | /** member access */ | |
| | | pointer operator->() const | |
| | | { | |
| | | return BaseType::operator->(); | |
| | | } | |
| | | | |
| | | /** Get the base iterator for the current neighbor. */ | |
| | | base_type const & base() const | |
| | | { | |
| | | return BaseType::base(); | |
| | | } | |
| | | | |
| | | /** Get the base iterator for the center of the circulator. */ | |
| | | base_type center() const | |
| | | { | |
| | | return BaseType::center(); | |
| | | } | |
| | | | |
| | | /** Get the current direction. */ | |
| | | Direction direction() const | |
| | | { | |
| | | return BaseType::direction(); | |
| | | } | |
| | | | |
| | | /** Get the current direction bit. */ | |
| | | unsigned int directionBit() const | |
| | | { | |
| | | return BaseType::directionBit(); | |
| | | } | |
| | | | |
| | | /** Get the difference vector (Diff2D) from the center to the curre | |
| | | nt neighbor. */ | |
| | | Diff2D const & diff() const | |
| | | { | |
| | | return BaseType::diff(); | |
| | | } | |
| | | | |
| | | /** Is the current neighbor a diagonal neighbor? */ | |
| | | bool isDiagonal() const | |
| | | { | |
| | | return BaseType::isDiagonal(); | |
| | | } | |
| | | | |
| | | private: | |
| | | AtImageBorder whichBorder_; | |
| | | signed char count_, current_; | |
| | | }; | |
| | | | |
| //@} | | //@} | |
| | | | |
| } // namespace vigra | | } // namespace vigra | |
| | | | |
| #endif /* VIGRA_PIXELNEIGHBORHOOD_HXX */ | | #endif /* VIGRA_PIXELNEIGHBORHOOD_HXX */ | |
| | | | |
End of changes. 20 change blocks. |
| 38 lines changed or deleted | | 553 lines changed or added | |
|
| rgbvalue.hxx | | rgbvalue.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_RGBVALUE_HXX | | #ifndef VIGRA_RGBVALUE_HXX | |
| #define VIGRA_RGBVALUE_HXX | | #define VIGRA_RGBVALUE_HXX | |
| | | | |
| #include <cmath> // abs(double) | | #include <cmath> // abs(double) | |
| #include <cstdlib> // abs(int) | | #include <cstdlib> // abs(int) | |
| #include "vigra/config.hxx" | | #include "vigra/config.hxx" | |
| #include "vigra/numerictraits.hxx" | | #include "vigra/numerictraits.hxx" | |
| #include "vigra/accessor.hxx" | | #include "vigra/accessor.hxx" | |
| #include "vigra/tinyvector.hxx" | | #include "vigra/tinyvector.hxx" | |
|
| | | #include "vigra/static_assert.hxx" | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
|
| | | namespace detail { | |
| | | | |
| | | template <unsigned int I, unsigned int R, unsigned int G, unsigned int B> | |
| | | struct SelectColorIndexRHS; | |
| | | | |
| | | template <unsigned int R, unsigned int G, unsigned int B> | |
| | | struct SelectColorIndexRHS<0, R, G, B> | |
| | | { | |
| | | enum { res = R }; | |
| | | }; | |
| | | | |
| | | template <unsigned int R, unsigned int G, unsigned int B> | |
| | | struct SelectColorIndexRHS<1, R, G, B> | |
| | | { | |
| | | enum { res = G }; | |
| | | }; | |
| | | | |
| | | template <unsigned int R, unsigned int G, unsigned int B> | |
| | | struct SelectColorIndexRHS<2, R, G, B> | |
| | | { | |
| | | enum { res = B }; | |
| | | }; | |
| | | | |
| | | } // namespace detail | |
| | | | |
| | | #ifndef DOXYGEN | |
| | | | |
| | | template <unsigned int R, unsigned int G, unsigned int B> | |
| | | struct RGBValue_bad_color_indices | |
| | | : staticAssert::AssertBool<(R < 3 && G < 3 && B < 3 && | |
| | | ((1 << R) + (1 << G) + (1 << B) == 7))> | |
| | | {}; | |
| | | | |
| | | #endif /* DOXYGEN */ | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* RGBValue */ | | /* RGBValue */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \brief Class for a single RGB value. | | /** \brief Class for a single RGB value. | |
| | | | |
| This class contains three values (of the specified type) that represent | | This class contains three values (of the specified type) that represent | |
|
| red, green, and blue color channels. There are three possibilities | | red, green, and blue color channels. By means of the template parameter | |
| to access these values: accessor functions (\ref red(), \ref green(), | | s | |
| \ref blue()), index operator (operator[](dx), where 0 is red, | | <tt>RED_IDX, GREEN_IDX, BLUE_IDX</tt>, the indices 0, 1, 2 can be assig | |
| 1 is green and 2 is blue) and iterator (STL-compatible random access | | ned to | |
| | | the three colors arbitrarily, so that, for example, a BGR type can be c | |
| | | reated | |
| | | as | |
| | | | |
| | | \code | |
| | | typedef RGBValue<unsigned char, 2,1,0> BGRValue; | |
| | | \endcode | |
| | | | |
| | | The standard order red=0, green=1, blue=2 is the default. There are thr | |
| | | ee possibilities | |
| | | to access the color values: accessor functions (\ref red(), \ref green( | |
| | | ), | |
| | | \ref blue()), index operator (operator[](dx), where the <tt>rgb[RED_IDX | |
| | | ]</tt> | |
| | | returns red etc.) and iterator (STL-compatible random access | |
| iterator that references the three colors in turn). The latter two | | iterator that references the three colors in turn). The latter two | |
| methods, together with the necessary embedded typedefs, ensure | | methods, together with the necessary embedded typedefs, ensure | |
| compatibility of a RGBValue with a STL vector. | | compatibility of a RGBValue with a STL vector. | |
| | | | |
| \ref RGBValueOperators "Arithmetic operations" are defined as component
-wise applications of these | | \ref RGBValueOperators "Arithmetic operations" are defined as component
-wise applications of these | |
| operations. Addition, subtraction, and multiplication of two RGBValues | | operations. Addition, subtraction, and multiplication of two RGBValues | |
| (+=, -=, *=, +, -, *, unary -), multiplication and division of an | | (+=, -=, *=, +, -, *, unary -), multiplication and division of an | |
| RGBValue with a double, and NumericTraits/PromoteTraits are defined, | | RGBValue with a double, and NumericTraits/PromoteTraits are defined, | |
| so that RGBValue fulfills the requirements of a \ref LinearAlgebra. | | so that RGBValue fulfills the requirements of a \ref LinearAlgebra. | |
| | | | |
| A number of \ref RGBValueAccessors "accessors" are provided | | A number of \ref RGBValueAccessors "accessors" are provided | |
| that support access to RGBValues as a whole, to a selected | | that support access to RGBValues as a whole, to a selected | |
| color component, or to the luminance value. | | color component, or to the luminance value. | |
| | | | |
| <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx
x</a>"<br> | | <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx
x</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
|
| template <class VALUETYPE> | | template <class VALUETYPE, unsigned int RED_IDX = 0, unsigned int GREEN_IDX
= 1, unsigned int BLUE_IDX = 2> | |
| class RGBValue | | class RGBValue | |
| : public TinyVector<VALUETYPE, 3> | | : public TinyVector<VALUETYPE, 3> | |
| { | | { | |
| typedef TinyVector<VALUETYPE, 3> Base; | | typedef TinyVector<VALUETYPE, 3> Base; | |
|
| | | | |
| | | // inverse mapping from index to color | |
| | | enum { | |
| | | IDX0 = (RED_IDX == 0) ? 0 : (GREEN_IDX == 0) ? 1 : 2, | |
| | | IDX1 = (RED_IDX == 1) ? 0 : (GREEN_IDX == 1) ? 1 : 2, | |
| | | IDX2 = (RED_IDX == 2) ? 0 : (GREEN_IDX == 2) ? 1 : 2 | |
| | | }; | |
| | | | |
| public: | | public: | |
| /** STL-compatible definition of valuetype | | /** STL-compatible definition of valuetype | |
| */ | | */ | |
|
| typedef VALUETYPE value_type; | | typedef typename Base::value_type value_type; | |
| /** STL-compatible definition of iterator | | /** STL-compatible definition of iterator | |
| */ | | */ | |
|
| typedef typename TinyVector<VALUETYPE, 3>::iterator iterator; | | typedef typename Base::iterator iterator; | |
| /** STL-compatible definition of const iterator | | /** STL-compatible definition of const iterator | |
| */ | | */ | |
|
| typedef typename TinyVector<VALUETYPE, 3>::const_iterator const_iterato
r; | | typedef typename Base::const_iterator const_iterator; | |
| /** squared norm type (result of squaredManitude()) | | /** squared norm type (result of squaredManitude()) | |
| */ | | */ | |
|
| typedef typename TinyVector<VALUETYPE, 3>::SquaredNormType SquaredNormT
ype; | | typedef typename Base::SquaredNormType SquaredNormType; | |
| /** norm type (result of magnitude()) | | /** norm type (result of magnitude()) | |
| */ | | */ | |
|
| typedef typename TinyVector<VALUETYPE, 3>::NormType NormType; | | typedef typename Base::NormType NormType; | |
| | | | |
|
| /** Construct from explicit color values | | /** Color index positions | |
| */ | | */ | |
|
| RGBValue(value_type red, value_type green, value_type blue) | | enum | |
| : Base(red, green, blue) | | { | |
| {} | | RedIdx = RED_IDX, | |
| | | GreenIdx = GREEN_IDX, | |
| | | BlueIdx = BLUE_IDX | |
| | | }; | |
| | | | |
| | | /** Construct from explicit color values. | |
| | | \a first, \a second, \a third are written in this order, | |
| | | irrespective of how the color indices are specified. | |
| | | */ | |
| | | RGBValue(value_type first, value_type second, value_type third) | |
| | | : Base(first, second, third) | |
| | | { | |
| | | VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, | |
| | | BLUE_IDX>)); | |
| | | } | |
| | | | |
| /** Construct gray value | | /** Construct gray value | |
| */ | | */ | |
| RGBValue(value_type gray) | | RGBValue(value_type gray) | |
| : Base(gray, gray, gray) | | : Base(gray, gray, gray) | |
|
| {} | | { | |
| | | VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, | |
| | | BLUE_IDX>)); | |
| | | } | |
| | | | |
| /** Construct from another sequence (must have length 3!) | | /** Construct from another sequence (must have length 3!) | |
| */ | | */ | |
| template <class Iterator> | | template <class Iterator> | |
| RGBValue(Iterator i, Iterator end) | | RGBValue(Iterator i, Iterator end) | |
| : Base(i[0], i[1], i[2]) | | : Base(i[0], i[1], i[2]) | |
|
| {} | | { | |
| | | VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, | |
| | | BLUE_IDX>)); | |
| | | } | |
| | | | |
| /** Default constructor (sets all components to 0) | | /** Default constructor (sets all components to 0) | |
| */ | | */ | |
| RGBValue() | | RGBValue() | |
| : Base(0, 0, 0) | | : Base(0, 0, 0) | |
|
| {} | | { | |
| | | VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, | |
| | | BLUE_IDX>)); | |
| | | } | |
| | | | |
| #if !defined(TEMPLATE_COPY_CONSTRUCTOR_BUG) | | #if !defined(TEMPLATE_COPY_CONSTRUCTOR_BUG) | |
| | | | |
| RGBValue(RGBValue const & r) | | RGBValue(RGBValue const & r) | |
| : Base(r) | | : Base(r) | |
|
| {} | | { | |
| | | VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, | |
| | | BLUE_IDX>)); | |
| | | } | |
| | | | |
| RGBValue & operator=(RGBValue const & r) | | RGBValue & operator=(RGBValue const & r) | |
| { | | { | |
| Base::operator=(r); | | Base::operator=(r); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| #endif // TEMPLATE_COPY_CONSTRUCTOR_BUG | | #endif // TEMPLATE_COPY_CONSTRUCTOR_BUG | |
| | | | |
| /** Copy constructor. | | /** Copy constructor. | |
| */ | | */ | |
|
| template <class U> | | template <class U, unsigned int R, unsigned int G, unsigned int B> | |
| RGBValue(RGBValue<U> const & r) | | RGBValue(RGBValue<U, R, G, B> const & r) | |
| : Base(r) | | : Base(detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectC | |
| {} | | olorIndexRHS<IDX0, R, G, B>::res]), | |
| | | detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectC | |
| | | olorIndexRHS<IDX1, R, G, B>::res]), | |
| | | detail::RequiresExplicitCast<value_type>::cast(r[detail::SelectC | |
| | | olorIndexRHS<IDX2, R, G, B>::res])) | |
| | | { | |
| | | VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, | |
| | | BLUE_IDX>)); | |
| | | } | |
| | | | |
| /** Copy assignment. | | /** Copy assignment. | |
| */ | | */ | |
|
| template <class U> | | template <class U, unsigned int R, unsigned int G, unsigned int B> | |
| RGBValue & operator=(RGBValue<U> const & r) | | RGBValue & operator=(RGBValue<U, R, G, B> const & r) | |
| { | | { | |
|
| Base::operator=(r); | | setRed(detail::RequiresExplicitCast<value_type>::cast(r.red())); | |
| | | setGreen(detail::RequiresExplicitCast<value_type>::cast(r.green())) | |
| | | ; | |
| | | setBlue(detail::RequiresExplicitCast<value_type>::cast(r.blue())); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** construct from TinyVector | | /** construct from TinyVector | |
| */ | | */ | |
| RGBValue(TinyVector<value_type, 3> const & r) | | RGBValue(TinyVector<value_type, 3> const & r) | |
| : Base(r) | | : Base(r) | |
|
| {} | | { | |
| | | VIGRA_STATIC_ASSERT((RGBValue_bad_color_indices<RED_IDX, GREEN_IDX, | |
| | | BLUE_IDX>)); | |
| | | } | |
| | | | |
| /** assign TinyVector. | | /** assign TinyVector. | |
| */ | | */ | |
| RGBValue & operator=(TinyVector<value_type, 3> const & r) | | RGBValue & operator=(TinyVector<value_type, 3> const & r) | |
| { | | { | |
| Base::operator=(r); | | Base::operator=(r); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| /** Unary negation (construct RGBValue with negative values) | | /** Unary negation (construct RGBValue with negative values) | |
| */ | | */ | |
| RGBValue operator-() const | | RGBValue operator-() const | |
| { | | { | |
| return RGBValue(-red(), -green(), -blue()); | | return RGBValue(-red(), -green(), -blue()); | |
| } | | } | |
| | | | |
| /** Access red component. | | /** Access red component. | |
| */ | | */ | |
|
| value_type & red() { return (*this)[0]; } | | value_type & red() { return (*this)[RED_IDX]; } | |
| | | | |
| /** Access green component. | | /** Access green component. | |
| */ | | */ | |
|
| value_type & green() { return (*this)[1]; } | | value_type & green() { return (*this)[GREEN_IDX]; } | |
| | | | |
| /** Access blue component. | | /** Access blue component. | |
| */ | | */ | |
|
| value_type & blue() { return (*this)[2]; } | | value_type & blue() { return (*this)[BLUE_IDX]; } | |
| | | | |
| /** Get red component. | | /** Get red component. | |
| */ | | */ | |
|
| value_type const & red() const { return (*this)[0]; } | | value_type const & red() const { return (*this)[RED_IDX]; } | |
| | | | |
| /** Get green component. | | /** Get green component. | |
| */ | | */ | |
|
| value_type const & green() const { return (*this)[1]; } | | value_type const & green() const { return (*this)[GREEN_IDX]; } | |
| | | | |
| /** Get blue component. | | /** Get blue component. | |
| */ | | */ | |
|
| value_type const & blue() const { return (*this)[2]; } | | value_type const & blue() const { return (*this)[BLUE_IDX]; } | |
| | | | |
| /** Calculate luminance. | | /** Calculate luminance. | |
| */ | | */ | |
| value_type luminance() const { | | value_type luminance() const { | |
| return detail::RequiresExplicitCast<value_type>::cast(0.3*red() +
0.59*green() + 0.11*blue()); } | | return detail::RequiresExplicitCast<value_type>::cast(0.3*red() +
0.59*green() + 0.11*blue()); } | |
| | | | |
| /** Calculate magnitude. | | /** Calculate magnitude. | |
| */ | | */ | |
| NormType magnitude() const { | | NormType magnitude() const { | |
|
| return VIGRA_CSTD::sqrt( | | return Base::magnitude(); | |
| (typename NumericTraits<VALUETYPE>::RealPromote)squaredMagnitud | | | |
| e()); | | | |
| } | | } | |
| | | | |
| /** Calculate squared magnitude. | | /** Calculate squared magnitude. | |
| */ | | */ | |
| SquaredNormType squaredMagnitude() const { | | SquaredNormType squaredMagnitude() const { | |
|
| return red()*red() + green()*green() + blue()*blue(); | | return Base::squaredMagnitude(); | |
| } | | } | |
| | | | |
| /** Set red component. The type <TT>V</TT> of the passed | | /** Set red component. The type <TT>V</TT> of the passed | |
| in <TT>value</TT> is automatically converted to <TT>VALUETYPE</
TT>. | | in <TT>value</TT> is automatically converted to <TT>VALUETYPE</
TT>. | |
| */ | | */ | |
| template <class V> | | template <class V> | |
|
| void setRed(V value) { (*this)[0] = detail::RequiresExplicitCast<value_
type>::cast(value); } | | void setRed(V value) { (*this)[RED_IDX] = detail::RequiresExplicitCast<
value_type>::cast(value); } | |
| | | | |
| /** Set green component.The type <TT>V</TT> of the passed | | /** Set green component.The type <TT>V</TT> of the passed | |
| in <TT>value</TT> is automatically converted to <TT>VALUETYPE</
TT>. | | in <TT>value</TT> is automatically converted to <TT>VALUETYPE</
TT>. | |
| */ | | */ | |
| template <class V> | | template <class V> | |
|
| void setGreen(V value) { (*this)[1] = detail::RequiresExplicitCast<valu
e_type>::cast(value); } | | void setGreen(V value) { (*this)[GREEN_IDX] = detail::RequiresExplicitC
ast<value_type>::cast(value); } | |
| | | | |
| /** Set blue component.The type <TT>V</TT> of the passed | | /** Set blue component.The type <TT>V</TT> of the passed | |
| in <TT>value</TT> is automatically converted to <TT>VALUETYPE</
TT>. | | in <TT>value</TT> is automatically converted to <TT>VALUETYPE</
TT>. | |
| */ | | */ | |
| template <class V> | | template <class V> | |
|
| void setBlue(V value) { (*this)[2] = detail::RequiresExplicitCast<value
_type>::cast(value); } | | void setBlue(V value) { (*this)[BLUE_IDX] = detail::RequiresExplicitCas
t<value_type>::cast(value); } | |
| | | | |
| template <class V> | | template <class V> | |
| void setRGB(V r, V g, V b) | | void setRGB(V r, V g, V b) | |
| { | | { | |
|
| (*this)[0] = detail::RequiresExplicitCast<value_type>::cast(r); | | (*this)[RED_IDX] = detail::RequiresExplicitCast<value_type>::cast(r | |
| (*this)[1] = detail::RequiresExplicitCast<value_type>::cast(g); | | ); | |
| (*this)[2] = detail::RequiresExplicitCast<value_type>::cast(b); | | (*this)[GREEN_IDX] = detail::RequiresExplicitCast<value_type>::cast | |
| | | (g); | |
| | | (*this)[BLUE_IDX] = detail::RequiresExplicitCast<value_type>::cast( | |
| | | b); | |
| } | | } | |
| }; | | }; | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* RGBValue Comparison */ | | /* RGBValue Comparison */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \addtogroup RGBValueOperators Functions for RGBValue | | /** \addtogroup RGBValueOperators Functions for RGBValue | |
| | | | |
| skipping to change at line 251 | | skipping to change at line 347 | |
| | | | |
| These functions fulfill the requirements of a Linear Algebra. | | These functions fulfill the requirements of a Linear Algebra. | |
| Return types are determined according to \ref RGBValueTraits. | | Return types are determined according to \ref RGBValueTraits. | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| <p> | | <p> | |
| | | | |
| */ | | */ | |
| //@{ | | //@{ | |
| /// component-wise equal | | /// component-wise equal | |
|
| template <class V1, class V2> | | template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI | |
| | | DX1, | |
| | | class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI | |
| | | DX2> | |
| inline | | inline | |
| bool | | bool | |
|
| operator==(RGBValue<V1> const & l, RGBValue<V2> const & r) | | operator==(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l, | |
| | | RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r) | |
| { | | { | |
| return (l.red() == r.red()) && | | return (l.red() == r.red()) && | |
|
| (l.green() == r.green()) && | | (l.green() == r.green()) && | |
| (l.blue() == r.blue()); | | (l.blue() == r.blue()); | |
| } | | } | |
| | | | |
| /// component-wise not equal | | /// component-wise not equal | |
|
| template <class V1, class V2> | | template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI | |
| | | DX1, | |
| | | class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI | |
| | | DX2> | |
| inline | | inline | |
| bool | | bool | |
|
| operator!=(RGBValue<V1> const & l, RGBValue<V2> const & r) | | operator!=(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & l, | |
| | | RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r) | |
| { | | { | |
| return (l.red() != r.red()) || | | return (l.red() != r.red()) || | |
|
| (l.green() != r.green()) || | | (l.green() != r.green()) || | |
| (l.blue() != r.blue()); | | (l.blue() != r.blue()); | |
| } | | } | |
| | | | |
| //@} | | //@} | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* RGBValue-Traits */ | | /* RGBValue-Traits */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \page RGBValueTraits Numeric and Promote Traits of RGBValue | | /** \page RGBValueTraits Numeric and Promote Traits of RGBValue | |
| The numeric and promote traits for RGBValues follow | | The numeric and promote traits for RGBValues follow | |
| the general specifications for \ref NumericPromotionTraits. | | the general specifications for \ref NumericPromotionTraits. | |
| They are implemented in terms of the traits of the basic types by | | They are implemented in terms of the traits of the basic types by | |
|
| partial template specialization: | | partial template specialization. Note that PromoteTraits are only defin | |
| | | ed | |
| | | for the case that the color indices are the same in both RGBValues. | |
| | | | |
| \code | | \code | |
| | | | |
|
| template <class T> | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| struct NumericTraits<RGBValue<T> > | | struct NumericTraits<RGBValue<T, R, G, B> > | |
| { | | { | |
|
| typedef RGBValue<typename NumericTraits<T>::Promote> Promote; | | typedef RGBValue<T, R, G, B> Type; | |
| typedef RGBValue<typename NumericTraits<T>::RealPromote> RealPromot | | typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promo | |
| e; | | te; | |
| | | typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> R | |
| | | ealPromote; | |
| | | typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B | |
| | | > ComplexPromote; | |
| | | typedef T ValueType; | |
| | | | |
| typedef typename NumericTraits<T>::isIntegral isIntegral; | | typedef typename NumericTraits<T>::isIntegral isIntegral; | |
| typedef VigraFalseType isScalar; | | typedef VigraFalseType isScalar; | |
|
| | | typedef typename NumericTraits<T>::isSigned isSigned; | |
| | | | |
| // etc. | | // etc. | |
| }; | | }; | |
| | | | |
|
| template <class T> | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| struct NormTraits<RGBValue<T> > | | struct NormTraits<RGBValue<T, R, G, B> > | |
| { | | { | |
|
| typedef RGBValue<T> Type; | | typedef RGBValue<T, R, G, B> Type; | |
| typedef typename Type::SquaredNormType SquaredNormType; | | typedef typename Type::SquaredNormType SquaredNormType; | |
| typedef typename Type::NormType NormType; | | typedef typename Type::NormType NormType; | |
| }; | | }; | |
| | | | |
|
| template <class T1, class T2> | | template <class T1, unsigned int R, unsigned int G, unsigned int B, cla | |
| struct PromoteTraits<RGBValue<T1>, RGBValue<T2> > | | ss T2> | |
| | | struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> > | |
| { | | { | |
|
| typedef RGBValue<typename PromoteTraits<T1, T2>::Promote> Promote; | | typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> | |
| | | Promote; | |
| | | }; | |
| | | | |
| | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| | | struct PromoteTraits<RGBValue<T, R, G, B>, double > | |
| | | { | |
| | | typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> P | |
| | | romote; | |
| | | }; | |
| | | | |
| | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| | | struct PromoteTraits<double, RGBValue<T, R, G, B> > | |
| | | { | |
| | | typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> P | |
| | | romote; | |
| }; | | }; | |
| \endcode | | \endcode | |
| | | | |
| <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx
x</a>"<br> | | <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx
x</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| | | | |
| */ | | */ | |
| | | | |
| #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION) | | #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION) | |
| | | | |
|
| template <class T> | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| struct NumericTraits<RGBValue<T> > | | struct NumericTraits<RGBValue<T, R, G, B> > | |
| { | | { | |
|
| typedef RGBValue<T> Type; | | typedef RGBValue<T, R, G, B> Type; | |
| typedef RGBValue<typename NumericTraits<T>::Promote> Promote; | | typedef RGBValue<typename NumericTraits<T>::Promote, R, G, B> Promote; | |
| typedef RGBValue<typename NumericTraits<T>::RealPromote> RealPromote; | | typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> RealP | |
| typedef RGBValue<typename NumericTraits<T>::ComplexPromote> ComplexProm | | romote; | |
| ote; | | typedef RGBValue<typename NumericTraits<T>::ComplexPromote, R, G, B> Co | |
| | | mplexPromote; | |
| typedef T ValueType; | | typedef T ValueType; | |
| | | | |
| typedef typename NumericTraits<T>::isIntegral isIntegral; | | typedef typename NumericTraits<T>::isIntegral isIntegral; | |
| typedef VigraFalseType isScalar; | | typedef VigraFalseType isScalar; | |
|
| | | typedef typename NumericTraits<T>::isSigned isSigned; | |
| typedef VigraFalseType isOrdered; | | typedef VigraFalseType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
|
| static RGBValue<T> zero() { | | static Type zero() { | |
| return RGBValue<T>(NumericTraits<T>::zero()); | | return Type(NumericTraits<T>::zero()); | |
| } | | } | |
|
| static RGBValue<T> one() { | | static Type one() { | |
| return RGBValue<T>(NumericTraits<T>::one()); | | return Type(NumericTraits<T>::one()); | |
| } | | } | |
|
| static RGBValue<T> nonZero() { | | static Type nonZero() { | |
| return RGBValue<T>(NumericTraits<T>::nonZero()); | | return Type(NumericTraits<T>::nonZero()); | |
| } | | } | |
| | | | |
|
| static Promote toPromote(RGBValue<T> const & v) { | | static Promote toPromote(Type const & v) { | |
| return Promote(v); | | return Promote(v); | |
| } | | } | |
|
| static RealPromote toRealPromote(RGBValue<T> const & v) { | | static RealPromote toRealPromote(Type const & v) { | |
| return RealPromote(v); | | return RealPromote(v); | |
| } | | } | |
|
| static RGBValue<T> fromPromote(Promote const & v) { | | static Type fromPromote(Promote const & v) { | |
| return RGBValue<T>(NumericTraits<T>::fromPromote(v.red()), | | return Type(NumericTraits<T>::fromPromote(v.red()), | |
| NumericTraits<T>::fromPromote(v.green()), | | NumericTraits<T>::fromPromote(v.green()), | |
| NumericTraits<T>::fromPromote(v.blue())); | | NumericTraits<T>::fromPromote(v.blue())); | |
| } | | } | |
|
| static RGBValue<T> fromRealPromote(RealPromote const & v) { | | static Type fromRealPromote(RealPromote const & v) { | |
| return RGBValue<T>(NumericTraits<T>::fromRealPromote(v.red()), | | return Type(NumericTraits<T>::fromRealPromote(v.red()), | |
| NumericTraits<T>::fromRealPromote(v.green()), | | NumericTraits<T>::fromRealPromote(v.green()), | |
| NumericTraits<T>::fromRealPromote(v.blue())); | | NumericTraits<T>::fromRealPromote(v.blue())); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| template <class T> | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| struct NormTraits<RGBValue<T> > | | struct NormTraits<RGBValue<T, R, G, B> > | |
| { | | { | |
|
| typedef RGBValue<T> Type; | | typedef RGBValue<T, R, G, B> Type; | |
| typedef typename Type::SquaredNormType SquaredNormType; | | typedef typename Type::SquaredNormType SquaredNormType; | |
| typedef typename Type::NormType NormType; | | typedef typename Type::NormType NormType; | |
| }; | | }; | |
| | | | |
|
| template <class T1, class T2> | | template <class T1, unsigned int R, unsigned int G, unsigned int B, class T | |
| struct PromoteTraits<RGBValue<T1>, RGBValue<T2> > | | 2> | |
| | | struct PromoteTraits<RGBValue<T1, R, G, B>, RGBValue<T2, R, G, B> > | |
| { | | { | |
|
| typedef RGBValue<typename PromoteTraits<T1, T2>::Promote> Promote; | | typedef RGBValue<typename PromoteTraits<T1, T2>::Promote, R, G, B> Prom
ote; | |
| }; | | }; | |
| | | | |
|
| template <class T> | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| struct PromoteTraits<RGBValue<T>, double > | | struct PromoteTraits<RGBValue<T, R, G, B>, double > | |
| { | | { | |
|
| typedef RGBValue<typename NumericTraits<T>::RealPromote> Promote; | | typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promo
te; | |
| }; | | }; | |
| | | | |
|
| template <class T> | | template <class T, unsigned int R, unsigned int G, unsigned int B> | |
| struct PromoteTraits<double, RGBValue<T> > | | struct PromoteTraits<double, RGBValue<T, R, G, B> > | |
| { | | { | |
|
| typedef RGBValue<typename NumericTraits<T>::RealPromote> Promote; | | typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> Promo
te; | |
| }; | | }; | |
| | | | |
| #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION | | #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION | |
| | | | |
| #define RGBVALUE_NUMTRAITS(T) \ | | #define RGBVALUE_NUMTRAITS(T) \ | |
| template<>\ | | template<>\ | |
|
| struct NumericTraits<RGBValue<T> >\ | | struct NumericTraits<RGBValue<T, 0, 1, 2> >\ | |
| {\ | | {\ | |
| typedef RGBValue<T> Type; \ | | typedef RGBValue<T> Type; \ | |
| typedef RGBValue<NumericTraits<T>::Promote> Promote; \ | | typedef RGBValue<NumericTraits<T>::Promote> Promote; \ | |
| typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \ | | typedef RGBValue<NumericTraits<T>::RealPromote> RealPromote; \ | |
| typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \ | | typedef RGBValue<NumericTraits<T>::ComplexPromote> ComplexPromote; \ | |
| typedef T ValueType; \ | | typedef T ValueType; \ | |
| \ | | \ | |
| typedef NumericTraits<T>::isIntegral isIntegral; \ | | typedef NumericTraits<T>::isIntegral isIntegral; \ | |
| typedef VigraFalseType isScalar; \ | | typedef VigraFalseType isScalar; \ | |
|
| | | typedef NumericTraits<T>::isSigned isSigned; \ | |
| typedef VigraFalseType isOrdered; \ | | typedef VigraFalseType isOrdered; \ | |
| typedef VigraFalseType isComplex; \ | | typedef VigraFalseType isComplex; \ | |
| \ | | \ | |
| static RGBValue<T> zero() { \ | | static RGBValue<T> zero() { \ | |
| return RGBValue<T>(NumericTraits<T>::zero()); \ | | return RGBValue<T>(NumericTraits<T>::zero()); \ | |
| }\ | | }\ | |
| static RGBValue<T> one() { \ | | static RGBValue<T> one() { \ | |
| return RGBValue<T>(NumericTraits<T>::one()); \ | | return RGBValue<T>(NumericTraits<T>::one()); \ | |
| }\ | | }\ | |
| static RGBValue<T> nonZero() { \ | | static RGBValue<T> nonZero() { \ | |
| | | | |
| skipping to change at line 441 | | skipping to change at line 560 | |
| static RGBValue<T> fromRealPromote(RealPromote const & v) {\ | | static RGBValue<T> fromRealPromote(RealPromote const & v) {\ | |
| RGBValue<T> res;\ | | RGBValue<T> res;\ | |
| RGBValue<T>::iterator d = res.begin();\ | | RGBValue<T>::iterator d = res.begin();\ | |
| RealPromote::const_iterator s = v.begin();\ | | RealPromote::const_iterator s = v.begin();\ | |
| for(; d != res.end(); ++d, ++s)\ | | for(; d != res.end(); ++d, ++s)\ | |
| *d = NumericTraits<T>::fromRealPromote(*s);\ | | *d = NumericTraits<T>::fromRealPromote(*s);\ | |
| return res;\ | | return res;\ | |
| }\ | | }\ | |
| }; \ | | }; \ | |
| template<>\ | | template<>\ | |
|
| struct NormTraits<RGBValue<T> >\ | | struct NormTraits<RGBValue<T, 0, 1, 2> >\ | |
| {\ | | {\ | |
| typedef RGBValue<T> Type;\ | | typedef RGBValue<T> Type;\ | |
| typedef Type::SquaredNormType SquaredNormType; \ | | typedef Type::SquaredNormType SquaredNormType; \ | |
| typedef Type::NormType NormType; \ | | typedef Type::NormType NormType; \ | |
| }; | | }; | |
| | | | |
| #define RGBVALUE_PROMTRAITS1(type1) \ | | #define RGBVALUE_PROMTRAITS1(type1) \ | |
| template<> \ | | template<> \ | |
|
| struct PromoteTraits<RGBValue<type1>, RGBValue<type1> > \ | | struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type1, 0, 1, 2> > \ | |
| { \ | | { \ | |
| typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \ | | typedef RGBValue<PromoteTraits<type1, type1>::Promote> Promote; \ | |
| static Promote toPromote(RGBValue<type1> const & v) { \ | | static Promote toPromote(RGBValue<type1> const & v) { \ | |
| return static_cast<Promote>(v); } \ | | return static_cast<Promote>(v); } \ | |
|
| | | }; \ | |
| | | template <> \ | |
| | | struct PromoteTraits<RGBValue<type1, 0, 1, 2>, double > \ | |
| | | { \ | |
| | | typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \ | |
| | | }; \ | |
| | | template <> \ | |
| | | struct PromoteTraits<double, RGBValue<type1, 0, 1, 2> > \ | |
| | | { \ | |
| | | typedef RGBValue<typename NumericTraits<type1>::RealPromote> Promote; \ | |
| }; | | }; | |
| | | | |
| #define RGBVALUE_PROMTRAITS2(type1, type2) \ | | #define RGBVALUE_PROMTRAITS2(type1, type2) \ | |
| template<> \ | | template<> \ | |
|
| struct PromoteTraits<RGBValue<type1>, RGBValue<type2> > \ | | struct PromoteTraits<RGBValue<type1, 0, 1, 2>, RGBValue<type2, 0, 1, 2> > \ | |
| { \ | | { \ | |
| typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \ | | typedef RGBValue<PromoteTraits<type1, type2>::Promote> Promote; \ | |
| static Promote toPromote(RGBValue<type1> const & v) { \ | | static Promote toPromote(RGBValue<type1> const & v) { \ | |
| return static_cast<Promote>(v); } \ | | return static_cast<Promote>(v); } \ | |
| static Promote toPromote(RGBValue<type2> const & v) { \ | | static Promote toPromote(RGBValue<type2> const & v) { \ | |
| return static_cast<Promote>(v); } \ | | return static_cast<Promote>(v); } \ | |
| }; | | }; | |
| | | | |
| RGBVALUE_NUMTRAITS(unsigned char) | | RGBVALUE_NUMTRAITS(unsigned char) | |
| RGBVALUE_NUMTRAITS(int) | | RGBVALUE_NUMTRAITS(int) | |
| | | | |
| skipping to change at line 505 | | skipping to change at line 634 | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* RGBValue-Arithmetic */ | | /* RGBValue-Arithmetic */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \addtogroup RGBValueOperators | | /** \addtogroup RGBValueOperators | |
| */ | | */ | |
| //@{ | | //@{ | |
| /// componentwise add-assignment | | /// componentwise add-assignment | |
|
| template <class V1, class V2> | | template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI | |
| | | DX1, | |
| | | class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI | |
| | | DX2> | |
| inline | | inline | |
|
| RGBValue<V1> & | | RGBValue<V1, RIDX1, GIDX1, BIDX1> & | |
| operator+=(RGBValue<V1> & l, RGBValue<V2> const & r) | | operator+=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l, | |
| | | RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r) | |
| { | | { | |
| l.red() += r.red(); | | l.red() += r.red(); | |
| l.green() += r.green(); | | l.green() += r.green(); | |
| l.blue() += r.blue(); | | l.blue() += r.blue(); | |
| return l; | | return l; | |
| } | | } | |
| | | | |
| /// componentwise subtract-assignment | | /// componentwise subtract-assignment | |
|
| template <class V1, class V2> | | template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI | |
| | | DX1, | |
| | | class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI | |
| | | DX2> | |
| inline | | inline | |
|
| RGBValue<V1> & | | RGBValue<V1, RIDX1, GIDX1, BIDX1> & | |
| operator-=(RGBValue<V1> & l, RGBValue<V2> const & r) | | operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l, | |
| | | RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r) | |
| { | | { | |
| l.red() -= r.red(); | | l.red() -= r.red(); | |
| l.green() -= r.green(); | | l.green() -= r.green(); | |
| l.blue() -= r.blue(); | | l.blue() -= r.blue(); | |
| return l; | | return l; | |
| } | | } | |
| | | | |
| /// componentwise multiply-assignment | | /// componentwise multiply-assignment | |
|
| template <class V1, class V2> | | template <class V1, unsigned int RIDX1, unsigned int BIDX1, unsigned int GI
DX1, class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2> | |
| inline | | inline | |
|
| RGBValue<V1> & | | RGBValue<V1, RIDX1, GIDX1, BIDX1> & | |
| operator*=(RGBValue<V1> & l, RGBValue<V2> const & r) | | operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l, | |
| | | RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r) | |
| { | | { | |
| l.red() *= r.red(); | | l.red() *= r.red(); | |
| l.green() *= r.green(); | | l.green() *= r.green(); | |
| l.blue() *= r.blue(); | | l.blue() *= r.blue(); | |
| return l; | | return l; | |
| } | | } | |
| | | | |
| /// componentwise scalar multiply-assignment | | /// componentwise scalar multiply-assignment | |
|
| template <class V> | | template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX> | |
| inline | | inline | |
|
| RGBValue<V> & | | RGBValue<V, RIDX, GIDX, BIDX> & | |
| operator*=(RGBValue<V> & l, double r) | | operator*=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r) | |
| { | | { | |
| l.red() *= r; | | l.red() *= r; | |
| l.green() *= r; | | l.green() *= r; | |
| l.blue() *= r; | | l.blue() *= r; | |
| return l; | | return l; | |
| } | | } | |
| | | | |
| /// componentwise scalar divide-assignment | | /// componentwise scalar divide-assignment | |
|
| template <class V> | | template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX> | |
| inline | | inline | |
|
| RGBValue<V> & | | RGBValue<V, RIDX, GIDX, BIDX> & | |
| operator/=(RGBValue<V> & l, double r) | | operator/=(RGBValue<V, RIDX, GIDX, BIDX> & l, double r) | |
| { | | { | |
| l.red() /= r; | | l.red() /= r; | |
| l.green() /= r; | | l.green() /= r; | |
| l.blue() /= r; | | l.blue() /= r; | |
| return l; | | return l; | |
| } | | } | |
| | | | |
| using VIGRA_CSTD::abs; | | using VIGRA_CSTD::abs; | |
| | | | |
| /// component-wise absolute value | | /// component-wise absolute value | |
|
| template <class T> | | template <class T, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX> | |
| inline | | inline | |
|
| RGBValue<T> abs(RGBValue<T> const & v) { | | RGBValue<T, RIDX, GIDX, BIDX> | |
| return RGBValue<T>(abs(v.red()), abs(v.green()), abs(v.blue())); | | abs(RGBValue<T, RIDX, GIDX, BIDX> const & v) | |
| | | { | |
| | | return RGBValue<T, RIDX, GIDX, BIDX>(abs(v.red()), abs(v.green()), abs(v. | |
| | | blue())); | |
| } | | } | |
| | | | |
| /// component-wise addition | | /// component-wise addition | |
|
| template <class V1, class V2> | | template <class V1, unsigned int R, unsigned int G, unsigned int B, class V
2> | |
| inline | | inline | |
|
| typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote | | typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| operator+(RGBValue<V1> const & r1, RGBValue<V2> const & r2) | | RGBValue<V2, R, G, B> >::Promote | |
| | | operator+(RGBValue<V1, R, G, B> const & r1, | |
| | | RGBValue<V2, R, G, B> const & r2) | |
| { | | { | |
|
| typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote res(r1); | | typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| | | RGBValue<V2, R, G, B> >::Promote res(r1); | |
| | | | |
| res += r2; | | res += r2; | |
| | | | |
| return res; | | return res; | |
| } | | } | |
| | | | |
| /// component-wise subtraction | | /// component-wise subtraction | |
|
| template <class V1, class V2> | | template <class V1, unsigned int R, unsigned int G, unsigned int B, class V
2> | |
| inline | | inline | |
|
| typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote | | typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| operator-(RGBValue<V1> const & r1, RGBValue<V2> const & r2) | | RGBValue<V2, R, G, B> >::Promote | |
| | | operator-(RGBValue<V1, R, G, B> const & r1, | |
| | | RGBValue<V2, R, G, B> const & r2) | |
| { | | { | |
|
| typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote res(r1); | | typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| | | RGBValue<V2, R, G, B> >::Promote res(r1); | |
| | | | |
| res -= r2; | | res -= r2; | |
| | | | |
| return res; | | return res; | |
| } | | } | |
| | | | |
| /// component-wise multiplication | | /// component-wise multiplication | |
|
| template <class V1, class V2> | | template <class V1, unsigned int R, unsigned int G, unsigned int B, class V
2> | |
| inline | | inline | |
|
| typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote | | typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| operator*(RGBValue<V1> const & r1, RGBValue<V2> const & r2) | | RGBValue<V2, R, G, B> >::Promote | |
| | | operator*(RGBValue<V1, R, G, B> const & r1, | |
| | | RGBValue<V2, R, G, B> const & r2) | |
| { | | { | |
|
| typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote res(r1); | | typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| | | RGBValue<V2, R, G, B> >::Promote res(r1); | |
| | | | |
| res *= r2; | | res *= r2; | |
| | | | |
| return res; | | return res; | |
| } | | } | |
| | | | |
| /// component-wise left scalar multiplication | | /// component-wise left scalar multiplication | |
|
| template <class V> | | template <class V, unsigned int R, unsigned int G, unsigned int B> | |
| inline | | inline | |
|
| typename NumericTraits<RGBValue<V> >::RealPromote | | typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote | |
| operator*(double v, RGBValue<V> const & r) | | operator*(double v, RGBValue<V, R, G, B> const & r) | |
| { | | { | |
|
| typename NumericTraits<RGBValue<V> >::RealPromote res(r); | | typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r); | |
| | | | |
| res *= v; | | res *= v; | |
| | | | |
| return res; | | return res; | |
| } | | } | |
| | | | |
| /// component-wise right scalar multiplication | | /// component-wise right scalar multiplication | |
|
| template <class V> | | template <class V, unsigned int R, unsigned int G, unsigned int B> | |
| inline | | inline | |
|
| typename NumericTraits<RGBValue<V> >::RealPromote | | typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote | |
| operator*(RGBValue<V> const & r, double v) | | operator*(RGBValue<V, R, G, B> const & r, double v) | |
| { | | { | |
|
| typename NumericTraits<RGBValue<V> >::RealPromote res(r); | | typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r); | |
| | | | |
| res *= v; | | res *= v; | |
| | | | |
| return res; | | return res; | |
| } | | } | |
| | | | |
| /// component-wise scalar division | | /// component-wise scalar division | |
|
| template <class V> | | template <class V, unsigned int R, unsigned int G, unsigned int B> | |
| inline | | inline | |
|
| typename NumericTraits<RGBValue<V> >::RealPromote | | typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote | |
| operator/(RGBValue<V> const & r, double v) | | operator/(RGBValue<V, R, G, B> const & r, double v) | |
| { | | { | |
|
| typename NumericTraits<RGBValue<V> >::RealPromote res(r); | | typename NumericTraits<RGBValue<V, R, G, B> >::RealPromote res(r); | |
| | | | |
| res /= v; | | res /= v; | |
| | | | |
| return res; | | return res; | |
| } | | } | |
| | | | |
| /// cross product | | /// cross product | |
|
| template <class V1, class V2> | | template <class V1, unsigned int R, unsigned int G, unsigned int B, class V
2> | |
| inline | | inline | |
|
| typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote | | typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| cross(RGBValue<V1> const & r1, RGBValue<V2> const & r2) | | RGBValue<V2, R, G, B> >::Promote | |
| | | cross(RGBValue<V1, R, G, B> const & r1, | |
| | | RGBValue<V2, R, G, B> const & r2) | |
| { | | { | |
|
| typedef typename PromoteTraits<RGBValue<V1>, RGBValue<V2> >::Promote | | typedef typename PromoteTraits<RGBValue<V1, R, G, B>, | |
| | | RGBValue<V2, R, G, B> >::Promote | |
| Res; | | Res; | |
|
| | | | |
| return Res(r1.green()*r2.blue() - r1.blue()*r2.green(), | | return Res(r1.green()*r2.blue() - r1.blue()*r2.green(), | |
| r1.blue()*r2.red() - r1.red()*r2.blue(), | | r1.blue()*r2.red() - r1.red()*r2.blue(), | |
| r1.red()*r2.green() - r1.green()*r2.red()); | | r1.red()*r2.green() - r1.green()*r2.red()); | |
| } | | } | |
| | | | |
| /// dot product | | /// dot product | |
|
| template <class V1, class V2> | | template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI | |
| | | DX1, | |
| | | class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI | |
| | | DX2> | |
| inline | | inline | |
| typename PromoteTraits<V1, V2>::Promote | | typename PromoteTraits<V1, V2>::Promote | |
|
| dot(RGBValue<V1> const & r1, RGBValue<V2> const & r2) | | dot(RGBValue<V1, RIDX1, GIDX1, BIDX1> const & r1, | |
| | | RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r2) | |
| { | | { | |
| return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue(); | | return r1.red()*r2.red() + r1.green()*r2.green() + r1.blue()*r2.blue(); | |
| } | | } | |
| | | | |
| using VIGRA_CSTD::ceil; | | using VIGRA_CSTD::ceil; | |
| | | | |
| /** Apply ceil() function to each RGB component. | | /** Apply ceil() function to each RGB component. | |
| */ | | */ | |
|
| template <class V> | | template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX> | |
| inline | | inline | |
|
| RGBValue<V> | | RGBValue<V, RIDX, GIDX, BIDX> | |
| ceil(RGBValue<V> const & r) | | ceil(RGBValue<V, RIDX, GIDX, BIDX> const & r) | |
| { | | { | |
|
| return RGBValue<V>(ceil(r.red()), | | return RGBValue<V, RIDX, GIDX, BIDX>(ceil(r.red()), | |
| ceil(r.green()), | | ceil(r.green()), | |
| ceil(r.blue())); | | ceil(r.blue())); | |
| } | | } | |
| | | | |
| using VIGRA_CSTD::floor; | | using VIGRA_CSTD::floor; | |
| | | | |
| /** Apply floor() function to each RGB component. | | /** Apply floor() function to each RGB component. | |
| */ | | */ | |
|
| template <class V> | | template <class V, unsigned int RIDX, unsigned int GIDX, unsigned int BIDX> | |
| inline | | inline | |
|
| RGBValue<V> | | RGBValue<V, RIDX, GIDX, BIDX> | |
| floor(RGBValue<V> const & r) | | floor(RGBValue<V, RIDX, GIDX, BIDX> const & r) | |
| { | | { | |
|
| return RGBValue<V>(floor(r.red()), | | return RGBValue<V, RIDX, GIDX, BIDX>(floor(r.red()), | |
| floor(r.green()), | | floor(r.green()), | |
| floor(r.blue())); | | floor(r.blue())); | |
| } | | } | |
| | | | |
| //@} | | //@} | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* RGBValue-Accessors */ | | /* RGBValue-Accessors */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| | | | |
End of changes. 115 change blocks. |
| 170 lines changed or deleted | | 360 lines changed or added | |
|
| splineimageview.hxx | | splineimageview.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2004 by Ullrich Koethe */ | | /* Copyright 1998-2004 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_SPLINEIMAGEVIEW_HXX | | #ifndef VIGRA_SPLINEIMAGEVIEW_HXX | |
| #define VIGRA_SPLINEIMAGEVIEW_HXX | | #define VIGRA_SPLINEIMAGEVIEW_HXX | |
| | | | |
| #include "vigra/mathutil.hxx" | | #include "vigra/mathutil.hxx" | |
| #include "vigra/recursiveconvolution.hxx" | | #include "vigra/recursiveconvolution.hxx" | |
| #include "vigra/splines.hxx" | | #include "vigra/splines.hxx" | |
| #include "vigra/array_vector.hxx" | | #include "vigra/array_vector.hxx" | |
| #include "vigra/basicimage.hxx" | | #include "vigra/basicimage.hxx" | |
| #include "vigra/copyimage.hxx" | | #include "vigra/copyimage.hxx" | |
|
| | | #include "vigra/tinyvector.hxx" | |
| | | #include "vigra/fixedpoint.hxx" | |
| | | #include "vigra/multi_array.hxx" | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* SplineImageView */ | | /* SplineImageView */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| /** \brief Create a continuous view onto a discrete image using splines. | | /** \brief Create a continuous view onto a discrete image using splines. | |
| | | | |
| This class is very useful if image values or derivatives at arbitrary | | This class is very useful if image values or derivatives at arbitrary | |
| real-valued coordinates are needed. Access at such coordinates is imple
mented by | | real-valued coordinates are needed. Access at such coordinates is imple
mented by | |
| interpolating the given discrete image values with a spline of the | | interpolating the given discrete image values with a spline of the | |
| specified <tt>ORDER</TT>. Continuous derivatives are available up to | | specified <tt>ORDER</TT>. Continuous derivatives are available up to | |
| degree <tt>ORDER-1</TT>. If the requested coordinates are near the imag
e border, | | degree <tt>ORDER-1</TT>. If the requested coordinates are near the imag
e border, | |
| reflective boundary conditions are applied. In principle, this class ca
n also be used | | reflective boundary conditions are applied. In principle, this class ca
n also be used | |
| for image resizing, but here the functions from the <tt>resize...</tt>
family are | | for image resizing, but here the functions from the <tt>resize...</tt>
family are | |
| more efficient. | | more efficient. | |
| | | | |
|
| | | The <tt>SplineImageView</tt> template is explicitly specialized to make | |
| | | it as efficient as possible. | |
| | | In particular, unnecessary copying of the image is avoided when the ite | |
| | | rators passed | |
| | | in the constructor originate from a \ref vigra::BasicImage. In addition | |
| | | , these specializations | |
| | | provide function <tt>unchecked(...)</tt> that do not perform bounds che | |
| | | cking. If the original image | |
| | | is not a variant of \ref vigra::BasicImage, one can customize the inter | |
| | | nal representation by | |
| | | using \ref vigra::SplineImageview0 or \ref vigra::SplineImageview1. | |
| | | | |
| | | <b>Usage:</b> | |
| | | | |
| | | <b>\#include</b> "<a href="splineimageview_8hxx-source.html">vigra/spli | |
| | | neimageview.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | | |
| | | \code | |
| | | BImage img(w,h); | |
| | | ... // fill img | |
| | | | |
| | | // construct spline view for quadratic interpolation | |
| | | SplineImageView<2, double> spi2(img); | |
| | | | |
| | | double x = ..., y = ...; | |
| | | double v2 = spi2(x, y); | |
| | | | |
| | | // construct spline view for linear interpolation | |
| | | SplineImageView<1, UInt32> spi1(img); | |
| | | | |
| | | UInt32 v1 = spi1(x, y); | |
| | | | |
| | | FixedPoint<16, 15> fx(...), fy(...); | |
| | | UInt32 vf = spi1.unchecked(fx, fy); | |
| | | \endcode | |
| */ | | */ | |
| template <int ORDER, class VALUETYPE> | | template <int ORDER, class VALUETYPE> | |
| class SplineImageView | | class SplineImageView | |
| { | | { | |
| typedef typename NumericTraits<VALUETYPE>::RealPromote InternalValue; | | typedef typename NumericTraits<VALUETYPE>::RealPromote InternalValue; | |
| | | | |
| public: | | public: | |
| | | | |
| /** The view's value type (return type of access and derivative fun
ctions). | | /** The view's value type (return type of access and derivative fun
ctions). | |
| */ | | */ | |
| | | | |
| skipping to change at line 129 | | skipping to change at line 177 | |
| image_(w_, h_), | | image_(w_, h_), | |
| x_(-1.0), y_(-1.0), | | x_(-1.0), y_(-1.0), | |
| u_(-1.0), v_(-1.0) | | u_(-1.0), v_(-1.0) | |
| { | | { | |
| copyImage(srcIterRange(s.first, s.second, s.third), destImage(image
_)); | | copyImage(srcIterRange(s.first, s.second, s.third), destImage(image
_)); | |
| if(!skipPrefiltering) | | if(!skipPrefiltering) | |
| init(); | | init(); | |
| } | | } | |
| | | | |
| /** Access interpolated function at real-valued coordinate <tt>(x,
y)</tt>. | | /** Access interpolated function at real-valued coordinate <tt>(x,
y)</tt>. | |
|
| | | If <tt>(x, y)</tt> is near the image border or outside the imag | |
| | | e, the value | |
| | | is calculated with reflective boundary conditions. An exception | |
| | | is thrown if the | |
| | | coordinate is outside the first reflection. | |
| */ | | */ | |
| value_type operator()(double x, double y) const; | | value_type operator()(double x, double y) const; | |
| | | | |
| /** Access derivative of order <tt>(dx, dy)</tt> at real-valued coo
rdinate <tt>(x, y)</tt>. | | /** Access derivative of order <tt>(dx, dy)</tt> at real-valued coo
rdinate <tt>(x, y)</tt>. | |
|
| | | If <tt>(x, y)</tt> is near the image border or outside the imag | |
| | | e, the value | |
| | | is calculated with reflective boundary conditions. An exception | |
| | | is thrown if the | |
| | | coordinate is outside the first reflection. | |
| */ | | */ | |
| value_type operator()(double x, double y, unsigned int dx, unsigned int
dy) const; | | value_type operator()(double x, double y, unsigned int dx, unsigned int
dy) const; | |
| | | | |
| /** Access 1st derivative in x-direction at real-valued coordinate
<tt>(x, y)</tt>. | | /** Access 1st derivative in x-direction at real-valued coordinate
<tt>(x, y)</tt>. | |
| Equivalent to <tt>splineView(x, y, 1, 0)</tt>. | | Equivalent to <tt>splineView(x, y, 1, 0)</tt>. | |
| */ | | */ | |
| value_type dx(double x, double y) const | | value_type dx(double x, double y) const | |
| { return operator()(x, y, 1, 0); } | | { return operator()(x, y, 1, 0); } | |
| | | | |
| /** Access 1st derivative in y-direction at real-valued coordinate
<tt>(x, y)</tt>. | | /** Access 1st derivative in y-direction at real-valued coordinate
<tt>(x, y)</tt>. | |
| | | | |
| skipping to change at line 385 | | skipping to change at line 439 | |
| for(int ny = 0; ny < ORDER + 1; ++ny) | | for(int ny = 0; ny < ORDER + 1; ++ny) | |
| for(int nx = 0; nx < ORDER + 1; ++nx) | | for(int nx = 0; nx < ORDER + 1; ++nx) | |
| f_x_y += pow(dx, nx) * pow(dy, ny) * coefficients(nx, n
y); | | f_x_y += pow(dx, nx) * pow(dy, ny) * coefficients(nx, n
y); | |
| | | | |
| assert(abs(f_x_y - view(x, y)) < 1e-6); | | assert(abs(f_x_y - view(x, y)) < 1e-6); | |
| \endcode | | \endcode | |
| */ | | */ | |
| template <class Array> | | template <class Array> | |
| void coefficientArray(double x, double y, Array & res) const; | | void coefficientArray(double x, double y, Array & res) const; | |
| | | | |
|
| /** Check if x is in the valid range. | | /** Check if x is in the original image range. | |
| Equivalent to <tt>0 <= x <= width()-1</tt>. | | Equivalent to <tt>0 <= x <= width()-1</tt>. | |
| */ | | */ | |
| bool isInsideX(double x) const | | bool isInsideX(double x) const | |
| { | | { | |
| return x >= 0.0 && x <= width()-1.0; | | return x >= 0.0 && x <= width()-1.0; | |
| } | | } | |
| | | | |
|
| /** Check if y is in the valid range. | | /** Check if y is in the original image range. | |
| Equivalent to <tt>0 <= y <= height()-1</tt>. | | Equivalent to <tt>0 <= y <= height()-1</tt>. | |
| */ | | */ | |
| bool isInsideY(double y) const | | bool isInsideY(double y) const | |
| { | | { | |
| return y >= 0.0 && y <= height()-1.0; | | return y >= 0.0 && y <= height()-1.0; | |
| } | | } | |
| | | | |
|
| /** Check if x and y are in the valid range. | | /** Check if x and y are in the original image range. | |
| Equivalent to <tt>0 <= x <= width()-1</tt> and <tt>0 <
= y <= height()-1</tt>. | | Equivalent to <tt>0 <= x <= width()-1</tt> and <tt>0 <
= y <= height()-1</tt>. | |
| */ | | */ | |
| bool isInside(double x, double y) const | | bool isInside(double x, double y) const | |
| { | | { | |
| return isInsideX(x) && isInsideY(y); | | return isInsideX(x) && isInsideY(y); | |
| } | | } | |
| | | | |
|
| | | /** Check if x and y are in the valid range. Points outside the ori | |
| | | ginal image range are computed | |
| | | by reflcective boundary conditions, but only within the first r | |
| | | eflection. | |
| | | Equivalent to <tt>-width() + ORDER/2 + 2 < x < 2*width() | |
| | | - ORDER/2 - 2</tt> and | |
| | | <tt>-height() + ORDER/2 + 2 < y < 2*height() - ORDER/2 - | |
| | | 2</tt>. | |
| | | */ | |
| | | bool isValid(double x, double y) const | |
| | | { | |
| | | return x < w1_ + x1_ && x > -x1_ && y < h1_ + y1_ && y > -y1_; | |
| | | } | |
| | | | |
| /** Check whether the points <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt
> are in | | /** Check whether the points <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt
> are in | |
| the same spline facet. For odd order splines, facets span the r
ange | | the same spline facet. For odd order splines, facets span the r
ange | |
| <tt>(floor(x), floor(x)+1) x (floor(y), floor(y)+1)</tt> (i.e.
we have | | <tt>(floor(x), floor(x)+1) x (floor(y), floor(y)+1)</tt> (i.e.
we have | |
| integer facet borders), whereas even order splines have facet b
etween | | integer facet borders), whereas even order splines have facet b
etween | |
| half integer values | | half integer values | |
| <tt>(floor(x)-0.5, floor(x)+0.5) x (floor(y)-0.5, floor(y)+0.5)
</tt>. | | <tt>(floor(x)-0.5, floor(x)+0.5) x (floor(y)-0.5, floor(y)+0.5)
</tt>. | |
| */ | | */ | |
| bool sameFacet(double x0, double y0, double x1, double y1) const | | bool sameFacet(double x0, double y0, double x1, double y1) const | |
| { | | { | |
| x0 = VIGRA_CSTD::floor((ORDER % 2) ? x0 : x0 + 0.5); | | x0 = VIGRA_CSTD::floor((ORDER % 2) ? x0 : x0 + 0.5); | |
| | | | |
| skipping to change at line 478 | | skipping to change at line 542 | |
| template <> | | template <> | |
| struct SplineImageViewUnrollLoop1<0> | | struct SplineImageViewUnrollLoop1<0> | |
| { | | { | |
| template <class Array> | | template <class Array> | |
| static void exec(int c0, Array c) | | static void exec(int c0, Array c) | |
| { | | { | |
| c[0] = c0; | | c[0] = c0; | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| template <int i> | | template <int i, class ValueType> | |
| struct SplineImageViewUnrollLoop2 | | struct SplineImageViewUnrollLoop2 | |
| { | | { | |
|
| template <class Array1, class Image, class Array2> | | template <class Array1, class RowIterator, class Array2> | |
| static typename Image::value_type | | static ValueType | |
| exec(Array1 k, Image const & img, Array2 x, int y) | | exec(Array1 k, RowIterator r, Array2 x) | |
| { | | { | |
|
| return k[i] * img(x[i], y) + SplineImageViewUnrollLoop2<i-1>::exec(
k, img, x, y); | | return k[i] * r[x[i]] + SplineImageViewUnrollLoop2<i-1, ValueType>:
:exec(k, r, x); | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| template <> | | template <class ValueType> | |
| struct SplineImageViewUnrollLoop2<0> | | struct SplineImageViewUnrollLoop2<0, ValueType> | |
| { | | { | |
|
| template <class Array1, class Image, class Array2> | | template <class Array1, class RowIterator, class Array2> | |
| static typename Image::value_type | | static ValueType | |
| exec(Array1 k, Image const & img, Array2 x, int y) | | exec(Array1 k, RowIterator r, Array2 x) | |
| { | | { | |
|
| return k[0] * img(x[0], y); | | return k[0] * r[x[0]]; | |
| } | | } | |
| }; | | }; | |
| | | | |
| } // namespace detail | | } // namespace detail | |
| | | | |
| template <int ORDER, class VALUETYPE> | | template <int ORDER, class VALUETYPE> | |
| void | | void | |
| SplineImageView<ORDER, VALUETYPE>::calculateIndices(double x, double y) con
st | | SplineImageView<ORDER, VALUETYPE>::calculateIndices(double x, double y) con
st | |
| { | | { | |
| if(x == x_ && y == y_) | | if(x == x_ && y == y_) | |
| return; // still in cache | | return; // still in cache | |
| | | | |
| if(x > x0_ && x < x1_ && y > y0_ && y < y1_) | | if(x > x0_ && x < x1_ && y > y0_ && y < y1_) | |
| { | | { | |
| detail::SplineImageViewUnrollLoop1<ORDER>::exec( | | detail::SplineImageViewUnrollLoop1<ORDER>::exec( | |
| (ORDER % 2) ? int(x - kcenter_) : int(x + 0
.5 - kcenter_), ix_); | | (ORDER % 2) ? int(x - kcenter_) : int(x + 0
.5 - kcenter_), ix_); | |
| detail::SplineImageViewUnrollLoop1<ORDER>::exec( | | detail::SplineImageViewUnrollLoop1<ORDER>::exec( | |
| (ORDER % 2) ? int(y - kcenter_) : int(y + 0
.5 - kcenter_), iy_); | | (ORDER % 2) ? int(y - kcenter_) : int(y + 0
.5 - kcenter_), iy_); | |
|
| | | | |
| | | u_ = x - ix_[kcenter_]; | |
| | | v_ = y - iy_[kcenter_]; | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| vigra_precondition(isInside(x, y), | | vigra_precondition(isValid(x,y), | |
| "SplineImageView<ORDER, VALUETYPE>::calculateIndices(): index | | "SplineImageView::calculateIndices(): coordinates out o | |
| out of bounds."); | | f range."); | |
| | | | |
|
| ix_[kcenter_] = (ORDER % 2) ? | | int xCenter = (ORDER % 2) ? | |
| (int)x : | | (int)VIGRA_CSTD::floor(x) : | |
| (int)(x + 0.5); | | (int)VIGRA_CSTD::floor(x + 0.5); | |
| iy_[kcenter_] = (ORDER % 2) ? | | int yCenter = (ORDER % 2) ? | |
| (int)y : | | (int)VIGRA_CSTD::floor(y) : | |
| (int)(y + 0.5); | | (int)VIGRA_CSTD::floor(y + 0.5); | |
| | | | |
|
| for(int i=0; i<kcenter_; ++i) | | if(x >= x1_) | |
| { | | { | |
|
| ix_[i] = vigra::abs(ix_[kcenter_] - (kcenter_ - i)); | | for(int i = 0; i < ksize_; ++i) | |
| iy_[i] = vigra::abs(iy_[kcenter_] - (kcenter_ - i)); | | ix_[i] = w1_ - vigra::abs(w1_ - xCenter - (i - kcenter_)); | |
| } | | } | |
|
| for(int i=kcenter_+1; i<ksize_; ++i) | | else | |
| { | | { | |
|
| ix_[i] = w1_ - vigra::abs(w1_ - ix_[kcenter_] - (i - kcenter_)) | | for(int i = 0; i < ksize_; ++i) | |
| ; | | ix_[i] = vigra::abs(xCenter - (kcenter_ - i)); | |
| iy_[i] = h1_ - vigra::abs(h1_ - iy_[kcenter_] - (i - kcenter_)) | | } | |
| ; | | if(y >= y1_) | |
| | | { | |
| | | for(int i = 0; i < ksize_; ++i) | |
| | | iy_[i] = h1_ - vigra::abs(h1_ - yCenter - (i - kcenter_)); | |
| } | | } | |
|
| | | else | |
| | | { | |
| | | for(int i = 0; i < ksize_; ++i) | |
| | | iy_[i] = vigra::abs(yCenter - (kcenter_ - i)); | |
| | | } | |
| | | u_ = x - xCenter; | |
| | | v_ = y - yCenter; | |
| } | | } | |
| x_ = x; | | x_ = x; | |
| y_ = y; | | y_ = y; | |
|
| u_ = x - ix_[kcenter_]; | | | |
| v_ = y - iy_[kcenter_]; | | | |
| } | | } | |
| | | | |
| template <int ORDER, class VALUETYPE> | | template <int ORDER, class VALUETYPE> | |
| void SplineImageView<ORDER, VALUETYPE>::coefficients(double t, double * con
st & c) const | | void SplineImageView<ORDER, VALUETYPE>::coefficients(double t, double * con
st & c) const | |
| { | | { | |
| t += kcenter_; | | t += kcenter_; | |
| for(int i = 0; i<ksize_; ++i) | | for(int i = 0; i<ksize_; ++i) | |
| c[i] = k_(t-i); | | c[i] = k_(t-i); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 566 | | skipping to change at line 643 | |
| { | | { | |
| t += kcenter_; | | t += kcenter_; | |
| for(int i = 0; i<ksize_; ++i) | | for(int i = 0; i<ksize_; ++i) | |
| c[i] = k_(t-i, d); | | c[i] = k_(t-i, d); | |
| } | | } | |
| | | | |
| template <int ORDER, class VALUETYPE> | | template <int ORDER, class VALUETYPE> | |
| VALUETYPE SplineImageView<ORDER, VALUETYPE>::convolve() const | | VALUETYPE SplineImageView<ORDER, VALUETYPE>::convolve() const | |
| { | | { | |
| InternalValue sum; | | InternalValue sum; | |
|
| sum = ky_[0]*detail::SplineImageViewUnrollLoop2<ORDER>::exec(kx_, image
_, ix_, iy_[0]); | | sum = ky_[0]*detail::SplineImageViewUnrollLoop2<ORDER, InternalValue>::
exec(kx_, image_.rowBegin(iy_[0]), ix_); | |
| | | | |
| for(int j=1; j<ksize_; ++j) | | for(int j=1; j<ksize_; ++j) | |
| { | | { | |
|
| sum += ky_[j]*detail::SplineImageViewUnrollLoop2<ORDER>::exec(kx_,
image_, ix_, iy_[j]); | | sum += ky_[j]*detail::SplineImageViewUnrollLoop2<ORDER, InternalVal
ue>::exec(kx_, image_.rowBegin(iy_[j]), ix_); | |
| } | | } | |
| return NumericTraits<VALUETYPE>::fromRealPromote(sum); | | return NumericTraits<VALUETYPE>::fromRealPromote(sum); | |
| } | | } | |
| | | | |
| template <int ORDER, class VALUETYPE> | | template <int ORDER, class VALUETYPE> | |
| template <class Array> | | template <class Array> | |
| void | | void | |
| SplineImageView<ORDER, VALUETYPE>::coefficientArray(double x, double y, Arr
ay & res) const | | SplineImageView<ORDER, VALUETYPE>::coefficientArray(double x, double y, Arr
ay & res) const | |
| { | | { | |
| typename Spline::WeightMatrix & weights = Spline::weights(); | | typename Spline::WeightMatrix & weights = Spline::weights(); | |
| | | | |
| skipping to change at line 664 | | skipping to change at line 741 | |
| { | | { | |
| return 2.0*(sq(dxy(x,y)) + dx(x,y) * dxyy(x,y) + sq(dyy(x,y)) + dy(x,y)
* dy3(x,y)); | | return 2.0*(sq(dxy(x,y)) + dx(x,y) * dxyy(x,y) + sq(dyy(x,y)) + dy(x,y)
* dy3(x,y)); | |
| } | | } | |
| | | | |
| template <int ORDER, class VALUETYPE> | | template <int ORDER, class VALUETYPE> | |
| VALUETYPE SplineImageView<ORDER, VALUETYPE>::g2xy(double x, double y) const | | VALUETYPE SplineImageView<ORDER, VALUETYPE>::g2xy(double x, double y) const | |
| { | | { | |
| return 2.0*(dx(x,y) * dxxy(x,y) + dy(x,y) * dxyy(x,y) + dxy(x,y) * (dxx
(x,y) + dyy(x,y))); | | return 2.0*(dx(x,y) * dxxy(x,y) + dy(x,y) * dxyy(x,y) + dxy(x,y) * (dxx
(x,y) + dyy(x,y))); | |
| } | | } | |
| | | | |
|
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* SplineImageView0 */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | template <class VALUETYPE, class INTERNAL_INDEXER> | |
| | | class SplineImageView0Base | |
| | | { | |
| | | typedef typename INTERNAL_INDEXER::value_type InternalValue; | |
| | | public: | |
| | | typedef VALUETYPE value_type; | |
| | | typedef Size2D size_type; | |
| | | typedef TinyVector<double, 2> difference_type; | |
| | | enum StaticOrder { order = 0 }; | |
| | | | |
| | | public: | |
| | | | |
| | | SplineImageView0Base(unsigned int w, unsigned int h) | |
| | | : w_(w), h_(h) | |
| | | {} | |
| | | | |
| | | SplineImageView0Base(int w, int h, INTERNAL_INDEXER i) | |
| | | : w_(w), h_(h), internalIndexer_(i) | |
| | | {} | |
| | | | |
| | | template <unsigned IntBits1, unsigned FractionalBits1, | |
| | | unsigned IntBits2, unsigned FractionalBits2> | |
| | | value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x, | |
| | | FixedPoint<IntBits2, FractionalBits2> y) const | |
| | | { | |
| | | return internalIndexer_(round(x), round(y)); | |
| | | } | |
| | | | |
| | | template <unsigned IntBits1, unsigned FractionalBits1, | |
| | | unsigned IntBits2, unsigned FractionalBits2> | |
| | | value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x, | |
| | | FixedPoint<IntBits2, FractionalBits2> y, | |
| | | unsigned int dx, unsigned int dy) const | |
| | | { | |
| | | if((dx != 0) || (dy != 0)) | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | return unchecked(x, y); | |
| | | } | |
| | | | |
| | | value_type unchecked(double x, double y) const | |
| | | { | |
| | | return internalIndexer_((int)(x + 0.5), (int)(y + 0.5)); | |
| | | } | |
| | | | |
| | | value_type unchecked(double x, double y, unsigned int dx, unsigned int | |
| | | dy) const | |
| | | { | |
| | | if((dx != 0) || (dy != 0)) | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | return unchecked(x, y); | |
| | | } | |
| | | | |
| | | value_type operator()(double x, double y) const | |
| | | { | |
| | | int ix, iy; | |
| | | if(x < 0.0) | |
| | | { | |
| | | ix = (int)(-x + 0.5); | |
| | | vigra_precondition(ix <= (int)w_ - 1, | |
| | | "SplineImageView::operator(): coordinates out of range. | |
| | | "); | |
| | | } | |
| | | else | |
| | | { | |
| | | ix = (int)(x + 0.5); | |
| | | if(ix >= (int)w_) | |
| | | { | |
| | | ix = 2*w_-2-ix; | |
| | | vigra_precondition(ix >= 0, | |
| | | "SplineImageView::operator(): coordinates out of ra | |
| | | nge."); | |
| | | } | |
| | | } | |
| | | if(y < 0.0) | |
| | | { | |
| | | iy = (int)(-y + 0.5); | |
| | | vigra_precondition(iy <= (int)h_ - 1, | |
| | | "SplineImageView::operator(): coordinates out of range. | |
| | | "); | |
| | | } | |
| | | else | |
| | | { | |
| | | iy = (int)(y + 0.5); | |
| | | if(iy >= (int)h_) | |
| | | { | |
| | | iy = 2*h_-2-iy; | |
| | | vigra_precondition(iy >= 0, | |
| | | "SplineImageView::operator(): coordinates out of ra | |
| | | nge."); | |
| | | } | |
| | | } | |
| | | return internalIndexer_(ix, iy); | |
| | | } | |
| | | | |
| | | value_type operator()(double x, double y, unsigned int dx, unsigned int | |
| | | dy) const | |
| | | { | |
| | | if((dx != 0) || (dy != 0)) | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | return operator()(x, y); | |
| | | } | |
| | | | |
| | | value_type dx(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxx(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dyy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dx3(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dy3(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxxy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxyy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type operator()(difference_type const & d) const | |
| | | { return operator()(d[0], d[1]); } | |
| | | | |
| | | value_type operator()(difference_type const & d, unsigned int dx, unsig | |
| | | ned int dy) const | |
| | | { return operator()(d[0], d[1], dx, dy); } | |
| | | | |
| | | value_type dx(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxx(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dyy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dx3(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dy3(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxxy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxyy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2x(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2y(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xx(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2yy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2x(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2y(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xx(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2yy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | unsigned int width() const | |
| | | { return w_; } | |
| | | | |
| | | unsigned int height() const | |
| | | { return h_; } | |
| | | | |
| | | size_type size() const | |
| | | { return size_type(w_, h_); } | |
| | | | |
| | | template <class Array> | |
| | | void coefficientArray(double x, double y, Array & res) const | |
| | | { | |
| | | res.resize(1, 1); | |
| | | res(0, 0) = operator()(x,y); | |
| | | } | |
| | | | |
| | | bool isInsideX(double x) const | |
| | | { | |
| | | return x >= 0.0 && x <= width() - 1.0; | |
| | | } | |
| | | | |
| | | bool isInsideY(double y) const | |
| | | { | |
| | | return y >= 0.0 && y <= height() - 1.0; | |
| | | } | |
| | | | |
| | | bool isInside(double x, double y) const | |
| | | { | |
| | | return isInsideX(x) && isInsideY(y); | |
| | | } | |
| | | | |
| | | bool isValid(double x, double y) const | |
| | | { | |
| | | return x < 2.0*w_-2.0 && x > -w_+1.0 && y < 2.0*h_-2.0 && y > -h_+1 | |
| | | .0; | |
| | | } | |
| | | | |
| | | bool sameFacet(double x0, double y0, double x1, double y1) const | |
| | | { | |
| | | x0 = VIGRA_CSTD::floor(x0 + 0.5); | |
| | | y0 = VIGRA_CSTD::floor(y0 + 0.5); | |
| | | x1 = VIGRA_CSTD::floor(x1 + 0.5); | |
| | | y1 = VIGRA_CSTD::floor(y1 + 0.5); | |
| | | return x0 == x1 && y0 == y1; | |
| | | } | |
| | | | |
| | | protected: | |
| | | unsigned int w_, h_; | |
| | | INTERNAL_INDEXER internalIndexer_; | |
| | | }; | |
| | | | |
| | | /** \brief Create an image view for nearest-neighbor interpolation. | |
| | | | |
| | | This class behaves like \ref vigra::SplineImageView<0, ...>, but | |
| | | one can pass | |
| | | an additional template argument that determined the internal representa | |
| | | tion of the image. | |
| | | If this is equal to the argument type passed in the constructor, the im | |
| | | age is not copied. | |
| | | By default, this works for \ref vigra::BasicImage, \ref vigra::BasicIma | |
| | | geView, | |
| | | \ref vigra::MultiArray<2, ...>, and \ref vigra::MultiArrayView< | |
| | | ;2, ...>. | |
| | | | |
| | | */ | |
| | | template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<V | |
| | | ALUETYPE>::const_traverser> | |
| | | class SplineImageView0 | |
| | | : public SplineImageView0Base<VALUETYPE, INTERNAL_TRAVERSER> | |
| | | { | |
| | | typedef SplineImageView0Base<VALUETYPE, INTERNAL_TRAVERSER> Base; | |
| | | public: | |
| | | typedef typename Base::value_type value_type; | |
| | | typedef typename Base::size_type size_type; | |
| | | typedef typename Base::difference_type difference_type; | |
| | | enum StaticOrder { order = Base::order }; | |
| | | typedef BasicImage<VALUETYPE> InternalImage; | |
| | | | |
| | | protected: | |
| | | typedef typename IteratorTraits<INTERNAL_TRAVERSER>::mutable_iterator I | |
| | | nternalTraverser; | |
| | | typedef typename IteratorTraits<InternalTraverser>::DefaultAccessor Int | |
| | | ernalAccessor; | |
| | | typedef typename IteratorTraits<INTERNAL_TRAVERSER>::const_iterator Int | |
| | | ernalConstTraverser; | |
| | | typedef typename IteratorTraits<InternalConstTraverser>::DefaultAccesso | |
| | | r InternalConstAccessor; | |
| | | | |
| | | public: | |
| | | | |
| | | /* when traverser and accessor types passed to the constructor are | |
| | | the same as the corresponding | |
| | | internal types, we need not copy the image (speed up) | |
| | | */ | |
| | | SplineImageView0(InternalTraverser is, InternalTraverser iend, Internal | |
| | | Accessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y, is) | |
| | | {} | |
| | | | |
| | | SplineImageView0(triple<InternalTraverser, InternalTraverser, InternalA | |
| | | ccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first) | |
| | | {} | |
| | | | |
| | | SplineImageView0(InternalConstTraverser is, InternalConstTraverser iend | |
| | | , InternalConstAccessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y, is) | |
| | | {} | |
| | | | |
| | | SplineImageView0(triple<InternalConstTraverser, InternalConstTraverser, | |
| | | InternalConstAccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first) | |
| | | {} | |
| | | | |
| | | template<class T, class SU> | |
| | | SplineImageView0(MultiArrayView<2, T, SU> const & i) | |
| | | : Base(i.shape(0), i.shape(1)), | |
| | | image_(i.shape(0), i.shape(1)) | |
| | | { | |
| | | for(unsigned int y=0; y<this->height(); ++y) | |
| | | for(unsigned int x=0; x<this->width(); ++x) | |
| | | image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast | |
| | | (i(x,y)); | |
| | | this->internalIndexer_ = image_.upperLeft(); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView0(SrcIterator is, SrcIterator iend, SrcAccessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y), | |
| | | image_(iend - is) | |
| | | { | |
| | | copyImage(srcIterRange(is, iend, sa), destImage(image_)); | |
| | | this->internalIndexer_ = image_.upperLeft(); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView0(triple<SrcIterator, SrcIterator, SrcAccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y), | |
| | | image_(s.second - s.first) | |
| | | { | |
| | | copyImage(s, destImage(image_)); | |
| | | this->internalIndexer_ = image_.upperLeft(); | |
| | | } | |
| | | | |
| | | InternalImage const & image() const | |
| | | { return image_; } | |
| | | | |
| | | protected: | |
| | | InternalImage image_; | |
| | | }; | |
| | | | |
| | | template <class VALUETYPE, class StridedOrUnstrided> | |
| | | class SplineImageView0<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUns | |
| | | trided> > | |
| | | : public SplineImageView0Base<VALUETYPE, MultiArrayView<2, VALUETYPE, Strid | |
| | | edOrUnstrided> > | |
| | | { | |
| | | typedef SplineImageView0Base<VALUETYPE, MultiArrayView<2, VALUETYPE, St | |
| | | ridedOrUnstrided> > Base; | |
| | | public: | |
| | | typedef typename Base::value_type value_type; | |
| | | typedef typename Base::size_type size_type; | |
| | | typedef typename Base::difference_type difference_type; | |
| | | enum StaticOrder { order = Base::order }; | |
| | | typedef BasicImage<VALUETYPE> InternalImage; | |
| | | | |
| | | protected: | |
| | | typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexe | |
| | | r; | |
| | | | |
| | | public: | |
| | | | |
| | | /* when traverser and accessor types passed to the constructor are | |
| | | the same as the corresponding | |
| | | internal types, we need not copy the image (speed up) | |
| | | */ | |
| | | SplineImageView0(InternalIndexer const & i) | |
| | | : Base(i.shape(0), i.shape(1), i) | |
| | | {} | |
| | | | |
| | | template<class T, class SU> | |
| | | SplineImageView0(MultiArrayView<2, T, SU> const & i) | |
| | | : Base(i.shape(0), i.shape(1)), | |
| | | image_(i.shape(0), i.shape(1)) | |
| | | { | |
| | | for(unsigned int y=0; y<this->height(); ++y) | |
| | | for(unsigned int x=0; x<this->width(); ++x) | |
| | | image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast | |
| | | (i(x,y)); | |
| | | this->internalIndexer_ = InternalIndexer(typename InternalIndexer:: | |
| | | difference_type(this->width(), this->height()), | |
| | | image_.data()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView0(SrcIterator is, SrcIterator iend, SrcAccessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y), | |
| | | image_(iend-is) | |
| | | { | |
| | | copyImage(srcIterRange(is, iend, sa), destImage(image_)); | |
| | | this->internalIndexer_ = InternalIndexer(typename InternalIndexer:: | |
| | | difference_type(this->width(), this->height()), | |
| | | image_.data()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView0(triple<SrcIterator, SrcIterator, SrcAccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y), | |
| | | image_(s.second - s.first) | |
| | | { | |
| | | copyImage(s, destImage(image_)); | |
| | | this->internalIndexer_ = InternalIndexer(typename InternalIndexer:: | |
| | | difference_type(this->width(), this->height()), | |
| | | image_.data()); | |
| | | } | |
| | | | |
| | | InternalImage const & image() const | |
| | | { return image_; } | |
| | | | |
| | | protected: | |
| | | InternalImage image_; | |
| | | }; | |
| | | | |
| | | template <class VALUETYPE> | |
| | | class SplineImageView<0, VALUETYPE> | |
| | | : public SplineImageView0<VALUETYPE> | |
| | | { | |
| | | typedef SplineImageView0<VALUETYPE> Base; | |
| | | public: | |
| | | typedef typename Base::value_type value_type; | |
| | | typedef typename Base::size_type size_type; | |
| | | typedef typename Base::difference_type difference_type; | |
| | | enum StaticOrder { order = Base::order }; | |
| | | typedef typename Base::InternalImage InternalImage; | |
| | | | |
| | | protected: | |
| | | typedef typename Base::InternalTraverser InternalTraverser; | |
| | | typedef typename Base::InternalAccessor InternalAccessor; | |
| | | typedef typename Base::InternalConstTraverser InternalConstTraverser; | |
| | | typedef typename Base::InternalConstAccessor InternalConstAccessor; | |
| | | | |
| | | public: | |
| | | | |
| | | /* when traverser and accessor types passed to the constructor are | |
| | | the same as the corresponding | |
| | | internal types, we need not copy the image (speed up) | |
| | | */ | |
| | | SplineImageView(InternalTraverser is, InternalTraverser iend, InternalA | |
| | | ccessor sa, bool /* unused */ = false) | |
| | | : Base(is, iend, sa) | |
| | | {} | |
| | | | |
| | | SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAc | |
| | | cessor> s, bool /* unused */ = false) | |
| | | : Base(s) | |
| | | {} | |
| | | | |
| | | SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, | |
| | | InternalConstAccessor sa, bool /* unused */ = false) | |
| | | : Base(is, iend, sa) | |
| | | {} | |
| | | | |
| | | SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, | |
| | | InternalConstAccessor> s, bool /* unused */ = false) | |
| | | : Base(s) | |
| | | {} | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa, bool | |
| | | /* unused */ = false) | |
| | | : Base(is, iend, sa) | |
| | | { | |
| | | copyImage(srcIterRange(is, iend, sa), destImage(this->image_)); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s, bool / | |
| | | * unused */ = false) | |
| | | : Base(s) | |
| | | { | |
| | | copyImage(s, destImage(this->image_)); | |
| | | } | |
| | | }; | |
| | | | |
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* SplineImageView1 */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | template <class VALUETYPE, class INTERNAL_INDEXER> | |
| | | class SplineImageView1Base | |
| | | { | |
| | | typedef typename INTERNAL_INDEXER::value_type InternalValue; | |
| | | public: | |
| | | typedef VALUETYPE value_type; | |
| | | typedef Size2D size_type; | |
| | | typedef TinyVector<double, 2> difference_type; | |
| | | enum StaticOrder { order = 1 }; | |
| | | | |
| | | public: | |
| | | | |
| | | SplineImageView1Base(unsigned int w, unsigned int h) | |
| | | : w_(w), h_(h) | |
| | | {} | |
| | | | |
| | | SplineImageView1Base(int w, int h, INTERNAL_INDEXER i) | |
| | | : w_(w), h_(h), internalIndexer_(i) | |
| | | {} | |
| | | | |
| | | template <unsigned IntBits1, unsigned FractionalBits1, | |
| | | unsigned IntBits2, unsigned FractionalBits2> | |
| | | value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x, | |
| | | FixedPoint<IntBits2, FractionalBits2> y) const | |
| | | { | |
| | | int ix = floor(x); | |
| | | FixedPoint<0, FractionalBits1> tx = frac(x - FixedPoint<IntBits1, F | |
| | | ractionalBits1>(ix)); | |
| | | FixedPoint<0, FractionalBits1> dtx = dual_frac(tx); | |
| | | if(ix == w_ - 1) | |
| | | { | |
| | | --ix; | |
| | | tx.value = FixedPoint<0, FractionalBits1>::ONE; | |
| | | dtx.value = 0; | |
| | | } | |
| | | int iy = floor(y); | |
| | | FixedPoint<0, FractionalBits2> ty = frac(y - FixedPoint<IntBits2, F | |
| | | ractionalBits2>(iy)); | |
| | | FixedPoint<0, FractionalBits2> dty = dual_frac(ty); | |
| | | if(iy == h_ - 1) | |
| | | { | |
| | | --iy; | |
| | | ty.value = FixedPoint<0, FractionalBits2>::ONE; | |
| | | dty.value = 0; | |
| | | } | |
| | | return fixed_point_cast<value_type>( | |
| | | dty*(dtx*fixedPoint(internalIndexer_(ix,iy)) + | |
| | | tx*fixedPoint(internalIndexer_(ix+1,iy)) | |
| | | ) + | |
| | | ty *(dtx*fixedPoint(internalIndexer_(ix,iy+1)) + | |
| | | tx*fixedPoint(internalIndexer_(ix+1,iy+1 | |
| | | )))); | |
| | | } | |
| | | | |
| | | template <unsigned IntBits1, unsigned FractionalBits1, | |
| | | unsigned IntBits2, unsigned FractionalBits2> | |
| | | value_type unchecked(FixedPoint<IntBits1, FractionalBits1> x, | |
| | | FixedPoint<IntBits2, FractionalBits2> y, | |
| | | unsigned int dx, unsigned int dy) const | |
| | | { | |
| | | int ix = floor(x); | |
| | | FixedPoint<0, FractionalBits1> tx = frac(x - FixedPoint<IntBits1, F | |
| | | ractionalBits1>(ix)); | |
| | | FixedPoint<0, FractionalBits1> dtx = dual_frac(tx); | |
| | | if(ix == w_ - 1) | |
| | | { | |
| | | --ix; | |
| | | tx.value = FixedPoint<0, FractionalBits1>::ONE; | |
| | | dtx.value = 0; | |
| | | } | |
| | | int iy = floor(y); | |
| | | FixedPoint<0, FractionalBits2> ty = frac(y - FixedPoint<IntBits2, F | |
| | | ractionalBits2>(iy)); | |
| | | FixedPoint<0, FractionalBits2> dty = dual_frac(ty); | |
| | | if(iy == h_ - 1) | |
| | | { | |
| | | --iy; | |
| | | ty.value = FixedPoint<0, FractionalBits2>::ONE; | |
| | | dty.value = 0; | |
| | | } | |
| | | switch(dx) | |
| | | { | |
| | | case 0: | |
| | | switch(dy) | |
| | | { | |
| | | case 0: | |
| | | return fixed_point_cast<value_type>( | |
| | | dty*(dtx*fixedPoint(internalIndexer_(ix,iy) | |
| | | ) + | |
| | | tx*fixedPoint(internalIndexe | |
| | | r_(ix+1,iy))) + | |
| | | ty *(dtx*fixedPoint(internalIndexer_(ix,iy+ | |
| | | 1)) + | |
| | | tx*fixedPoint(internalIndexe | |
| | | r_(ix+1,iy+1)))); | |
| | | case 1: | |
| | | return fixed_point_cast<value_type>( | |
| | | (dtx*fixedPoint(internalIndexer_(ix,iy+1)) + tx* | |
| | | fixedPoint(internalIndexer_(ix+1,iy+1))) - | |
| | | (dtx*fixedPoint(internalIndexer_(ix,iy)) + tx*fi | |
| | | xedPoint(internalIndexer_(ix+1,iy)))); | |
| | | default: | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | } | |
| | | case 1: | |
| | | switch(dy) | |
| | | { | |
| | | case 0: | |
| | | return fixed_point_cast<value_type>( | |
| | | dty*(fixedPoint(internalIndexer_(ix+1,iy)) | |
| | | - fixedPoint(internalIndexer_(ix,iy))) + | |
| | | ty *(fixedPoint(internalIndexer_(ix+1,iy+1) | |
| | | ) - fixedPoint(internalIndexer_(ix,iy+1)))); | |
| | | case 1: | |
| | | return detail::RequiresExplicitCast<value_type>::cast( | |
| | | (internalIndexer_(ix+1,iy+1) - internalInde | |
| | | xer_(ix,iy+1)) - | |
| | | (internalIndexer_(ix+1,iy) - internalIndexe | |
| | | r_(ix,iy))); | |
| | | default: | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | } | |
| | | default: | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | } | |
| | | } | |
| | | | |
| | | value_type unchecked(double x, double y) const | |
| | | { | |
| | | int ix = (int)std::floor(x); | |
| | | if(ix == w_ - 1) | |
| | | --ix; | |
| | | double tx = x - ix; | |
| | | int iy = (int)std::floor(y); | |
| | | if(iy == h_ - 1) | |
| | | --iy; | |
| | | double ty = y - iy; | |
| | | return NumericTraits<value_type>::fromRealPromote( | |
| | | (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + tx*internal | |
| | | Indexer_(ix+1,iy)) + | |
| | | ty *((1.0-tx)*internalIndexer_(ix,iy+1) + tx*internalIn | |
| | | dexer_(ix+1,iy+1))); | |
| | | } | |
| | | | |
| | | value_type unchecked(double x, double y, unsigned int dx, unsigned int | |
| | | dy) const | |
| | | { | |
| | | int ix = (int)std::floor(x); | |
| | | if(ix == w_ - 1) | |
| | | --ix; | |
| | | double tx = x - ix; | |
| | | int iy = (int)std::floor(y); | |
| | | if(iy == h_ - 1) | |
| | | --iy; | |
| | | double ty = y - iy; | |
| | | switch(dx) | |
| | | { | |
| | | case 0: | |
| | | switch(dy) | |
| | | { | |
| | | case 0: | |
| | | return NumericTraits<value_type>::fromRealPromote( | |
| | | (1.0-ty)*((1.0-tx)*internalIndexer_(ix,iy) + | |
| | | tx*internalIndexer_(ix+1,iy)) + | |
| | | ty *((1.0-tx)*internalIndexer_(ix,iy+1) + t | |
| | | x*internalIndexer_(ix+1,iy+1))); | |
| | | case 1: | |
| | | return NumericTraits<value_type>::fromRealPromote( | |
| | | ((1.0-tx)*internalIndexer_(ix,iy+1) + tx*int | |
| | | ernalIndexer_(ix+1,iy+1)) - | |
| | | ((1.0-tx)*internalIndexer_(ix,iy) + tx*inter | |
| | | nalIndexer_(ix+1,iy))); | |
| | | default: | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | } | |
| | | case 1: | |
| | | switch(dy) | |
| | | { | |
| | | case 0: | |
| | | return NumericTraits<value_type>::fromRealPromote( | |
| | | (1.0-ty)*(internalIndexer_(ix+1,iy) - intern | |
| | | alIndexer_(ix,iy)) + | |
| | | ty *(internalIndexer_(ix+1,iy+1) - internal | |
| | | Indexer_(ix,iy+1))); | |
| | | case 1: | |
| | | return detail::RequiresExplicitCast<value_type>::cast( | |
| | | (internalIndexer_(ix+1,iy+1) - internalIndexe | |
| | | r_(ix,iy+1)) - | |
| | | (internalIndexer_(ix+1,iy) - internalIndexer_ | |
| | | (ix,iy))); | |
| | | default: | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | } | |
| | | default: | |
| | | return NumericTraits<VALUETYPE>::zero(); | |
| | | } | |
| | | } | |
| | | | |
| | | value_type operator()(double x, double y) const | |
| | | { | |
| | | return operator()(x, y, 0, 0); | |
| | | } | |
| | | | |
| | | value_type operator()(double x, double y, unsigned int dx, unsigned int | |
| | | dy) const | |
| | | { | |
| | | value_type mul = NumericTraits<value_type>::one(); | |
| | | if(x < 0.0) | |
| | | { | |
| | | x = -x; | |
| | | vigra_precondition(x <= w_ - 1.0, | |
| | | "SplineImageView::operator(): coordinates out of range. | |
| | | "); | |
| | | if(dx % 2) | |
| | | mul = -mul; | |
| | | } | |
| | | else if(x > w_ - 1.0) | |
| | | { | |
| | | x = 2.0*w_-2.0-x; | |
| | | vigra_precondition(x >= 0.0, | |
| | | "SplineImageView::operator(): coordinates out of range. | |
| | | "); | |
| | | if(dx % 2) | |
| | | mul = -mul; | |
| | | } | |
| | | if(y < 0.0) | |
| | | { | |
| | | y = -y; | |
| | | vigra_precondition(y <= h_ - 1.0, | |
| | | "SplineImageView::operator(): coordinates out of range. | |
| | | "); | |
| | | if(dy % 2) | |
| | | mul = -mul; | |
| | | } | |
| | | else if(y > h_ - 1.0) | |
| | | { | |
| | | y = 2.0*h_-2.0-y; | |
| | | vigra_precondition(y >= 0.0, | |
| | | "SplineImageView::operator(): coordinates out of range. | |
| | | "); | |
| | | if(dy % 2) | |
| | | mul = -mul; | |
| | | } | |
| | | return mul*unchecked(x, y, dx, dy); | |
| | | } | |
| | | | |
| | | value_type dx(double x, double y) const | |
| | | { return operator()(x, y, 1, 0); } | |
| | | | |
| | | value_type dy(double x, double y) const | |
| | | { return operator()(x, y, 0, 1); } | |
| | | | |
| | | value_type dxx(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxy(double x, double y) const | |
| | | { return operator()(x, y, 1, 1); } | |
| | | | |
| | | value_type dyy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dx3(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dy3(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxxy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxyy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type operator()(difference_type const & d) const | |
| | | { return operator()(d[0], d[1]); } | |
| | | | |
| | | value_type operator()(difference_type const & d, unsigned int dx, unsig | |
| | | ned int dy) const | |
| | | { return operator()(d[0], d[1], dx, dy); } | |
| | | | |
| | | value_type dx(difference_type const & d) const | |
| | | { return operator()(d[0], d[1], 1, 0); } | |
| | | | |
| | | value_type dy(difference_type const & d) const | |
| | | { return operator()(d[0], d[1], 0, 1); } | |
| | | | |
| | | value_type dxx(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxy(difference_type const & d) const | |
| | | { return operator()(d[0], d[1], 1, 1); } | |
| | | | |
| | | value_type dyy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dx3(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dy3(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxxy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type dxyy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2(double x, double y) const | |
| | | { return sq(dx(x,y)) + sq(dy(x,y)); } | |
| | | | |
| | | value_type g2x(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2y(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xx(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2yy(double x, double y) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2(difference_type const & d) const | |
| | | { return g2(d[0], d[1]); } | |
| | | | |
| | | value_type g2x(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2y(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xx(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2xy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | value_type g2yy(difference_type const & d) const | |
| | | { return NumericTraits<VALUETYPE>::zero(); } | |
| | | | |
| | | unsigned int width() const | |
| | | { return w_; } | |
| | | | |
| | | unsigned int height() const | |
| | | { return h_; } | |
| | | | |
| | | size_type size() const | |
| | | { return size_type(w_, h_); } | |
| | | | |
| | | template <class Array> | |
| | | void coefficientArray(double x, double y, Array & res) const; | |
| | | | |
| | | void calculateIndices(double x, double y, int & ix, int & iy, int & ix1 | |
| | | , int & iy1) const; | |
| | | | |
| | | bool isInsideX(double x) const | |
| | | { | |
| | | return x >= 0.0 && x <= width() - 1.0; | |
| | | } | |
| | | | |
| | | bool isInsideY(double y) const | |
| | | { | |
| | | return y >= 0.0 && y <= height() - 1.0; | |
| | | } | |
| | | | |
| | | bool isInside(double x, double y) const | |
| | | { | |
| | | return isInsideX(x) && isInsideY(y); | |
| | | } | |
| | | | |
| | | bool isValid(double x, double y) const | |
| | | { | |
| | | return x < 2.0*w_-2.0 && x > -w_+1.0 && y < 2.0*h_-2.0 && y > -h_+1 | |
| | | .0; | |
| | | } | |
| | | | |
| | | bool sameFacet(double x0, double y0, double x1, double y1) const | |
| | | { | |
| | | x0 = VIGRA_CSTD::floor(x0); | |
| | | y0 = VIGRA_CSTD::floor(y0); | |
| | | x1 = VIGRA_CSTD::floor(x1); | |
| | | y1 = VIGRA_CSTD::floor(y1); | |
| | | return x0 == x1 && y0 == y1; | |
| | | } | |
| | | | |
| | | protected: | |
| | | unsigned int w_, h_; | |
| | | INTERNAL_INDEXER internalIndexer_; | |
| | | }; | |
| | | | |
| | | template <class VALUETYPE, class INTERNAL_INDEXER> | |
| | | template <class Array> | |
| | | void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::coefficientArray(do | |
| | | uble x, double y, Array & res) const | |
| | | { | |
| | | int ix, iy, ix1, iy1; | |
| | | calculateIndices(x, y, ix, iy, ix1, iy1); | |
| | | res.resize(2, 2); | |
| | | res(0,0) = internalIndexer_(ix,iy); | |
| | | res(1,0) = internalIndexer_(ix1,iy) - internalIndexer_(ix,iy); | |
| | | res(0,1) = internalIndexer_(ix,iy1) - internalIndexer_(ix,iy); | |
| | | res(1,1) = internalIndexer_(ix,iy) - internalIndexer_(ix1,iy) - | |
| | | internalIndexer_(ix,iy1) + internalIndexer_(ix1,iy1); | |
| | | } | |
| | | | |
| | | template <class VALUETYPE, class INTERNAL_INDEXER> | |
| | | void SplineImageView1Base<VALUETYPE, INTERNAL_INDEXER>::calculateIndices(do | |
| | | uble x, double y, int & ix, int & iy, int & ix1, int & iy1) const | |
| | | { | |
| | | if(x < 0.0) | |
| | | { | |
| | | x = -x; | |
| | | vigra_precondition(x <= w_ - 1.0, | |
| | | "SplineImageView::calculateIndices(): coordinates out of ra | |
| | | nge."); | |
| | | ix = (int)VIGRA_CSTD::ceil(x); | |
| | | ix1 = ix - 1; | |
| | | } | |
| | | else if(x >= w_ - 1.0) | |
| | | { | |
| | | x = 2.0*w_-2.0-x; | |
| | | vigra_precondition(x > 0.0, | |
| | | "SplineImageView::calculateIndices(): coordinates out of ra | |
| | | nge."); | |
| | | ix = (int)VIGRA_CSTD::ceil(x); | |
| | | ix1 = ix - 1; | |
| | | } | |
| | | else | |
| | | { | |
| | | ix = (int)VIGRA_CSTD::floor(x); | |
| | | ix1 = ix + 1; | |
| | | } | |
| | | if(y < 0.0) | |
| | | { | |
| | | y = -y; | |
| | | vigra_precondition(y <= h_ - 1.0, | |
| | | "SplineImageView::calculateIndices(): coordinates out of ra | |
| | | nge."); | |
| | | iy = (int)VIGRA_CSTD::ceil(y); | |
| | | iy1 = iy - 1; | |
| | | } | |
| | | else if(y >= h_ - 1.0) | |
| | | { | |
| | | y = 2.0*h_-2.0-y; | |
| | | vigra_precondition(y > 0.0, | |
| | | "SplineImageView::calculateIndices(): coordinates out of ra | |
| | | nge."); | |
| | | iy = (int)VIGRA_CSTD::ceil(y); | |
| | | iy1 = iy - 1; | |
| | | } | |
| | | else | |
| | | { | |
| | | iy = (int)VIGRA_CSTD::floor(y); | |
| | | iy1 = iy + 1; | |
| | | } | |
| | | } | |
| | | | |
| | | /** \brief Create an image view for bi-linear interpolation. | |
| | | | |
| | | This class behaves like \ref vigra::SplineImageView<1, ...>, but | |
| | | one can pass | |
| | | an additional template argument that determined the internal representa | |
| | | tion of the image. | |
| | | If this is equal to the argument type passed in the constructor, the im | |
| | | age is not copied. | |
| | | By default, this works for \ref vigra::BasicImage, \ref vigra::BasicIma | |
| | | geView, | |
| | | \ref vigra::MultiArray<2, ...>, and \ref vigra::MultiArrayView< | |
| | | ;2, ...>. | |
| | | | |
| | | In addition to the function provided by \ref vigra::SplineImageView, t | |
| | | here are functions | |
| | | <tt>unchecked(x,y)</tt> and <tt>unchecked(x,y, xorder, yorder)</tt> whi | |
| | | ch improve speed by | |
| | | not applying bounds checking and reflective border treatment (<tt>isIns | |
| | | ide(x, y)</tt> must | |
| | | be <tt>true</tt>), but otherwise behave identically to their checked co | |
| | | unterparts. | |
| | | In addition, <tt>x</tt> and <tt>y</tt> can have type \ref vigra::FixedP | |
| | | oint instead of | |
| | | <tt>double</tt>. | |
| | | */ | |
| | | template <class VALUETYPE, class INTERNAL_TRAVERSER = typename BasicImage<V | |
| | | ALUETYPE>::const_traverser> | |
| | | class SplineImageView1 | |
| | | : public SplineImageView1Base<VALUETYPE, INTERNAL_TRAVERSER> | |
| | | { | |
| | | typedef SplineImageView1Base<VALUETYPE, INTERNAL_TRAVERSER> Base; | |
| | | public: | |
| | | typedef typename Base::value_type value_type; | |
| | | typedef typename Base::size_type size_type; | |
| | | typedef typename Base::difference_type difference_type; | |
| | | enum StaticOrder { order = Base::order }; | |
| | | typedef BasicImage<VALUETYPE> InternalImage; | |
| | | | |
| | | protected: | |
| | | typedef typename IteratorTraits<INTERNAL_TRAVERSER>::mutable_iterator I | |
| | | nternalTraverser; | |
| | | typedef typename IteratorTraits<InternalTraverser>::DefaultAccessor Int | |
| | | ernalAccessor; | |
| | | typedef typename IteratorTraits<INTERNAL_TRAVERSER>::const_iterator Int | |
| | | ernalConstTraverser; | |
| | | typedef typename IteratorTraits<InternalConstTraverser>::DefaultAccesso | |
| | | r InternalConstAccessor; | |
| | | | |
| | | public: | |
| | | | |
| | | /* when traverser and accessor types passed to the constructor are | |
| | | the same as the corresponding | |
| | | internal types, we need not copy the image (speed up) | |
| | | */ | |
| | | SplineImageView1(InternalTraverser is, InternalTraverser iend, Internal | |
| | | Accessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y, is) | |
| | | {} | |
| | | | |
| | | SplineImageView1(triple<InternalTraverser, InternalTraverser, InternalA | |
| | | ccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first) | |
| | | {} | |
| | | | |
| | | SplineImageView1(InternalConstTraverser is, InternalConstTraverser iend | |
| | | , InternalConstAccessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y, is) | |
| | | {} | |
| | | | |
| | | SplineImageView1(triple<InternalConstTraverser, InternalConstTraverser, | |
| | | InternalConstAccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y, s.first) | |
| | | {} | |
| | | | |
| | | template<class T, class SU> | |
| | | SplineImageView1(MultiArrayView<2, T, SU> const & i) | |
| | | : Base(i.shape(0), i.shape(1)), | |
| | | image_(i.shape(0), i.shape(1)) | |
| | | { | |
| | | for(unsigned int y=0; y<this->height(); ++y) | |
| | | for(unsigned int x=0; x<this->width(); ++x) | |
| | | image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast | |
| | | (i(x,y)); | |
| | | this->internalIndexer_ = image_.upperLeft(); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView1(SrcIterator is, SrcIterator iend, SrcAccessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y), | |
| | | image_(iend - is) | |
| | | { | |
| | | copyImage(srcIterRange(is, iend, sa), destImage(image_)); | |
| | | this->internalIndexer_ = image_.upperLeft(); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView1(triple<SrcIterator, SrcIterator, SrcAccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y), | |
| | | image_(s.second - s.first) | |
| | | { | |
| | | copyImage(s, destImage(image_)); | |
| | | this->internalIndexer_ = image_.upperLeft(); | |
| | | } | |
| | | | |
| | | InternalImage const & image() const | |
| | | { return image_; } | |
| | | | |
| | | protected: | |
| | | InternalImage image_; | |
| | | }; | |
| | | | |
| | | template <class VALUETYPE, class StridedOrUnstrided> | |
| | | class SplineImageView1<VALUETYPE, MultiArrayView<2, VALUETYPE, StridedOrUns | |
| | | trided> > | |
| | | : public SplineImageView1Base<VALUETYPE, MultiArrayView<2, VALUETYPE, Strid | |
| | | edOrUnstrided> > | |
| | | { | |
| | | typedef SplineImageView1Base<VALUETYPE, MultiArrayView<2, VALUETYPE, St | |
| | | ridedOrUnstrided> > Base; | |
| | | public: | |
| | | typedef typename Base::value_type value_type; | |
| | | typedef typename Base::size_type size_type; | |
| | | typedef typename Base::difference_type difference_type; | |
| | | enum StaticOrder { order = Base::order }; | |
| | | typedef BasicImage<VALUETYPE> InternalImage; | |
| | | | |
| | | protected: | |
| | | typedef MultiArrayView<2, VALUETYPE, StridedOrUnstrided> InternalIndexe | |
| | | r; | |
| | | | |
| | | public: | |
| | | | |
| | | /* when traverser and accessor types passed to the constructor are | |
| | | the same as the corresponding | |
| | | internal types, we need not copy the image (speed up) | |
| | | */ | |
| | | SplineImageView1(InternalIndexer const & i) | |
| | | : Base(i.shape(0), i.shape(1), i) | |
| | | {} | |
| | | | |
| | | template<class T, class SU> | |
| | | SplineImageView1(MultiArrayView<2, T, SU> const & i) | |
| | | : Base(i.shape(0), i.shape(1)), | |
| | | image_(i.shape(0), i.shape(1)) | |
| | | { | |
| | | for(unsigned int y=0; y<this->height(); ++y) | |
| | | for(unsigned int x=0; x<this->width(); ++x) | |
| | | image_(x,y) = detail::RequiresExplicitCast<VALUETYPE>::cast | |
| | | (i(x,y)); | |
| | | this->internalIndexer_ = InternalIndexer(typename InternalIndexer:: | |
| | | difference_type(this->width(), this->height()), | |
| | | image_.data()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView1(SrcIterator is, SrcIterator iend, SrcAccessor sa) | |
| | | : Base(iend.x - is.x, iend.y - is.y), | |
| | | image_(iend-is) | |
| | | { | |
| | | copyImage(srcIterRange(is, iend, sa), destImage(image_)); | |
| | | this->internalIndexer_ = InternalIndexer(typename InternalIndexer:: | |
| | | difference_type(this->width(), this->height()), | |
| | | image_.data()); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView1(triple<SrcIterator, SrcIterator, SrcAccessor> s) | |
| | | : Base(s.second.x - s.first.x, s.second.y - s.first.y), | |
| | | image_(s.second - s.first) | |
| | | { | |
| | | copyImage(s, destImage(image_)); | |
| | | this->internalIndexer_ = InternalIndexer(typename InternalIndexer:: | |
| | | difference_type(this->width(), this->height()), | |
| | | image_.data()); | |
| | | } | |
| | | | |
| | | InternalImage const & image() const | |
| | | { return image_; } | |
| | | | |
| | | protected: | |
| | | InternalImage image_; | |
| | | }; | |
| | | | |
| | | template <class VALUETYPE> | |
| | | class SplineImageView<1, VALUETYPE> | |
| | | : public SplineImageView1<VALUETYPE> | |
| | | { | |
| | | typedef SplineImageView1<VALUETYPE> Base; | |
| | | public: | |
| | | typedef typename Base::value_type value_type; | |
| | | typedef typename Base::size_type size_type; | |
| | | typedef typename Base::difference_type difference_type; | |
| | | enum StaticOrder { order = Base::order }; | |
| | | typedef typename Base::InternalImage InternalImage; | |
| | | | |
| | | protected: | |
| | | typedef typename Base::InternalTraverser InternalTraverser; | |
| | | typedef typename Base::InternalAccessor InternalAccessor; | |
| | | typedef typename Base::InternalConstTraverser InternalConstTraverser; | |
| | | typedef typename Base::InternalConstAccessor InternalConstAccessor; | |
| | | | |
| | | public: | |
| | | | |
| | | /* when traverser and accessor types passed to the constructor are | |
| | | the same as the corresponding | |
| | | internal types, we need not copy the image (speed up) | |
| | | */ | |
| | | SplineImageView(InternalTraverser is, InternalTraverser iend, InternalA | |
| | | ccessor sa, bool /* unused */ = false) | |
| | | : Base(is, iend, sa) | |
| | | {} | |
| | | | |
| | | SplineImageView(triple<InternalTraverser, InternalTraverser, InternalAc | |
| | | cessor> s, bool /* unused */ = false) | |
| | | : Base(s) | |
| | | {} | |
| | | | |
| | | SplineImageView(InternalConstTraverser is, InternalConstTraverser iend, | |
| | | InternalConstAccessor sa, bool /* unused */ = false) | |
| | | : Base(is, iend, sa) | |
| | | {} | |
| | | | |
| | | SplineImageView(triple<InternalConstTraverser, InternalConstTraverser, | |
| | | InternalConstAccessor> s, bool /* unused */ = false) | |
| | | : Base(s) | |
| | | {} | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView(SrcIterator is, SrcIterator iend, SrcAccessor sa, bool | |
| | | /* unused */ = false) | |
| | | : Base(is, iend, sa) | |
| | | { | |
| | | copyImage(srcIterRange(is, iend, sa), destImage(this->image_)); | |
| | | } | |
| | | | |
| | | template <class SrcIterator, class SrcAccessor> | |
| | | SplineImageView(triple<SrcIterator, SrcIterator, SrcAccessor> s, bool / | |
| | | * unused */ = false) | |
| | | : Base(s) | |
| | | { | |
| | | copyImage(s, destImage(this->image_)); | |
| | | } | |
| | | }; | |
| | | | |
| } // namespace vigra | | } // namespace vigra | |
| | | | |
| #endif /* VIGRA_SPLINEIMAGEVIEW_HXX */ | | #endif /* VIGRA_SPLINEIMAGEVIEW_HXX */ | |
| | | | |
End of changes. 29 change blocks. |
| 44 lines changed or deleted | | 1330 lines changed or added | |
|
| stdconvolution.hxx | | stdconvolution.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_STDCONVOLUTION_HXX | | #ifndef VIGRA_STDCONVOLUTION_HXX | |
| #define VIGRA_STDCONVOLUTION_HXX | | #define VIGRA_STDCONVOLUTION_HXX | |
| | | | |
| #include <cmath> | | #include <cmath> | |
| #include "vigra/stdimage.hxx" | | #include "vigra/stdimage.hxx" | |
| #include "vigra/bordertreatment.hxx" | | #include "vigra/bordertreatment.hxx" | |
| #include "vigra/separableconvolution.hxx" | | #include "vigra/separableconvolution.hxx" | |
| #include "vigra/utilities.hxx" | | #include "vigra/utilities.hxx" | |
|
| | | #include "vigra/sized_int.hxx" | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| template <class SrcIterator, class SrcAccessor, | | template <class SrcIterator, class SrcAccessor, | |
| class DestIterator, class DestAccessor, | | class DestIterator, class DestAccessor, | |
| class KernelIterator, class KernelAccessor, | | class KernelIterator, class KernelAccessor, | |
| class KSumType> | | class KSumType> | |
| void internalPixelEvaluationByClip(int x, int y, int w, int h, SrcIterator
xs, | | void internalPixelEvaluationByClip(int x, int y, int w, int h, SrcIterator
xs, | |
| SrcAccessor src_acc, DestIterator xd, De
stAccessor dest_acc, | | SrcAccessor src_acc, DestIterator xd, De
stAccessor dest_acc, | |
| KernelIterator ki, Diff2D kul, Diff2D kl
r, KernelAccessor ak, | | KernelIterator ki, Diff2D kul, Diff2D kl
r, KernelAccessor ak, | |
| | | | |
| skipping to change at line 116 | | skipping to change at line 132 | |
| SrcIterator src_ul = xs - Diff2D(x, y); | | SrcIterator src_ul = xs - Diff2D(x, y); | |
| SrcIterator src_lr = src_ul + Diff2D(src_width, src_height); | | SrcIterator src_lr = src_ul + Diff2D(src_width, src_height); | |
| | | | |
| SrcIterator yys = xs; | | SrcIterator yys = xs; | |
| KernelIterator yk = ki; | | KernelIterator yk = ki; | |
| | | | |
| // calculate width and height of the kernel | | // calculate width and height of the kernel | |
| int kernel_width = klr.x - kul.x + 1; | | int kernel_width = klr.x - kul.x + 1; | |
| int kernel_height = klr.y - kul.y + 1; | | int kernel_height = klr.y - kul.y + 1; | |
| | | | |
|
| //Zeigt an wo der Kernel | | // where the kernel is beyond the borders: | |
| bool top_to_much = (y<klr.y) ? true : false; | | bool top_to_much = (y<klr.y) ? true : false; | |
| bool down_to_much = (src_height-y-1<-kul.y)? true : false; | | bool down_to_much = (src_height-y-1<-kul.y)? true : false; | |
| bool left_to_much = (x<klr.x)? true : false; | | bool left_to_much = (x<klr.x)? true : false; | |
| bool right_to_much = (src_width-x-1<-kul.x)? true : false; | | bool right_to_much = (src_width-x-1<-kul.x)? true : false; | |
| | | | |
|
| //Die Richtung x und y !!! | | // direction of iteration, | |
| //in der bei der Iteration | | // e.g. (-1, +1) for ll->ur or (-1, -1) for lr->ul | |
| //iteriert wird. Also wenn von ur->ll dann (-1, +1) und wenn lr->ul | | | |
| //dann (-1, -1). | | | |
| Diff2D way_increment; | | Diff2D way_increment; | |
| | | | |
|
| /* iteriert wird immer aus dem g | | /* Iteration is always done from valid to invalid range. | |
| Bereich! dieser Tupel setzt sich wie folgt zusammen: | | The following tuple is composed as such: | |
| 1. Wird bei der Iteration in X-Richtung ung | | - If an invalid range is reached while iterating in X, | |
| erreicht so wird mit border_increment.first gesprungen und | | a jump of border_increment.first is performed and | |
| mit border_increment.third weiter iteriert. | | border_increment.third is used for further iterating. | |
| 2. Wird bei der Iteration in Y-Richtung ung | | - If an invalid range is reached while iterating in Y, | |
| erreicht so wird mit border_increment.second gesprungen und | | a jump of border_increment.second is performed and | |
| mit border_increment.fourth weiter iteriert. | | border_increment.fourth is used for further iterating. | |
| */ | | */ | |
| tuple4<int, int, int, int> border_increment; | | tuple4<int, int, int, int> border_increment; | |
| if (border == BORDER_TREATMENT_REPEAT){ | | if (border == BORDER_TREATMENT_REPEAT){ | |
| border_increment = tuple4<int, int, int, int>(1, 1, 0, 0); | | border_increment = tuple4<int, int, int, int>(1, 1, 0, 0); | |
| }else if (border == BORDER_TREATMENT_REFLECT){ | | }else if (border == BORDER_TREATMENT_REFLECT){ | |
| border_increment = tuple4<int, int, int, int>(2, 2, -1, -1); | | border_increment = tuple4<int, int, int, int>(2, 2, -1, -1); | |
| }else{ // BORDER_TREATMENT_WRAP | | }else{ // BORDER_TREATMENT_WRAP | |
| border_increment = tuple4<int, int, int, int>(src_width, src_height
, 1, 1); | | border_increment = tuple4<int, int, int, int>(src_width, src_height
, 1, 1); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 223 | | skipping to change at line 237 | |
| yys += kul + Diff2D(0, kernel_height - 1); | | yys += kul + Diff2D(0, kernel_height - 1); | |
| yk += kul + Diff2D(kernel_width - 1, 0); | | yk += kul + Diff2D(kernel_width - 1, 0); | |
| way_increment = Diff2D(1, -1); | | way_increment = Diff2D(1, -1); | |
| border_increment.first = -border_increment.first; | | border_increment.first = -border_increment.first; | |
| border_increment.fourth = -border_increment.fourth; | | border_increment.fourth = -border_increment.fourth; | |
| valid_step_count = std::make_pair((src_lr - yys).x, (yys - src_ul).
y + 1); | | valid_step_count = std::make_pair((src_lr - yys).x, (yys - src_ul).
y + 1); | |
| } | | } | |
| | | | |
| int yy = 0, xx; | | int yy = 0, xx; | |
| | | | |
|
| //laeuft den zul | | //laeuft den zul | |
| for(; yy < valid_step_count.second; ++yy, yys.y += way_increment.y, yk.
y -= way_increment.y ) | | for(; yy < valid_step_count.second; ++yy, yys.y += way_increment.y, yk.
y -= way_increment.y ) | |
| { | | { | |
| SrcIterator xxs = yys; | | SrcIterator xxs = yys; | |
| KernelIterator xk = yk; | | KernelIterator xk = yk; | |
| | | | |
|
| //laeuft den zul | | //laeuft den zul | |
| for(xx = 0; xx < valid_step_count.first; ++xx, xxs.x += way_increme
nt.x, xk.x -= way_increment.x) | | for(xx = 0; xx < valid_step_count.first; ++xx, xxs.x += way_increme
nt.x, xk.x -= way_increment.x) | |
| { | | { | |
| sum += ak(xk) * src_acc(xxs); | | sum += ak(xk) * src_acc(xxs); | |
| } | | } | |
| | | | |
|
| //N | | //N | |
| //bringen => Sprung in zulaessigen Bereich | | //bringen => Sprung in zulaessigen Bereich | |
| xxs.x += border_increment.first; | | xxs.x += border_increment.first; | |
| | | | |
| for( ; xx < kernel_width; ++xx, xxs.x += border_increment.third, xk
.x -= way_increment.x ) | | for( ; xx < kernel_width; ++xx, xxs.x += border_increment.third, xk
.x -= way_increment.x ) | |
| { | | { | |
| sum += ak(xk) * src_acc(xxs); | | sum += ak(xk) * src_acc(xxs); | |
| } | | } | |
| } | | } | |
| | | | |
|
| //N | | //N | |
| //bringen => Sprung in zulaessigen Bereich | | //bringen => Sprung in zulaessigen Bereich | |
| yys.y += border_increment.second; | | yys.y += border_increment.second; | |
| | | | |
| for( ; yy < kernel_height; ++yy, yys.y += border_increment.third, yk.y
-= way_increment.y) | | for( ; yy < kernel_height; ++yy, yys.y += border_increment.third, yk.y
-= way_increment.y) | |
| { | | { | |
| SrcIterator xxs = yys; | | SrcIterator xxs = yys; | |
| KernelIterator xk = yk; | | KernelIterator xk = yk; | |
| | | | |
| for(xx=0; xx < valid_step_count.first; ++xx, xxs.x += way_increment
.x, xk.x -= way_increment.x) | | for(xx=0; xx < valid_step_count.first; ++xx, xxs.x += way_increment
.x, xk.x -= way_increment.x) | |
| { | | { | |
| | | | |
| skipping to change at line 463 | | skipping to change at line 477 | |
| | | | |
| vigra_precondition(kul.x <= 0 && kul.y <= 0, | | vigra_precondition(kul.x <= 0 && kul.y <= 0, | |
| "convolveImage(): coordinates of " | | "convolveImage(): coordinates of " | |
| "kernel's upper left must be <= 0."); | | "kernel's upper left must be <= 0."); | |
| vigra_precondition(klr.x >= 0 && klr.y >= 0, | | vigra_precondition(klr.x >= 0 && klr.y >= 0, | |
| "convolveImage(): coordinates of " | | "convolveImage(): coordinates of " | |
| "kernel's lower right must be >= 0."); | | "kernel's lower right must be >= 0."); | |
| | | | |
| // use traits to determine SumType as to prevent possible overflow | | // use traits to determine SumType as to prevent possible overflow | |
| typedef typename | | typedef typename | |
|
| NumericTraits<typename SrcAccessor::value_type>::RealPromote SumTyp | | PromoteTraits<typename SrcAccessor::value_type, | |
| e; | | typename KernelAccessor::value_type>::Promote SumType | |
| | | ; | |
| typedef typename | | typedef typename | |
| NumericTraits<typename KernelAccessor::value_type>::RealPromote Ker
nelSumType; | | NumericTraits<typename KernelAccessor::value_type>::RealPromote Ker
nelSumType; | |
| typedef | | typedef | |
| NumericTraits<typename DestAccessor::value_type> DestTraits; | | NumericTraits<typename DestAccessor::value_type> DestTraits; | |
| | | | |
| // calculate width and height of the image | | // calculate width and height of the image | |
| int w = src_lr.x - src_ul.x; | | int w = src_lr.x - src_ul.x; | |
| int h = src_lr.y - src_ul.y; | | int h = src_lr.y - src_ul.y; | |
| | | | |
| // calculate width and height of the kernel | | // calculate width and height of the kernel | |
| | | | |
| skipping to change at line 572 | | skipping to change at line 587 | |
| borderinc = 1; | | borderinc = 1; | |
| } | | } | |
| | | | |
| // create iterators for the entire image | | // create iterators for the entire image | |
| yd = dest_ul; | | yd = dest_ul; | |
| ys = src_ul; | | ys = src_ul; | |
| | | | |
| // go over the entire image (but skip the already computed points in th
e loop) | | // go over the entire image (but skip the already computed points in th
e loop) | |
| for(y=0; y < h; ++y, ++ys.y, ++yd.y) | | for(y=0; y < h; ++y, ++ys.y, ++yd.y) | |
| { | | { | |
|
| int top = std::max(-klr.y, src_ul.y - ys.y); | | int top = std::max(static_cast<IntBiggest>(-klr.y), | |
| int bottom = std::min(-kul.y, src_lr.y - ys.y - 1); | | static_cast<IntBiggest>(src_ul.y - ys.y)); | |
| | | int bottom = std::min(static_cast<IntBiggest>(-kul.y), | |
| | | static_cast<IntBiggest>(src_lr.y - ys.y - 1)) | |
| | | ; | |
| | | | |
| // create x iterators | | // create x iterators | |
| DestIterator xd(yd); | | DestIterator xd(yd); | |
| SrcIterator xs(ys); | | SrcIterator xs(ys); | |
| | | | |
| for(x=0; x < w; ++x, ++xs.x, ++xd.x) | | for(x=0; x < w; ++x, ++xs.x, ++xd.x) | |
| { | | { | |
| // check if we are away from the border | | // check if we are away from the border | |
| if(y >= klr.y && y < h+kul.y && x == klr.x) | | if(y >= klr.y && y < h+kul.y && x == klr.x) | |
| { | | { | |
| | | | |
End of changes. 13 change blocks. |
| 30 lines changed or deleted | | 48 lines changed or added | |
|
| stdimage.hxx | | stdimage.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_STDIMAGE_HXX | | #ifndef VIGRA_STDIMAGE_HXX | |
| #define VIGRA_STDIMAGE_HXX | | #define VIGRA_STDIMAGE_HXX | |
| | | | |
|
| | | #include "vigra/sized_int.hxx" | |
| #include "vigra/tuple.hxx" | | #include "vigra/tuple.hxx" | |
| #include "vigra/basicimage.hxx" | | #include "vigra/basicimage.hxx" | |
| #include "vigra/iteratortraits.hxx" | | #include "vigra/iteratortraits.hxx" | |
| #include "vigra/accessor.hxx" | | #include "vigra/accessor.hxx" | |
| #include "vigra/rgbvalue.hxx" | | #include "vigra/rgbvalue.hxx" | |
| | | | |
| namespace vigra { | | namespace vigra { | |
| | | | |
| /** \addtogroup StandardImageTypes Standard Image Types | | /** \addtogroup StandardImageTypes Standard Image Types | |
| | | | |
| | | | |
| skipping to change at line 47 | | skipping to change at line 63 | |
| */ | | */ | |
| //@{ | | //@{ | |
| | | | |
| /** Byte (8-bit unsigned) image. | | /** Byte (8-bit unsigned) image. | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
|
| typedef BasicImage<unsigned char> BImage; | | typedef BasicImage<UInt8> BImage; | |
| | | | |
| | | /** Byte (8-bit unsigned) image. | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce | |
| | | ssor and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<UInt8> UInt8Image; | |
| | | | |
| | | /** Signed byte (8-bit signed) image. | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce | |
| | | ssor and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<Int8> Int8Image; | |
| | | | |
| /** Short integer (16-bit signed) image. | | /** Short integer (16-bit signed) image. | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
|
| typedef BasicImage<short> SImage; | | typedef BasicImage<Int16> SImage; | |
| | | | |
| | | /** Short integer (16-bit unsigned) image. | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce | |
| | | ssor and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<UInt16> UInt16Image; | |
| | | | |
| | | /** Short integer (16-bit signed) image. | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce | |
| | | ssor and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<Int16> Int16Image; | |
| | | | |
| /** Integer (32-bit signed) image. | | /** Integer (32-bit signed) image. | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
|
| typedef BasicImage<int> IImage; | | typedef BasicImage<Int32> IImage; | |
| | | | |
| | | /** Integer (32-bit unsigned) image. | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce | |
| | | ssor and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<UInt32> UInt32Image; | |
| | | | |
| | | /** Integer (32-bit signed) image. | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce | |
| | | ssor and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<Int32> Int32Image; | |
| | | | |
| /** Float (float) image. | | /** Float (float) image. | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<float> FImage; | | typedef BasicImage<float> FImage; | |
| | | | |
| /** Double (double) image. | | /** Double (double) image. | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | | It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce
ssor and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimage
.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimage
.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<double> DImage; | | typedef BasicImage<double> DImage; | |
| | | | |
| /** Byte (3x 8-bit unsigned) RGB image. | | /** Byte (3x 8-bit unsigned) RGB image. | |
|
| The pixel type is \ref vigra::RGBValue "vigra::RGBValue<unsigned ch
ar>". | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt
8>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
|
| typedef BasicImage<RGBValue<unsigned char> > BRGBImage; | | typedef BasicImage<RGBValue<UInt8> > BRGBImage; | |
| | | | |
| | | /** Byte (3x 8-bit unsigned) RGB image. | |
| | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt | |
| | | 8>". | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor | |
| | | and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<RGBValue<UInt8> > UInt8RGBImage; | |
| | | | |
| | | /** Byte (3x 8-bit signed) RGB image. | |
| | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt | |
| | | 8>". | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor | |
| | | and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<RGBValue<Int8> > Int8RGBImage; | |
| | | | |
| | | /** Short (3x 16-bit signed) RGB image. | |
| | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 | |
| | | 6>". | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor | |
| | | and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<RGBValue<Int16> > SRGBImage; | |
| | | | |
| | | /** Short (3x 16-bit unsigned) RGB image. | |
| | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 | |
| | | 6>". | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor | |
| | | and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<RGBValue<UInt16> > UInt16RGBImage; | |
| | | | |
| | | /** Short (3x 16-bit signed) RGB image. | |
| | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 | |
| | | 6>". | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor | |
| | | and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<RGBValue<Int16> > Int16RGBImage; | |
| | | | |
| /** Integer (3x 32-bit signed) RGB image. | | /** Integer (3x 32-bit signed) RGB image. | |
|
| The pixel type is \ref vigra::RGBValue "RGBValue<int>". | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3
2>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
|
| typedef BasicImage<RGBValue<int> > IRGBImage; | | typedef BasicImage<RGBValue<Int32> > IRGBImage; | |
| | | | |
| | | /** Integer (3x 32-bit unsigned) RGB image. | |
| | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 | |
| | | 2>". | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor | |
| | | and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<RGBValue<UInt32> > UInt32RGBImage; | |
| | | | |
| | | /** Integer (3x 32-bit signed) RGB image. | |
| | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 | |
| | | 2>". | |
| | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor | |
| | | and | |
| | | their const counterparts to access the data. | |
| | | | |
| | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag | |
| | | e.hxx</a>"<br> | |
| | | Namespace: vigra | |
| | | */ | |
| | | typedef BasicImage<RGBValue<Int32> > Int32RGBImage; | |
| | | | |
| /** Floating-point (3x float) RGB image. | | /** Floating-point (3x float) RGB image. | |
|
| The pixel type is \ref vigra::RGBValue "RGBValue<float>". | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<float>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<RGBValue<float> > FRGBImage; | | typedef BasicImage<RGBValue<float> > FRGBImage; | |
| | | | |
| /** Double-precision floating-point (3x double) RGB image. | | /** Double-precision floating-point (3x double) RGB image. | |
|
| The pixel type is \ref vigra::RGBValue "RGBValue<double>". | | The pixel type is \ref vigra::RGBValue "vigra::RGBValue<double>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | | It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor
and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<RGBValue<double> > DRGBImage; | | typedef BasicImage<RGBValue<double> > DRGBImage; | |
| | | | |
| /** Floating-point TinyVector image. | | /** Floating-point TinyVector image. | |
|
| The pixel type is \ref vigra::TinyVector "TinyVector<float, 2>". | | The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float,
2>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | | It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<TinyVector<float, 2> > FVector2Image; | | typedef BasicImage<TinyVector<float, 2> > FVector2Image; | |
| | | | |
| /** Floating-point TinyVector image. | | /** Floating-point TinyVector image. | |
|
| The pixel type is \ref vigra::TinyVector "TinyVector<float, 3>". | | The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float,
3>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | | It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<TinyVector<float, 3> > FVector3Image; | | typedef BasicImage<TinyVector<float, 3> > FVector3Image; | |
| | | | |
| /** Floating-point TinyVector image. | | /** Floating-point TinyVector image. | |
|
| The pixel type is \ref vigra::TinyVector "TinyVector<float, 4>". | | The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float,
4>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | | It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<TinyVector<float, 4> > FVector4Image; | | typedef BasicImage<TinyVector<float, 4> > FVector4Image; | |
| | | | |
| /** Floating-point TinyVector image. | | /** Floating-point TinyVector image. | |
|
| The pixel type is \ref vigra::TinyVector "TinyVector<double, 2>". | | The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double,
2>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | | It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<TinyVector<double, 2> > DVector2Image; | | typedef BasicImage<TinyVector<double, 2> > DVector2Image; | |
| | | | |
| /** Floating-point TinyVector image. | | /** Floating-point TinyVector image. | |
|
| The pixel type is \ref vigra::TinyVector "TinyVector<double, 3>". | | The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double,
3>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | | It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| //typedef BasicImage<TinyVector<double, 3> > DVector3Image; | | //typedef BasicImage<TinyVector<double, 3> > DVector3Image; | |
| typedef BasicImage<TinyVector<double, 3> > DVector3Image; | | typedef BasicImage<TinyVector<double, 3> > DVector3Image; | |
| | | | |
| /** Floating-point TinyVector image. | | /** Floating-point TinyVector image. | |
|
| The pixel type is \ref vigra::TinyVector "TinyVector<double, 4>". | | The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double,
4>". | |
| It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | | It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess
or and | |
| their const counterparts to access the data. | | their const counterparts to access the data. | |
| | | | |
| <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | | <b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag
e.hxx</a>"<br> | |
| Namespace: vigra | | Namespace: vigra | |
| */ | | */ | |
| typedef BasicImage<TinyVector<double, 4> > DVector4Image; | | typedef BasicImage<TinyVector<double, 4> > DVector4Image; | |
| | | | |
| //@} | | //@} | |
| | | | |
| | | | |
End of changes. 19 change blocks. |
| 24 lines changed or deleted | | 197 lines changed or added | |
|
| tinyvector.hxx | | tinyvector.hxx | |
| /************************************************************************/ | | /************************************************************************/ | |
| /* */ | | /* */ | |
| /* Copyright 1998-2002 by Ullrich Koethe */ | | /* Copyright 1998-2002 by Ullrich Koethe */ | |
| /* Cognitive Systems Group, University of Hamburg, Germany */ | | /* Cognitive Systems Group, University of Hamburg, Germany */ | |
| /* */ | | /* */ | |
| /* This file is part of the VIGRA computer vision library. */ | | /* This file is part of the VIGRA computer vision library. */ | |
|
| /* ( Version 1.3.3, Aug 18 2005 ) */ | | /* ( Version 1.4.0, Dec 21 2005 ) */ | |
| /* You may use, modify, and distribute this software according */ | | | |
| /* to the terms stated in the LICENSE file included in */ | | | |
| /* the VIGRA distribution. */ | | | |
| /* */ | | | |
| /* The VIGRA Website is */ | | /* The VIGRA Website is */ | |
| /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | | /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ | |
| /* Please direct questions, bug reports, and contributions to */ | | /* Please direct questions, bug reports, and contributions to */ | |
|
| /* koethe@informatik.uni-hamburg.de */ | | /* koethe@informatik.uni-hamburg.de or */ | |
| | | /* vigra@kogs1.informatik.uni-hamburg.de */ | |
| /* */ | | /* */ | |
|
| /* THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR */ | | /* Permission is hereby granted, free of charge, to any person */ | |
| /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ | | /* obtaining a copy of this software and associated documentation */ | |
| /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ | | /* files (the "Software"), to deal in the Software without */ | |
| | | /* restriction, including without limitation the rights to use, */ | |
| | | /* copy, modify, merge, publish, distribute, sublicense, and/or */ | |
| | | /* sell copies of the Software, and to permit persons to whom the */ | |
| | | /* Software is furnished to do so, subject to the following */ | |
| | | /* conditions: */ | |
| | | /* */ | |
| | | /* The above copyright notice and this permission notice shall be */ | |
| | | /* included in all copies or substantial portions of the */ | |
| | | /* Software. */ | |
| | | /* */ | |
| | | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ | |
| | | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ | |
| | | /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ | |
| | | /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ | |
| | | /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ | |
| | | /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ | |
| | | /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ | |
| | | /* OTHER DEALINGS IN THE SOFTWARE. */ | |
| /* */ | | /* */ | |
| /************************************************************************/ | | /************************************************************************/ | |
| | | | |
| #ifndef VIGRA_TINYVECTOR_HXX | | #ifndef VIGRA_TINYVECTOR_HXX | |
| #define VIGRA_TINYVECTOR_HXX | | #define VIGRA_TINYVECTOR_HXX | |
| | | | |
| #include <cmath> // abs(double) | | #include <cmath> // abs(double) | |
| #include <cstdlib> // abs(int) | | #include <cstdlib> // abs(int) | |
| #include <iosfwd> // ostream | | #include <iosfwd> // ostream | |
| #include "vigra/config.hxx" | | #include "vigra/config.hxx" | |
| | | | |
| skipping to change at line 414 | | skipping to change at line 429 | |
| /** the scalar type for the outer product | | /** the scalar type for the outer product | |
| */ | | */ | |
| typedef double scalar_multiplier; | | typedef double scalar_multiplier; | |
| | | | |
| /** the vector's squared norm type | | /** the vector's squared norm type | |
| */ | | */ | |
| typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType
; | | typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType
; | |
| | | | |
| /** the vector's norm type | | /** the vector's norm type | |
| */ | | */ | |
|
| typedef typename NumericTraits<SquaredNormType>::RealPromote NormType; | | typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No
rmType; | |
| | | | |
| /** the vector's size | | /** the vector's size | |
| */ | | */ | |
| enum { static_size = SIZE }; | | enum { static_size = SIZE }; | |
| | | | |
| /** Initialize from another sequence (must have length SIZE!) | | /** Initialize from another sequence (must have length SIZE!) | |
| */ | | */ | |
| template <class Iterator> | | template <class Iterator> | |
| void init(Iterator i, Iterator end) | | void init(Iterator i, Iterator end) | |
| { | | { | |
| | | | |
| skipping to change at line 477 | | skipping to change at line 492 | |
| DERIVED & operator/=(double r) | | DERIVED & operator/=(double r) | |
| { | | { | |
| Loop::divScalar(data_, r); | | Loop::divScalar(data_, r); | |
| return static_cast<DERIVED &>(*this); | | return static_cast<DERIVED &>(*this); | |
| } | | } | |
| | | | |
| /** Calculate magnitude. | | /** Calculate magnitude. | |
| */ | | */ | |
| NormType magnitude() const | | NormType magnitude() const | |
| { | | { | |
|
| return VIGRA_CSTD::sqrt(static_cast<NormType>(squaredMagnitude())) | | return sqrt(static_cast<typename | |
| ; | | SquareRootTraits<SquaredNormType>::SquareRootArgument>(square | |
| | | dMagnitude())); | |
| } | | } | |
| | | | |
| /** Calculate squared magnitude. | | /** Calculate squared magnitude. | |
| */ | | */ | |
| SquaredNormType squaredMagnitude() const | | SquaredNormType squaredMagnitude() const | |
| { | | { | |
| return Loop::squaredNorm(data_); | | return Loop::squaredNorm(data_); | |
| } | | } | |
| | | | |
| /** Access component by index. | | /** Access component by index. | |
| | | | |
| skipping to change at line 783 | | skipping to change at line 799 | |
| /** Copy the data of the rhs with cast. | | /** Copy the data of the rhs with cast. | |
| */ | | */ | |
| template <class U, class DATA, class DERIVED> | | template <class U, class DATA, class DERIVED> | |
| TinyVectorView & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const
& r) | | TinyVectorView & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const
& r) | |
| { | | { | |
| Loop::assignCast(BaseType::data_, r.begin()); | | Loop::assignCast(BaseType::data_, r.begin()); | |
| return *this; | | return *this; | |
| } | | } | |
| }; | | }; | |
| | | | |
|
| } // namespace vigra | | | |
| | | | |
| /********************************************************/ | | | |
| /* */ | | | |
| /* TinyVector Output */ | | | |
| /* */ | | | |
| /********************************************************/ | | | |
| | | | |
| /** \addtogroup TinyVectorOperators | | | |
| */ | | | |
| //@{ | | | |
| /// stream output | | | |
| template <class V1, int SIZE, class DATA, class DERIVED> | | | |
| std::ostream & | | | |
| operator<<(std::ostream & out, vigra::TinyVectorBase<V1, SIZE, DATA, DERIVE | | | |
| D> const & l) | | | |
| { | | | |
| out << "("; | | | |
| int i; | | | |
| for(i=0; i<SIZE-1; ++i) | | | |
| out << l[i] << ", "; | | | |
| out << l[i] << ")"; | | | |
| return out; | | | |
| } | | | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* TinyVector Comparison */ | | /* TinyVector Comparison */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
|
| namespace vigra { | | | |
| | | | |
| /** \addtogroup TinyVectorOperators Functions for TinyVector | | /** \addtogroup TinyVectorOperators Functions for TinyVector | |
| | | | |
| \brief <b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/ti
nyvector.hxx</a> | | \brief <b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/ti
nyvector.hxx</a> | |
| | | | |
| These functions fulfill the requirements of a Linear Space (vector spac
e). | | These functions fulfill the requirements of a Linear Space (vector spac
e). | |
| Return types are determined according to \ref TinyVectorTraits. | | Return types are determined according to \ref TinyVectorTraits. | |
| | | | |
| Namespace: vigra | | Namespace: vigra | |
| <p> | | <p> | |
| | | | |
| | | | |
| skipping to change at line 846 | | skipping to change at line 836 | |
| /// component-wise not equal | | /// component-wise not equal | |
| template <class V1, int SIZE, class D1, class D2, class V2, class D3, class
D4> | | template <class V1, int SIZE, class D1, class D2, class V2, class D3, class
D4> | |
| inline bool | | inline bool | |
| operator!=(TinyVectorBase<V1, SIZE, D1, D2> const & l, | | operator!=(TinyVectorBase<V1, SIZE, D1, D2> const & l, | |
| TinyVectorBase<V2, SIZE, D3, D4> const & r) | | TinyVectorBase<V2, SIZE, D3, D4> const & r) | |
| { | | { | |
| typedef typename detail::LoopType<SIZE>::type ltype; | | typedef typename detail::LoopType<SIZE>::type ltype; | |
| return ltype::notEqual(l.begin(), r.begin()); | | return ltype::notEqual(l.begin(), r.begin()); | |
| } | | } | |
| | | | |
|
| | | /********************************************************/ | |
| | | /* */ | |
| | | /* TinyVector Output */ | |
| | | /* */ | |
| | | /********************************************************/ | |
| | | | |
| | | /// stream output | |
| | | template <class V1, int SIZE, class DATA, class DERIVED> | |
| | | std::ostream & | |
| | | operator<<(std::ostream & out, TinyVectorBase<V1, SIZE, DATA, DERIVED> cons | |
| | | t & l) | |
| | | { | |
| | | out << "("; | |
| | | int i; | |
| | | for(i=0; i<SIZE-1; ++i) | |
| | | out << l[i] << ", "; | |
| | | out << l[i] << ")"; | |
| | | return out; | |
| | | } | |
| //@} | | //@} | |
| | | | |
| /********************************************************/ | | /********************************************************/ | |
| /* */ | | /* */ | |
| /* TinyVector-Traits */ | | /* TinyVector-Traits */ | |
| /* */ | | /* */ | |
| /********************************************************/ | | /********************************************************/ | |
| | | | |
| /** \page TinyVectorTraits Numeric and Promote Traits of TinyVector | | /** \page TinyVectorTraits Numeric and Promote Traits of TinyVector | |
| The numeric and promote traits for TinyVectors follow | | The numeric and promote traits for TinyVectors follow | |
| | | | |
| skipping to change at line 870 | | skipping to change at line 878 | |
| \code | | \code | |
| | | | |
| template <class T, int SIZE> | | template <class T, int SIZE> | |
| struct NumericTraits<TinyVector<T, SIZE> > | | struct NumericTraits<TinyVector<T, SIZE> > | |
| { | | { | |
| typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promot
e; | | typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promot
e; | |
| typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Re
alPromote; | | typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Re
alPromote; | |
| | | | |
| typedef typename NumericTraits<T>::isIntegral isIntegral; | | typedef typename NumericTraits<T>::isIntegral isIntegral; | |
| typedef VigraFalseType isScalar; | | typedef VigraFalseType isScalar; | |
|
| | | typedef typename NumericTraits<T>::isSigned isSigned; | |
| | | | |
| // etc. | | // etc. | |
| }; | | }; | |
| | | | |
| template <class T, int SIZE> | | template <class T, int SIZE> | |
| struct NormTraits<TinyVector<T, SIZE> > | | struct NormTraits<TinyVector<T, SIZE> > | |
| { | | { | |
| typedef TinyVector<T, SIZE> Type; | | typedef TinyVector<T, SIZE> Type; | |
| typedef typename Type::SquaredNormType SquaredNormType; | | typedef typename Type::SquaredNormType SquaredNormType; | |
| typedef typename Type::NormType NormType; | | typedef typename Type::NormType NormType; | |
| | | | |
| skipping to change at line 912 | | skipping to change at line 921 | |
| struct NumericTraits<TinyVector<T, SIZE> > | | struct NumericTraits<TinyVector<T, SIZE> > | |
| { | | { | |
| typedef TinyVector<T, SIZE> Type; | | typedef TinyVector<T, SIZE> Type; | |
| typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote; | | typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote; | |
| typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPr
omote; | | typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPr
omote; | |
| typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> Com
plexPromote; | | typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> Com
plexPromote; | |
| typedef T ValueType; | | typedef T ValueType; | |
| | | | |
| typedef typename NumericTraits<T>::isIntegral isIntegral; | | typedef typename NumericTraits<T>::isIntegral isIntegral; | |
| typedef VigraFalseType isScalar; | | typedef VigraFalseType isScalar; | |
|
| | | typedef typename NumericTraits<T>::isSigned isSigned; | |
| typedef VigraFalseType isOrdered; | | typedef VigraFalseType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| | | | |
| static TinyVector<T, SIZE> zero() { | | static TinyVector<T, SIZE> zero() { | |
| return TinyVector<T, SIZE>(NumericTraits<T>::zero()); | | return TinyVector<T, SIZE>(NumericTraits<T>::zero()); | |
| } | | } | |
| static TinyVector<T, SIZE> one() { | | static TinyVector<T, SIZE> one() { | |
| return TinyVector<T, SIZE>(NumericTraits<T>::one()); | | return TinyVector<T, SIZE>(NumericTraits<T>::one()); | |
| } | | } | |
| static TinyVector<T, SIZE> nonZero() { | | static TinyVector<T, SIZE> nonZero() { | |
| | | | |
| skipping to change at line 970 | | skipping to change at line 980 | |
| : public NumericTraits<TinyVector<T, SIZE> > | | : public NumericTraits<TinyVector<T, SIZE> > | |
| { | | { | |
| typedef TinyVector<T, SIZE> Type; | | typedef TinyVector<T, SIZE> Type; | |
| typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote; | | typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote; | |
| typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPr
omote; | | typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPr
omote; | |
| typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> Com
plexPromote; | | typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> Com
plexPromote; | |
| typedef T ValueType; | | typedef T ValueType; | |
| | | | |
| typedef typename NumericTraits<T>::isIntegral isIntegral; | | typedef typename NumericTraits<T>::isIntegral isIntegral; | |
| typedef VigraFalseType isScalar; | | typedef VigraFalseType isScalar; | |
|
| | | typedef typename NumericTraits<T>::isSigned isSigned; | |
| typedef VigraFalseType isOrdered; | | typedef VigraFalseType isOrdered; | |
| typedef VigraFalseType isComplex; | | typedef VigraFalseType isComplex; | |
| }; | | }; | |
| | | | |
| template <class T, int SIZE> | | template <class T, int SIZE> | |
| struct NormTraits<TinyVector<T, SIZE> > | | struct NormTraits<TinyVector<T, SIZE> > | |
| { | | { | |
| typedef TinyVector<T, SIZE> Type; | | typedef TinyVector<T, SIZE> Type; | |
| typedef typename Type::SquaredNormType SquaredNormType; | | typedef typename Type::SquaredNormType SquaredNormType; | |
| typedef typename Type::NormType NormType; | | typedef typename Type::NormType NormType; | |
| | | | |
| skipping to change at line 1051 | | skipping to change at line 1062 | |
| template<>\ | | template<>\ | |
| struct NumericTraits<TinyVector<T, SIZE> >\ | | struct NumericTraits<TinyVector<T, SIZE> >\ | |
| {\ | | {\ | |
| typedef TinyVector<T, SIZE> Type;\ | | typedef TinyVector<T, SIZE> Type;\ | |
| typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\ | | typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\ | |
| typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\ | | typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\ | |
| typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromo
te;\ | | typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromo
te;\ | |
| typedef T ValueType; \ | | typedef T ValueType; \ | |
| typedef NumericTraits<T>::isIntegral isIntegral;\ | | typedef NumericTraits<T>::isIntegral isIntegral;\ | |
| typedef VigraFalseType isScalar;\ | | typedef VigraFalseType isScalar;\ | |
|
| | | typedef NumericTraits<T>::isSigned isSigned; \ | |
| typedef VigraFalseType isOrdered;\ | | typedef VigraFalseType isOrdered;\ | |
| typedef VigraFalseType isComplex;\ | | typedef VigraFalseType isComplex;\ | |
| \ | | \ | |
| static TinyVector<T, SIZE> zero() { \ | | static TinyVector<T, SIZE> zero() { \ | |
| return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \ | | return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \ | |
| }\ | | }\ | |
| static TinyVector<T, SIZE> one() { \ | | static TinyVector<T, SIZE> one() { \ | |
| return TinyVector<T, SIZE>(NumericTraits<T>::one()); \ | | return TinyVector<T, SIZE>(NumericTraits<T>::one()); \ | |
| }\ | | }\ | |
| static TinyVector<T, SIZE> nonZero() { \ | | static TinyVector<T, SIZE> nonZero() { \ | |
| | | | |
| skipping to change at line 1266 | | skipping to change at line 1278 | |
| inline | | inline | |
| TinyVector<V, SIZE> | | TinyVector<V, SIZE> | |
| floor(TinyVectorBase<V, SIZE, D1, D2> const & v) | | floor(TinyVectorBase<V, SIZE, D1, D2> const & v) | |
| { | | { | |
| TinyVector<V, SIZE> res(detail::dontInit()); | | TinyVector<V, SIZE> res(detail::dontInit()); | |
| typedef typename detail::LoopType<SIZE>::type ltype; | | typedef typename detail::LoopType<SIZE>::type ltype; | |
| ltype::floor(res.begin(), v.begin()); | | ltype::floor(res.begin(), v.begin()); | |
| return res; | | return res; | |
| } | | } | |
| | | | |
|
| | | /// cross product | |
| | | template <class V1, class D1, class D2, class V2, class D3, class D4> | |
| | | inline | |
| | | TinyVector<typename PromoteTraits<V1, V2>::Promote, 3> | |
| | | cross(TinyVectorBase<V1, 3, D1, D2> const & r1, | |
| | | TinyVectorBase<V2, 3, D3, D4> const & r2) | |
| | | { | |
| | | typedef TinyVector<typename PromoteTraits<V1, V2>::Promote, 3> | |
| | | Res; | |
| | | return Res(r1[1]*r2[2] - r1[2]*r2[1], | |
| | | r1[2]*r2[0] - r1[0]*r2[2], | |
| | | r1[0]*r2[1] - r1[1]*r2[0]); | |
| | | } | |
| | | | |
| /// dot product | | /// dot product | |
| template <class V1, int SIZE, class D1, class D2, class V2, class D3, class
D4> | | template <class V1, int SIZE, class D1, class D2, class V2, class D3, class
D4> | |
| inline | | inline | |
| typename PromoteTraits<V1, V2>::Promote | | typename PromoteTraits<V1, V2>::Promote | |
| dot(TinyVectorBase<V1, SIZE, D1, D2> const & l, | | dot(TinyVectorBase<V1, SIZE, D1, D2> const & l, | |
| TinyVectorBase<V2, SIZE, D3, D4> const & r) | | TinyVectorBase<V2, SIZE, D3, D4> const & r) | |
| { | | { | |
| typedef typename detail::LoopType<SIZE>::type ltype; | | typedef typename detail::LoopType<SIZE>::type ltype; | |
| return ltype::dot(l.begin(), r.begin()); | | return ltype::dot(l.begin(), r.begin()); | |
| } | | } | |
| | | | |
End of changes. 13 change blocks. |
| 39 lines changed or deleted | | 65 lines changed or added | |
|