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