36 #ifndef VIGRA_BASICGEOMETRY_HXX
37 #define VIGRA_BASICGEOMETRY_HXX
40 #include "stdimage.hxx"
41 #include "copyimage.hxx"
117 doxygen_overloaded_function(template <...>
void rotateImage)
119 template <
class SrcIterator,
class SrcAccessor,
120 class DestIterator,
class DestAccessor>
121 void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
122 DestIterator
id, DestAccessor ad,
int rotation)
125 int ws = end.x - is.x;
126 int hs = end.y - is.y;
128 vigra_precondition(rotation % 90 == 0,
130 "This function rotates images only about multiples of 90 degree");
132 rotation = rotation%360;
143 for(x=0; x != ws; x++, is.x--,
id.y++)
145 typename SrcIterator::column_iterator cs = is.columnIterator();
146 typename DestIterator::row_iterator rd =
id.rowIterator();
147 for(y=0; y != hs; y++, cs++, rd++)
158 for(x=0; x != ws; x++, end.x--,
id.x++)
160 typename SrcIterator::column_iterator cs = end.columnIterator();
161 typename DestIterator::column_iterator cd =
id.columnIterator();
162 for(y=0; y != hs; y++, cs--, cd++)
172 for(x=0; x != ws; x++, is.x++,
id.y++)
174 typename SrcIterator::column_iterator cs = is.columnIterator();
175 typename DestIterator::row_iterator rd =
id.rowIterator();
176 for(y=0; y != hs; y++, cs--, rd++)
184 vigra_fail(
"internal error");
188 template <
class SrcImageIterator,
class SrcAccessor,
189 class DestImageIterator,
class DestAccessor>
191 rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
192 pair<DestImageIterator, DestAccessor> dest,
int rotation)
194 rotateImage(src.first, src.second, src.third, dest.first, dest.second, rotation);
203 enum Reflect {horizontal = 1, vertical = 2};
206 Reflect operator|(Reflect l, Reflect r)
208 return Reflect((
unsigned int)l | (
unsigned int)r);
276 doxygen_overloaded_function(template <...>
void reflectImage)
278 template <
class SrcIterator,
class SrcAccessor,
279 class DestIterator,
class DestAccessor>
280 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
281 DestIterator
id, DestAccessor ad, Reflect reflect)
284 int ws = end.x - is.x;
285 int hs = end.y - is.y;
289 if(reflect == horizontal)
292 for(x=0; x<ws; ++x, ++is.x, ++
id.x)
294 typename SrcIterator::column_iterator cs = is.columnIterator();
295 typename DestIterator::column_iterator cd =
id.columnIterator();
296 for(y=0; y!=hs;y++, cs--, cd++)
302 else if(reflect == vertical)
305 for(x=0; x < ws; ++x, --is.x, ++
id.x)
308 typename SrcIterator::column_iterator cs = is.columnIterator();
309 typename DestIterator::column_iterator cd =
id.columnIterator();
310 for(y=0; y!=hs;y++, cs++, cd++)
316 else if(reflect == (horizontal | vertical))
320 for(x=0; x != ws; x++, end.x--,
id.x++)
322 typename SrcIterator::column_iterator cs = end.columnIterator();
323 typename DestIterator::column_iterator cd =
id.columnIterator();
324 for(y=0; y != hs; y++, cs--, cd++)
331 vigra_fail(
"reflectImage(): "
332 "This function reflects horizontal or vertical,"
333 " 'and' is included");
336 template <
class SrcImageIterator,
class SrcAccessor,
337 class DestImageIterator,
class DestAccessor>
339 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
340 pair<DestImageIterator, DestAccessor> dest, Reflect reflect)
342 reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect);
352 enum Transpose{major = 1, minor = 2};
425 template <
class SrcIterator,
class SrcAccessor,
426 class DestIterator,
class DestAccessor>
427 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
428 DestIterator
id, DestAccessor ad, Transpose
transpose)
430 int ws = end.x - is.x;
431 int hs = end.y - is.y;
435 if(transpose == major)
437 for(x=0; x != ws; x++, is.x++,
id.y++)
440 typename SrcIterator::column_iterator cs = is.columnIterator();
441 typename DestIterator::row_iterator rd =
id.rowIterator();
442 for(y=0; y != hs; y++, cs++, rd++)
448 else if(transpose == minor)
452 for(x=0; x != ws; x++, --end.x, ++
id.y)
455 typename SrcIterator::column_iterator cs = end.columnIterator();
456 typename DestIterator::row_iterator rd =
id.rowIterator();
457 for(y=0; y != hs; y++, --cs, ++rd)
463 else if(transpose == (major | minor))
467 for(x=0; x != ws; x++, end.x--,
id.x++)
469 typename SrcIterator::column_iterator cs = end.columnIterator();
470 typename DestIterator::column_iterator cd =
id.columnIterator();
471 for(y=0; y != hs; y++, cs--, cd++)
479 vigra_fail(
"transposeImage(): "
480 "This function transposes major or minor,"
481 " 'and' is included");
485 template <
class SrcImageIterator,
class SrcAccessor,
486 class DestImageIterator,
class DestAccessor>
488 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
489 pair<DestImageIterator, DestAccessor> dest, Transpose transpose)
491 transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose);
512 template <
class SrcIterator,
class SrcAccessor,
513 class DestIterator,
class DestAccessor>
514 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
515 DestIterator dest_iter, DestAccessor dest_acc,
double factor)
518 int src_width = src_iter_end - src_iter;
520 vigra_precondition(src_width > 0,
521 "resampleLine(): input image too small.");
522 vigra_precondition(factor > 0.0,
523 "resampleLine(): factor must be positive.");
527 int int_factor = (int)factor;
528 double dx = factor - int_factor;
530 for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx)
534 saver = saver - (int)saver;
535 dest_acc.set(src_acc(src_iter), dest_iter);
538 for(
int i = 0 ; i < int_factor ; i++, ++dest_iter)
540 dest_acc.set(src_acc(src_iter), dest_iter);
546 DestIterator dest_end = dest_iter + (int)
VIGRA_CSTD::ceil(src_width*factor);
548 int int_factor = (int)factor;
549 double dx = factor - int_factor;
552 for ( ; src_iter != src_iter_end && dest_iter != dest_end ;
553 ++dest_iter, src_iter += int_factor, saver += dx)
557 saver = saver - (int)saver;
560 dest_acc.set(src_acc(src_iter), dest_iter);
562 if (dest_iter != dest_end)
564 dest_acc.set(src_acc(src_iter_end), dest_iter);
569 inline int sizeForResamplingFactor(
int oldsize,
double factor)
571 return (factor < 1.0)
573 : (int)(oldsize * factor);
672 doxygen_overloaded_function(template <...>
void resampleImage)
674 template <
class SrcIterator,
class SrcAccessor,
675 class DestIterator,
class DestAccessor>
677 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
678 DestIterator
id, DestAccessor ad,
double xfactor,
double yfactor)
680 int width_old = iend.x - is.x;
681 int height_old = iend.y - is.y;
687 int height_new = sizeForResamplingFactor(height_old, yfactor);
688 int width_new = sizeForResamplingFactor(width_old, xfactor);
690 vigra_precondition((width_old > 1) && (height_old > 1),
692 "Source image too small.\n");
693 vigra_precondition((width_new > 1) && (height_new > 1),
695 "Destination image too small.\n");
697 typedef typename SrcAccessor::value_type SRCVT;
698 typedef BasicImage<SRCVT> TmpImage;
699 typedef typename TmpImage::traverser TmpImageIterator;
701 BasicImage<SRCVT> tmp(width_old, height_new);
705 typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft();
707 for(x=0; x<width_old; ++x, ++is.x, ++yt.x)
709 typename SrcIterator::column_iterator c1 = is.columnIterator();
710 typename TmpImageIterator::column_iterator ct = yt.columnIterator();
711 resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor);
714 yt = tmp.upperLeft();
716 for(y=0; y < height_new; ++y, ++yt.y, ++
id.y)
718 typename DestIterator::row_iterator rd =
id.rowIterator();
719 typename TmpImageIterator::row_iterator rt = yt.rowIterator();
720 resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor);
725 template <
class SrcIterator,
class SrcAccessor,
726 class DestIterator,
class DestAccessor>
728 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
729 DestIterator
id, DestAccessor ad,
double factor)
734 template <
class SrcImageIterator,
class SrcAccessor,
735 class DestImageIterator,
class DestAccessor>
737 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
738 pair<DestImageIterator, DestAccessor> dest,
double factor)
740 resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor);
743 template <
class SrcImageIterator,
class SrcAccessor,
744 class DestImageIterator,
class DestAccessor>
746 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
747 pair<DestImageIterator, DestAccessor> dest,
double xfactor,
double yfactor)
749 resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor);
void transpose(const MultiArrayView< 2, T, C1 > &v, MultiArrayView< 2, T, C2 > &r)
Definition: matrix.hxx:963
void copyImage(...)
Copy source image into destination image.
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition: fixedpoint.hxx:675