37 #ifndef VIGRA_MULTI_ARRAY_HXX
38 #define VIGRA_MULTI_ARRAY_HXX
42 #include "accessor.hxx"
43 #include "tinyvector.hxx"
44 #include "rgbvalue.hxx"
45 #include "basicimage.hxx"
46 #include "imageiterator.hxx"
47 #include "numerictraits.hxx"
48 #include "multi_iterator.hxx"
49 #include "multi_pointoperators.hxx"
50 #include "metaprogramming.hxx"
51 #include "mathutil.hxx"
52 #include "algorithm.hxx"
55 #ifdef VIGRA_CHECK_BOUNDS
56 #define VIGRA_ASSERT_INSIDE(diff) \
57 vigra_precondition(this->isInside(diff), "Index out of bounds")
59 #define VIGRA_ASSERT_INSIDE(diff)
81 template <
class Str
ideTag,
unsigned int N>
84 typedef StrideTag type;
87 template <
class Str
ideTag>
88 struct MaybeStrided <StrideTag, 0>
90 typedef StridedArrayTag type;
106 struct MultiIteratorChooser;
120 struct MultiIteratorChooser <StridedArrayTag>
122 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
125 typedef StridedMultiIterator <N, T, REFERENCE, POINTER> type;
128 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
131 typedef StridedScanOrderIterator <N, T, REFERENCE, POINTER> type;
134 template <
class Iter,
class View>
135 static Iter constructIterator(View * v)
153 struct MultiIteratorChooser <UnstridedArrayTag>
155 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
158 typedef MultiIterator <N, T, REFERENCE, POINTER> type;
161 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
164 typedef POINTER type;
167 template <
class Iter,
class View>
168 static Iter constructIterator(View * v)
180 template <
class DestIterator,
class Shape,
class T>
182 initMultiArrayData(DestIterator d, Shape
const & shape, T
const & init, MetaInt<0>)
184 DestIterator dend = d + shape[0];
191 template <
class DestIterator,
class Shape,
class T,
int N>
193 initMultiArrayData(DestIterator d, Shape
const & shape, T
const & init, MetaInt<N>)
195 DestIterator dend = d + shape[N];
198 initMultiArrayData(d.begin(), shape, init, MetaInt<N-1>());
203 #define VIGRA_COPY_MULTI_ARRAY_DATA(name, op) \
204 template <class SrcIterator, class Shape, class DestIterator> \
206 name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<0>) \
208 for(MultiArrayIndex i=0; i < shape[0]; ++i, ++s, ++d) \
210 *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(*s); \
214 template <class Ref, class Ptr, class Shape, class DestIterator> \
216 name##MultiArrayData(MultiIterator<1, UInt8, Ref, Ptr> si, Shape const & shape, DestIterator d, MetaInt<0>) \
219 for(MultiArrayIndex i=0; i < shape[0]; ++i, ++s, ++d) \
221 *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(*s); \
225 template <class SrcIterator, class Shape, class DestIterator, int N> \
227 name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<N>) \
229 for(MultiArrayIndex i=0; i < shape[N]; ++i, ++s, ++d) \
231 name##MultiArrayData(s.begin(), shape, d.begin(), MetaInt<N-1>()); \
235 template <class DestIterator, class Shape, class T> \
237 name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<0>) \
239 for(MultiArrayIndex i=0; i < shape[0]; ++i, ++d) \
241 *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(init); \
245 template <class DestIterator, class Shape, class T, int N> \
247 name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<N>) \
249 for(MultiArrayIndex i=0; i < shape[N]; ++i, ++d) \
251 name##ScalarMultiArrayData(d.begin(), shape, init, MetaInt<N-1>()); \
255 VIGRA_COPY_MULTI_ARRAY_DATA(copy, =)
256 VIGRA_COPY_MULTI_ARRAY_DATA(copyAdd, +=)
257 VIGRA_COPY_MULTI_ARRAY_DATA(copySub, -=)
258 VIGRA_COPY_MULTI_ARRAY_DATA(copyMul, *=)
259 VIGRA_COPY_MULTI_ARRAY_DATA(copyDiv, /=)
261 #undef VIGRA_COPY_MULTI_ARRAY_DATA
263 template <
class SrcIterator,
class Shape,
class T,
class ALLOC>
265 uninitializedCopyMultiArrayData(SrcIterator s, Shape
const & shape, T * & d, ALLOC & a, MetaInt<0>)
267 SrcIterator send = s + shape[0];
268 for(; s < send; ++s, ++d)
270 a.construct(d, static_cast<T const &>(*s));
275 template <
class Ref,
class Ptr,
class Shape,
class T,
class ALLOC>
277 uninitializedCopyMultiArrayData(MultiIterator<1, UInt8, Ref, Ptr> si, Shape
const & shape, T * & d, ALLOC & a, MetaInt<0>)
279 Ptr s = &(*si), send = s + shape[0];
280 for(; s < send; ++s, ++d)
282 a.construct(d, static_cast<T const &>(*s));
286 template <
class SrcIterator,
class Shape,
class T,
class ALLOC,
int N>
288 uninitializedCopyMultiArrayData(SrcIterator s, Shape
const & shape, T * & d, ALLOC & a, MetaInt<N>)
290 SrcIterator send = s + shape[N];
293 uninitializedCopyMultiArrayData(s.begin(), shape, d, a, MetaInt<N-1>());
297 template <
class SrcIterator,
class Shape,
class T,
class Functor>
299 reduceOverMultiArray(SrcIterator s, Shape
const & shape, T & result, Functor
const & f, MetaInt<0>)
301 SrcIterator send = s + shape[0];
308 template <
class SrcIterator,
class Shape,
class T,
class Functor,
int N>
310 reduceOverMultiArray(SrcIterator s, Shape
const & shape, T & result, Functor
const & f, MetaInt<N>)
312 SrcIterator send = s + shape[N];
315 reduceOverMultiArray(s.begin(), shape, result, f, MetaInt<N-1>());
319 struct MaxNormReduceFunctor
321 template <
class T,
class U>
322 void operator()(T & result, U
const & u)
const
330 struct L1NormReduceFunctor
332 template <
class T,
class U>
333 void operator()(T & result, U
const & u)
const
339 struct SquaredL2NormReduceFunctor
341 template <
class T,
class U>
342 void operator()(T & result, U
const & u)
const
349 struct WeightedL2NormReduceFunctor
353 WeightedL2NormReduceFunctor(T s)
358 void operator()(T & result, U
const & u)
const
364 struct SumReduceFunctor
366 template <
class T,
class U>
367 void operator()(T & result, U
const & u)
const
373 struct ProdReduceFunctor
375 template <
class T,
class U>
376 void operator()(T & result, U
const & u)
const
382 struct MinmaxReduceFunctor
384 template <
class T,
class U>
385 void operator()(T & result, U
const & u)
const
389 if(result.second < u)
394 struct MeanVarianceReduceFunctor
396 template <
class T,
class U>
397 void operator()(T & result, U
const & u)
const
400 typename T::second_type t1 = u - result.second;
401 typename T::second_type t2 = t1 / result.first;
403 result.third += (result.first-1.0)*t1*t2;
407 struct AllTrueReduceFunctor
409 template <
class T,
class U>
410 void operator()(T & result, U
const & u)
const
412 result = result && (u != NumericTraits<U>::zero());
416 struct AnyTrueReduceFunctor
418 template <
class T,
class U>
419 void operator()(T & result, U
const & u)
const
421 result = result || (u != NumericTraits<U>::zero());
425 template <
class SrcIterator,
class Shape,
class DestIterator>
427 equalityOfMultiArrays(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<0>)
429 SrcIterator send = s + shape[0];
430 for(; s < send; ++s, ++d)
438 template <
class SrcIterator,
class Shape,
class DestIterator,
int N>
440 equalityOfMultiArrays(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<N>)
442 SrcIterator send = s + shape[N];
443 for(; s < send; ++s, ++d)
445 if(!equalityOfMultiArrays(s.begin(), shape, d.begin(), MetaInt<N-1>()))
452 template <
class SrcIterator,
class Shape,
class DestIterator>
454 swapDataImpl(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<0>)
456 SrcIterator send = s + shape[0];
457 for(; s < send; ++s, ++d)
461 template <
class SrcIterator,
class Shape,
class DestIterator,
int N>
463 swapDataImpl(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<N>)
465 SrcIterator send = s + shape[N];
466 for(; s < send; ++s, ++d)
467 swapDataImpl(s.begin(), shape, d.begin(), MetaInt<N-1>());
480 namespace multi_math {
483 struct MultiMathOperand;
485 namespace math_detail {
487 template <
unsigned int N,
class T,
class C,
class E>
488 void assign(MultiArrayView<N, T, C>, MultiMathOperand<E>
const &);
490 template <
unsigned int N,
class T,
class C,
class E>
491 void plusAssign(MultiArrayView<N, T, C>, MultiMathOperand<E>
const &);
493 template <
unsigned int N,
class T,
class C,
class E>
494 void minusAssign(MultiArrayView<N, T, C>, MultiMathOperand<E>
const &);
496 template <
unsigned int N,
class T,
class C,
class E>
497 void multiplyAssign(MultiArrayView<N, T, C>, MultiMathOperand<E>
const &);
499 template <
unsigned int N,
class T,
class C,
class E>
500 void divideAssign(MultiArrayView<N, T, C>, MultiMathOperand<E>
const &);
502 template <
unsigned int N,
class T,
class A,
class E>
503 void assignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E>
const &);
505 template <
unsigned int N,
class T,
class A,
class E>
506 void plusAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E>
const &);
508 template <
unsigned int N,
class T,
class A,
class E>
509 void minusAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E>
const &);
511 template <
unsigned int N,
class T,
class A,
class E>
512 void multiplyAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E>
const &);
514 template <
unsigned int N,
class T,
class A,
class E>
515 void divideAssignOrResize(MultiArray<N, T, A> &, MultiMathOperand<E>
const &);
521 template <
class T>
class FindSum;
523 struct UnsuitableTypeForExpandElements {};
526 struct ExpandElementResult
528 typedef UnsuitableTypeForExpandElements type;
532 struct ExpandElementResult<std::complex<T> >
542 struct ExpandElementResult<FFTWComplex<T> >
548 template <
class T,
int SIZE>
549 struct ExpandElementResult<TinyVector<T, SIZE> >
552 enum { size = SIZE };
555 template <
class T,
unsigned int R,
unsigned int G,
unsigned int B>
556 struct ExpandElementResult<RGBValue<T, R, G, B> >
562 #define VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(TYPE) \
564 struct ExpandElementResult<TYPE> \
570 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
bool)
571 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
char)
572 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
signed char)
573 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
signed short)
574 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
signed int)
575 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
signed long)
576 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
signed long long)
577 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
unsigned char)
578 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
unsigned short)
579 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
unsigned int)
580 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
unsigned long)
581 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
unsigned long long)
582 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
float)
583 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
double)
584 VIGRA_DEFINE_EXPAND_ELEMENT_RESULT(
long double)
586 #undef VIGRA_DEFINE_EXPAND_ELEMENT_RESULT
595 template <
unsigned int N,
class T,
class C>
596 struct NormTraits<MultiArrayView<N, T, C> >
598 typedef MultiArrayView<N, T, C> Type;
599 typedef typename NormTraits<T>::SquaredNormType SquaredNormType;
600 typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
603 template <
unsigned int N,
class T,
class A>
604 struct NormTraits<MultiArray<N, T, A> >
605 :
public NormTraits<typename MultiArray<N, T, A>::view_type>
607 typedef NormTraits<typename MultiArray<N, T, A>::view_type> BaseType;
608 typedef MultiArray<N, T, A> Type;
609 typedef typename BaseType::SquaredNormType SquaredNormType;
610 typedef typename BaseType::NormType NormType;
651 template <
unsigned int N,
class T,
class Str
ideTag>
711 typedef typename vigra::detail::MultiIteratorChooser <
712 StrideTag>::template Traverser <actual_dimension, T, T &, T *>::type
traverser;
716 typedef typename vigra::detail::MultiIteratorChooser <
717 StrideTag>::template Traverser <actual_dimension, T, T const &, T const *>::type
const_traverser;
739 typedef typename difference_type::value_type diff_zero_t;
757 template <
class U,
class CN>
760 template <
class U,
class CN>
766 template <
class U,
class CN>
778 : m_shape (diff_zero_t(0)), m_stride (diff_zero_t(0)), m_ptr (0)
785 template <
class Str
ide>
787 : m_shape (other.shape()),
788 m_stride (other.
stride()),
791 vigra_precondition(other.checkInnerStride(StrideTag()),
792 "MultiArrayView<..., UnstridedArrayTag>(MultiArrayView const &): cannot create unstrided view from strided array.");
799 m_stride (detail::defaultStride<actual_dimension>(shape)),
800 m_ptr (const_cast<pointer>(ptr))
809 const difference_type &
stride,
813 m_ptr (const_cast<pointer>(ptr))
815 vigra_precondition(checkInnerStride(StrideTag()),
816 "MultiArrayView<..., UnstridedArrayTag>::MultiArrayView(): First dimension of given array is not unstrided.");
821 template <
class ALLOC>
824 m_stride (detail::defaultStride<actual_dimension>(m_shape)),
825 m_ptr (const_cast<pointer>(image.
data()))
852 template<
class Str
ide2>
863 template<
class U,
class C1>
866 vigra_precondition(this->
shape() == rhs.
shape(),
867 "MultiArrayView::operator=(): shape mismatch.");
882 template<
class U,
class C1>
888 template<
class U,
class C1>
894 template<
class U,
class C1>
900 template<
class U,
class C1>
907 detail::copyAddScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
915 detail::copySubScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
923 detail::copyMulScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
931 detail::copyDivScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
938 template<
class Expression>
941 multi_math::math_detail::assign(*
this, rhs);
948 template<
class Expression>
951 multi_math::math_detail::plusAssign(*
this, rhs);
958 template<
class Expression>
961 multi_math::math_detail::minusAssign(*
this, rhs);
968 template<
class Expression>
971 multi_math::math_detail::multiplyAssign(*
this, rhs);
978 template<
class Expression>
981 multi_math::math_detail::divideAssign(*
this, rhs);
989 VIGRA_ASSERT_INSIDE(d);
990 return m_ptr [
dot (d, m_stride)];
997 VIGRA_ASSERT_INSIDE(d);
998 return m_ptr [
dot (d, m_stride)];
1022 return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d, m_shape, m_stride)];
1038 return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d, m_shape, m_stride)];
1045 difference_type result;
1046 detail::ScanOrderToCoordinate<actual_dimension>::exec(d, m_shape, result);
1054 return detail::CoordinateToScanOrder<actual_dimension>::exec(m_shape, d);
1062 return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x)];
1070 return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x, y)];
1075 reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z)
1078 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
1084 difference_type_1 z, difference_type_1 u)
1087 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u];
1092 reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z,
1093 difference_type_1 u, difference_type_1 v)
1096 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u + m_stride[4]*v];
1104 return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x)];
1109 const_reference
operator() (difference_type_1 x, difference_type_1 y)
const
1112 return m_ptr [detail::CoordinatesToOffest<StrideTag>::exec(m_stride, x, y)];
1117 const_reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z)
const
1120 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
1125 const_reference
operator() (difference_type_1 x, difference_type_1 y,
1126 difference_type_1 z, difference_type_1 u)
const
1129 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u];
1134 const_reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z,
1135 difference_type_1 u, difference_type_1 v)
const
1138 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u + m_stride[4]*v];
1147 detail::copyScalarMultiArrayData(
traverser_begin(),
shape(), init, MetaInt<actual_dimension-1>());
1158 this->copyImpl(rhs);
1163 template <
class U,
class CN>
1166 this->copyImpl(rhs);
1183 template <
class T2,
class C2>
1197 difference_type s = vigra::detail::defaultStride<actual_dimension>(
shape());
1198 for(
unsigned int k = 0; k <= dimension; ++k)
1218 template <
int M,
class Index>
1235 template <
int M,
class Index>
1255 template <
unsigned int M>
1256 MultiArrayView <N-1, T,
typename vigra::detail::MaybeStrided<StrideTag, M>::type >
1257 bind (difference_type_1 d)
const;
1306 bindAt (difference_type_1 m, difference_type_1 d)
const;
1326 vigra_precondition(0 <= i && i < ExpandElementResult<T>::size,
1327 "MultiArrayView::bindElementChannel(i): 'i' out of range.");
1439 detail::RelativeToAbsoluteCoordinate<actual_dimension-1>::exec(
shape(), p);
1440 detail::RelativeToAbsoluteCoordinate<actual_dimension-1>::exec(
shape(), q);
1441 const difference_type_1 offset =
dot (m_stride, p);
1454 difference_type shape =
m_shape;
1455 for (
unsigned int i = 0; i < actual_dimension; ++i)
1478 difference_type
shape(m_shape.begin(), difference_type::ReverseCopy),
1479 stride(m_stride.begin(), difference_type::ReverseCopy);
1504 return permuteDimensions(permutation);
1508 permuteDimensions (
const difference_type &s)
const;
1541 difference_type_1 ret = m_shape[0];
1542 for(
int i = 1; i < actual_dimension; ++i)
1564 difference_type_1
size (difference_type_1 n)
const
1572 difference_type_1
shape (difference_type_1 n)
const
1602 return m_stride [n];
1607 template <
class U,
class C1>
1618 template <
class U,
class C1>
1628 for(
int d=0; d<actual_dimension; ++d)
1629 if(p[d] < 0 || p[d] >=
shape(d))
1637 for(
int d=0; d<actual_dimension; ++d)
1638 if(p[d] < 0 || p[d] >=
shape(d))
1651 detail::AllTrueReduceFunctor(),
1652 MetaInt<actual_dimension-1>());
1664 detail::AnyTrueReduceFunctor(),
1665 MetaInt<actual_dimension-1>());
1675 std::pair<T, T> res(NumericTraits<T>::max(), NumericTraits<T>::min());
1678 detail::MinmaxReduceFunctor(),
1679 MetaInt<actual_dimension-1>());
1680 *minimum = res.first;
1681 *maximum = res.second;
1691 typedef typename NumericTraits<U>::RealPromote R;
1693 triple<double, R, R> res(0.0, zero, zero);
1696 detail::MeanVarianceReduceFunctor(),
1697 MetaInt<actual_dimension-1>());
1699 *variance = res.third / res.first;
1714 U res = NumericTraits<U>::zero();
1717 detail::SumReduceFunctor(),
1718 MetaInt<actual_dimension-1>());
1747 template <
class U,
class S>
1751 destMultiArrayRange(sums),
1767 U res = NumericTraits<U>::one();
1770 detail::ProdReduceFunctor(),
1771 MetaInt<actual_dimension-1>());
1777 typename NormTraits<MultiArrayView>::SquaredNormType
1780 typedef typename NormTraits<MultiArrayView>::SquaredNormType SquaredNormType;
1781 SquaredNormType res = NumericTraits<SquaredNormType>::zero();
1784 detail::SquaredL2NormReduceFunctor(),
1785 MetaInt<actual_dimension-1>());
1802 typename NormTraits<MultiArrayView>::NormType
1803 norm(
int type = 2,
bool useSquaredNorm =
true)
const;
1812 pointer & unsafePtr()
1848 return begin().getEndIterator();
1856 return begin().getEndIterator();
1864 traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1873 const_traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1883 traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1884 ret += m_shape [actual_dimension-1];
1894 const_traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1895 ret += m_shape [actual_dimension-1];
1899 view_type view ()
const
1905 template <
unsigned int N,
class T,
class Str
ideTag>
1916 template <
unsigned int N,
class T,
class Str
ide1>
1917 template <
class Str
ide2>
1919 MultiArrayView <N, T, Stride1>::assignImpl(MultiArrayView<N, T, Stride2>
const & rhs)
1923 vigra_precondition(rhs.checkInnerStride(Stride1()),
1924 "MultiArrayView<..., UnstridedArrayTag>::operator=(MultiArrayView const &): cannot create unstrided view from strided array.");
1932 vigra_precondition(this->
shape() == rhs.shape(),
1933 "MultiArrayView::operator=(MultiArrayView const &): shape mismatch.");
1934 this->copyImpl(rhs);
1938 template <
unsigned int N,
class T,
class Str
ideTag>
1941 MultiArrayView <N, T, StrideTag>::arraysOverlap(
const MultiArrayView <N, T, CN>& rhs)
const
1943 vigra_precondition (shape () == rhs.shape (),
1944 "MultiArrayView::arraysOverlap(): shape mismatch.");
1947 typename MultiArrayView <N, T, CN>::const_pointer
1948 rhs_first_element = rhs.data(),
1949 rhs_last_element = rhs_first_element +
dot(rhs.shape() -
difference_type(1), rhs.stride());
1950 return !(last_element < rhs_first_element || rhs_last_element < first_element);
1953 template <
unsigned int N,
class T,
class Str
ideTag>
1954 template <
class U,
class CN>
1956 MultiArrayView <N, T, StrideTag>::copyImpl(
const MultiArrayView <N, U, CN>& rhs)
1958 if(!arraysOverlap(rhs))
1961 detail::copyMultiArrayData(rhs.traverser_begin(),
shape(),
traverser_begin(), MetaInt<actual_dimension-1>());
1967 MultiArray<N, T> tmp(rhs);
1968 detail::copyMultiArrayData(tmp.traverser_begin(),
shape(),
traverser_begin(), MetaInt<actual_dimension-1>());
1972 #define VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(name, op) \
1973 template <unsigned int N, class T, class StrideTag> \
1974 template<class U, class C1> \
1975 MultiArrayView<N, T, StrideTag> & \
1976 MultiArrayView <N, T, StrideTag>::operator op(MultiArrayView<N, U, C1> const & rhs) \
1978 vigra_precondition(this->shape() == rhs.shape(), "MultiArrayView::operator" #op "() size mismatch."); \
1979 if(!arraysOverlap(rhs)) \
1981 detail::name##MultiArrayData(rhs.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>()); \
1985 MultiArray<N, T> tmp(rhs); \
1986 detail::name##MultiArrayData(tmp.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>()); \
1991 VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copyAdd, +=)
1992 VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copySub, -=)
1993 VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copyMul, *=)
1994 VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT(copyDiv, /=)
1996 #undef VIGRA_MULTI_ARRAY_COMPUTED_ASSIGNMENT
1998 template <
unsigned int N,
class T,
class Str
ideTag>
1999 template <
class U,
class CN>
2001 MultiArrayView <N, T, StrideTag>::swapDataImpl(MultiArrayView <N, U, CN> rhs)
2003 vigra_precondition (shape () == rhs.shape (),
2004 "MultiArrayView::swapData(): shape mismatch.");
2009 typename MultiArrayView <N, U, CN>::const_pointer
2010 rhs_first_element = rhs.data(),
2011 rhs_last_element = rhs_first_element +
dot(rhs.shape() -
difference_type(1), rhs.stride());
2012 if(last_element < rhs_first_element || rhs_last_element < first_element)
2015 detail::swapDataImpl(
traverser_begin(),
shape(), rhs.traverser_begin(), MetaInt<actual_dimension-1>());
2021 MultiArray<N, T> tmp(*
this);
2027 template <
unsigned int N,
class T,
class Str
ideTag>
2028 MultiArrayView <N, T, StridedArrayTag>
2029 MultiArrayView <N, T, StrideTag>::permuteDimensions (
const difference_type &s)
const
2032 for (
unsigned int i = 0; i < actual_dimension; ++i)
2034 shape[i] = m_shape[s[i]];
2039 "MultiArrayView::transpose(): every dimension must occur exactly once.");
2043 template <
unsigned int N,
class T,
class Str
ideTag>
2044 typename MultiArrayView <N, T, StrideTag>::difference_type
2048 for(
int k=0; k<(int)N; ++k)
2050 for(
int k=0; k<(int)N-1; ++k)
2053 for(
int j=k+1; j<(int)N; ++j)
2055 if(stride[j] < stride[smallest])
2060 std::swap(stride[k], stride[smallest]);
2061 std::swap(permutation[k], permutation[smallest]);
2065 for(
unsigned int k=0; k<N; ++k)
2066 ordering[permutation[k]] = k;
2070 template <
unsigned int N,
class T,
class Str
ideTag>
2076 permutation[ordering[k]] = k;
2077 return permuteDimensions(permutation);
2080 template <
unsigned int N,
class T,
class Str
ideTag>
2086 permutation[N-1-ordering[k]] = k;
2087 return permuteDimensions(permutation);
2090 template <
unsigned int N,
class T,
class Str
ideTag>
2091 template <
int M,
class Index>
2098 static const int NNew = (N-M == 0) ? 1 : N-M;
2102 inner_shape [0] = 1;
2103 inner_stride [0] = 1;
2107 inner_shape.
init (m_shape.begin (), m_shape.end () - M);
2110 return MultiArrayView <N-M, T, StrideTag> (inner_shape, inner_stride, ptr);
2113 template <
unsigned int N,
class T,
class Str
ideTag>
2114 template <
int M,
class Index>
2121 static const int NNew = (N-M == 0) ? 1 : N-M;
2125 outer_shape [0] = 1;
2126 outer_stride [0] = 1;
2130 outer_shape.
init (m_shape.begin () + M, m_shape.end ());
2134 (outer_shape, outer_stride, ptr);
2137 template <
unsigned int N,
class T,
class Str
ideTag>
2138 template <
unsigned int M>
2139 MultiArrayView <N-1, T,
typename detail::MaybeStrided<StrideTag, M>::type >
2142 static const int NNew = (N-1 == 0) ? 1 : N-1;
2152 std::copy (m_shape.begin (), m_shape.begin () + M, shape.
begin ());
2153 std::copy (m_shape.begin () + M+1, m_shape.end (),
2154 shape.
begin () + M);
2157 stride.
begin () + M);
2159 return MultiArrayView <N-1, T,
typename detail::MaybeStrided<StrideTag, M>::type>
2163 template <
unsigned int N,
class T,
class Str
ideTag>
2167 static const int NNew = (N-1 == 0) ? 1 : N-1;
2171 inner_shape [0] = 1;
2172 inner_stride [0] = 1;
2176 inner_shape.
init (m_shape.begin (), m_shape.end () - 1);
2179 return MultiArrayView <N-1, T, StrideTag> (inner_shape, inner_stride,
2183 template <
unsigned int N,
class T,
class Str
ideTag>
2187 static const int NNew = (N-1 == 0) ? 1 : N-1;
2191 outer_shape [0] = 1;
2192 outer_stride [0] = 1;
2196 outer_shape.
init (m_shape.begin () + 1, m_shape.end ());
2203 template <
unsigned int N,
class T,
class Str
ideTag>
2207 vigra_precondition (
2208 n < static_cast <int> (N),
2209 "MultiArrayView <N, T, StrideTag>::bindAt(): dimension out of range.");
2210 static const int NNew = (N-1 == 0) ? 1 : N-1;
2220 std::copy (m_shape.begin (), m_shape.begin () + n, shape.
begin ());
2221 std::copy (m_shape.begin () + n+1, m_shape.end (),
2222 shape.
begin () + n);
2225 stride.
begin () + n);
2232 template <
unsigned int N,
class T,
class Str
ideTag>
2236 vigra_precondition(0 <= d && d <= static_cast <difference_type_1> (N),
2237 "MultiArrayView<N, ...>::expandElements(d): 0 <= 'd' <= N required.");
2239 int elementSize = ExpandElementResult<T>::size;
2241 for(
int k=0; k<d; ++k)
2243 newShape[k] = m_shape[k];
2244 newStrides[k] =
m_stride[k]*elementSize;
2247 newShape[d] = elementSize;
2250 for(
int k=d; k<N; ++k)
2252 newShape[k+1] = m_shape[k];
2253 newStrides[k+1] =
m_stride[k]*elementSize;
2256 typedef typename ExpandElementResult<T>::type U;
2258 newShape, newStrides,
reinterpret_cast<U*
>(
m_ptr));
2261 template <
unsigned int N,
class T,
class Str
ideTag>
2265 vigra_precondition (
2266 0 <= i && i <= static_cast <difference_type_1> (N),
2267 "MultiArrayView <N, T, StrideTag>::insertSingletonDimension(): index out of range.");
2269 std::copy (m_shape.begin (), m_shape.begin () + i, shape.
begin ());
2270 std::copy (m_shape.begin () + i, m_shape.end (), shape.
begin () + i + 1);
2279 template <
unsigned int N,
class T,
class Str
ideTag>
2280 typename NormTraits<MultiArrayView <N, T, StrideTag> >::NormType
2283 typedef typename NormTraits<MultiArrayView>::NormType NormType;
2289 NormType res = NumericTraits<NormType>::zero();
2292 detail::MaxNormReduceFunctor(),
2293 MetaInt<actual_dimension-1>());
2298 NormType res = NumericTraits<NormType>::zero();
2301 detail::L1NormReduceFunctor(),
2302 MetaInt<actual_dimension-1>());
2313 NormType normMax = NumericTraits<NormType>::zero();
2316 detail::MaxNormReduceFunctor(),
2317 MetaInt<actual_dimension-1>());
2318 if(normMax == NumericTraits<NormType>::zero())
2320 NormType res = NumericTraits<NormType>::zero();
2323 detail::WeightedL2NormReduceFunctor<NormType>(1.0/normMax),
2324 MetaInt<actual_dimension-1>());
2325 return sqrt(res)*normMax;
2329 vigra_precondition(
false,
"MultiArrayView::norm(): Unknown norm type.");
2330 return NumericTraits<NormType>::zero();
2341 template <
unsigned int N,
class T,
class Str
ideTag>
2342 inline typename NormTraits<MultiArrayView <N, T, StrideTag> >::SquaredNormType
2348 template <
unsigned int N,
class T,
class Str
ideTag>
2349 inline typename NormTraits<MultiArrayView <N, T, StrideTag> >::NormType
2350 norm(MultiArrayView <N, T, StrideTag>
const & a)
2382 template <
unsigned int N,
class T,
class A >
2384 :
public MultiArrayView <N, typename vigra::detail::ResolveMultiband<T>::type,
2385 typename vigra::detail::ResolveMultiband<T>::Stride>
2395 using view_type::actual_dimension;
2465 typedef typename difference_type::value_type diff_zero_t;
2485 template <
class U,
class Str
ideTag>
2492 template <
class U,
class Str
ideTag>
2515 allocator_type
const & alloc = allocator_type());
2523 allocator_type
const & alloc = allocator_type());
2528 allocator_type
const & alloc = allocator_type());
2533 allocator_type
const & alloc = allocator_type());
2539 allocator_type
const & alloc = allocator_type());
2544 allocator_type
const & alloc = allocator_type());
2550 m_alloc (rhs.m_alloc)
2557 template<
class Expression>
2558 MultiArray (multi_math::MultiMathOperand<Expression>
const & rhs,
2564 multi_math::math_detail::assignOrResize(*
this, rhs);
2569 template <
class U,
class Str
ideTag>
2571 allocator_type
const & alloc = allocator_type());
2581 this->copyOrReshape(rhs);
2590 template <
class U,
class Str
ideTag>
2593 this->copyOrReshape(rhs);
2602 return this->
init(v);
2611 template <
class U,
class Str
ideTag>
2627 template <
class U,
class Str
ideTag>
2631 this->reshape(rhs.shape());
2642 template <
class U,
class Str
ideTag>
2648 this->reshape(rhs.shape());
2658 template <
class U,
class Str
ideTag>
2664 this->reshape(rhs.shape());
2702 template<
class Expression>
2705 multi_math::math_detail::assignOrResize(*
this, rhs);
2712 template<
class Expression>
2715 multi_math::math_detail::plusAssignOrResize(*
this, rhs);
2722 template<
class Expression>
2725 multi_math::math_detail::minusAssignOrResize(*
this, rhs);
2732 template<
class Expression>
2735 multi_math::math_detail::multiplyAssignOrResize(*
this, rhs);
2742 template<
class Expression>
2745 multi_math::math_detail::divideAssignOrResize(*
this, rhs);
2826 return vigra::detail::ResolveMultiband<T>::defaultStride(shape);
2830 template <
unsigned int N,
class T,
class A>
2841 template <
unsigned int N,
class T,
class A>
2852 template <
unsigned int N,
class T,
class A>
2856 defaultStride(shape),
2862 this->m_shape [0] = 1;
2868 template <
unsigned int N,
class T,
class A>
2872 defaultStride(shape),
2878 this->m_shape [0] = 1;
2884 template <
unsigned int N,
class T,
class A>
2888 defaultStride(shape),
2894 this->m_shape [0] = 1;
2904 vigra_precondition(
false,
2905 "MultiArray(): invalid MultiArrayInitializationTag.");
2909 template <
unsigned int N,
class T,
class A>
2913 defaultStride(shape),
2919 this->m_shape [0] = 1;
2925 template <
unsigned int N,
class T,
class A>
2926 template <
class U,
class Str
ideTag>
2930 defaultStride(rhs.shape()),
2934 allocate (this->
m_ptr, rhs);
2937 template <
unsigned int N,
class T,
class A>
2938 template <
class U,
class Str
ideTag>
2942 if (this->
shape() == rhs.shape())
2951 template <
unsigned int N,
class T,
class A>
2959 else if(new_shape == this->
shape())
2961 this->
init(initial);
2968 allocate (new_ptr, new_size, initial);
2970 this->
m_ptr = new_ptr;
2971 this->m_shape = new_shape;
2977 template <
unsigned int N,
class T,
class A>
2983 std::swap(this->m_shape, other.m_shape);
2984 std::swap(this->
m_stride, other.m_stride);
2985 std::swap(this->
m_ptr, other.m_ptr);
2986 std::swap(this->m_alloc, other.m_alloc);
2989 template <
unsigned int N,
class T,
class A>
2998 ptr = m_alloc.
allocate ((
typename A::size_type)s);
3002 m_alloc.construct (ptr + i, init);
3006 m_alloc.destroy (ptr + j);
3007 m_alloc.deallocate (ptr, (
typename A::size_type)s);
3012 template <
unsigned int N,
class T,
class A>
3022 ptr = m_alloc.
allocate ((
typename A::size_type)s);
3025 for (; i < s; ++i, ++
init)
3026 m_alloc.construct (ptr + i, *init);
3030 m_alloc.destroy (ptr + j);
3031 m_alloc.deallocate (ptr, (
typename A::size_type)s);
3036 template <
unsigned int N,
class T,
class A>
3037 template <
class U,
class Str
ideTag>
3046 ptr = m_alloc.
allocate ((
typename A::size_type)s);
3049 detail::uninitializedCopyMultiArrayData(init.traverser_begin(), init.shape(),
3050 p, m_alloc, MetaInt<actual_dimension-1>());
3053 for (
pointer pp = ptr; pp < p; ++pp)
3054 m_alloc.destroy (pp);
3055 m_alloc.deallocate (ptr, (
typename A::size_type)s);
3060 template <
unsigned int N,
class T,
class A>
3066 m_alloc.destroy (ptr + i);
3067 m_alloc.
deallocate (ptr, (
typename A::size_type)s);
3077 template <
unsigned int N,
class T,
class Str
ideTag>
3078 inline triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3083 return triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3086 ( array.traverser_begin(),
3091 template <
unsigned int N,
class T,
class Str
ideTag,
class Accessor>
3092 inline triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3093 typename MultiArrayView<N,T,StrideTag>::difference_type,
3095 srcMultiArrayRange( MultiArrayView<N,T,StrideTag>
const & array, Accessor a )
3097 return triple<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3098 typename MultiArrayView<N,T,StrideTag>::difference_type,
3100 ( array.traverser_begin(),
3105 template <
unsigned int N,
class T,
class Str
ideTag>
3106 inline pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3107 typename AccessorTraits<T>::default_const_accessor >
3108 srcMultiArray( MultiArrayView<N,T,StrideTag>
const & array )
3110 return pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3111 typename AccessorTraits<T>::default_const_accessor >
3112 ( array.traverser_begin(),
3113 typename AccessorTraits<T>::default_const_accessor() );
3116 template <
unsigned int N,
class T,
class Str
ideTag,
class Accessor>
3117 inline pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3119 srcMultiArray( MultiArrayView<N,T,StrideTag>
const & array, Accessor a )
3121 return pair<typename MultiArrayView<N,T,StrideTag>::const_traverser,
3123 ( array.traverser_begin(), a );
3126 template <
unsigned int N,
class T,
class Str
ideTag>
3127 inline triple<typename MultiArrayView<N,T,StrideTag>::traverser,
3128 typename MultiArrayView<N,T,StrideTag>::difference_type,
3129 typename AccessorTraits<T>::default_accessor >
3130 destMultiArrayRange( MultiArrayView<N,T,StrideTag> & array )
3132 return triple<typename MultiArrayView<N,T,StrideTag>::traverser,
3133 typename MultiArrayView<N,T,StrideTag>::difference_type,
3134 typename AccessorTraits<T>::default_accessor >
3135 ( array.traverser_begin(),
3137 typename AccessorTraits<T>::default_accessor() );
3140 template <
unsigned int N,
class T,
class Str
ideTag,
class Accessor>
3141 inline triple<typename MultiArrayView<N,T,StrideTag>::traverser,
3142 typename MultiArrayView<N,T,StrideTag>::difference_type,
3144 destMultiArrayRange( MultiArrayView<N,T,StrideTag> & array, Accessor a )
3146 return triple<typename MultiArrayView<N,T,StrideTag>::traverser,
3147 typename MultiArrayView<N,T,StrideTag>::difference_type,
3149 ( array.traverser_begin(),
3154 template <
unsigned int N,
class T,
class Str
ideTag>
3155 inline pair<typename MultiArrayView<N,T,StrideTag>::traverser,
3156 typename AccessorTraits<T>::default_accessor >
3157 destMultiArray( MultiArrayView<N,T,StrideTag> & array )
3159 return pair<typename MultiArrayView<N,T,StrideTag>::traverser,
3160 typename AccessorTraits<T>::default_accessor >
3161 ( array.traverser_begin(),
3162 typename AccessorTraits<T>::default_accessor() );
3165 template <
unsigned int N,
class T,
class Str
ideTag,
class Accessor>
3166 inline pair<typename MultiArrayView<N,T,StrideTag>::traverser,
3168 destMultiArray( MultiArrayView<N,T,StrideTag> & array, Accessor a )
3170 return pair<typename MultiArrayView<N,T,StrideTag>::traverser,
3172 ( array.traverser_begin(), a );
3177 template <
class PixelType,
class Accessor>
3178 inline triple<ConstStridedImageIterator<PixelType>,
3179 ConstStridedImageIterator<PixelType>, Accessor>
3180 srcImageRange(
const MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
3182 ConstStridedImageIterator<PixelType>
3183 ul(img.data(), 1, img.stride(0), img.stride(1));
3184 return triple<ConstStridedImageIterator<PixelType>,
3185 ConstStridedImageIterator<PixelType>,
3187 ul, ul + Size2D(img.shape(0), img.shape(1)), a);
3190 template <
class PixelType,
class Accessor>
3191 inline pair<ConstStridedImageIterator<PixelType>, Accessor>
3192 srcImage(
const MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
3194 ConstStridedImageIterator<PixelType>
3195 ul(img.data(), 1, img.stride(0), img.stride(1));
3196 return pair<ConstStridedImageIterator<PixelType>, Accessor>
3200 template <
class PixelType,
class Accessor>
3201 inline triple<StridedImageIterator<PixelType>,
3202 StridedImageIterator<PixelType>, Accessor>
3203 destImageRange(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
3205 StridedImageIterator<PixelType>
3206 ul(img.data(), 1, img.stride(0), img.stride(1));
3207 return triple<StridedImageIterator<PixelType>,
3208 StridedImageIterator<PixelType>,
3210 ul, ul + Size2D(img.shape(0), img.shape(1)), a);
3213 template <
class PixelType,
class Accessor>
3214 inline pair<StridedImageIterator<PixelType>, Accessor>
3215 destImage(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
3217 StridedImageIterator<PixelType>
3218 ul(img.data(), 1, img.stride(0), img.stride(1));
3219 return pair<StridedImageIterator<PixelType>, Accessor>
3223 template <
class PixelType,
class Accessor>
3224 inline pair<StridedImageIterator<PixelType>, Accessor>
3225 maskImage(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
3227 StridedImageIterator<PixelType>
3228 ul(img.data(), 1, img.stride(0), img.stride(1));
3229 return pair<StridedImageIterator<PixelType>, Accessor>
3235 template <
class PixelType>
3236 inline triple<ConstStridedImageIterator<PixelType>,
3237 ConstStridedImageIterator<PixelType>,
3238 typename AccessorTraits<PixelType>::default_const_accessor>
3239 srcImageRange(MultiArrayView<2, PixelType, StridedArrayTag>
const & img)
3241 ConstStridedImageIterator<PixelType>
3242 ul(img.data(), 1, img.stride(0), img.stride(1));
3243 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
3244 return triple<ConstStridedImageIterator<PixelType>,
3245 ConstStridedImageIterator<PixelType>,
3247 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
3250 template <
class PixelType>
3251 inline triple<ConstImageIterator<PixelType>,
3252 ConstImageIterator<PixelType>,
3253 typename AccessorTraits<PixelType>::default_const_accessor>
3254 srcImageRange(MultiArrayView<2, PixelType, UnstridedArrayTag>
const & img)
3256 ConstImageIterator<PixelType>
3257 ul(img.data(), img.stride(1));
3258 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
3259 return triple<ConstImageIterator<PixelType>,
3260 ConstImageIterator<PixelType>,
3262 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
3265 template <
class PixelType>
3266 inline pair< ConstStridedImageIterator<PixelType>,
3267 typename AccessorTraits<PixelType>::default_const_accessor>
3268 srcImage(MultiArrayView<2, PixelType, StridedArrayTag>
const & img)
3270 ConstStridedImageIterator<PixelType>
3271 ul(img.data(), 1, img.stride(0), img.stride(1));
3272 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
3273 return pair<ConstStridedImageIterator<PixelType>,
3278 template <
class PixelType>
3279 inline pair< ConstImageIterator<PixelType>,
3280 typename AccessorTraits<PixelType>::default_const_accessor>
3281 srcImage(MultiArrayView<2, PixelType, UnstridedArrayTag>
const & img)
3283 ConstImageIterator<PixelType>
3284 ul(img.data(), img.stride(1));
3285 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
3286 return pair<ConstImageIterator<PixelType>,
3291 template <
class PixelType>
3292 inline triple< StridedImageIterator<PixelType>,
3293 StridedImageIterator<PixelType>,
3294 typename AccessorTraits<PixelType>::default_accessor>
3295 destImageRange(MultiArrayView<2, PixelType, StridedArrayTag> & img)
3297 StridedImageIterator<PixelType>
3298 ul(img.data(), 1, img.stride(0), img.stride(1));
3299 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
3300 return triple<StridedImageIterator<PixelType>,
3301 StridedImageIterator<PixelType>,
3303 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
3306 template <
class PixelType>
3307 inline triple< ImageIterator<PixelType>,
3308 ImageIterator<PixelType>,
3309 typename AccessorTraits<PixelType>::default_accessor>
3310 destImageRange(MultiArrayView<2, PixelType, UnstridedArrayTag> & img)
3312 ImageIterator<PixelType>
3313 ul(img.data(), img.stride(1));
3314 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
3315 return triple<ImageIterator<PixelType>,
3316 ImageIterator<PixelType>,
3318 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
3321 template <
class PixelType>
3322 inline pair< StridedImageIterator<PixelType>,
3323 typename AccessorTraits<PixelType>::default_accessor>
3324 destImage(MultiArrayView<2, PixelType, StridedArrayTag> & img)
3326 StridedImageIterator<PixelType>
3327 ul(img.data(), 1, img.stride(0), img.stride(1));
3328 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
3329 return pair<StridedImageIterator<PixelType>, Accessor>
3333 template <
class PixelType>
3334 inline pair< ImageIterator<PixelType>,
3335 typename AccessorTraits<PixelType>::default_accessor>
3336 destImage(MultiArrayView<2, PixelType, UnstridedArrayTag> & img)
3338 ImageIterator<PixelType> ul(img.data(), img.stride(1));
3339 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
3340 return pair<ImageIterator<PixelType>, Accessor>(ul, Accessor());
3343 template <
class PixelType>
3344 inline pair< ConstStridedImageIterator<PixelType>,
3345 typename AccessorTraits<PixelType>::default_accessor>
3346 maskImage(MultiArrayView<2, PixelType, StridedArrayTag>
const & img)
3348 ConstStridedImageIterator<PixelType>
3349 ul(img.data(), 1, img.stride(0), img.stride(1));
3350 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
3351 return pair<ConstStridedImageIterator<PixelType>, Accessor>
3355 template <
class PixelType>
3356 inline pair< ConstImageIterator<PixelType>,
3357 typename AccessorTraits<PixelType>::default_accessor>
3358 maskImage(MultiArrayView<2, PixelType, UnstridedArrayTag>
const & img)
3360 ConstImageIterator<PixelType>
3361 ul(img.data(), img.stride(1));
3362 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
3363 return pair<ConstImageIterator<PixelType>, Accessor>
3385 template <
class T,
class Str
ide>
3390 "makeBasicImageView(array): array must be unstrided (i.e. array.isUnstrided() == true).");
3407 vigra_precondition(array.stride(1) == array.shape(0),
3408 "makeBasicImageView(): cannot join strided dimensions");
3410 array.shape (0)*array.shape (1), array.shape (2), array.stride(2));
3421 template <
class T,
class Str
ide>
3422 BasicImageView <RGBValue<T> >
3425 vigra_precondition(array.shape (0) == 3,
3426 "makeRGBImageView(): array.shape(0) must be 3.");
3427 vigra_precondition(array.isUnstrided(),
3428 "makeRGBImageView(array): array must be unstrided (i.e. array.isUnstrided() == true).");
3431 array.shape (1), array.shape (2));
3438 #undef VIGRA_ASSERT_INSIDE
3440 #endif // VIGRA_MULTI_ARRAY_HXX