#include "ruby_vips.h" #include "image.h" #include "interpolator.h" #include "header.h" #include "image_resample.h" /* * call-seq: * im.affinei(interpolator, a, b, c, d, dx, dy) -> image * im.affinei(interpolator, a, b, c, d, dx, dy, ox, oy, ow, oh) -> image * * Applies an affine transformation on *self*. *self* many have any number of * bands, be any size, and have any non-complex type. * * The transformation is described by a, b, c, d, * dx, dy. The point (x,y) in * the input is mapped onto point (X,Y) in the output by * * X = a * x + b * y + dx * Y = c * x + d * y + dy * * In the first form, the entire image is transformed. In the second form, the * area of the output image given by ow, oh, ox, oy * is generated. (0,0) is the position of the transformed top-left-hand corner * of the input image. * * Points are generated using the supplied interpolator. */ VALUE img_affinei(int argc, VALUE *argv, VALUE obj) { VALUE interpolator, a, b, c, d, dx, dy, ox, oy, ow, oh; VipsInterpolate *itrp_vips; rb_scan_args(argc, argv, "74", &interpolator, &a, &b, &c, &d, &dx, &dy, &ox, &oy, &ow, &oh); itrp_vips = interp_lookup(interpolator); GetImg(obj, data, im); OutImg(obj, new, data_new, im_new); if (NIL_P(ox)) { if (im_affinei_all(im, im_new, itrp_vips, NUM2DBL(a), NUM2DBL(b), NUM2DBL(c), NUM2DBL(d), NUM2DBL(dx), NUM2DBL(dy))) vips_lib_error(); } else { if (NIL_P(oh)) rb_raise(rb_eArgError, "If you supply any output parameters, you have to supply them all"); if (im_affinei(im, im_new, itrp_vips, NUM2DBL(a), NUM2DBL(b), NUM2DBL(c), NUM2DBL(d), NUM2DBL(dx), NUM2DBL(dy), NUM2INT(ox), NUM2INT(oy), NUM2INT(ow), NUM2INT(oh))) vips_lib_error(); } return new; } /* * call-seq: * im.affinei_resize(interpolator, x [,y]) -> image * * Applies an affine resize using the supplied interpolator. If y is * ommitted then the aspect ratio of *self* will be maintained. */ VALUE img_affinei_resize(int argc, VALUE *argv, VALUE obj) { VALUE interpolator, x_scale, y_scale; VipsInterpolate *itrp_vips; rb_scan_args(argc, argv, "21", &interpolator, &x_scale, &y_scale); GetImg(obj, data, im); OutImg(obj, new, data_new, im_new); itrp_vips = interp_lookup(interpolator); if (NIL_P(y_scale)) y_scale = x_scale; if (im_affinei_all(im, im_new, itrp_vips, NUM2DBL(x_scale), 0, 0, NUM2DBL(y_scale), 0, 0)) vips_lib_error(); return new; } /* * call-seq: * im.stretch3(dx [,dy]) -> image * * Stretches the input image by 3% horizontally, and displaces it by * dx/dy. It uses bi-cubic interpolation, but runs quickly. It * works only for unsigned short images. * * This function is part of the MARC acquisition software, but is generally * useful for squaring up the pixels in images from the Kontron ProgRes camera * range. */ VALUE img_stretch3(int argc, VALUE *argv, VALUE obj) { VALUE dx, dy; rb_scan_args(argc, argv, "11", &dx, &dy); if (NIL_P(dy)) dy = dx; GetImg(obj, data, im); OutImg(obj, new, data_new, im_new); if (im_stretch3(im, im_new, NUM2DBL(dx), NUM2DBL(dy))) vips_lib_error(); return new; } /* * call-seq: * im.shrink(width_ratio [,height_ratio]) -> image * * Shrink *self* by width_ratio along the horizontal and * height_ratio along the vertical direction. If height_ratio is * not given, it uses width_ratio. The function does not perform * subpixel interpolation and therefore the resultant image can present * aliasing especially for small x and y factors. Any size image, any * non-complex type, any number of bands. */ VALUE img_shrink(int argc, VALUE *argv, VALUE obj) { VALUE width_ratio, height_ratio; rb_scan_args(argc, argv, "11", &width_ratio, &height_ratio); if (NIL_P(height_ratio)) height_ratio = width_ratio; GetImg(obj, data, im); OutImg(obj, new, data_new, im_new); if (im_shrink(im, im_new, NUM2DBL(width_ratio), NUM2DBL(height_ratio))) vips_lib_error(); return new; } /* * call-seq: * im.rightshift_size(xshift, yshift, fmt) -> image * * Decreases the size of an integer type image by a power-of-two factor, very * quickly, by summing the values of adjacent pixels. The sum is shifted to * produce output of the specified band format. * * xshift and yshift are positive and give the base-two * logarithms of the scale factors. * * If the input image is a signed type, then the band format must be one of * :CHAR, :SHORT or :INT. If it is an unsigned type, then the band format must * be one of :UCHAR, :USHORT or :UINT. */ VALUE img_rightshift_size(VALUE obj, VALUE xshift, VALUE yshift, VALUE fmt) { GetImg(obj, data, im); OutImg(obj, new, data_new, im_new); if(im_rightshift_size(im, im_new, NUM2DBL(xshift), NUM2DBL(yshift), header_id_to_band_fmt(SYM2ID(fmt)))) vips_lib_error(); return new; } /* * call-seq: * im.match_linear(other_image, xr1, yr1, xs1, ys1, xr2, yr2, xs2, * ys2) -> image * * Works exactly as Image#match_linear_search, but does not attempt to * correlate to correct your tie points. It can thus be used for any angle and * any scale, but you must be far more careful in your selection. */ VALUE img_match_linear(VALUE obj, VALUE obj2, VALUE xr1, VALUE yr1, VALUE xs1, VALUE ys1, VALUE xr2, VALUE yr2, VALUE xs2, VALUE ys2) { GetImg(obj, data, im); GetImg(obj2, data2, im2); OutImg(obj, new, data_new, im_new); if (im_match_linear(im, im2, im_new, NUM2INT(xr1), NUM2INT(yr1), NUM2INT(xs1), NUM2INT(ys1), NUM2INT(xr2), NUM2INT(yr2), NUM2INT(xs2), NUM2INT(ys2))) vips_lib_error(); return new; } /* * call-seq: * im.match_linear_search(other_image, xr1, yr1, xs1, ys1, xr2, yr2, xs2, * ys2, hwindowsize, hsearchsize) -> image * * Attempts to transform sec to make it match ref. The transformation is * linear, that is, it only involves scale, rotate and translate. * * Requires a pair of tie points to fix the parameters of its transformation. * You should pick points as far apart as possible to increase accuracy. It * will search the area in the image around each tie point for a good fit, so * your selection of points need not be exact. WARNING! This searching process * will fail for rotations of more than about 10 degrees or for scales of more * than about 10 percent. * * The best you can hope for is < 1 pixel error, since the command does not * attempt sub-pixel correlation. * * hwindowsize and hsearchsize set the size of the area to be * searched: we recommend values of 5 and 14. * * The output image is positioned and clipped so that you can immediately * subtract it from orig to obtain pixel difference images. */ VALUE img_match_linear_search(VALUE obj, VALUE obj2, VALUE xr1, VALUE yr1, VALUE xs1, VALUE ys1, VALUE xr2, VALUE yr2, VALUE xs2, VALUE ys2, VALUE hwindowsize, VALUE hsearchsize) { GetImg(obj, data, im); GetImg(obj2, data2, im2); OutImg(obj, new, data_new, im_new); if (im_match_linear_search(im, im2, im_new, NUM2INT(xr1), NUM2INT(yr1), NUM2INT(xs1), NUM2INT(ys1), NUM2INT(xr2), NUM2INT(yr2), NUM2INT(xs2), NUM2INT(ys2), NUM2INT(hwindowsize), NUM2INT(hsearchsize))) vips_lib_error(); return new; }