From d329fb165d815fd2b78f5a8cb324b46d6c2479f9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 2 Oct 2013 10:16:46 +0100 Subject: [PATCH] im_ismonotonic() becomes a class --- ChangeLog | 4 +- TODO | 4 -- libvips/deprecated/vips7compat.c | 13 ++++++ libvips/histogram/Makefile.am | 3 +- libvips/histogram/hist_ismonotonic.c | 26 ++++++------ libvips/histogram/histogram.c | 8 ++-- .../histogram/{hist_percent.c => percent.c} | 40 +++++++++--------- libvips/histogram/tone.c | 42 ------------------- libvips/include/vips/histogram.h | 4 +- libvips/include/vips/vips7compat.h | 1 + 10 files changed, 59 insertions(+), 86 deletions(-) rename libvips/histogram/{hist_percent.c => percent.c} (78%) diff --git a/ChangeLog b/ChangeLog index 54eeaa12..c916f548 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,8 +5,8 @@ - rewrite im_buildlut(), im_identity*(), im_maplut(), im_falsecolour(), im_gammacorrect(), im_histgr(), im_histcum(), im_histnorm(), im_heq(), im_histnD(), im_histindexed(), im_histspec(), im_invertlut(), im_lhisteq(), - im_stdif(), im_project(), im_profile(), im_tone_build*(), im_mpercent*() - as classes + im_stdif(), im_project(), im_profile(), im_tone_build*(), im_mpercent*(), + im_ismonotonic() as classes - vips_hist_local(), vips_stdif() do any number of bands - thin vips8 wrapper for im_histplot() - added vips_error_freeze() / vips_error_thaw() diff --git a/TODO b/TODO index eed347b9..eb5eafd7 100644 --- a/TODO +++ b/TODO @@ -3,10 +3,6 @@ $ vips shrink wtc.png x.v 230 230 memory: high-water mark 322.13 MB -- finish hist_ismonotonic() - - needs im_conv() - - do conv and morph quickly as simple wrappers over the vips7 operations - with VIPS_ARRAY() etc., we could note the mem use on the object we alloc diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 062c2b06..5ab023a7 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -3397,6 +3397,19 @@ im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut ) return( 0 ); } +int +im_ismonotonic( IMAGE *lut, int *out ) +{ + gboolean monotonic; + + if( vips_hist_ismonotonic( lut, &monotonic, NULL ) ) + return( -1 ); + + *out = monotonic ? 255 : 0; + + return( 0 ); +} + int im_histcum( IMAGE *in, IMAGE *out ) { diff --git a/libvips/histogram/Makefile.am b/libvips/histogram/Makefile.am index 30a70359..33291d5e 100644 --- a/libvips/histogram/Makefile.am +++ b/libvips/histogram/Makefile.am @@ -12,7 +12,8 @@ libhistogram_la_SOURCES = \ hist_plot.c \ hist_match.c \ hist_local.c \ - hist_percent.c \ + percent.c \ + hist_ismonotonic.c \ stdif.c \ \ tone.c diff --git a/libvips/histogram/hist_ismonotonic.c b/libvips/histogram/hist_ismonotonic.c index 5ef2170d..b4782738 100644 --- a/libvips/histogram/hist_ismonotonic.c +++ b/libvips/histogram/hist_ismonotonic.c @@ -58,7 +58,7 @@ typedef struct _VipsHistIsmonotonic { VipsImage *in; - int *monotonic; + gboolean monotonic; } VipsHistIsmonotonic; typedef VipsOperationClass VipsHistIsmonotonicClass; @@ -73,6 +73,8 @@ vips_hist_ismonotonic_build( VipsObject *object ) VipsHistIsmonotonic *ismonotonic = (VipsHistIsmonotonic *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 ); + double m; + if( VIPS_OBJECT_CLASS( vips_hist_ismonotonic_parent_class )-> build( object ) ) return( -1 ); @@ -81,19 +83,19 @@ vips_hist_ismonotonic_build( VipsObject *object ) return( -1 ); if( ismonotonic->in->Xsize == 1 ) - t[0] = vips_image_new_matrixv( 1, 2, -1, 1 ); + t[0] = vips_image_new_matrixv( 1, 2, -1.0, 1.0 ); else - t[0] = vips_image_new_matrixv( 2, 1, -1, 1 ); + t[0] = vips_image_new_matrixv( 2, 1, -1.0, 1.0 ); vips_image_set_double( t[0], "offset", 128 ); /* We want >=128 everywhere, ie. no -ve transitions. */ - if( im_conv( lut, t[0], mask ) || - im_moreeqconst( t[0], t[1], 128 ) || - im_min( t[1], &m ) ) + if( vips_conv( ismonotonic->in, &t[1], t[0], NULL ) || + vips_moreeq_const1( t[1], &t[2], 128, NULL ) || + vips_min( t[2], &m, NULL ) ) return( -1 ); - *out = m; + g_object_set( ismonotonic, "monotonic", (int) m == 255, NULL ); return( 0 ); } @@ -113,16 +115,16 @@ vips_hist_ismonotonic_class_init( VipsHistIsmonotonicClass *class ) VIPS_ARG_IMAGE( class, "in", 1, _( "Input" ), - _( "Input image" ), + _( "Input histogram image" ), VIPS_ARGUMENT_REQUIRED_INPUT, G_STRUCT_OFFSET( VipsHistIsmonotonic, in ) ); - VIPS_ARG_INT( class, "monotonic", 2, + VIPS_ARG_BOOL( class, "monotonic", 2, _( "Monotonic" ), - _( "non-zero if in is monotonic" ), + _( "true if in is monotonic" ), VIPS_ARGUMENT_REQUIRED_OUTPUT, G_STRUCT_OFFSET( VipsHistIsmonotonic, monotonic ), - 0, 1, 0 ); + FALSE ); } @@ -132,7 +134,7 @@ vips_hist_ismonotonic_init( VipsHistIsmonotonic *ismonotonic ) } /** - * vips_ismonotonic: + * vips_hist_ismonotonic: * @in: lookup-table to test * @out: set non-zero if @in is monotonic * @...: %NULL-terminated list of optional named arguments diff --git a/libvips/histogram/histogram.c b/libvips/histogram/histogram.c index 6f99d5ea..a2c024ef 100644 --- a/libvips/histogram/histogram.c +++ b/libvips/histogram/histogram.c @@ -229,22 +229,24 @@ void vips_histogram_operation_init( void ) { extern GType vips_maplut_get_type( void ); + extern GType vips_percent_get_type( void ); extern GType vips_hist_cum_get_type( void ); extern GType vips_hist_norm_get_type( void ); extern GType vips_hist_equal_get_type( void ); extern GType vips_hist_plot_get_type( void ); extern GType vips_hist_match_get_type( void ); extern GType vips_hist_local_get_type( void ); - extern GType vips_hist_percent_get_type( void ); + extern GType vips_hist_ismonotonic_get_type( void ); extern GType vips_stdif_get_type( void ); vips_maplut_get_type(); + vips_percent_get_type(); + vips_stdif_get_type(); vips_hist_cum_get_type(); vips_hist_norm_get_type(); vips_hist_equal_get_type(); vips_hist_plot_get_type(); vips_hist_match_get_type(); vips_hist_local_get_type(); - vips_hist_percent_get_type(); - vips_stdif_get_type(); + vips_hist_ismonotonic_get_type(); } diff --git a/libvips/histogram/hist_percent.c b/libvips/histogram/percent.c similarity index 78% rename from libvips/histogram/hist_percent.c rename to libvips/histogram/percent.c index 2009ce24..b952904a 100644 --- a/libvips/histogram/hist_percent.c +++ b/libvips/histogram/percent.c @@ -54,28 +54,28 @@ #include -typedef struct _VipsHistPercent { +typedef struct _VipsPercent { VipsOperation parent_instance; VipsImage *in; double percent; int threshold; -} VipsHistPercent; +} VipsPercent; -typedef VipsOperationClass VipsHistPercentClass; +typedef VipsOperationClass VipsPercentClass; -G_DEFINE_TYPE( VipsHistPercent, vips_hist_percent, VIPS_TYPE_OPERATION ); +G_DEFINE_TYPE( VipsPercent, vips_percent, VIPS_TYPE_OPERATION ); static int -vips_hist_percent_build( VipsObject *object ) +vips_percent_build( VipsObject *object ) { - VipsHistPercent *percent = (VipsHistPercent *) object; + VipsPercent *percent = (VipsPercent *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 ); double threshold; - if( VIPS_OBJECT_CLASS( vips_hist_percent_parent_class )-> + if( VIPS_OBJECT_CLASS( vips_percent_parent_class )-> build( object ) ) return( -1 ); @@ -94,7 +94,7 @@ vips_hist_percent_build( VipsObject *object ) } static void -vips_hist_percent_class_init( VipsHistPercentClass *class ) +vips_percent_class_init( VipsPercentClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; @@ -102,34 +102,34 @@ vips_hist_percent_class_init( VipsHistPercentClass *class ) gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; - object_class->nickname = "hist_percent"; + object_class->nickname = "percent"; object_class->description = _( "find threshold for percent of pixels" ); - object_class->build = vips_hist_percent_build; + object_class->build = vips_percent_build; VIPS_ARG_IMAGE( class, "in", 1, _( "Input" ), _( "Input image" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsHistPercent, in ) ); + G_STRUCT_OFFSET( VipsPercent, in ) ); VIPS_ARG_DOUBLE( class, "percent", 2, _( "Percent" ), - _( "percent of pixels" ), + _( "Percent of pixels" ), VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsHistPercent, percent ), + G_STRUCT_OFFSET( VipsPercent, percent ), 0, 100, 50 ); VIPS_ARG_INT( class, "threshold", 3, - _( "threshold" ), - _( "threshold above which lie percent of pixels" ), + _( "Threshold" ), + _( "Threshold above which lie percent of pixels" ), VIPS_ARGUMENT_REQUIRED_OUTPUT, - G_STRUCT_OFFSET( VipsHistPercent, threshold ), + G_STRUCT_OFFSET( VipsPercent, threshold ), 0, 65535, 0 ); } static void -vips_hist_percent_init( VipsHistPercent *percent ) +vips_percent_init( VipsPercent *percent ) { } @@ -141,7 +141,7 @@ vips_hist_percent_init( VipsHistPercent *percent ) * @...: %NULL-terminated list of optional named arguments * * vips_percent() returns (through the @threshold parameter) the threshold - * above which there are @percent values of @in. If for example percent=.1, the + * above which there are @percent values of @in. If for example percent=10, the * number of pels of the input image with values greater than @threshold * will correspond to 10% of all pels of the image. * @@ -153,13 +153,13 @@ vips_hist_percent_init( VipsHistPercent *percent ) * Returns: 0 on success, -1 on error */ int -vips_hist_percent( VipsImage *in, double percent, int *threshold, ... ) +vips_percent( VipsImage *in, double percent, int *threshold, ... ) { va_list ap; int result; va_start( ap, threshold ); - result = vips_call_split( "hist_percent", ap, in, percent, threshold ); + result = vips_call_split( "percent", ap, in, percent, threshold ); va_end( ap ); return( result ); diff --git a/libvips/histogram/tone.c b/libvips/histogram/tone.c index 410fd2b0..2969406c 100644 --- a/libvips/histogram/tone.c +++ b/libvips/histogram/tone.c @@ -53,48 +53,6 @@ #include -/** - * im_ismonotonic: - * @lut: lookup-table to test - * @out: set non-zero if @lut is monotonic - * - * Test @lut for monotonicity. @out is set non-zero if @lut is monotonic. - * - * See also: im_tone_build_range(). - * - * Returns: 0 on success, -1 on error - */ -int -im_ismonotonic( IMAGE *lut, int *out ) -{ - IMAGE *t[2]; - INTMASK *mask; - double m; - - if( im_check_hist( "im_ismonotonic", lut ) || - im_open_local_array( lut, t, 2, "im_ismonotonic", "p" ) ) - return( -1 ); - - if( lut->Xsize == 1 ) - mask = im_create_imaskv( "im_ismonotonic", 1, 2, -1, 1 ); - else - mask = im_create_imaskv( "im_ismonotonic", 2, 1, -1, 1 ); - if( !(mask = im_local_imask( lut, mask )) ) - return( -1 ); - mask->offset = 128; - - /* We want >=128 everywhere, ie. no -ve transitions. - */ - if( im_conv( lut, t[0], mask ) || - im_moreeqconst( t[0], t[1], 128 ) || - im_min( t[1], &m ) ) - return( -1 ); - - *out = m; - - return( 0 ); -} - /** * im_tone_map: * @in: input image diff --git a/libvips/include/vips/histogram.h b/libvips/include/vips/histogram.h index cee11eef..f85ecba1 100644 --- a/libvips/include/vips/histogram.h +++ b/libvips/include/vips/histogram.h @@ -57,8 +57,8 @@ int vips_hist_percent( VipsImage *in, double percent, int *threshold, ... ) __attribute__((sentinel)); int vips_stdif( VipsImage *in, VipsImage **out, int width, int height, ... ) __attribute__((sentinel)); - -int im_ismonotonic( VipsImage *lut, int *out ); +int vips_hist_ismonotonic( VipsImage *in, int *monotonic, ... ) + __attribute__((sentinel)); int im_tone_analyse( VipsImage *in, VipsImage *out, double Ps, double Pm, double Ph, double S, double M, double H ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 2db3c4d8..2f9b293d 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -879,6 +879,7 @@ int im_stdif( VipsImage *in, VipsImage *out, double a, double m0, double b, double s0, int xwin, int ywin ); int im_mpercent( VipsImage *in, double percent, int *out ); int im_mpercent_hist( VipsImage *hist, double percent, int *out ); +int im_ismonotonic( VipsImage *lut, int *out ); /* Not really correct, but who uses these. */