36 #ifndef VIGRA_OVERLAPPED_BLOCKS_HXX
37 #define VIGRA_OVERLAPPED_BLOCKS_HXX
42 #include <vigra/multi_array.hxx>
43 #include <vigra/multi_array_chunked.hxx>
48 namespace overlapped_blocks_detail
51 template <
class Shape>
52 std::pair<Shape, Shape> blockBoundsAt(
const Shape& coordinates,
const Shape& global_shape,
const Shape& block_shape)
55 for(
int i = 0; i != Shape::static_size; ++i)
57 block_begin[i] = coordinates[i] * block_shape[i];
58 vigra_assert(block_begin[i] < global_shape[i],
"block coordinates out of bounds");
61 for(
int i = 0; i != Shape::static_size; ++i)
63 block_end[i] = std::min(block_begin[i] + block_shape[i], global_shape[i]);
65 return std::make_pair(block_begin, block_end);
68 template <
class Shape>
69 std::pair<Shape, Shape> overlapBoundsAt(
const std::pair<Shape, Shape>& block_bounds,
const Shape& global_shape,
70 const Shape& overlap_before,
const Shape& overlap_after)
72 Shape overlapped_block_begin = block_bounds.first;
73 Shape overlapped_block_end = block_bounds.second;
74 for(
int i = 0; i != Shape::static_size; ++i)
76 if(overlapped_block_begin[i] >= overlap_before[i])
77 overlapped_block_begin[i] -= overlap_before[i];
79 overlapped_block_begin[i] = 0;
81 if(overlapped_block_end[i] <= global_shape[i] - overlap_after[i])
82 overlapped_block_end[i] += overlap_after[i];
84 overlapped_block_end[i] = global_shape[i];
86 return std::make_pair(overlapped_block_begin, overlapped_block_end);
89 template <
class Shape>
90 Shape blocksShape(
const Shape& global_shape,
const Shape& block_shape)
93 for(
int i = 0; i != Shape::static_size; ++i)
95 result[i] = global_shape[i] / block_shape[i];
96 if(block_shape[i] * result[i] != global_shape[i])
105 template <
class Shape>
107 within(
const Shape& coordinates,
const std::pair<Shape, Shape>& bounds)
112 template <
class ArrayType>
113 struct OverlappingBlock;
115 template <
class ArrayType>
118 template <
unsigned int N,
class T,
class S>
119 struct OverlappingBlock<MultiArrayView<N, T, S> >
123 MultiArrayView<N, T, S> block;
124 std::pair<Shape, Shape> inner_bounds;
127 template <
unsigned int N,
class T,
class S>
128 class Overlaps<MultiArrayView<N, T, S> >
131 typedef MultiArrayView<N, T, S> View;
132 typedef typename View::difference_type Shape;
136 Shape overlap_before;
139 Overlaps(View view,
const Shape& block_shape,
const Shape& overlap_before,
const Shape& overlap_after)
141 block_shape(block_shape),
142 overlap_before(overlap_before),
143 overlap_after(overlap_after)
145 OverlappingBlock<View> operator[](
const Shape& coordinates)
const
147 using namespace overlapped_blocks_detail;
148 std::pair<Shape, Shape> block_bounds = blockBoundsAt(coordinates, view.shape(), block_shape);
149 std::pair<Shape, Shape> overlap_bounds = overlapBoundsAt(block_bounds, view.shape(), overlap_before, overlap_after);
151 OverlappingBlock<View> result;
152 result.block = view.subarray(overlap_bounds.first, overlap_bounds.second);
153 result.inner_bounds = std::make_pair(block_bounds.first - overlap_bounds.first, block_bounds.second - overlap_bounds.first);
158 using namespace overlapped_blocks_detail;
159 return blocksShape(view.shape(), block_shape);
163 template <
unsigned int N,
class T>
164 struct OverlappingBlock<ChunkedArray<N, T> >
166 typedef typename MultiArrayShape<N>::type Shape;
168 MultiArray<N, T> block;
169 std::pair<Shape, Shape> inner_bounds;
172 template <
unsigned int N,
class T>
173 class Overlaps<ChunkedArray<N, T> >
176 typedef ChunkedArray<N, T> Array;
177 typedef typename MultiArrayShape<N>::type Shape;
181 Shape overlap_before;
184 Overlaps(
const Array& array,
const Shape& block_shape,
const Shape& overlap_before,
const Shape& overlap_after)
186 block_shape(block_shape),
187 overlap_before(overlap_before),
188 overlap_after(overlap_after)
191 OverlappingBlock<Array> operator[](
const Shape& coordinates)
const
193 using namespace overlapped_blocks_detail;
194 std::pair<Shape, Shape> block_bounds = blockBoundsAt(coordinates, array.shape(), block_shape);
195 std::pair<Shape, Shape> overlap_bounds = overlapBoundsAt(block_bounds, array.shape(), overlap_before, overlap_after);
197 OverlappingBlock<Array> result;
198 result.block.reshape(overlap_bounds.second - overlap_bounds.first);
199 array.checkoutSubarray(overlap_bounds.first, result.block);
200 result.inner_bounds = std::make_pair(block_bounds.first - overlap_bounds.first, block_bounds.second - overlap_bounds.first);
206 using namespace overlapped_blocks_detail;
207 return blocksShape(array.shape(), block_shape);
213 #endif // VIGRA_OVERLAPPED_BLOCKS_HXX
MultiArrayShape< actual_dimension >::type difference_type
Definition: multi_array.hxx:739
bool allLess(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-than
Definition: tinyvector.hxx:1375
bool allLessEqual(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-equal
Definition: tinyvector.hxx:1399