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