From f18a3ccdc74fb0a566bd20858b33b86a15ffafd2 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 30 Oct 2009 18:39:58 +0000 Subject: [PATCH] added im__colour_binary --- ChangeLog | 1 + libvips/arithmetic/im_add.c | 13 ++--- libvips/colour/derived.c | 10 ++-- libvips/colour/im_dE00_fromLab.c | 85 +++++++++++++++++++------------- libvips/include/vips/check.h | 5 +- libvips/include/vips/internal.h | 3 ++ libvips/iofuncs/check.c | 73 ++++++++++++++++++--------- 7 files changed, 118 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ca6f68f..ee4e70d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -69,6 +69,7 @@ - added im_copy_file() - added im_insertplaceset() - im_insertplace() allows small to be outside big +- added im__colour_binary(), colour ops now work on any image format 25/3/09 started 7.18.0 - revised version numbers diff --git a/libvips/arithmetic/im_add.c b/libvips/arithmetic/im_add.c index 64a3f102..f94372a9 100644 --- a/libvips/arithmetic/im_add.c +++ b/libvips/arithmetic/im_add.c @@ -240,12 +240,12 @@ im__bandalike( IMAGE *in1, IMAGE *in2, IMAGE *out1, IMAGE *out2 ) * - check in and out * - cast in1 and in2 up to a common format * - cast the common format to the output format with the supplied table - * - equalise bands and size + * - equalise bands * - run the supplied buffer operation passing one of the up-banded, * up-casted and up-sized inputs as the first param */ int -im__arith_binary( const char *name, +im__arith_binary( const char *domain, IMAGE *in1, IMAGE *in2, IMAGE *out, int format_table[10], im_wrapmany_fn fn, void *b ) @@ -254,14 +254,15 @@ im__arith_binary( const char *name, if( im_piocheck( in1, out ) || im_pincheck( in2 ) || - im_check_bands_1orn( name, in1, in2 ) || - im_check_uncoded( name, in1 ) || - im_check_uncoded( name, in2 ) ) + im_check_bands_1orn( domain, in1, in2 ) || + im_check_same_size( domain, in1, in2 ) || + im_check_uncoded( domain, in1 ) || + im_check_uncoded( domain, in2 ) ) return( -1 ); /* Cast our input images up to a common format and bands. */ - if( im_open_local_array( out, t, 4, "im__arith_binary", "p" ) || + if( im_open_local_array( out, t, 4, domain, "p" ) || im__formatalike( in1, in2, t[0], t[1] ) || im__bandalike( t[0], t[1], t[2], t[3] ) ) return( -1 ); diff --git a/libvips/colour/derived.c b/libvips/colour/derived.c index e5c88814..a7158230 100644 --- a/libvips/colour/derived.c +++ b/libvips/colour/derived.c @@ -95,7 +95,6 @@ im_Lab2UCS( IMAGE *in, IMAGE *out ) return( 0 ); } - /** * im_UCS2Lab: * @in: input image @@ -212,7 +211,8 @@ im_sRGB2XYZ( IMAGE *in, IMAGE *out ) /** * im_dE_fromXYZ: - * @in: input image + * @in1: first input image + * @in2: second input image * @out: output image * * Calculate CIELAB dE 1976 from a pair of XYZ images. @@ -220,13 +220,13 @@ im_sRGB2XYZ( IMAGE *in, IMAGE *out ) * Returns: 0 on success, -1 on error. */ int -im_dE_fromXYZ( IMAGE *im1, IMAGE *im2, IMAGE *out ) +im_dE_fromXYZ( IMAGE *in1, IMAGE *in2, IMAGE *out ) { IMAGE *t[2]; if( im_open_local_array( out, t, 2, "im_dE_fromXYZ:1", "p" ) || - im_XYZ2Lab( im1, t[0] ) || - im_XYZ2Lab( im2, t[1] ) || + im_XYZ2Lab( in1, t[0] ) || + im_XYZ2Lab( in2, t[1] ) || im_dE_fromLab( t[0], t[1], out ) ) return( -1 ); diff --git a/libvips/colour/im_dE00_fromLab.c b/libvips/colour/im_dE00_fromLab.c index 3345b514..ce760e49 100644 --- a/libvips/colour/im_dE00_fromLab.c +++ b/libvips/colour/im_dE00_fromLab.c @@ -1,14 +1,10 @@ -/* @(#) Calculate dE00 from two Lab images - * @(#) - * @(#) Usage: - * @(#) im_dE00_fromLab( im1, im2, im_out ) - * @(#) IMAGE *im1, *im2, *im_out; - * @(#) - * @(#) float out. - * @(#) - * @(#) Returns: -1 on error, else 0 +/* im_dE00_fromLab.c + * * 10/10/02 JC * - from dECMC + * 30/10/09 + * - add im__colour_binary() and use it + * - gtkdoc comment */ /* @@ -51,6 +47,36 @@ #include #endif /*WITH_DMALLOC*/ +/* An n-input colour operation. Cast the inputs to three-band float and call. + */ +int +im__colour_binary( const char *domain, + IMAGE *in1, IMAGE *in2, int bands, IMAGE *out, + im_wrapmany_fn buffer_fn, void *a, void *b ) +{ + IMAGE *t[3]; + + if( im_check_uncoded( domain, in1 ) || + im_check_uncoded( domain, in2 ) || + im_check_bands( domain, in1, 3 ) || + im_check_bands( domain, in2, 3 ) || + im_check_same_size( domain, in1, in2 ) || + im_open_local_array( out, t, 2, domain, "p" ) || + im_clip2fmt( in1, t[0], IM_BANDFMT_FLOAT ) || + im_clip2fmt( in2, t[1], IM_BANDFMT_FLOAT ) ) + return( -1 ); + + if( im_cp_descv( out, t[0], t[1], NULL ) ) + return( -1 ); + out->Bands = bands; + + t[2] = NULL; + if( im_wrapmany( t, out, buffer_fn, a, b ) ) + return( -1 ); + + return( 0 ); +} + /* Process a buffer. */ void @@ -75,36 +101,25 @@ imb_dE00_fromLab( float **p, float *q, int n ) } } +/** + * im_dE00_fromLab: + * @in1: first input image + * @in2: second input image + * @out: output image + * + * Calculate CIE dE00 from two Lab images. + * + * Returns: 0 on success, -1 on error. + */ int -im_dE00_fromLab( IMAGE *im1, IMAGE *im2, IMAGE *out ) +im_dE00_fromLab( IMAGE *in1, IMAGE *in2, IMAGE *out ) { - IMAGE *invec[3]; - - /* Check input types. - */ - if( im1->Bands != 3 || im1->BandFmt != IM_BANDFMT_FLOAT || - im1->Coding != IM_CODING_NONE || - im2->Bands != 3 || im2->BandFmt != IM_BANDFMT_FLOAT || - im2->Coding != IM_CODING_NONE ) { - im_error( "im_dE00_fromLab", "%s", _( "3-band float only" ) ); - return( -1 ); - } - - /* Prepare the output image - */ - if( im_cp_descv( out, im1, im2, NULL ) ) - return( -1 ); - out->Bbits = IM_BBITS_FLOAT; - out->Bands = 1; - out->BandFmt = IM_BANDFMT_FLOAT; - out->Type = IM_TYPE_B_W; - - /* Do the processing. - */ - invec[0] = im1; invec[1] = im2; invec[2] = NULL; - if( im_wrapmany( invec, out, + if( im__colour_binary( "im_dE00_fromLab", + in1, in2, 1, out, (im_wrapmany_fn) imb_dE00_fromLab, NULL, NULL ) ) return( -1 ); + out->Type = IM_TYPE_B_W; + return( 0 ); } diff --git a/libvips/include/vips/check.h b/libvips/include/vips/check.h index 85a96e42..3026846e 100644 --- a/libvips/include/vips/check.h +++ b/libvips/include/vips/check.h @@ -46,12 +46,13 @@ int im_poutcheck( IMAGE *im ); int im_check_uncoded( const char *domain, IMAGE *im ); int im_check_known_coded( const char *domain, IMAGE *im ); +int im_check_mono( const char *domain, IMAGE *im ); +int im_check_bands( const char *domain, IMAGE *im, int bands ); int im_check_bands_1orn( const char *domain, IMAGE *im1, IMAGE *im2 ); +int im_check_int( const char *domain, IMAGE *im ); int im_check_noncomplex( const char *domain, IMAGE *im ); int im_check_complex( const char *domain, IMAGE *im ); int im_check_format( const char *domain, IMAGE *im, VipsBandFmt fmt ); -int im_check_mono( const char *domain, IMAGE *im ); -int im_check_int( const char *domain, IMAGE *im ); int im_check_u8or16( const char *domain, IMAGE *im ); int im_check_same_size( const char *domain, IMAGE *im1, IMAGE *im2 ); int im_check_same_bands( const char *domain, IMAGE *im1, IMAGE *im2 ); diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 74446477..7c70006a 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -163,6 +163,9 @@ typedef int (*im__wrapscan_fn)( void *p, int n, void *seq, void *a, void *b ); int im__wrapscan( IMAGE *in, im_start_fn start, im__wrapscan_fn scan, im_stop_fn stop, void *a, void *b ); +int im__colour_binary( const char *domain, + IMAGE *in1, IMAGE *in2, int bands, IMAGE *out, + im_wrapmany_fn buffer_fn, void *a, void *b ); int im__test_kill( IMAGE *im ); void *im__mmap( int fd, int writeable, size_t length, gint64 offset ); diff --git a/libvips/iofuncs/check.c b/libvips/iofuncs/check.c index 5c888bed..6814ee28 100644 --- a/libvips/iofuncs/check.c +++ b/libvips/iofuncs/check.c @@ -586,6 +586,55 @@ im_check_known_coded( const char *domain, IMAGE *im ) return( 0 ); } +/** + * im_check_mono: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image has exactly one band. + * Otherwise set an error message + * and return non-zero. + * + * See also: im_error(). + * + * Returns: 0 if OK, -1 otherwise. + */ +int +im_check_mono( const char *domain, IMAGE *im ) +{ + if( im->Bands != 1 ) { + im_error( domain, "%s", _( "image must one band" ) ); + return( -1 ); + } + + return( 0 ); +} + +/** + * im_check_bands: + * @domain: the originating domain for the error message + * @im: image to check + * @bands: must have this many bands + * + * Check that the image has @bands bands. + * Otherwise set an error message + * and return non-zero. + * + * See also: im_error(). + * + * Returns: 0 if OK, -1 otherwise. + */ +int +im_check_bands( const char *domain, IMAGE *im, int bands ) +{ + if( im->Bands != bands ) { + im_error( domain, _( "image must %d bands" ), bands ); + return( -1 ); + } + + return( 0 ); +} + /** * im_check_bands_1orn: * @domain: the originating domain for the error message @@ -689,30 +738,6 @@ im_check_format( const char *domain, IMAGE *im, VipsBandFmt fmt ) return( 0 ); } -/** - * im_check_mono: - * @domain: the originating domain for the error message - * @im: image to check - * - * Check that the image has exactly one band. - * Otherwise set an error message - * and return non-zero. - * - * See also: im_error(). - * - * Returns: 0 if OK, -1 otherwise. - */ -int -im_check_mono( const char *domain, IMAGE *im ) -{ - if( im->Bands != 1 ) { - im_error( domain, "%s", _( "image must one band" ) ); - return( -1 ); - } - - return( 0 ); -} - /** * im_check_int: * @domain: the originating domain for the error message