diff --git a/ChangeLog b/ChangeLog index 387b53d2..0dae0f96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,8 @@ thanks Lovell - im_tone_map() and im_tone_analyse() deprecated - new --band arg to vips_maplut() replaces im_tone_map() functionality +- added vips_similarity(), simple wrapper for vips_affine() that lets you + give a scale and rotate 3/7/13 started 7.34.2 - lower priority for Matlab load to reduce segvs from Mat_Open(), thanks diff --git a/libvips/convolution/conv.c b/libvips/convolution/conv.c index ff4ce882..759b91b8 100644 --- a/libvips/convolution/conv.c +++ b/libvips/convolution/conv.c @@ -1,27 +1,7 @@ -/* histogram cumulativisation +/* convolution * - * Author: N. Dessipris - * Written on: 02/08/1990 - * 24/5/95 JC - * - tidied up and ANSIfied - * 20/7/95 JC - * - smartened up again - * - now works for hists >256 elements - * 3/3/01 JC - * - broken into cum and norm ... helps im_histspec() - * - better behaviour for >8 bit hists - * 31/10/05 JC - * - was broken for vertical histograms, gah - * - neater im_histnorm() - * 23/7/07 - * - eek, off by 1 for more than 1 band hists - * 12/5/08 - * - histcum works for signed hists now as well - * 24/3/10 - * - gtkdoc - * - small cleanups * 12/8/13 - * - redone im_histcum() as a class, vips_conv() + * - from vips_hist_cum() */ /* @@ -51,6 +31,11 @@ */ +/* This is a simple wrapper over the old vips7 functions. At some point we + * should rewrite this as a pure vips8 class and redo the vips7 functions as + * wrappers over this. + */ + #ifdef HAVE_CONFIG_H #include #endif /*HAVE_CONFIG_H*/ diff --git a/libvips/include/vips/resample.h b/libvips/include/vips/resample.h index 6f94dadc..e692952c 100644 --- a/libvips/include/vips/resample.h +++ b/libvips/include/vips/resample.h @@ -41,6 +41,8 @@ extern "C" { int vips_shrink( VipsImage *in, VipsImage **out, double xshrink, double yshrink, ... ) __attribute__((sentinel)); +int vips_similarity( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); int vips_affine( VipsImage *in, VipsImage **out, double a, double b, double c, double d, ... ) __attribute__((sentinel)); diff --git a/libvips/resample/Makefile.am b/libvips/resample/Makefile.am index 4831c471..c0e61caf 100644 --- a/libvips/resample/Makefile.am +++ b/libvips/resample/Makefile.am @@ -8,6 +8,7 @@ libresample_la_SOURCES = \ affine.c \ quadratic.c \ resample.c \ + similarity.c \ presample.h \ shrink.c \ interpolate.c \ @@ -22,6 +23,7 @@ else libresample_la_SOURCES = \ resample.c \ + similarity.c \ presample.h \ shrink.c \ affine.c \ diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index 5fc9ea8f..76789ba6 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -398,7 +398,7 @@ vips_affine_build( VipsObject *object ) affine->oarea->n, 4 ) ) return( -1 ); - if( !vips_object_argument_isset( object, "interpolate" ) ) + if( !affine->interpolate ) affine->interpolate = vips_interpolate_new( "bilinear" ); in = resample->in; @@ -443,11 +443,9 @@ vips_affine_build( VipsObject *object ) if( vips__transform_calc_inverse( &affine->trn ) ) return( -1 ); - - /* + if( vips__transform_isidentity( &affine->trn ) ) return( vips_image_write( in, resample->out ) ); - */ /* Check for coordinate overflow ... we want to be able to hold the * output space inside INT_MAX / TRANSFORM_SCALE. diff --git a/libvips/resample/resample.c b/libvips/resample/resample.c index dcdecbd8..f6718feb 100644 --- a/libvips/resample/resample.c +++ b/libvips/resample/resample.c @@ -114,9 +114,11 @@ vips_resample_operation_init( void ) extern GType vips_shrink_get_type( void ); extern GType vips_quadratic_get_type( void ); extern GType vips_affine_get_type( void ); + extern GType vips_similarity_get_type( void ); vips_shrink_get_type(); vips_quadratic_get_type(); vips_affine_get_type(); + vips_similarity_get_type(); } diff --git a/libvips/resample/similarity.c b/libvips/resample/similarity.c new file mode 100644 index 00000000..bffc2ba4 --- /dev/null +++ b/libvips/resample/similarity.c @@ -0,0 +1,201 @@ +/* simple wrapper over vips_similarity() to make scale / rotate easy from the + * command-line + * + * 3/10/13 + * - from similarity.c + */ + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +/* +#define DEBUG + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include + +#include + +#include "presample.h" + +typedef struct _VipsSimilarity { + VipsResample parent_instance; + + double scale; + double angle; + VipsInterpolate *interpolate; + double odx; + double ody; + double idx; + double idy; + +} VipsSimilarity; + +typedef VipsResampleClass VipsSimilarityClass; + +G_DEFINE_TYPE( VipsSimilarity, vips_similarity, VIPS_TYPE_RESAMPLE ); + +static int +vips_similarity_build( VipsObject *object ) +{ + VipsResample *resample = VIPS_RESAMPLE( object ); + VipsSimilarity *similarity = (VipsSimilarity *) object; + + VipsImage **t = (VipsImage **) + vips_object_local_array( object, 4 ); + + double a, b, c, d; + + if( VIPS_OBJECT_CLASS( vips_similarity_parent_class )->build( object ) ) + return( -1 ); + + a = similarity->scale * cos( VIPS_RAD( similarity->angle ) ); + b = sin( VIPS_RAD( similarity->angle ) ); + c = -b; + d = a; + + if( vips_affine( resample->in, &t[0], a, b, c, d, + "interpolate", similarity->interpolate, + "odx", similarity->odx, + "ody", similarity->ody, + "idx", similarity->idx, + "idy", similarity->idy, + NULL ) || + vips_image_write( t[0], resample->out ) ) + return( -1 ); + + return( 0 ); +} + +static void +vips_similarity_class_init( VipsSimilarityClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + vobject_class->nickname = "similarity"; + vobject_class->description = _( "similarity transform of an image" ); + vobject_class->build = vips_similarity_build; + + VIPS_ARG_DOUBLE( class, "scale", 3, + _( "Scale" ), + _( "Scale by this factor" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSimilarity, scale ), + 0, 10000000, 1 ); + + VIPS_ARG_DOUBLE( class, "angle", 4, + _( "Angle" ), + _( "Rotate anticlockwise by this many degrees" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSimilarity, angle ), + -10000000, 10000000, 0 ); + + VIPS_ARG_INTERPOLATE( class, "interpolate", 2, + _( "Interpolate" ), + _( "Interpolate pixels with this" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSimilarity, interpolate ) ); + + VIPS_ARG_DOUBLE( class, "odx", 112, + _( "Output offset" ), + _( "Horizontal output displacement" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSimilarity, odx ), + -10000000, 10000000, 0 ); + + VIPS_ARG_DOUBLE( class, "ody", 113, + _( "Output offset" ), + _( "Vertical output displacement" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSimilarity, ody ), + -10000000, 10000000, 0 ); + + VIPS_ARG_DOUBLE( class, "idx", 114, + _( "Input offset" ), + _( "Horizontal input displacement" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSimilarity, idx ), + -10000000, 10000000, 0 ); + + VIPS_ARG_DOUBLE( class, "idy", 115, + _( "Input offset" ), + _( "Vertical input displacement" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsSimilarity, idy ), + -10000000, 10000000, 0 ); +} + +static void +vips_similarity_init( VipsSimilarity *similarity ) +{ + similarity->scale = 1; +} + +/** + * vips_similarity: + * @in: input image + * @out: output image + * + * Optional arguments: + * + * @scale: scale by this factor + * @angle: rotate by this many degrees anticlockwise + * @interpolate: interpolate pixels with this + * @idx: input horizontal offset + * @idy: input vertical offset + * @odx: output horizontal offset + * @ody: output vertical offset + * + * This operator calls vips_affine() for you, calculating the matrix for the + * affine transform from @scale and @angle. Other parameters are passed on to + * vips_affine() unaltered. + * + * See also: vips_affine(), #VipsInterpolate. + * + * Returns: 0 on success, -1 on error + */ +int +vips_similarity( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "similarity", ap, in, out ); + va_end( ap ); + + return( result ); +}