From 822f1bbdd929c11ba6983aaf73dd6a15b8bbce9f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 31 Aug 2012 17:27:30 +0100 Subject: [PATCH] hackety hack make a base class for colorimetric operations --- ChangeLog | 3 + configure.in | 8 +- libvips/colour/colour.c | 190 +++++++++++++++++++++++---------- libvips/colour/colour.h | 41 ++++++- tools/Makefile.am | 4 +- tools/{vips-7.30 => vips-7.31} | 0 6 files changed, 180 insertions(+), 66 deletions(-) rename tools/{vips-7.30 => vips-7.31} (100%) diff --git a/ChangeLog b/ChangeLog index f8031307..bcdb7325 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +31/8/12 started 7.31.0 +- work on moving colour to vips8 + 6/8/12 started 7.30.1 - fixes to dzsave: shrink down to a 1x1 pixel tile, round image size up on shrink, write a .dzi file with the pyramid params, default tile size and diff --git a/configure.in b/configure.in index 4a5246a1..c06eb024 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ # also update the version number in the m4 macros below -AC_INIT([vips], [7.30.1], [vipsip@jiscmail.ac.uk]) +AC_INIT([vips], [7.31.0], [vipsip@jiscmail.ac.uk]) # required for gobject-introspection AC_PREREQ(2.62) @@ -16,8 +16,8 @@ AC_CONFIG_MACRO_DIR([m4]) # user-visible library versioning m4_define([vips_major_version], [7]) -m4_define([vips_minor_version], [30]) -m4_define([vips_micro_version], [1]) +m4_define([vips_minor_version], [31]) +m4_define([vips_micro_version], [0]) m4_define([vips_version], [vips_major_version.vips_minor_version.vips_micro_version]) @@ -37,7 +37,7 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date` # binary interface changes not backwards compatible?: reset age to 0 LIBRARY_CURRENT=33 -LIBRARY_REVISION=4 +LIBRARY_REVISION=5 LIBRARY_AGE=1 # patched into include/vips/version.h diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index 4c7c48f9..642c414f 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -46,27 +46,37 @@ G_DEFINE_ABSTRACT_TYPE( VipsColour, vips_colour, VIPS_TYPE_OPERATION ); +/* Maximum number of input images -- why not? + */ +#define MAX_INPUT_IMAGES (64) + static int vips_colour_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) { - VipsRegion *ir = (VipsRegion *) seq; + VipsRegion **ir = (VipsRegion **) seq; VipsColour *colour = VIPS_COLOUR( b ); VipsColourClass *class = VIPS_COLOUR_GET_CLASS( colour ); Rect *r = &or->valid; - VipsPel *p, *q; - int y; + VipsPel *p[MAX_INPUT_IMAGES], *q; + int i, y; - if( vips_region_prepare( ir, r ) ) - return( -1 ); - p = (VipsPel *) VIPS_REGION_ADDR( ir, r->left, r->top ); + /* Prepare all input regions and make buffer pointers. + */ + for( i = 0; ir[i]; i++ ) { + if( vips_region_prepare( ir[i], r ) ) + return( -1 ); + p[i] = (VipsPel *) VIPS_REGION_ADDR( ir[i], r->left, r->top ); + } + p[i] = NULL; q = (VipsPel *) VIPS_REGION_ADDR( or, r->left, r->top ); for( y = 0; y < r->height; y++ ) { - class->process_line( colour, q, p, r->width ); + class->process_line( arithmetic, q, p, r->width ); - p += VIPS_REGION_LSKIP( ir ); + for( i = 0; ir[i]; i++ ) + p[i] += VIPS_REGION_LSKIP( ir[i] ); q += VIPS_REGION_LSKIP( or ); } @@ -78,8 +88,6 @@ vips_colour_build( VipsObject *object ) { VipsColour *colour = VIPS_COLOUR( object ); - VipsImage **t; - #ifdef DEBUG printf( "vips_colour_build: " ); vips_object_print_name( object ); @@ -92,52 +100,24 @@ vips_colour_build( VipsObject *object ) g_object_set( colour, "out", vips_image_new(), NULL ); - if( vips_image_pio_input( colour->in ) || - vips_check_bands_1or3( "VipsColour", colour->in ) || - vips_check_uncoded( "VipsColour", colour->in ) ) + if( colour->n > MAX_INPUT_IMAGES ) { + vips_error( "VipsColour", + "%s", _( "too many input images" ) ); return( -1 ); + } + for( i = 0; i < arithmetic->n; i++ ) + if( vips_image_pio_input( colour->in[i] ) ) + return( -1 ); - t = (VipsImage **) vips_object_local_array( object, 5 ); - - /* Always process float. - */ - if( vips_cast_float( colour->in, &t[0], NULL ) ) + if( vips_image_copy_fields_array( colour->out, colour->in ) ) return( -1 ); + vips_demand_hint_array( arithmetic->out, + VIPS_DEMAND_STYLE_THINSTRIP, colour->in ); - /* 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 ); - } + if( vips_image_generate( colour->out, + vips_start_many, vips_colour_gen, vips_stop_many, + colour->in, colour ) ) + return( -1 ); return( 0 ); } @@ -155,12 +135,6 @@ vips_colour_class_init( VipsColourClass *class ) vobject_class->description = _( "colour operations" ); vobject_class->build = vips_colour_build; - VIPS_ARG_IMAGE( class, "in", 1, - _( "Input" ), - _( "Input image" ), - VIPS_ARGUMENT_REQUIRED_INPUT, - G_STRUCT_OFFSET( VipsColour, in ) ); - VIPS_ARG_IMAGE( class, "out", 100, _( "Output" ), _( "Output image" ), @@ -173,6 +147,106 @@ vips_colour_init( VipsColour *colour ) { } +G_DEFINE_ABSTRACT_TYPE( VipsColorimetric, vips_colorimetric, VIPS_TYPE_COLOUR ); + +static int +vips_colourmetric_build( VipsObject *object ) +{ + VipsColour *colour = VIPS_COLOUR( object ); + VipsColorimetric *colorimetric = VIPS_COLORIMETRIC( object ); + + VipsImage **t; + + t = (VipsImage **) vips_object_local_array( object, 1 ); + + /* We only process float. + */ + if( vips_cast_float( colorimetric->in, &t[0] ) ) + return( -1 ); + + + + + arithmetic->n = 1; + arithmetic->in = (VipsImage **) vips_object_local_array( object, 1 ); + + /* We always process float + + + + arithmetic->in[0] = unary->in; + if( arithmetic->in[0] ) + g_object_ref( arithmetic->in[0] ); + + if( VIPS_OBJECT_CLASS( vips_unary_parent_class )->build( object ) ) + return( -1 ); + + + /* 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 ) ) + 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_many, vips_colour_gen, vips_stop_many, + 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_many, vips_colour_gen, vips_stop_many, + t[1], colour ) ) + return( -1 ); + } + + return( 0 ); +} + +static void +vips_colorimetric_class_init( VipsColorimetricClass *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 = "colour"; + vobject_class->description = _( "colorimetric operations" ); + vobject_class->build = vips_colorimetric_build; + + VIPS_ARG_IMAGE( class, "in", 1, + _( "Input" ), + _( "Input image" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsColorimetric, in ) ); +} + +static void +vips_colorimetric_init( VipsColorimetric *colorimetric ) +{ +} + /* Called from iofuncs to init all operations in this dir. Use a plugin system * instead? */ diff --git a/libvips/colour/colour.h b/libvips/colour/colour.h index 7ade76ae..976100d6 100644 --- a/libvips/colour/colour.h +++ b/libvips/colour/colour.h @@ -57,13 +57,18 @@ extern "C" { struct _VipsColour; typedef void (*VipsColourProcessFn)( struct _VipsColour *colour, - VipsPel *out, VipsPel *in, int width ); + VipsPel *out, VipsPel **in, int width ); typedef struct _VipsColour { VipsOperation parent_instance; + /* Null-terminated array of input arguments, set these from a + * subclass. + */ + VipsImage **in; + int n; + VipsImage *out; - VipsImage *in; } VipsColour; typedef struct _VipsColourClass { @@ -76,6 +81,38 @@ typedef struct _VipsColourClass { GType vips_colour_get_type( void ); +/* A three float bands in, three float bands out colourspace transformation. + */ + +#define VIPS_TYPE_COLORIMETRIC (vips_colorimetric_get_type()) +#define VIPS_COLORIMETRIC( obj ) \ + (G_TYPE_CHECK_INSTANCE_CAST( (obj), \ + VIPS_TYPE_COLORIMETRIC, VipsColorimetric )) +#define VIPS_COLORIMETRIC_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_CAST( (klass), \ + VIPS_TYPE_COLORIMETRIC, VipsColorimetricClass)) +#define VIPS_IS_COLORIMETRIC( obj ) \ + (G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_COLORIMETRIC )) +#define VIPS_IS_COLORIMETRIC_CLASS( klass ) \ + (G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_COLORIMETRIC )) +#define VIPS_COLORIMETRIC_GET_CLASS( obj ) \ + (G_TYPE_INSTANCE_GET_CLASS( (obj), \ + VIPS_TYPE_COLORIMETRIC, VipsColorimetricClass )) + +typedef struct _VipsColorimetric { + VipsColour parent_instance; + + VipsImage *in; + +} VipsColorimetric; + +typedef struct _VipsColorimetricClass { + VipsColourClass parent_class; + +} VipsColorimetricClass; + +GType vips_colorimetric_get_type( void ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/tools/Makefile.am b/tools/Makefile.am index ea6c2690..887fe4b7 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -26,10 +26,10 @@ bin_SCRIPTS = \ batch_image_convert \ batch_rubber_sheet \ batch_crop \ - vips-7.30 + vips-7.31 EXTRA_DIST = \ - vips-7.30 \ + vips-7.31 \ light_correct.in \ shrink_width.in \ batch_image_convert.in \ diff --git a/tools/vips-7.30 b/tools/vips-7.31 similarity index 100% rename from tools/vips-7.30 rename to tools/vips-7.31