36#ifndef VIGRA_BASICGEOMETRY_HXX
37#define VIGRA_BASICGEOMETRY_HXX
40#include "stdimage.hxx"
41#include "copyimage.hxx"
42#include "multi_shape.hxx"
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");
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");
260template <
class SrcImageIterator,
class SrcAccessor,
261 class DestImageIterator,
class DestAccessor>
263rotateImage(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);
269template <
class T1,
class S1,
272rotateImage(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);
291enum Reflect {horizontal = 1, vertical = 2};
294Reflect operator|(Reflect l, Reflect r)
296 return Reflect((
unsigned int)l | (
unsigned int)r);
390 int ws = end.x -
is.x;
391 int hs = end.y -
is.y;
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++)
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");
442template <
class SrcImageIterator,
class SrcAccessor,
443 class DestImageIterator,
class DestAccessor>
445reflectImage(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);
451template <
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);
469enum Transpose{major = 1, minor = 2};
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");
632template <
class SrcImageIterator,
class SrcAccessor,
633 class DestImageIterator,
class DestAccessor>
635transposeImage(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);
641template <
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.");
670template <
class SrcIterator,
class SrcAccessor,
671 class DestIterator,
class DestAccessor>
672void 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);
727inline int sizeForResamplingFactor(
int oldsize,
double factor)
729 return (factor < 1.0)
730 ? (int)VIGRA_CSTD::ceil(oldsize * factor)
731 : (int)(oldsize * factor);
870 "Source image too small.\n");
873 "Destination image too small.\n");
875 typedef typename SrcAccessor::value_type
SRCVT;
887 typename SrcIterator::column_iterator
c1 =
is.columnIterator();
888 typename TmpImageIterator::column_iterator
ct =
yt.columnIterator();
892 yt =
tmp.upperLeft();
896 typename DestIterator::row_iterator rd =
id.rowIterator();
897 typename TmpImageIterator::row_iterator
rt =
yt.rowIterator();
903template <
class SrcIterator,
class SrcAccessor,
904 class DestIterator,
class DestAccessor>
906resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
907 DestIterator
id, DestAccessor ad,
double factor)
912template <
class SrcImageIterator,
class SrcAccessor,
913 class DestImageIterator,
class DestAccessor>
915resampleImage(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);
921template <
class SrcImageIterator,
class SrcAccessor,
922 class DestImageIterator,
class DestAccessor>
924resampleImage(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);
930template <
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.");
946template <
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);
Class for a single RGB value.
Definition rgbvalue.hxx:128
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition fixedpoint.hxx:667
void reflectImage(...)
Reflect image horizontally or vertically.
void resampleImage(...)
Resample image by a given factor.
void transposeImage(...)
Transpose an image over the major or minor diagonal.
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition fixedpoint.hxx:675
void copyImage(...)
Copy source image into destination image.