36 #ifndef VIGRA_BASICGEOMETRY_HXX
37 #define VIGRA_BASICGEOMETRY_HXX
40 #include "stdimage.hxx"
41 #include "copyimage.hxx"
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};
272 template <
class SrcIterator,
class SrcAccessor,
273 class DestIterator,
class DestAccessor>
274 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
275 DestIterator
id, DestAccessor ad, Reflect reflect)
278 int ws = end.x - is.x;
279 int hs = end.y - is.y;
283 if(reflect == horizontal)
286 for(x=0; x<ws; ++x, ++is.x, ++
id.x)
288 typename SrcIterator::column_iterator cs = is.columnIterator();
289 typename DestIterator::column_iterator cd =
id.columnIterator();
290 for(y=0; y!=hs;y++, cs--, cd++)
296 else if(reflect == vertical)
299 for(x=0; x < ws; ++x, --is.x, ++
id.x)
302 typename SrcIterator::column_iterator cs = is.columnIterator();
303 typename DestIterator::column_iterator cd =
id.columnIterator();
304 for(y=0; y!=hs;y++, cs++, cd++)
310 else if(reflect == (horizontal | vertical))
314 for(x=0; x != ws; x++, end.x--,
id.x++)
316 typename SrcIterator::column_iterator cs = end.columnIterator();
317 typename DestIterator::column_iterator cd =
id.columnIterator();
318 for(y=0; y != hs; y++, cs--, cd++)
325 vigra_fail(
"reflectImage(): "
326 "This function reflects horizontal or vertical,"
327 " 'and' is included");
330 template <
class SrcImageIterator,
class SrcAccessor,
331 class DestImageIterator,
class DestAccessor>
333 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
334 pair<DestImageIterator, DestAccessor> dest, Reflect reflect)
336 reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect);
346 enum Transpose{major = 1, minor = 2};
419 template <
class SrcIterator,
class SrcAccessor,
420 class DestIterator,
class DestAccessor>
421 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
422 DestIterator
id, DestAccessor ad, Transpose
transpose)
424 int ws = end.x - is.x;
425 int hs = end.y - is.y;
429 if(transpose == major)
431 for(x=0; x != ws; x++, is.x++,
id.y++)
434 typename SrcIterator::column_iterator cs = is.columnIterator();
435 typename DestIterator::row_iterator rd =
id.rowIterator();
436 for(y=0; y != hs; y++, cs++, rd++)
442 else if(transpose == minor)
446 for(x=0; x != ws; x++, --end.x, ++
id.y)
449 typename SrcIterator::column_iterator cs = end.columnIterator();
450 typename DestIterator::row_iterator rd =
id.rowIterator();
451 for(y=0; y != hs; y++, --cs, ++rd)
457 else if(transpose == (major | minor))
461 for(x=0; x != ws; x++, end.x--,
id.x++)
463 typename SrcIterator::column_iterator cs = end.columnIterator();
464 typename DestIterator::column_iterator cd =
id.columnIterator();
465 for(y=0; y != hs; y++, cs--, cd++)
473 vigra_fail(
"transposeImage(): "
474 "This function transposes major or minor,"
475 " 'and' is included");
479 template <
class SrcImageIterator,
class SrcAccessor,
480 class DestImageIterator,
class DestAccessor>
482 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
483 pair<DestImageIterator, DestAccessor> dest, Transpose transpose)
485 transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose);
506 template <
class SrcIterator,
class SrcAccessor,
507 class DestIterator,
class DestAccessor>
508 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
509 DestIterator dest_iter, DestAccessor dest_acc,
double factor)
512 int src_width = src_iter_end - src_iter;
514 vigra_precondition(src_width > 0,
515 "resampleLine(): input image too small.");
516 vigra_precondition(factor > 0.0,
517 "resampleLine(): factor must be positive.");
521 int int_factor = (int)factor;
522 double dx = factor - int_factor;
524 for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx)
528 saver = saver - (int)saver;
529 dest_acc.set(src_acc(src_iter), dest_iter);
532 for(
int i = 0 ; i < int_factor ; i++, ++dest_iter)
534 dest_acc.set(src_acc(src_iter), dest_iter);
540 DestIterator dest_end = dest_iter + (int)
VIGRA_CSTD::ceil(src_width*factor);
542 int int_factor = (int)factor;
543 double dx = factor - int_factor;
546 for ( ; src_iter != src_iter_end && dest_iter != dest_end ;
547 ++dest_iter, src_iter += int_factor, saver += dx)
551 saver = saver - (int)saver;
554 dest_acc.set(src_acc(src_iter), dest_iter);
556 if (dest_iter != dest_end)
558 dest_acc.set(src_acc(src_iter_end), dest_iter);
563 inline int sizeForResamplingFactor(
int oldsize,
double factor)
565 return (factor < 1.0)
567 : (int)(oldsize * factor);
668 template <
class SrcIterator,
class SrcAccessor,
669 class DestIterator,
class DestAccessor>
671 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
672 DestIterator
id, DestAccessor ad,
double xfactor,
double yfactor)
674 int width_old = iend.x - is.x;
675 int height_old = iend.y - is.y;
681 int height_new = sizeForResamplingFactor(height_old, yfactor);
682 int width_new = sizeForResamplingFactor(width_old, xfactor);
684 vigra_precondition((width_old > 1) && (height_old > 1),
686 "Source image to small.\n");
687 vigra_precondition((width_new > 1) && (height_new > 1),
689 "Destination image to small.\n");
691 typedef typename SrcAccessor::value_type SRCVT;
692 typedef BasicImage<SRCVT> TmpImage;
693 typedef typename TmpImage::traverser TmpImageIterator;
695 BasicImage<SRCVT> tmp(width_old, height_new);
699 typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft();
701 for(x=0; x<width_old; ++x, ++is.x, ++yt.x)
703 typename SrcIterator::column_iterator c1 = is.columnIterator();
704 typename TmpImageIterator::column_iterator ct = yt.columnIterator();
705 resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor);
708 yt = tmp.upperLeft();
710 for(y=0; y < height_new; ++y, ++yt.y, ++
id.y)
712 typename DestIterator::row_iterator rd =
id.rowIterator();
713 typename TmpImageIterator::row_iterator rt = yt.rowIterator();
714 resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor);
719 template <
class SrcIterator,
class SrcAccessor,
720 class DestIterator,
class DestAccessor>
722 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
723 DestIterator
id, DestAccessor ad,
double factor)
728 template <
class SrcImageIterator,
class SrcAccessor,
729 class DestImageIterator,
class DestAccessor>
731 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
732 pair<DestImageIterator, DestAccessor> dest,
double factor)
734 resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor);
737 template <
class SrcImageIterator,
class SrcAccessor,
738 class DestImageIterator,
class DestAccessor>
740 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
741 pair<DestImageIterator, DestAccessor> dest,
double xfactor,
double yfactor)
743 resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor);