diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index 824824b6..4c7c48f9 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -56,9 +56,9 @@ vips_colour_gen( VipsRegion *or, Rect *r = &or->valid; VipsPel *p, *q; - int i, y; + int y; - if( vips_region_prepare( ir[i], r ) ) + if( vips_region_prepare( ir, r ) ) return( -1 ); p = (VipsPel *) VIPS_REGION_ADDR( ir, r->left, r->top ); q = (VipsPel *) VIPS_REGION_ADDR( or, r->left, r->top ); @@ -77,7 +77,8 @@ static int vips_colour_build( VipsObject *object ) { VipsColour *colour = VIPS_COLOUR( object ); - VipsColourClass *aclass = VIPS_COLOUR_GET_CLASS( colour ); + + VipsImage **t; #ifdef DEBUG printf( "vips_colour_build: " ); @@ -91,16 +92,53 @@ vips_colour_build( VipsObject *object ) g_object_set( colour, "out", vips_image_new(), NULL ); - if( vips_image_copy_fields( colour->out, colour->in ) ) + if( vips_image_pio_input( colour->in ) || + vips_check_bands_1or3( "VipsColour", colour->in ) || + vips_check_uncoded( "VipsColour", colour->in ) ) return( -1 ); - vips_demand_hint( colour->out, - VIPS_DEMAND_STYLE_THINSTRIP, colour->in, NULL ); - if( vips_image_generate( colour->out, - vips_start_one, vips_colour_gen, vips_stop_one, - colour->in, colour ) ) + t = (VipsImage **) vips_object_local_array( object, 5 ); + + /* Always process float. + */ + if( vips_cast_float( colour->in, &t[0], NULL ) ) return( -1 ); + /* If there are more than bands, process just the first three and + * reattach the rest after. + */ + 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 ) ) + return( -1 ); + + if( vips_image_copy_fields( t[3], t[1] ) ) + return( -1 ); + vips_demand_hint( t[3], + VIPS_DEMAND_STYLE_THINSTRIP, t[1], NULL ); + + if( vips_image_generate( t[3], + vips_start_one, vips_colour_gen, vips_stop_one, + t[1], colour ) ) + return( -1 ); + + if( vips_bandjoin2( t[3], t[2], &t[4], NULL ) || + vips_image_write( t[4], colour->out ) ) + return( -1 ); + } + else { + if( vips_image_copy_fields( colour->out, t[1] ) ) + return( -1 ); + vips_demand_hint( colour->out, + VIPS_DEMAND_STYLE_THINSTRIP, t[1], NULL ); + + if( vips_image_generate( colour->out, + vips_start_one, vips_colour_gen, vips_stop_one, + t[1], colour ) ) + return( -1 ); + } + return( 0 ); } diff --git a/libvips/include/vips/error.h b/libvips/include/vips/error.h index 2681efae..27695213 100644 --- a/libvips/include/vips/error.h +++ b/libvips/include/vips/error.h @@ -62,8 +62,9 @@ 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_1or3( const char *domain, VipsImage *in ); 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_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/iofuncs/error.c b/libvips/iofuncs/error.c index b6ee8530..257954af 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -606,7 +606,7 @@ vips_check_bands( const char *domain, VipsImage *im, int bands ) } /** - * vips_check_1or3: + * vips_check_bands_1or3: * @domain: the originating domain for the error message * @im: image to check * @@ -630,6 +630,31 @@ vips_check_bands_1or3( const char *domain, VipsImage *im ) return( 0 ); } +/** + * vips_check_bands_3ormore: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image has at least three bands. + * Otherwise set an error message + * and return non-zero. + * + * See also: vips_error(). + * + * Returns: 0 if OK, -1 otherwise. + */ +int +vips_check_bands_3ormore( const char *domain, VipsImage *im ) +{ + if( im->Bands < 3 ) { + vips_error( domain, "%s", + _( "image must have at least three bands" ) ); + return( -1 ); + } + + return( 0 ); +} + /** * vips_check_bands_1orn: * @domain: the originating domain for the error message diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index e3537d8a..0add3a6b 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -349,9 +349,6 @@ void * vips_argument_map( VipsObject *object, VipsArgumentMapFn fn, void *a, void *b ) { - VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object ); - GSList *p; - /* Make sure we can't go during the loop. This can happen if eg. we * flush an arg that refs us. */ @@ -370,7 +367,7 @@ vips_argument_map( VipsObject *object, g_object_unref( object ); return( result ); } - } + } VIPS_ARGUMENT_FOR_ALL_END g_object_unref( object );