36 #ifndef VIGRA_BASICGEOMETRY_HXX
37 #define VIGRA_BASICGEOMETRY_HXX
40 #include "stdimage.hxx"
41 #include "copyimage.hxx"
42 #include "multi_shape.hxx"
191 template <
class SrcIterator,
class SrcAccessor,
192 class DestIterator,
class DestAccessor>
193 void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
194 DestIterator
id, DestAccessor ad,
int rotation)
197 int ws = end.x - is.x;
198 int hs = end.y - is.y;
200 vigra_precondition(rotation % 90 == 0,
202 "This function rotates images only about multiples of 90 degree");
204 rotation = rotation%360;
215 for(x=0; x != ws; x++, is.x--,
id.y++)
217 typename SrcIterator::column_iterator cs = is.columnIterator();
218 typename DestIterator::row_iterator rd =
id.rowIterator();
219 for(y=0; y != hs; y++, cs++, rd++)
230 for(x=0; x != ws; x++, end.x--,
id.x++)
232 typename SrcIterator::column_iterator cs = end.columnIterator();
233 typename DestIterator::column_iterator cd =
id.columnIterator();
234 for(y=0; y != hs; y++, cs--, cd++)
244 for(x=0; x != ws; x++, is.x++,
id.y++)
246 typename SrcIterator::column_iterator cs = is.columnIterator();
247 typename DestIterator::row_iterator rd =
id.rowIterator();
248 for(y=0; y != hs; y++, cs--, rd++)
256 vigra_fail(
"internal error");
260 template <
class SrcImageIterator,
class SrcAccessor,
261 class DestImageIterator,
class DestAccessor>
263 rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
264 pair<DestImageIterator, DestAccessor> dest,
int rotation)
266 rotateImage(src.first, src.second, src.third, dest.first, dest.second, rotation);
269 template <
class T1,
class S1,
272 rotateImage(MultiArrayView<2, T1, S1>
const & src,
273 MultiArrayView<2, T2, S2> dest,
276 if(rotation % 180 == 0)
277 vigra_precondition(src.shape() == dest.shape(),
278 "rotateImage(): shape mismatch between input and output.");
280 vigra_precondition(src.shape() == reverse(dest.shape()),
281 "rotateImage(): shape mismatch between input and output.");
282 rotateImage(srcImageRange(src), destImage(dest), rotation);
291 enum Reflect {horizontal = 1, vertical = 2};
294 Reflect operator|(Reflect l, Reflect r)
296 return Reflect((
unsigned int)l | (
unsigned int)r);
384 template <
class SrcIterator,
class SrcAccessor,
385 class DestIterator,
class DestAccessor>
386 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
387 DestIterator
id, DestAccessor ad, Reflect reflect)
390 int ws = end.x - is.x;
391 int hs = end.y - is.y;
395 if(reflect == horizontal)
398 for(x=0; x<ws; ++x, ++is.x, ++
id.x)
400 typename SrcIterator::column_iterator cs = is.columnIterator();
401 typename DestIterator::column_iterator cd =
id.columnIterator();
402 for(y=0; y!=hs;y++, cs--, cd++)
408 else if(reflect == vertical)
411 for(x=0; x < ws; ++x, --is.x, ++
id.x)
414 typename SrcIterator::column_iterator cs = is.columnIterator();
415 typename DestIterator::column_iterator cd =
id.columnIterator();
416 for(y=0; y!=hs;y++, cs++, cd++)
422 else if(reflect == (horizontal | vertical))
426 for(x=0; x != ws; x++, end.x--,
id.x++)
428 typename SrcIterator::column_iterator cs = end.columnIterator();
429 typename DestIterator::column_iterator cd =
id.columnIterator();
430 for(y=0; y != hs; y++, cs--, cd++)
437 vigra_fail(
"reflectImage(): "
438 "This function reflects horizontal or vertical,"
439 " 'and' is included");
442 template <
class SrcImageIterator,
class SrcAccessor,
443 class DestImageIterator,
class DestAccessor>
445 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
446 pair<DestImageIterator, DestAccessor> dest, Reflect reflect)
448 reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect);
451 template <
class T1,
class S1,
455 MultiArrayView<2, T2, S2> dest, Reflect reflect)
457 vigra_precondition(src.shape() == dest.shape(),
458 "reflectImage(): shape mismatch between input and output.");
459 reflectImage(srcImageRange(src), destImage(dest), reflect);
469 enum Transpose{major = 1, minor = 2};
572 template <
class SrcIterator,
class SrcAccessor,
573 class DestIterator,
class DestAccessor>
574 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
575 DestIterator
id, DestAccessor ad, Transpose transpose)
577 int ws = end.x - is.x;
578 int hs = end.y - is.y;
582 if(transpose == major)
584 for(x=0; x != ws; x++, is.x++,
id.y++)
587 typename SrcIterator::column_iterator cs = is.columnIterator();
588 typename DestIterator::row_iterator rd =
id.rowIterator();
589 for(y=0; y != hs; y++, cs++, rd++)
595 else if(transpose == minor)
599 for(x=0; x != ws; x++, --end.x, ++
id.y)
602 typename SrcIterator::column_iterator cs = end.columnIterator();
603 typename DestIterator::row_iterator rd =
id.rowIterator();
604 for(y=0; y != hs; y++, --cs, ++rd)
610 else if(transpose == (major | minor))
614 for(x=0; x != ws; x++, end.x--,
id.x++)
616 typename SrcIterator::column_iterator cs = end.columnIterator();
617 typename DestIterator::column_iterator cd =
id.columnIterator();
618 for(y=0; y != hs; y++, cs--, cd++)
626 vigra_fail(
"transposeImage(): "
627 "This function transposes major or minor,"
628 " 'and' is included");
632 template <
class SrcImageIterator,
class SrcAccessor,
633 class DestImageIterator,
class DestAccessor>
635 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
636 pair<DestImageIterator, DestAccessor> dest, Transpose transpose)
638 transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose);
641 template <
class T1,
class S1,
645 MultiArrayView<2, T2, S2> dest, Transpose transpose)
647 vigra_precondition(src.shape() == reverse(dest.shape()),
648 "transposeImage(): shape mismatch between input and output.");
670 template <
class SrcIterator,
class SrcAccessor,
671 class DestIterator,
class DestAccessor>
672 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
673 DestIterator dest_iter, DestAccessor dest_acc,
double factor)
676 int src_width = src_iter_end - src_iter;
678 vigra_precondition(src_width > 0,
679 "resampleLine(): input image too small.");
680 vigra_precondition(factor > 0.0,
681 "resampleLine(): factor must be positive.");
685 int int_factor = (int)factor;
686 double dx = factor - int_factor;
688 for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx)
692 saver = saver - (int)saver;
693 dest_acc.set(src_acc(src_iter), dest_iter);
696 for(
int i = 0 ; i < int_factor ; i++, ++dest_iter)
698 dest_acc.set(src_acc(src_iter), dest_iter);
704 DestIterator dest_end = dest_iter + (int)
VIGRA_CSTD::ceil(src_width*factor);
706 int int_factor = (int)factor;
707 double dx = factor - int_factor;
710 for ( ; src_iter != src_iter_end && dest_iter != dest_end ;
711 ++dest_iter, src_iter += int_factor, saver += dx)
715 saver = saver - (int)saver;
718 dest_acc.set(src_acc(src_iter), dest_iter);
720 if (dest_iter != dest_end)
722 dest_acc.set(src_acc(src_iter_end), dest_iter);
727 inline int sizeForResamplingFactor(
int oldsize,
double factor)
729 return (factor < 1.0)
731 : (int)(oldsize * factor);
852 template <
class SrcIterator,
class SrcAccessor,
853 class DestIterator,
class DestAccessor>
855 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
856 DestIterator
id, DestAccessor ad,
double xfactor,
double yfactor)
858 int width_old = iend.x - is.x;
859 int height_old = iend.y - is.y;
865 int height_new = sizeForResamplingFactor(height_old, yfactor);
866 int width_new = sizeForResamplingFactor(width_old, xfactor);
868 vigra_precondition((width_old > 1) && (height_old > 1),
870 "Source image too small.\n");
871 vigra_precondition((width_new > 1) && (height_new > 1),
873 "Destination image too small.\n");
875 typedef typename SrcAccessor::value_type SRCVT;
876 typedef BasicImage<SRCVT> TmpImage;
877 typedef typename TmpImage::traverser TmpImageIterator;
879 BasicImage<SRCVT> tmp(width_old, height_new);
883 typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft();
885 for(x=0; x<width_old; ++x, ++is.x, ++yt.x)
887 typename SrcIterator::column_iterator c1 = is.columnIterator();
888 typename TmpImageIterator::column_iterator ct = yt.columnIterator();
889 resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor);
892 yt = tmp.upperLeft();
894 for(y=0; y < height_new; ++y, ++yt.y, ++
id.y)
896 typename DestIterator::row_iterator rd =
id.rowIterator();
897 typename TmpImageIterator::row_iterator rt = yt.rowIterator();
898 resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor);
903 template <
class SrcIterator,
class SrcAccessor,
904 class DestIterator,
class DestAccessor>
906 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
907 DestIterator
id, DestAccessor ad,
double factor)
912 template <
class SrcImageIterator,
class SrcAccessor,
913 class DestImageIterator,
class DestAccessor>
915 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
916 pair<DestImageIterator, DestAccessor> dest,
double factor)
918 resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor);
921 template <
class SrcImageIterator,
class SrcAccessor,
922 class DestImageIterator,
class DestAccessor>
924 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
925 pair<DestImageIterator, DestAccessor> dest,
double xfactor,
double yfactor)
927 resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor);
930 template <
class T1,
class S1,
934 MultiArrayView<2, T2, S2> dest,
double factor)
937 vigra_precondition(
floor(factor*src.shape()) == dest.shape(),
938 "resampleImage(): shape mismatch between input and output.");
940 vigra_precondition(
ceil(factor*src.shape()) == dest.shape(),
941 "resampleImage(): shape mismatch between input and output.");
946 template <
class T1,
class S1,
950 MultiArrayView<2, T2, S2> dest,
double xfactor,
double yfactor)
953 vigra_precondition(
floor(xfactor*src.shape(0)) == dest.shape(0),
954 "resampleImage(): shape mismatch between input and output.");
956 vigra_precondition(
ceil(xfactor*src.shape(0)) == dest.shape(0),
957 "resampleImage(): shape mismatch between input and output.");
959 vigra_precondition(
floor(yfactor*src.shape(1)) == dest.shape(1),
960 "resampleImage(): shape mismatch between input and output.");
962 vigra_precondition(
ceil(yfactor*src.shape(1)) == dest.shape(1),
963 "resampleImage(): shape mismatch between input and output.");
965 resampleImage(srcImageRange(src), destImage(dest), xfactor, yfactor);
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void copyImage(...)
Copy source image into destination image.
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition: fixedpoint.hxx:675
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition: fixedpoint.hxx:667