36 #ifndef VIGRA_MULTI_SHAPE_HXX
37 #define VIGRA_MULTI_SHAPE_HXX
39 #include <sys/types.h>
40 #include "tinyvector.hxx"
41 #include "array_vector.hxx"
42 #include "numerictraits.hxx"
77 struct NumericTraits<Singleband<T> >
78 :
public NumericTraits<T>
82 struct NumericTraits<Multiband<T> >
84 typedef Multiband<T> Type;
91 typedef Type ValueType;
93 typedef typename NumericTraits<T>::isIntegral isIntegral;
94 typedef VigraFalseType isScalar;
95 typedef typename NumericTraits<T>::isSigned isSigned;
96 typedef typename NumericTraits<T>::isSigned isOrdered;
97 typedef typename NumericTraits<T>::isSigned isComplex;
140 inline TinyVector <MultiArrayIndex, N>
141 defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
143 TinyVector <MultiArrayIndex, N> ret;
145 for (
int i = 1; i < (int)N; ++i)
146 ret [i] = ret [i-1] * shape [i-1];
153 inline TinyVector <MultiArrayIndex, N>
154 defaultMultibandStride(
const TinyVector <MultiArrayIndex, N> &shape)
156 TinyVector <MultiArrayIndex, N> ret;
158 for (
int i = 0; i < (int)N-1; ++i)
160 int j = (i + int(N - 1)) % N;
161 ret [i] = ret [j] * shape [j];
173 struct ResolveMultiband
176 typedef StridedArrayTag Stride;
177 static const bool value =
false;
180 static TinyVector <MultiArrayIndex, N>
181 defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
183 return vigra::detail::defaultStride(shape);
188 struct ResolveMultiband<Singleband<T> >
191 typedef StridedArrayTag Stride;
192 static const bool value =
false;
195 static TinyVector <MultiArrayIndex, N>
196 defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
198 return vigra::detail::defaultStride(shape);
203 struct ResolveMultiband<Multiband<T> >
206 typedef StridedArrayTag Stride;
207 static const bool value =
true;
210 static TinyVector <MultiArrayIndex, N>
211 defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
213 return vigra::detail::defaultMultibandStride(shape);
219 template <
unsigned int N,
class T,
class C = Str
idedArrayTag>
220 class MultiArrayView;
222 template <
unsigned int N,
class T,
223 class A = std::allocator<typename vigra::detail::ResolveMultiband<T>::type> >
230 template <
unsigned int N>
270 struct CoordinateToScanOrder
272 template <
int N,
class D1,
class D2,
class D3,
class D4>
274 exec(
const TinyVectorBase <MultiArrayIndex, N, D1, D2> &shape,
275 const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
277 return coordinate[N-K] + shape[N-K] * CoordinateToScanOrder<K-1>::exec(shape, coordinate);
282 struct CoordinateToScanOrder<1>
284 template <
int N,
class D1,
class D2,
class D3,
class D4>
286 exec(
const TinyVectorBase <MultiArrayIndex, N, D1, D2> & ,
287 const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
289 return coordinate[N-1];
302 struct ScanOrderToCoordinate
307 TinyVector <MultiArrayIndex, N> & result)
309 result[N-K] = (d % shape[N-K]);
310 ScanOrderToCoordinate<K-1>::exec(d / shape[N-K], shape, result);
315 struct ScanOrderToCoordinate<1>
320 TinyVector <MultiArrayIndex, N> & result)
336 struct ScanOrderToOffset
341 const TinyVector <MultiArrayIndex, N> & stride)
343 return stride[N-K] * (d % shape[N-K]) +
344 ScanOrderToOffset<K-1>::exec(d / shape[N-K], shape, stride);
349 struct ScanOrderToOffset<1>
354 const TinyVector <MultiArrayIndex, N> & stride)
356 return stride[N-1] * d;
370 struct CoordinatesToOffest
374 exec(
const TinyVector <MultiArrayIndex, N> & stride,
MultiArrayIndex x)
376 return stride[0] * x;
382 return stride[0] * x + stride[1] * y;
387 struct CoordinatesToOffest<UnstridedArrayTag>
399 return x + stride[1] * y;
413 struct RelativeToAbsoluteCoordinate
417 exec(
const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
419 RelativeToAbsoluteCoordinate<M-1>::exec(shape, coord);
421 coord[M] += shape[M];
426 struct RelativeToAbsoluteCoordinate<0>
430 exec(
const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
433 coord[0] += shape[0];
450 template <
unsigned int N,
unsigned int DIMENSION=N-1>
451 struct BorderTypeImpl
453 typedef typename MultiArrayShape<N>::type shape_type;
455 static unsigned int exec(shape_type
const & point, shape_type
const & shape)
457 unsigned int res = BorderTypeImpl<N, DIMENSION-1>::exec(point, shape);
458 if(point[DIMENSION] == 0)
459 res |= (1 << 2*DIMENSION);
460 if(point[DIMENSION] == shape[DIMENSION]-1)
461 res |= (2 << 2*DIMENSION);
466 template <
unsigned int N>
467 struct BorderTypeImpl<N, 0>
469 typedef typename MultiArrayShape<N>::type shape_type;
470 static const unsigned int DIMENSION = 0;
472 static unsigned int exec(shape_type
const & point, shape_type
const & shape)
474 unsigned int res = 0;
475 if(point[DIMENSION] == 0)
476 res |= (1 << 2*DIMENSION);
477 if(point[DIMENSION] == shape[DIMENSION]-1)
478 res |= (2 << 2*DIMENSION);
499 template <
unsigned int Level>
500 struct MakeDirectArrayNeighborhood
502 template <
class Array>
503 static void offsets(Array & a)
505 typedef typename Array::value_type Shape;
510 MakeDirectArrayNeighborhood<Level-1>::offsets(a);
515 template <
class Array>
516 static void exists(Array & a,
unsigned int borderType)
518 a.push_back((borderType & (1 << 2*Level)) == 0);
519 MakeDirectArrayNeighborhood<Level-1>::exists(a, borderType);
520 a.push_back((borderType & (2 << 2*Level)) == 0);
525 struct MakeDirectArrayNeighborhood<0>
527 template <
class Array>
528 static void offsets(Array & a)
530 typedef typename Array::value_type Shape;
539 template <
class Array>
540 static void exists(Array & a,
unsigned int borderType)
542 a.push_back((borderType & 1) == 0);
543 a.push_back((borderType & 2) == 0);
548 template <
unsigned int Level>
549 struct MakeIndirectArrayNeighborhood
551 template <
class Array,
class Shape>
552 static void offsets(Array & a, Shape point,
bool isCenter =
true)
555 MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point,
false);
557 MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, isCenter);
559 MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point,
false);
562 template <
class Array>
563 static void exists(Array & a,
unsigned int borderType,
bool isCenter =
true)
565 if((borderType & (1 << 2*Level)) == 0)
566 MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType,
false);
568 MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
570 MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, isCenter);
572 if((borderType & (2 << 2*Level)) == 0)
573 MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType,
false);
575 MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
578 template <
class Array>
579 static void markOutside(Array & a)
582 MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
583 MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
584 MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
590 struct MakeIndirectArrayNeighborhood<0>
592 template <
class Array,
class Shape>
593 static void offsets(Array & a, Shape point,
bool isCenter =
true)
606 template <
class Array>
607 static void exists(Array & a,
unsigned int borderType,
bool isCenter =
true)
609 a.push_back((borderType & 1) == 0);
614 a.push_back((borderType & 2) == 0);
617 template <
class Array>
618 static void markOutside(Array & a)
633 template <
class Shape>
635 makeArrayNeighborhood(ArrayVector<Shape> & neighborOffsets,
636 ArrayVector<ArrayVector<bool> > & neighborExists,
639 enum { N = Shape::static_size };
641 neighborOffsets.clear();
644 MakeDirectArrayNeighborhood<N-1>::offsets(neighborOffsets);
649 MakeIndirectArrayNeighborhood<N-1>::offsets(neighborOffsets, point);
652 unsigned int borderTypeCount = 1 << 2*N;
653 neighborExists.resize(borderTypeCount);
655 for(
unsigned int k=0; k<borderTypeCount; ++k)
657 neighborExists[k].clear();
660 MakeDirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
664 MakeIndirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
675 #endif // VIGRA_MULTI_SHAPE_HXX
MultiArrayShape< 3 >::type Shape3
shape type for MultiArray<3, T>
Definition: multi_shape.hxx:242
std::ptrdiff_t MultiArrayIndex
Definition: multi_shape.hxx:55
Definition: multi_shape.hxx:231
TinyVector< MultiArrayIndex, N > type
Definition: multi_shape.hxx:237
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
MultiArrayShape< 5 >::type Shape5
shape type for MultiArray<5, T>
Definition: multi_shape.hxx:244
MultiArrayShape< 2 >::type Shape2
shape type for MultiArray<2, T>
Definition: multi_shape.hxx:241
use direct and indirect neighbors
Definition: multi_shape.hxx:254
MultiArrayShape< 1 >::type Shape1
shape type for MultiArray<1, T>
Definition: multi_shape.hxx:240
use only direct neighbors
Definition: multi_shape.hxx:253
NeighborhoodType
Choose the neighborhood system in a dimension-independent way.
Definition: multi_shape.hxx:252
MultiArrayShape< 4 >::type Shape4
shape type for MultiArray<4, T>
Definition: multi_shape.hxx:243