36 #ifndef VIGRA_MULTI_SHAPE_HXX 
   37 #define VIGRA_MULTI_SHAPE_HXX 
   39 #include "multi_fwd.hxx" 
   40 #include <sys/types.h> 
   41 #include "tinyvector.hxx" 
   42 #include "array_vector.hxx" 
   43 #include "numerictraits.hxx" 
   72 struct IsMultiband : VigraFalseType{
 
   76 struct IsMultiband<Multiband<T> > : VigraTrueType{
 
   86 struct NumericTraits<Singleband<T> >
 
   87 : 
public NumericTraits<T>
 
   91 struct NumericTraits<Multiband<T> >
 
   93     typedef Multiband<T> Type;
 
  100     typedef Type ValueType;
 
  102     typedef typename NumericTraits<T>::isIntegral isIntegral;
 
  103     typedef VigraFalseType isScalar;
 
  104     typedef typename NumericTraits<T>::isSigned isSigned;
 
  105     typedef typename NumericTraits<T>::isSigned isOrdered;
 
  106     typedef typename NumericTraits<T>::isSigned isComplex;
 
  149 inline TinyVector <MultiArrayIndex, N>
 
  150 defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
 
  152     TinyVector <MultiArrayIndex, N> ret;
 
  154     for (
int i = 1; i < (int)N; ++i)
 
  155         ret [i] = ret [i-1] * shape [i-1];
 
  162 inline TinyVector <MultiArrayIndex, N>
 
  163 defaultMultibandStride(
const TinyVector <MultiArrayIndex, N> &shape)
 
  165     TinyVector <MultiArrayIndex, N> ret;
 
  167     for (
int i = 0; i < (int)N-1; ++i)
 
  169         int j = (i + int(N - 1)) % N;
 
  170         ret [i] = ret [j] * shape [j];
 
  182 struct ResolveMultiband
 
  185     typedef StridedArrayTag Stride;
 
  186     static const bool value = 
false;
 
  189     static TinyVector <MultiArrayIndex, N>
 
  190     defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
 
  192         return vigra::detail::defaultStride(shape);
 
  197 struct ResolveMultiband<Singleband<T> >
 
  200     typedef StridedArrayTag Stride;
 
  201     static const bool value = 
false;
 
  204     static TinyVector <MultiArrayIndex, N>
 
  205     defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
 
  207         return vigra::detail::defaultStride(shape);
 
  212 struct ResolveMultiband<Multiband<T> >
 
  215     typedef StridedArrayTag Stride;
 
  216     static const bool value = 
true;
 
  219     static TinyVector <MultiArrayIndex, N>
 
  220     defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
 
  222         return vigra::detail::defaultMultibandStride(shape);
 
  227 struct ResolveChunkedMemory
 
  233 struct ResolveChunkedMemory<ChunkedMemory<T> >
 
  265 template <
unsigned int N>
 
  266 class MultiArrayShape
 
  290 template <
unsigned int N, 
class T = 
int>
 
  294     static Shape defaultShape()
 
  297         res.template subarray<0,5>() = ChunkShape<5,T>::defaultShape();
 
  303 struct ChunkShape<0, T>
 
  305     static Shape1 defaultShape()
 
  312 struct ChunkShape<1, T>
 
  314     static Shape1 defaultShape()
 
  316         return Shape1(1 << 18);
 
  321 struct ChunkShape<2, T>
 
  323     static Shape2 defaultShape()
 
  325         return Shape2(1 << 9, 1 << 9);
 
  330 struct ChunkShape<3, T>
 
  332     static Shape3 defaultShape()
 
  334         return Shape3(1 << 6, 1 << 6, 1 << 6);
 
  339 struct ChunkShape<4, T>
 
  341     static Shape4 defaultShape()
 
  343         return Shape4(1 << 6, 1 << 6, 1 << 4, 1 << 2);
 
  348 struct ChunkShape<5, T>
 
  350     static Shape5 defaultShape()
 
  352         return Shape5(1 << 6, 1 << 6, 1 << 4, 1 << 2, 1 << 2);
 
  371 struct CoordinateToScanOrder
 
  373     template <
int N, 
class D1, 
class D2, 
class D3, 
class D4>
 
  375     exec(
const TinyVectorBase <MultiArrayIndex, N, D1, D2> &shape,
 
  376          const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
 
  378         return coordinate[N-K] + shape[N-K] * CoordinateToScanOrder<K-1>::exec(shape, coordinate);
 
  383 struct CoordinateToScanOrder<1>
 
  385     template <
int N, 
class D1, 
class D2, 
class D3, 
class D4>
 
  387     exec(
const TinyVectorBase <MultiArrayIndex, N, D1, D2> & ,
 
  388          const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
 
  390         return coordinate[N-1];
 
  403 struct ScanOrderToCoordinate
 
  408          TinyVector <MultiArrayIndex, N> & result)
 
  410         result[N-K] = (d % shape[N-K]);
 
  411         ScanOrderToCoordinate<K-1>::exec(d / shape[N-K], shape, result);
 
  416 struct ScanOrderToCoordinate<1>
 
  421          TinyVector <MultiArrayIndex, N> & result)
 
  437 struct ScanOrderToOffset
 
  442          const TinyVector <MultiArrayIndex, N> & stride)
 
  444         return stride[N-K] * (d % shape[N-K]) +
 
  445                ScanOrderToOffset<K-1>::exec(d / shape[N-K], shape, stride);
 
  450 struct ScanOrderToOffset<1>
 
  455          const TinyVector <MultiArrayIndex, N> & stride)
 
  457         return stride[N-1] * d;
 
  471 struct CoordinatesToOffest
 
  475     exec(
const TinyVector <MultiArrayIndex, N> & stride, 
MultiArrayIndex x)
 
  477         return stride[0] * x;
 
  483         return stride[0] * x + stride[1] * y;
 
  488 struct CoordinatesToOffest<UnstridedArrayTag>
 
  500         return x + stride[1] * y;
 
  514 struct RelativeToAbsoluteCoordinate
 
  518     exec(
const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
 
  520         RelativeToAbsoluteCoordinate<M-1>::exec(shape, coord);
 
  522             coord[M] += shape[M];
 
  527 struct RelativeToAbsoluteCoordinate<0>
 
  531     exec(
const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
 
  534             coord[0] += shape[0];
 
  551 template <
unsigned int N, 
unsigned int DIMENSION=N-1>
 
  552 struct BorderTypeImpl
 
  554     typedef TinyVectorView<MultiArrayIndex, N> shape_type;
 
  556     static unsigned int exec(shape_type 
const & point, shape_type 
const & shape)
 
  558         unsigned int res = BorderTypeImpl<N, DIMENSION-1>::exec(point, shape);
 
  559         if(point[DIMENSION] == 0)
 
  560             res |= (1 << 2*DIMENSION);
 
  561         if(point[DIMENSION] == shape[DIMENSION]-1)
 
  562             res |= (2 << 2*DIMENSION);
 
  567 template <
unsigned int N>
 
  568 struct BorderTypeImpl<N, 0>
 
  570     typedef TinyVectorView<MultiArrayIndex, N> shape_type;
 
  571     static const unsigned int DIMENSION = 0;
 
  573     static unsigned int exec(shape_type 
const & point, shape_type 
const & shape)
 
  575         unsigned int res = 0;
 
  576         if(point[DIMENSION] == 0)
 
  577             res |= (1 << 2*DIMENSION);
 
  578         if(point[DIMENSION] == shape[DIMENSION]-1)
 
  579             res |= (2 << 2*DIMENSION);
 
  600 template <
unsigned int Level>
 
  601 struct MakeDirectArrayNeighborhood
 
  603     template <
class Array>
 
  604     static void offsets(Array & a)
 
  606         typedef typename Array::value_type Shape;
 
  611         MakeDirectArrayNeighborhood<Level-1>::offsets(a);
 
  616     template <
class Array>
 
  617     static void exists(Array & a, 
unsigned int borderType)
 
  619         a.push_back((borderType & (1 << 2*Level)) == 0);
 
  620         MakeDirectArrayNeighborhood<Level-1>::exists(a, borderType);
 
  621         a.push_back((borderType & (2 << 2*Level)) == 0);
 
  626 struct MakeDirectArrayNeighborhood<0>
 
  628     template <
class Array>
 
  629     static void offsets(Array & a)
 
  631         typedef typename Array::value_type Shape;
 
  640     template <
class Array>
 
  641     static void exists(Array & a, 
unsigned int borderType)
 
  643         a.push_back((borderType & 1) == 0);
 
  644         a.push_back((borderType & 2) == 0);
 
  649 template <
unsigned int Level>
 
  650 struct MakeIndirectArrayNeighborhood
 
  652     template <
class Array, 
class Shape>
 
  653     static void offsets(Array & a, Shape point, 
bool isCenter = 
true)
 
  656         MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, 
false);
 
  658         MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, isCenter);
 
  660         MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, 
false);
 
  663     template <
class Array>
 
  664     static void exists(Array & a, 
unsigned int borderType, 
bool isCenter = 
true)
 
  666         if((borderType & (1 << 2*Level)) == 0)
 
  667             MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, 
false);
 
  669             MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
 
  671         MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, isCenter);
 
  673         if((borderType & (2 << 2*Level)) == 0)
 
  674             MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, 
false);
 
  676             MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
 
  679     template <
class Array>
 
  680     static void markOutside(Array & a)
 
  683         MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
 
  684         MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
 
  685         MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
 
  691 struct MakeIndirectArrayNeighborhood<0>
 
  693     template <
class Array, 
class Shape>
 
  694     static void offsets(Array & a, Shape point, 
bool isCenter = 
true)
 
  707     template <
class Array>
 
  708     static void exists(Array & a, 
unsigned int borderType, 
bool isCenter = 
true)
 
  710         a.push_back((borderType & 1) == 0);
 
  715         a.push_back((borderType & 2) == 0);
 
  718     template <
class Array>
 
  719     static void markOutside(Array & a)
 
  734 template <
class Shape>
 
  736 makeArrayNeighborhood(ArrayVector<Shape> & neighborOffsets,
 
  737                       ArrayVector<ArrayVector<bool> > & neighborExists,
 
  740     enum { N = Shape::static_size };
 
  742     neighborOffsets.clear();
 
  745         MakeDirectArrayNeighborhood<N-1>::offsets(neighborOffsets);
 
  750         MakeIndirectArrayNeighborhood<N-1>::offsets(neighborOffsets, point);
 
  753     unsigned int borderTypeCount = 1 << 2*N;
 
  754     neighborExists.resize(borderTypeCount);
 
  756     for(
unsigned int k=0; k<borderTypeCount; ++k)
 
  758         neighborExists[k].clear();
 
  761             MakeDirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
 
  765             MakeIndirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
 
  776 #endif // VIGRA_MULTI_SHAPE_HXX 
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
Definition: multi_fwd.hxx:63
TinyVector< MultiArrayIndex, N > type
Definition: multi_shape.hxx:272
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
use only direct neighbors 
Definition: multi_fwd.hxx:187
NeighborhoodType
Choose the neighborhood system in a dimension-independent way. 
Definition: multi_fwd.hxx:186