From 7130a74d0e88524154cff6de76ddcdbd0cf5a854 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 20 Sep 2012 15:13:44 +0100 Subject: [PATCH] redo rad2float / float2rad as classes --- ChangeLog | 3 +- TODO | 11 +- libvips/colour/Makefile.am | 6 +- libvips/colour/XYZ2Yxy.c | 2 + libvips/colour/Yxy2XYZ.c | 2 + libvips/colour/colour.c | 164 ++++++++++++++++-- libvips/colour/colour.h | 56 +++++- libvips/colour/colour_funcs.c | 26 --- .../colour/{im_float2rad.c => float2rad.c} | 72 +++++--- .../colour/{im_rad2float.c => rad2float.c} | 59 +++++-- libvips/deprecated/rename.c | 18 ++ libvips/deprecated/vips7compat.c | 32 ++++ libvips/include/vips/colour.h | 2 - libvips/include/vips/error.h | 5 +- libvips/include/vips/vips7compat.h | 6 + libvips/iofuncs/error.c | 53 ++---- 16 files changed, 382 insertions(+), 135 deletions(-) rename libvips/colour/{im_float2rad.c => float2rad.c} (81%) rename libvips/colour/{im_rad2float.c => rad2float.c} (81%) diff --git a/ChangeLog b/ChangeLog index d48bf2f0..1bfb7523 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 31/8/12 started 7.31.0 - redone im_Lab2XYZ(), im_XYZ2Lab(), im_Lab2LCh(), im_LCh2Lab(), im_UCS2LCh, - im_LCh2UCS(), im_XYZ2Yxy(), im_Yxy2XYZ() as classes + im_LCh2UCS(), im_XYZ2Yxy(), im_Yxy2XYZ(), im_float2rad(), im_rad2float() + as classes 13/9/12 started 7.30.3 - linecache sized itself too large diff --git a/TODO b/TODO index 5289ff14..bd8cd700 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,13 @@ -- see comment on make_CI() -- investigate +- boolean.c has - add l:c args + vips_check_noncomplex( "VipsBoolean", binary->left ) ) + + why not + + vips_check_noncomplex( VIPS_OBJECT_GET_CLASS( object )->nickname, + binary->left ) + + many other places too - can we make DOUBLE ARRAY args easier from C? diff --git a/libvips/colour/Makefile.am b/libvips/colour/Makefile.am index c4c498ca..2323cc1f 100644 --- a/libvips/colour/Makefile.am +++ b/libvips/colour/Makefile.am @@ -14,6 +14,8 @@ libcolour_la_SOURCES = \ XYZ2Lab.c \ XYZ2Yxy.c \ Yxy2XYZ.c \ + float2rad.c \ + rad2float.c \ im_icc_transform.c \ im_Lab2LabQ.c \ im_Lab2LabS.c \ @@ -23,12 +25,10 @@ libcolour_la_SOURCES = \ im_LabS2LabQ.c \ im_LabS2Lab.c \ im_lab_morph.c \ - im_float2rad.c \ im_XYZ2disp.c \ im_dE00_fromLab.c \ im_dECMC_fromLab.c \ im_dE_fromLab.c \ - im_disp2XYZ.c \ - im_rad2float.c + im_disp2XYZ.c INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@ diff --git a/libvips/colour/XYZ2Yxy.c b/libvips/colour/XYZ2Yxy.c index 02575c46..d8b4f504 100644 --- a/libvips/colour/XYZ2Yxy.c +++ b/libvips/colour/XYZ2Yxy.c @@ -6,6 +6,8 @@ * 2/11/09 * - gtkdoc * - cleanups + * 20/9/12 + * redo as a class */ /* diff --git a/libvips/colour/Yxy2XYZ.c b/libvips/colour/Yxy2XYZ.c index 70b12692..3f656bdd 100644 --- a/libvips/colour/Yxy2XYZ.c +++ b/libvips/colour/Yxy2XYZ.c @@ -6,6 +6,8 @@ * 2/11/09 * - gtkdoc * - cleanups + * 20/9/12 + * redo as a class */ /* diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index 47c92c7e..cd351866 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -116,7 +116,10 @@ vips_colour_build( VipsObject *object ) return( -1 ); vips_demand_hint_array( colour->out, VIPS_DEMAND_STYLE_THINSTRIP, colour->in ); + colour->out->Coding = class->coding; colour->out->Type = class->interpretation; + colour->out->BandFmt = class->format; + colour->out->Bands = class->bands; if( vips_image_generate( colour->out, vips_start_many, vips_colour_gen, vips_stop_many, @@ -142,7 +145,10 @@ vips_colour_class_init( VipsColourClass *class ) operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + class->coding = VIPS_CODING_NONE; class->interpretation = VIPS_INTERPRETATION_sRGB; + class->format = VIPS_FORMAT_UCHAR; + class->bands = 3; VIPS_ARG_IMAGE( class, "out", 100, _( "Output" ), @@ -156,52 +162,61 @@ vips_colour_init( VipsColour *colour ) { } -G_DEFINE_ABSTRACT_TYPE( VipsColourSpace, vips_space, VIPS_TYPE_COLOUR ); +G_DEFINE_ABSTRACT_TYPE( VipsColourSpace, vips_colour_space, VIPS_TYPE_COLOUR ); static int -vips_space_build( VipsObject *object ) +vips_colour_space_build( VipsObject *object ) { VipsColour *colour = VIPS_COLOUR( object ); VipsColourSpace *space = VIPS_COLOUR_SPACE( object ); VipsImage **t; + VipsImage *in; + VipsImage *extra; t = (VipsImage **) vips_object_local_array( object, 4 ); - colour->n = 1; - colour->in = (VipsImage **) vips_object_local_array( object, 1 ); + in = space->in; + extra = NULL; /* We only process float. */ - if( vips_cast_float( space->in, &t[0], NULL ) ) + if( vips_cast_float( in, &t[0], NULL ) ) return( -1 ); - colour->in[0] = t[0]; + in = t[0]; /* If there are more than n bands, process just the first three and * reattach the rest after. This lets us handle RGBA etc. */ - if( t[0]->Bands > 3 ) { - if( vips_extract_band( t[0], &t[1], 0, "n", 3, NULL ) || - vips_extract_band( t[0], &t[2], 0, - "n", t[0]->Bands - 3, NULL ) ) + if( in->Bands > 3 ) { + if( vips_extract_band( in, &t[1], 0, "n", 3, NULL ) || + vips_extract_band( in, &t[2], 3, + "n", in->Bands - 3, NULL ) ) return( -1 ); - colour->in[0] = t[1]; + in = t[1]; + extra = t[2]; } + else if( vips_check_bands_atleast( + VIPS_OBJECT_GET_CLASS( object )->nickname, in, 3 ) ) + return( -1 ); + colour->n = 1; + colour->in = (VipsImage **) vips_object_local_array( object, 1 ); + colour->in[0] = in; if( colour->in[0] ) g_object_ref( colour->in[0] ); - if( VIPS_OBJECT_CLASS( vips_space_parent_class )-> + if( VIPS_OBJECT_CLASS( vips_colour_space_parent_class )-> build( object ) ) return( -1 ); /* Reattach higher bands, if necessary. */ - if( t[0]->Bands > 3 ) { + if( extra ) { VipsImage *x; - if( vips_bandjoin2( colour->out, t[2], &x, NULL ) ) + if( vips_bandjoin2( colour->out, extra, &x, NULL ) ) return( -1 ); VIPS_UNREF( colour->out ); @@ -213,17 +228,23 @@ vips_space_build( VipsObject *object ) } static void -vips_space_class_init( VipsColourSpaceClass *class ) +vips_colour_space_class_init( VipsColourSpaceClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + VipsColourClass *colour_class = VIPS_COLOUR_CLASS( class ); gobject_class->set_property = vips_object_set_property; gobject_class->get_property = vips_object_get_property; vobject_class->nickname = "space"; vobject_class->description = _( "colour space transformations" ); - vobject_class->build = vips_space_build; + vobject_class->build = vips_colour_space_build; + + colour_class->coding = VIPS_CODING_NONE; + colour_class->interpretation = VIPS_INTERPRETATION_sRGB; + colour_class->format = VIPS_FORMAT_FLOAT; + colour_class->bands = 3; VIPS_ARG_IMAGE( class, "in", 1, _( "Input" ), @@ -233,7 +254,116 @@ vips_space_class_init( VipsColourSpaceClass *class ) } static void -vips_space_init( VipsColourSpace *space ) +vips_colour_space_init( VipsColourSpace *space ) +{ +} + +G_DEFINE_ABSTRACT_TYPE( VipsColourCode, vips_colour_code, VIPS_TYPE_COLOUR ); + +static int +vips_colour_code_build( VipsObject *object ) +{ + VipsColour *colour = VIPS_COLOUR( object ); + VipsColourCode *code = VIPS_COLOUR_CODE( object ); + VipsColourCodeClass *class = VIPS_COLOUR_CODE_GET_CLASS( object ); + VipsColourClass *colour_class = VIPS_COLOUR_CLASS( class ); + + VipsImage **t; + VipsImage *in; + VipsImage *extra; + + t = (VipsImage **) vips_object_local_array( object, 4 ); + + in = code->in; + extra = NULL; + + if( in && + vips_check_coding( VIPS_OBJECT_CLASS( class )->nickname, + in, class->input_coding ) ) + return( -1 ); + + /* Extra band processing. don't do automatic detach/reattach if either + * input or output will be coded. + */ + if( in && + class->input_coding == VIPS_CODING_NONE && + colour_class->coding == VIPS_CODING_NONE && + class->input_bands > 0 ) { + if( in->Bands > class->input_bands ) { + if( vips_extract_band( in, &t[1], 0, + "n", class->input_bands, NULL ) ) + return( -1 ); + if( vips_extract_band( in, &t[2], class->input_bands, + "n", in->Bands - class->input_bands, + NULL ) ) + return( -1 ); + in = t[1]; + extra = t[2]; + } + else if( vips_check_bands_atleast( + VIPS_OBJECT_CLASS( class )->nickname, + in, class->input_bands ) ) + return( -1 ); + } + + if( in && + class->input_coding == VIPS_CODING_NONE && + class->input_format != VIPS_FORMAT_NOTSET ) { + if( vips_cast( in, &t[3], class->input_format, NULL ) ) + return( -1 ); + in = t[3]; + } + + colour->n = 1; + colour->in = (VipsImage **) vips_object_local_array( object, 1 ); + colour->in[0] = in; + if( colour->in[0] ) + g_object_ref( colour->in[0] ); + + if( VIPS_OBJECT_CLASS( vips_colour_space_parent_class )-> + build( object ) ) + return( -1 ); + + /* Reattach higher bands, if necessary. + */ + if( extra ) { + VipsImage *x; + + if( vips_bandjoin2( colour->out, extra, &x, NULL ) ) + return( -1 ); + + VIPS_UNREF( colour->out ); + + colour->out = x; + } + + return( 0 ); +} + +static void +vips_colour_code_class_init( VipsColourCodeClass *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 = "code"; + vobject_class->description = _( "change colour coding" ); + vobject_class->build = vips_colour_code_build; + + class->input_coding = VIPS_CODING_ERROR; + + VIPS_ARG_IMAGE( class, "in", 1, + _( "Input" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsColourCode, in ) ); +} + +static void +vips_colour_code_init( VipsColourCode *code ) { } diff --git a/libvips/colour/colour.h b/libvips/colour/colour.h index 8abba81f..6922a019 100644 --- a/libvips/colour/colour.h +++ b/libvips/colour/colour.h @@ -78,17 +78,20 @@ typedef struct _VipsColourClass { */ VipsColourProcessFn process_line; - /* What to set Type to for this subclass. + /* Set fields on ->out from these. */ + VipsCoding coding; VipsInterpretation interpretation; + VipsBandFormat format; + int bands; } VipsColourClass; GType vips_colour_get_type( void ); -/* A three float bands in, three float bands out colourspace transformation. +/* A float in, float out colourspace transformation. */ -#define VIPS_TYPE_COLOUR_SPACE (vips_space_get_type()) +#define VIPS_TYPE_COLOUR_SPACE (vips_colour_space_get_type()) #define VIPS_COLOUR_SPACE( obj ) \ (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ VIPS_TYPE_COLOUR_SPACE, VipsColourSpace )) @@ -115,7 +118,52 @@ typedef struct _VipsColourSpaceClass { } VipsColourSpaceClass; -GType vips_space_get_type( void ); +GType vips_colour_space_get_type( void ); + +/* Change colour encoding ... either in or out is not three-band float. + */ + +#define VIPS_TYPE_COLOUR_CODE (vips_colour_code_get_type()) +#define VIPS_COLOUR_CODE( obj ) \ + (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ + VIPS_TYPE_COLOUR_CODE, VipsColourCode )) +#define VIPS_COLOUR_CODE_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_CAST( (klass), \ + VIPS_TYPE_COLOUR_CODE, VipsColourCodeClass)) +#define VIPS_IS_COLOUR_CODE( obj ) \ + (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_COLOUR_CODE )) +#define VIPS_IS_COLOUR_CODE_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_COLOUR_CODE )) +#define VIPS_COLOUR_CODE_GET_CLASS( obj ) \ + (G_TYPE_INSTANCE_GET_CLASS( (obj), \ + VIPS_TYPE_COLOUR_CODE, VipsColourCodeClass )) + +typedef struct _VipsColourCode { + VipsColour parent_instance; + + VipsImage *in; + +} VipsColourCode; + +typedef struct _VipsColourCodeClass { + VipsColourClass parent_class; + + /* Input must be in this coding. + */ + VipsCoding input_coding; + + /* If set, cast input to this. + */ + VipsBandFormat input_format; + + /* If >0, the number of bands we process. Extra bands are removed and + * reattached to the output, if it's uncoded. + */ + int input_bands; + +} VipsColourCodeClass; + +GType vips_colour_code_get_type( void ); #ifdef __cplusplus } diff --git a/libvips/colour/colour_funcs.c b/libvips/colour/colour_funcs.c index 7b689af1..f34bc77f 100644 --- a/libvips/colour/colour_funcs.c +++ b/libvips/colour/colour_funcs.c @@ -308,19 +308,6 @@ vips_LabQ2disp( VipsImage *in, VipsImage **out, return( result ); } -int -vips_rad2float( VipsImage *in, VipsImage **out, ... ) -{ - va_list ap; - int result; - - va_start( ap, out ); - result = vips_call_split( "im_rad2float", ap, in, out ); - va_end( ap ); - - return( result ); -} - int vips_argb2rgba( VipsImage *in, VipsImage **out, ... ) { @@ -334,19 +321,6 @@ vips_argb2rgba( VipsImage *in, VipsImage **out, ... ) return( result ); } -int -vips_float2rad( VipsImage *in, VipsImage **out, ... ) -{ - va_list ap; - int result; - - va_start( ap, out ); - result = vips_call_split( "im_float2rad", ap, in, out ); - va_end( ap ); - - return( result ); -} - int vips_LabS2LabQ( VipsImage *in, VipsImage **out, ... ) { diff --git a/libvips/colour/im_float2rad.c b/libvips/colour/float2rad.c similarity index 81% rename from libvips/colour/im_float2rad.c rename to libvips/colour/float2rad.c index d9882d73..5e92acb4 100644 --- a/libvips/colour/im_float2rad.c +++ b/libvips/colour/float2rad.c @@ -4,6 +4,8 @@ * - from im_rad2float and Radiance sources * 2/11/09 * - gtkdoc + * 20/9/12 + * redo as a class */ /* @@ -106,6 +108,8 @@ #include +#include "colour.h" + /* Begin copy-paste from Radiance sources. */ @@ -162,25 +166,56 @@ setcolr( COLR clr, double r, double g, double b ) /* assign a short co clr[EXP] = e + COLXS; } - - - /* End copy-paste from Radiance sources. */ +typedef VipsColourCode VipsFloat2rad; +typedef VipsColourCodeClass VipsFloat2radClass; + +G_DEFINE_TYPE( VipsFloat2rad, vips_float2rad, VIPS_TYPE_COLOUR_CODE ); static void -float2rad( COLOR *inp, COLR *outbuf, int n ) +vips_float2rad_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) { - while (n-- > 0) { + COLOR *inp = (COLOR *) in[0]; + COLR *outbuf = (COLR *) out; + + while( width-- > 0 ) { setcolr( outbuf[0], inp[0][RED], inp[0][GRN], inp[0][BLU] ); inp++; outbuf++; } } +static void +vips_float2rad_class_init( VipsFloat2radClass *class ) +{ + VipsObjectClass *object_class = (VipsObjectClass *) class; + VipsColourClass *colour_class = VIPS_COLOUR_CLASS( class ); + VipsColourCodeClass *code_class = VIPS_COLOUR_CODE_CLASS( class ); + + object_class->nickname = "float2rad"; + object_class->description = + _( "transform float RGB to Radiance coding" ); + + colour_class->process_line = vips_float2rad_line; + colour_class->coding = VIPS_CODING_RAD; + colour_class->interpretation = VIPS_INTERPRETATION_sRGB; + colour_class->format = VIPS_FORMAT_UCHAR; + colour_class->bands = 4; + + code_class->input_coding = VIPS_CODING_NONE; + code_class->input_format = VIPS_FORMAT_FLOAT; + code_class->input_bands = 3; +} + +static void +vips_float2rad_init( VipsFloat2rad *float2rad ) +{ +} + /** - * im_float2rad: + * vips_float2rad: * @in: input image * @out: output image * @@ -191,25 +226,14 @@ float2rad( COLOR *inp, COLR *outbuf, int n ) * Returns: 0 on success, -1 on error. */ int -im_float2rad( IMAGE *in, IMAGE *out ) +vips_float2rad( VipsImage *in, VipsImage **out, ... ) { - IMAGE *t[1]; + va_list ap; + int result; - if( im_check_uncoded( "im_float2rad", in ) || - im_check_bands( "im_float2rad", in, 3 ) || - im_open_local_array( out, t, 1, "im_float2rad", "p" ) || - im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ) - return( -1 ); + va_start( ap, out ); + result = vips_call_split( "float2rad", ap, in, out ); + va_end( ap ); - if( im_cp_desc( out, t[0] ) ) - return( -1 ); - out->Bands = 4; - out->BandFmt = IM_BANDFMT_UCHAR; - out->Coding = IM_CODING_RAD; - - if( im_wrapone( t[0], out, - (im_wrapone_fn) float2rad, NULL, NULL ) ) - return( -1 ); - - return( 0 ); + return( result ); } diff --git a/libvips/colour/im_rad2float.c b/libvips/colour/rad2float.c similarity index 81% rename from libvips/colour/im_rad2float.c rename to libvips/colour/rad2float.c index f63be113..a1989b32 100644 --- a/libvips/colour/im_rad2float.c +++ b/libvips/colour/rad2float.c @@ -3,6 +3,8 @@ * - from LabQ2Lab and Radiance sources * 2/11/09 * - gtkdoc + * 20/9/12 + * redo as a class */ /* @@ -105,6 +107,8 @@ #include +#include "colour.h" + /* Begin copy-paste from Radiance sources. */ @@ -148,12 +152,19 @@ register COLR clr; /* End copy-paste from Radiance sources. */ +typedef VipsColourCode VipsRad2float; +typedef VipsColourCodeClass VipsRad2floatClass; + +G_DEFINE_TYPE( VipsRad2float, vips_rad2float, VIPS_TYPE_COLOUR_CODE ); static void -rad2float( COLR *inp, COLOR *outbuf, int n ) +vips_rad2float_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ) { + COLOR *inp = (COLOR *) in[0]; + COLR *outbuf = (COLR *) out; + colr_color(outbuf[0], inp[0]); - while (--n > 0) { + while (--width > 0) { outbuf++; inp++; if (inp[0][RED] == inp[-1][RED] && inp[0][GRN] == inp[-1][GRN] && @@ -165,9 +176,33 @@ rad2float( COLR *inp, COLOR *outbuf, int n ) } } +static void +vips_rad2float_class_init( VipsRad2floatClass *class ) +{ + VipsObjectClass *object_class = (VipsObjectClass *) class; + VipsColourClass *colour_class = VIPS_COLOUR_CLASS( class ); + VipsColourCodeClass *code_class = VIPS_COLOUR_CODE_CLASS( class ); + + object_class->nickname = "rad2float"; + object_class->description = + _( "unpack Radiance coding to float RGB" ); + + colour_class->process_line = vips_rad2float_line; + colour_class->coding = VIPS_CODING_NONE; + colour_class->interpretation = VIPS_INTERPRETATION_sRGB; + colour_class->format = VIPS_FORMAT_FLOAT; + colour_class->bands = 3; + + code_class->input_coding = VIPS_CODING_RAD; +} + +static void +vips_rad2float_init( VipsRad2float *rad2float ) +{ +} /** - * im_rad2float: + * vips_rad2float: * @in: input image * @out: output image * @@ -178,18 +213,14 @@ rad2float( COLR *inp, COLOR *outbuf, int n ) * Returns: 0 on success, -1 on error. */ int -im_rad2float( IMAGE *in, IMAGE *out ) +vips_rad2float( VipsImage *in, VipsImage **out, ... ) { - if( vips_check_coding_rad( "argb2rgba", in ) || - im_cp_desc( out, in ) ) - return( -1 ); - out->Bands = 3; - out->BandFmt = IM_BANDFMT_FLOAT; - out->Coding = IM_CODING_NONE; + va_list ap; + int result; - if( im_wrapone( in, out, - (im_wrapone_fn) rad2float, NULL, NULL ) ) - return( -1 ); + va_start( ap, out ); + result = vips_call_split( "rad2float", ap, in, out ); + va_end( ap ); - return( 0 ); + return( result ); } diff --git a/libvips/deprecated/rename.c b/libvips/deprecated/rename.c index fe8d8ea5..7bc55f63 100644 --- a/libvips/deprecated/rename.c +++ b/libvips/deprecated/rename.c @@ -705,3 +705,21 @@ im_flood_other( IMAGE *test, IMAGE *mark, { return( im_draw_flood_other( mark, test, x, y, serial, dout ) ); } + +int +vips_check_coding_rad( const char *domain, VipsImage *im ) +{ + return( vips_check_coding( domain, im, VIPS_CODING_RAD ) ); +} + +int +vips_check_coding_labq( const char *domain, VipsImage *im ) +{ + return( vips_check_coding( domain, im, VIPS_CODING_LABQ ) ); +} + +int +vips_check_bands_3ormore( const char *domain, VipsImage *im ) +{ + return( vips_check_bands_atleast( domain, im, 3 ) ); +} diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index f7a47725..9e0086b0 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -2323,3 +2323,35 @@ im_Yxy2XYZ( IMAGE *in, IMAGE *out ) return( 0 ); } + +int +im_float2rad( IMAGE *in, IMAGE *out ) +{ + VipsImage *x; + + if( vips_float2rad( in, &x, NULL ) ) + return( -1 ); + if( im_copy( x, out ) ) { + g_object_unref( x ); + return( -1 ); + } + g_object_unref( x ); + + return( 0 ); +} + +int +im_rad2float( IMAGE *in, IMAGE *out ) +{ + VipsImage *x; + + if( vips_rad2float( in, &x, NULL ) ) + return( -1 ); + if( im_copy( x, out ) ) { + g_object_unref( x ); + return( -1 ); + } + g_object_unref( x ); + + return( 0 ); +} diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index cdea862a..55a58857 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -164,8 +164,6 @@ float im_col_dE00( float L1, float a1, float b1, float L2, float a2, float b2 ); int im_LabQ2XYZ( VipsImage *in, VipsImage *out ); -int im_rad2float( VipsImage *in, VipsImage *out ); -int im_float2rad( VipsImage *in, VipsImage *out ); int im_Lab2LabQ( VipsImage *in, VipsImage *out ); int im_Lab2LabS( VipsImage *in, VipsImage *out ); int im_LabQ2Lab( VipsImage *in, VipsImage *out ); diff --git a/libvips/include/vips/error.h b/libvips/include/vips/error.h index 19f8c9e1..2153336e 100644 --- a/libvips/include/vips/error.h +++ b/libvips/include/vips/error.h @@ -56,15 +56,14 @@ void vips_error_exit( const char *fmt, ... ) __attribute__((noreturn, format(printf, 1, 2))); int vips_check_uncoded( const char *domain, VipsImage *im ); +int vips_check_coding( const char *domain, VipsImage *im, VipsCoding coding ); int vips_check_coding_known( const char *domain, VipsImage *im ); -int vips_check_coding_labq( const char *domain, VipsImage *im ); -int vips_check_coding_rad( const char *domain, VipsImage *im ); int vips_check_coding_noneorlabq( const char *domain, VipsImage *im ); int vips_check_coding_same( const char *domain, VipsImage *im1, VipsImage *im2 ); int vips_check_mono( const char *domain, VipsImage *im ); int vips_check_bands( const char *domain, VipsImage *im, int bands ); int vips_check_bands_1or3( const char *domain, VipsImage *in ); -int vips_check_bands_3ormore( const char *domain, VipsImage *im ); +int vips_check_bands_atleast( const char *domain, VipsImage *im, int bands ); 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 ); diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 75755439..af4ec8bc 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -428,6 +428,10 @@ G_STMT_START { \ #define im__change_suffix vips__change_suffix +int vips_check_coding_labq( const char *domain, VipsImage *im ); +int vips_check_coding_rad( const char *domain, VipsImage *im ); +int vips_check_bands_3ormore( const char *domain, VipsImage *im ); + /* Buffer processing. */ typedef void (*im_wrapone_fn)( void *in, void *out, int width, @@ -718,6 +722,8 @@ int im_LCh2UCS( VipsImage *in, VipsImage *out ); int im_UCS2LCh( VipsImage *in, VipsImage *out ); int im_XYZ2Yxy( VipsImage *in, VipsImage *out ); int im_Yxy2XYZ( VipsImage *in, VipsImage *out ); +int im_float2rad( VipsImage *in, VipsImage *out ); +int im_rad2float( VipsImage *in, VipsImage *out ); /* ruby-vips uses this */ diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index a9729b96..b9657dd6 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -516,11 +516,12 @@ vips_check_coding_known( const char *domain, VipsImage *im ) } /** - * vips_check_coding_rad: + * vips_check_coding: * @domain: the originating domain for the error message * @im: image to check + * @coding: required coding * - * Check that the image is in Radiance coding. + * Check that the image has the required @coding. * If not, set an error message * and return non-zero. * @@ -529,38 +530,11 @@ vips_check_coding_known( const char *domain, VipsImage *im ) * Returns: 0 on OK, or -1 on error. */ int -vips_check_coding_rad( const char *domain, VipsImage *im ) +vips_check_coding( const char *domain, VipsImage *im, VipsCoding coding ) { - if( im->Coding != VIPS_CODING_RAD || - im->BandFmt != VIPS_FORMAT_UCHAR || - im->Bands != 4 ) { - vips_error( domain, "%s", _( "Radiance coding only" ) ); - return( -1 ); - } - - return( 0 ); -} - -/** - * vips_check_coding_labq: - * @domain: the originating domain for the error message - * @im: image to check - * - * Check that the image is in LABQ coding. - * 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_coding_labq( const char *domain, VipsImage *im ) -{ - if( im->Coding != VIPS_CODING_LABQ || - im->BandFmt != VIPS_FORMAT_UCHAR || - im->Bands != 4 ) { - vips_error( domain, "%s", _( "LABQ coding only" ) ); + if( im->Coding != coding ) { + vips_error( domain, _( "%s coding only" ), + vips_enum_nick( VIPS_TYPE_CODING, coding ) ); return( -1 ); } @@ -642,11 +616,12 @@ vips_check_bands_1or3( const char *domain, VipsImage *im ) } /** - * vips_check_bands_3ormore: + * vips_check_bands_atleast: * @domain: the originating domain for the error message * @im: image to check + * @bands: at least this many bands * - * Check that the image has at least three bands. + * Check that the image has at least @bands bands. * Otherwise set an error message * and return non-zero. * @@ -655,11 +630,11 @@ vips_check_bands_1or3( const char *domain, VipsImage *im ) * Returns: 0 if OK, -1 otherwise. */ int -vips_check_bands_3ormore( const char *domain, VipsImage *im ) +vips_check_bands_atleast( const char *domain, VipsImage *im, int bands ) { - if( im->Bands < 3 ) { - vips_error( domain, "%s", - _( "image must have at least three bands" ) ); + if( im->Bands < bands ) { + vips_error( domain, + _( "image must have at least %d bands" ), bands ); return( -1 ); }