diff --git a/ChangeLog b/ChangeLog index 36217b0e..aec48727 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,8 @@ - support tiff XMP metadata - support @density arg to magickload [Lovell] - support python3.4 and python2.7 in new python binding +- vips_gaussmat() and vips_logmat() are now int by default, to match + vips_conv(), and use @precision, not @integer 25/7/14 started 7.41.0 - start working on --disable-deprecated diff --git a/TODO b/TODO index 797bfee0..5dce5c3f 100644 --- a/TODO +++ b/TODO @@ -1,15 +1,3 @@ -- try: - - vips gaussmat m2.v 2 0.1 --separable - vips convsep k2.jpg x2.jpg m2.v - eog x2.jpg - - it's too bright ... because gaussmat makes a float mask by default, but - conv does an int convolution by default - - rather than an --integer switch on gaussmat, should it take --precision - instead, and default to INT, like conv? - - configure should check for pygobject too PKG_CHECK_MODULES(PYTHON, [pygobject-3.0 >= $PYGOBJECT_REQUIRED]) diff --git a/libvips/convolution/gaussblur.c b/libvips/convolution/gaussblur.c index d1bf2ac9..322b656c 100644 --- a/libvips/convolution/gaussblur.c +++ b/libvips/convolution/gaussblur.c @@ -75,7 +75,7 @@ vips_gaussblur_build( VipsObject *object ) if( vips_gaussmat( &t[0], gaussblur->sigma, gaussblur->min_ampl, "separable", TRUE, - "integer", gaussblur->precision != VIPS_PRECISION_FLOAT, + "precision", gaussblur->precision, NULL ) ) return( -1 ); diff --git a/libvips/convolution/sharpen.c b/libvips/convolution/sharpen.c index 0a2fc3fb..c4424c73 100644 --- a/libvips/convolution/sharpen.c +++ b/libvips/convolution/sharpen.c @@ -236,7 +236,7 @@ vips_sharpen_build( VipsObject *object ) */ if( vips_gaussmat( &t[1], 1 + sharpen->radius / 2, 0.2, "separable", TRUE, - "integer", TRUE, + "precision", VIPS_PRECISION_INTEGER, NULL ) ) return( -1 ); diff --git a/libvips/create/gaussmat.c b/libvips/create/gaussmat.c index 1b83f836..e0de1a9a 100644 --- a/libvips/create/gaussmat.c +++ b/libvips/create/gaussmat.c @@ -15,6 +15,9 @@ * - gtkdoc * 20/10/13 * - redone as a class + * 16/12/14 + * - default to int output to match vips_conv() + * - use @precision, not @integer */ /* @@ -69,7 +72,8 @@ typedef struct _VipsGaussmat { double min_ampl; gboolean separable; - gboolean integer; + gboolean integer; /* Deprecated */ + VipsPrecision precision; } VipsGaussmat; @@ -96,6 +100,13 @@ vips_gaussmat_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_gaussmat_parent_class )->build( object ) ) return( -1 ); + if( vips_object_argument_isset( object, "integer" ) ) + vips_warn( class->nickname, + "'integer' is deprecated, use 'precision' instead" ); + if( vips_check_precision_intfloat( class->nickname, + gaussmat->precision ) ) + return( -1 ); + /* Find the size of the mask. Limit the mask size to 10k x 10k for * sanity. */ @@ -129,7 +140,7 @@ vips_gaussmat_build( VipsObject *object ) double distance = xo * xo + yo * yo; double v = exp( -distance / sig2 ); - if( gaussmat->integer ) + if( gaussmat->precision == VIPS_PRECISION_INTEGER ) v = VIPS_RINT( 20 * v ); *VIPS_MATRIX( create->out, x, y ) = v; @@ -180,10 +191,17 @@ vips_gaussmat_class_init( VipsGaussmatClass *class ) VIPS_ARG_BOOL( class, "integer", 5, _( "Integer" ), _( "Generate integer Gaussian" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, G_STRUCT_OFFSET( VipsGaussmat, integer ), FALSE ); + VIPS_ARG_ENUM( class, "precision", 6, + _( "Precision" ), + _( "Generate with this precision" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsGaussmat, precision ), + VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER ); + } static void @@ -191,6 +209,7 @@ vips_gaussmat_init( VipsGaussmat *gaussmat ) { gaussmat->sigma = 1; gaussmat->min_ampl = 0.1; + gaussmat->precision = VIPS_PRECISION_INTEGER; } /** @@ -203,7 +222,7 @@ vips_gaussmat_init( VipsGaussmat *gaussmat ) * Optional arguments: * * @separable: generate a separable gaussian - * @integer: generate an integer gaussian + * @precision: #VipsPrecision for @out * * Creates a circularly symmetric Gaussian image of radius * @sigma. The size of the mask is determined by the variable @min_ampl; @@ -215,13 +234,13 @@ vips_gaussmat_init( VipsGaussmat *gaussmat ) * H(r) = exp( -(r * r) / (2 * @sigma * @sigma) ) * * The generated image has odd size and its maximum value is normalised to - * 1.0, unless @integer is set. + * 1.0, unless @precision is #VIPS_PRECISION_INTEGER. * * If @separable is set, only the centre horizontal is generated. This is * useful for separable convolutions. * - * If @integer is set, an integer gaussian is generated. This is useful for - * integer convolutions. + * If @precision is #VIPS_PRECISION_INTEGER, an integer gaussian is generated. + * This is useful for integer convolutions. * * "scale" is set to the sum of all the mask elements. * diff --git a/libvips/create/logmat.c b/libvips/create/logmat.c index 09bcb6ef..087060c8 100644 --- a/libvips/create/logmat.c +++ b/libvips/create/logmat.c @@ -14,6 +14,9 @@ * - gtkdoc * 20/10/13 * - redone as a class from logmat.c + * 16/12/14 + * - default to int output to match vips_conv() + * - use @precision, not @integer */ /* @@ -68,7 +71,8 @@ typedef struct _VipsLogmat { double min_ampl; gboolean separable; - gboolean integer; + gboolean integer; /* Deprecated */ + VipsPrecision precision; } VipsLogmat; @@ -95,6 +99,13 @@ vips_logmat_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_logmat_parent_class )->build( object ) ) return( -1 ); + if( vips_object_argument_isset( object, "integer" ) ) + vips_warn( class->nickname, + "'integer' is deprecated, use 'precision' instead" ); + if( vips_check_precision_intfloat( class->nickname, + logmat->precision ) ) + return( -1 ); + /* Find the size of the mask. We want to eval the mask out to the * flat zero part, ie. beyond the minimum and to the point where it * comes back up towards zero. @@ -153,7 +164,7 @@ vips_logmat_build( VipsObject *object ) (2.0 - (distance / sig2)) * exp( -distance / (2.0 * sig2) ); - if( logmat->integer ) + if( logmat->precision == VIPS_PRECISION_INTEGER ) v = VIPS_RINT( 20 * v ); *VIPS_MATRIX( create->out, x, y ) = v; @@ -204,10 +215,17 @@ vips_logmat_class_init( VipsLogmatClass *class ) VIPS_ARG_BOOL( class, "integer", 5, _( "Integer" ), _( "Generate integer Logmatian" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, G_STRUCT_OFFSET( VipsLogmat, integer ), FALSE ); + VIPS_ARG_ENUM( class, "precision", 6, + _( "Precision" ), + _( "Generate with this precision" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsLogmat, precision ), + VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER ); + } static void @@ -215,6 +233,7 @@ vips_logmat_init( VipsLogmat *logmat ) { logmat->sigma = 1; logmat->min_ampl = 0.1; + logmat->precision = VIPS_PRECISION_INTEGER; } /** @@ -226,8 +245,8 @@ vips_logmat_init( VipsLogmat *logmat ) * * Optional arguments: * - * @separable: generate a separable logmatian - * @integer: generate an integer logmatian + * @separable: generate a separable mask + * @precision: #VipsPrecision for @out * * Creates a circularly symmetric Laplacian of Gaussian mask * of radius @@ -246,13 +265,13 @@ vips_logmat_init( VipsLogmat *logmat ) * where s2 = @sigma * @sigma, s4 = s2 * s2, r2 = r * r. * * The generated mask has odd size and its maximum value is normalised to - * 1.0, unless @integer is set. + * 1.0, unless @precision is #VIPS_PRECISION_INTEGER. * * If @separable is set, only the centre horizontal is generated. This is * useful for separable convolutions. * - * If @integer is set, an integer logmatian is generated. This is useful for - * integer convolutions. + * If @precision is #VIPS_PRECISION_INTEGER, an integer mask is generated. + * This is useful for integer convolutions. * * "scale" is set to the sum of all the mask elements. * diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 4e432db0..75ec4ad8 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -2169,6 +2169,7 @@ im_gauss_dmask( const char *filename, double sigma, double min_ampl ) DOUBLEMASK *msk; if( vips_gaussmat( &t, sigma, min_ampl, + "precision", VIPS_PRECISION_FLOAT, NULL ) ) return( NULL ); if( !(msk = im_vips2mask( t, filename )) ) { @@ -2187,6 +2188,7 @@ im_gauss_dmask_sep( const char *filename, double sigma, double min_ampl ) DOUBLEMASK *msk; if( vips_gaussmat( &t, sigma, min_ampl, + "precision", VIPS_PRECISION_FLOAT, "separable", TRUE, NULL ) ) return( NULL ); @@ -2205,9 +2207,7 @@ im_gauss_imask( const char *filename, double sigma, double min_ampl ) VipsImage *t; INTMASK *msk; - if( vips_gaussmat( &t, sigma, min_ampl, - "integer", TRUE, - NULL ) ) + if( vips_gaussmat( &t, sigma, min_ampl, NULL ) ) return( NULL ); if( !(msk = im_vips2imask( t, filename )) ) { g_object_unref( t ); @@ -2225,7 +2225,6 @@ im_gauss_imask_sep( const char *filename, double sigma, double min_ampl ) INTMASK *msk; if( vips_gaussmat( &t, sigma, min_ampl, - "integer", TRUE, "separable", TRUE, NULL ) ) return( NULL ); @@ -2244,9 +2243,7 @@ im_log_imask( const char *filename, double sigma, double min_ampl ) VipsImage *t; INTMASK *msk; - if( vips_logmat( &t, sigma, min_ampl, - "integer", TRUE, - NULL ) ) + if( vips_logmat( &t, sigma, min_ampl, NULL ) ) return( NULL ); if( !(msk = im_vips2imask( t, filename )) ) { g_object_unref( t ); @@ -2264,6 +2261,7 @@ im_log_dmask( const char *filename, double sigma, double min_ampl ) DOUBLEMASK *msk; if( vips_logmat( &t, sigma, min_ampl, + "precision", VIPS_PRECISION_FLOAT, NULL ) ) return( NULL ); if( !(msk = im_vips2mask( t, filename )) ) { diff --git a/libvips/include/vips/Makefile.am b/libvips/include/vips/Makefile.am index 0f264c6a..ddaf6cc2 100644 --- a/libvips/include/vips/Makefile.am +++ b/libvips/include/vips/Makefile.am @@ -69,6 +69,7 @@ vips_scan_headers = \ ${top_srcdir}/libvips/include/vips/convolution.h \ ${top_srcdir}/libvips/include/vips/morphology.h \ ${top_srcdir}/libvips/include/vips/draw.h \ + ${top_srcdir}/libvips/include/vips/basic.h \ ${top_srcdir}/libvips/include/vips/object.h enumtypes.h: $(vips_scan_headers) Makefile diff --git a/libvips/include/vips/basic.h b/libvips/include/vips/basic.h index 633f4f31..8f846531 100644 --- a/libvips/include/vips/basic.h +++ b/libvips/include/vips/basic.h @@ -59,6 +59,13 @@ typedef void *(*VipsSListMap4Fn)( void *item, typedef void *(*VipsSListFold2Fn)( void *item, void *a, void *b, void *c ); +typedef enum { + VIPS_PRECISION_INTEGER, + VIPS_PRECISION_FLOAT, + VIPS_PRECISION_APPROXIMATE, + VIPS_PRECISION_LAST +} VipsPrecision; + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/convolution.h b/libvips/include/vips/convolution.h index f2685542..1240301e 100644 --- a/libvips/include/vips/convolution.h +++ b/libvips/include/vips/convolution.h @@ -38,13 +38,6 @@ extern "C" { #endif /*__cplusplus*/ -typedef enum { - VIPS_PRECISION_INTEGER, - VIPS_PRECISION_FLOAT, - VIPS_PRECISION_APPROXIMATE, - VIPS_PRECISION_LAST -} VipsPrecision; - typedef enum { VIPS_COMBINE_MAX, VIPS_COMBINE_SUM, diff --git a/libvips/include/vips/enumtypes.h b/libvips/include/vips/enumtypes.h index 251d387f..37380972 100644 --- a/libvips/include/vips/enumtypes.h +++ b/libvips/include/vips/enumtypes.h @@ -78,8 +78,6 @@ GType vips_pcs_get_type (void) G_GNUC_CONST; GType vips_operation_flags_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_OPERATION_FLAGS (vips_operation_flags_get_type()) /* enumerations from "../../../libvips/include/vips/convolution.h" */ -GType vips_precision_get_type (void) G_GNUC_CONST; -#define VIPS_TYPE_PRECISION (vips_precision_get_type()) GType vips_combine_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_COMBINE (vips_combine_get_type()) /* enumerations from "../../../libvips/include/vips/morphology.h" */ @@ -88,6 +86,9 @@ GType vips_operation_morphology_get_type (void) G_GNUC_CONST; /* enumerations from "../../../libvips/include/vips/draw.h" */ GType vips_combine_mode_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_COMBINE_MODE (vips_combine_mode_get_type()) +/* enumerations from "../../../libvips/include/vips/basic.h" */ +GType vips_precision_get_type (void) G_GNUC_CONST; +#define VIPS_TYPE_PRECISION (vips_precision_get_type()) /* enumerations from "../../../libvips/include/vips/object.h" */ GType vips_argument_flags_get_type (void) G_GNUC_CONST; #define VIPS_TYPE_ARGUMENT_FLAGS (vips_argument_flags_get_type()) diff --git a/libvips/include/vips/error.h b/libvips/include/vips/error.h index d445eb0c..d7699e9d 100644 --- a/libvips/include/vips/error.h +++ b/libvips/include/vips/error.h @@ -73,6 +73,7 @@ int vips_check_bands_1orn( const char *domain, VipsImage *im1, VipsImage *im2 ); int vips_check_bands_1orn_unary( const char *domain, VipsImage *im, int n ); int vips_check_bands_same( const char *domain, VipsImage *im1, VipsImage *im2 ); int vips_check_bandno( const char *domain, VipsImage *im, int bandno ); + int vips_check_int( const char *domain, VipsImage *im ); int vips_check_uint( const char *domain, VipsImage *im ); int vips_check_uintorf( const char *domain, VipsImage *im ); @@ -91,6 +92,9 @@ int vips_check_hist( const char *domain, VipsImage *im ); int vips_check_matrix( const char *domain, VipsImage *im, VipsImage **out ); int vips_check_separable( const char *domain, VipsImage *im ); +int vips_check_precision_intfloat( const char *domain, + VipsPrecision precision ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/iofuncs/Makefile.am b/libvips/iofuncs/Makefile.am index 9cc0c7bf..d0d32998 100644 --- a/libvips/iofuncs/Makefile.am +++ b/libvips/iofuncs/Makefile.am @@ -66,6 +66,7 @@ vips_scan_headers = \ ${top_srcdir}/libvips/include/vips/convolution.h \ ${top_srcdir}/libvips/include/vips/morphology.h \ ${top_srcdir}/libvips/include/vips/draw.h \ + ${top_srcdir}/libvips/include/vips/basic.h \ ${top_srcdir}/libvips/include/vips/object.h enumtypes.c: $(vips_scan_headers) Makefile diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index e182bfc8..540f49c4 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -674,25 +674,6 @@ vips_operation_flags_get_type( void ) } /* enumerations from "../../libvips/include/vips/convolution.h" */ GType -vips_precision_get_type( void ) -{ - static GType etype = 0; - - if( etype == 0 ) { - static const GEnumValue values[] = { - {VIPS_PRECISION_INTEGER, "VIPS_PRECISION_INTEGER", "integer"}, - {VIPS_PRECISION_FLOAT, "VIPS_PRECISION_FLOAT", "float"}, - {VIPS_PRECISION_APPROXIMATE, "VIPS_PRECISION_APPROXIMATE", "approximate"}, - {VIPS_PRECISION_LAST, "VIPS_PRECISION_LAST", "last"}, - {0, NULL, NULL} - }; - - etype = g_enum_register_static( "VipsPrecision", values ); - } - - return( etype ); -} -GType vips_combine_get_type( void ) { static GType etype = 0; @@ -748,6 +729,26 @@ vips_combine_mode_get_type( void ) return( etype ); } +/* enumerations from "../../libvips/include/vips/basic.h" */ +GType +vips_precision_get_type( void ) +{ + static GType etype = 0; + + if( etype == 0 ) { + static const GEnumValue values[] = { + {VIPS_PRECISION_INTEGER, "VIPS_PRECISION_INTEGER", "integer"}, + {VIPS_PRECISION_FLOAT, "VIPS_PRECISION_FLOAT", "float"}, + {VIPS_PRECISION_APPROXIMATE, "VIPS_PRECISION_APPROXIMATE", "approximate"}, + {VIPS_PRECISION_LAST, "VIPS_PRECISION_LAST", "last"}, + {0, NULL, NULL} + }; + + etype = g_enum_register_static( "VipsPrecision", values ); + } + + return( etype ); +} /* enumerations from "../../libvips/include/vips/object.h" */ GType vips_argument_flags_get_type( void ) diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index 6df5f743..15e879ef 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -1317,3 +1317,29 @@ vips_check_separable( const char *domain, VipsImage *im ) return( 0 ); } + +/** + * vips_check_precision_intfloat: + * @domain: the originating domain for the error message + * @precision: precision to check + * + * Check that @prec image is either float or int. + * If not, set an error message + * and return non-zero. + * + * See also: vips_error(). + * + * Returns: 0 on OK, or -1 on error. + */ +int +vips_check_precision_intfloat( const char *domain, VipsPrecision precision ) +{ + if( precision != VIPS_PRECISION_INTEGER && + precision != VIPS_PRECISION_FLOAT ) { + vips_error( domain, + "%s", _( "precision must be int or float" ) ); + return( -1 ); + } + + return( 0 ); +}