From 351a2ad71c2923f09e14a1d13cf3dd27ae789d08 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 12 Jan 2012 13:39:58 +0000 Subject: [PATCH] better saving of coded images --- libvips/foreign/foreign.c | 55 +++++++++++++++++++--------------- libvips/foreign/radsave.c | 3 +- libvips/foreign/tiffsave.c | 1 + libvips/foreign/vipssave.c | 4 +++ libvips/include/vips/foreign.h | 7 +++-- libvips/include/vips/image.h | 3 +- libvips/iofuncs/enumtypes.c | 1 + libvips/iofuncs/image.c | 31 +++++++++++-------- tools/vips.c | 37 +++++++++++------------ 9 files changed, 83 insertions(+), 59 deletions(-) diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index fc270f9e..483feb25 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -890,11 +890,10 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) */ g_object_ref( in ); - /* Does this class want a coded image we are already in? Nothing to - * do. + + /* Can this class save the coding we are in now? Nothing to do. */ - if( class->coding != VIPS_CODING_NONE && - class->coding == in->Coding ) { + if( class->coding[in->Coding] ) { VIPS_UNREF( save->ready ); save->ready = in; @@ -1095,32 +1094,34 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) in = out; } - /* Does this class want a coded image? The format_table[] should have - * got the format right for us. + /* Does this class want a coded image? Search the coding table for the + * first one. */ - if( class->coding != VIPS_CODING_NONE ) { - if( class->coding == VIPS_CODING_RAD ) { - VipsImage *out; + if( class->coding[VIPS_CODING_NONE] ) { + /* Already NONE, nothing to do. + */ + } + else if( class->coding[VIPS_CODING_RAD] ) { + VipsImage *out; - if( vips_float2rad( in, &out, NULL ) ) { - g_object_unref( in ); - return( -1 ); - } + if( vips_float2rad( in, &out, NULL ) ) { g_object_unref( in ); - - in = out; + return( -1 ); } - else if( class->coding == VIPS_CODING_LABQ ) { - VipsImage *out; + g_object_unref( in ); - if( vips_Lab2LabQ( in, &out, NULL ) ) { - g_object_unref( in ); - return( -1 ); - } + in = out; + } + else if( class->coding[VIPS_CODING_LABQ] ) { + VipsImage *out; + + if( vips_Lab2LabQ( in, &out, NULL ) ) { g_object_unref( in ); - - in = out; + return( -1 ); } + g_object_unref( in ); + + in = out; } VIPS_UNREF( save->ready ); @@ -1147,6 +1148,8 @@ vips_foreign_save_build( VipsObject *object ) static void vips_foreign_save_class_init( VipsForeignSaveClass *class ) { + int i; + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; @@ -1160,7 +1163,11 @@ vips_foreign_save_class_init( VipsForeignSaveClass *class ) object_class->nickname = "filesave"; object_class->description = _( "file savers" ); - class->coding = VIPS_CODING_NONE; + /* Default to no coding allowed. + */ + for( i = 0; i < VIPS_CODING_LAST; i++ ) + class->coding[i] = FALSE; + class->coding[VIPS_CODING_NONE] = TRUE; VIPS_ARG_IMAGE( class, "in", 0, _( "Input" ), diff --git a/libvips/foreign/radsave.c b/libvips/foreign/radsave.c index 513d868a..6732b62d 100644 --- a/libvips/foreign/radsave.c +++ b/libvips/foreign/radsave.c @@ -112,7 +112,8 @@ vips_foreign_save_rad_class_init( VipsForeignSaveRadClass *class ) save_class->saveable = VIPS_SAVEABLE_RGB; save_class->format_table = bandfmt_rad; - save_class->coding = VIPS_CODING_RAD; + save_class->coding[VIPS_CODING_NONE] = FALSE; + save_class->coding[VIPS_CODING_RAD] = TRUE; VIPS_ARG_STRING( class, "filename", 1, _( "Filename" ), diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index f3bb88a8..df139373 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -163,6 +163,7 @@ vips_foreign_save_tiff_class_init( VipsForeignSaveTiffClass *class ) save_class->saveable = VIPS_SAVEABLE_ANY; save_class->format_table = bandfmt_tiff; + save_class->coding[VIPS_CODING_LABQ] = TRUE; VIPS_ARG_STRING( class, "filename", 1, _( "Filename" ), diff --git a/libvips/foreign/vipssave.c b/libvips/foreign/vipssave.c index c58fceea..f08111e4 100644 --- a/libvips/foreign/vipssave.c +++ b/libvips/foreign/vipssave.c @@ -100,6 +100,8 @@ static const char *vips_suffs[] = { ".v", NULL }; static void vips_foreign_save_vips_class_init( VipsForeignSaveVipsClass *class ) { + int i; + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; VipsForeignClass *foreign_class = (VipsForeignClass *) class; @@ -116,6 +118,8 @@ vips_foreign_save_vips_class_init( VipsForeignSaveVipsClass *class ) save_class->saveable = VIPS_SAVEABLE_ANY; save_class->format_table = vips_bandfmt_vips; + for( i = 0; i < VIPS_CODING_LAST; i++ ) + save_class->coding[i] = TRUE; VIPS_ARG_STRING( class, "filename", 1, _( "Filename" ), diff --git a/libvips/include/vips/foreign.h b/libvips/include/vips/foreign.h index 79ff6bb7..fa75713a 100644 --- a/libvips/include/vips/foreign.h +++ b/libvips/include/vips/foreign.h @@ -266,9 +266,12 @@ typedef struct _VipsForeignSaveClass { */ VipsBandFormat *format_table; - /* If this format needs a coding, the coding it wants (default NONE). + /* The set of coding types this format can save. For example, jpeg can + * only save NONE, so has NONE TRUE and RAD and LABQ FALSE. + * + * Default NONE TRUE, RAD and LABQ FALSE. */ - VipsCoding coding; + gboolean coding[VIPS_CODING_LAST]; } VipsForeignSaveClass; GType vips_foreign_save_get_type( void ); diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 8386ce08..8aad4468 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -208,7 +208,8 @@ typedef enum { typedef enum { VIPS_CODING_NONE = 0, VIPS_CODING_LABQ = 2, - VIPS_CODING_RAD = 6 + VIPS_CODING_RAD = 6, + VIPS_CODING_LAST = 7 } VipsCoding; /* Struct we keep a record of execution time in. Passed to eval signal so diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index b9086cf2..4199bd8f 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -460,6 +460,7 @@ vips_coding_get_type( void ) {VIPS_CODING_NONE, "VIPS_CODING_NONE", "none"}, {VIPS_CODING_LABQ, "VIPS_CODING_LABQ", "labq"}, {VIPS_CODING_RAD, "VIPS_CODING_RAD", "rad"}, + {VIPS_CODING_LAST, "VIPS_CODING_LAST", "last"}, {0, NULL, NULL} }; diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index a9d87dda..89efcc12 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -386,18 +386,25 @@ vips_image_print_summary( VipsObject *object, VipsBuf *buf ) { VipsImage *image = VIPS_IMAGE( object ); - vips_buf_appendf( buf, - ngettext( - "%dx%d %s, %d band, %s", - "%dx%d %s, %d bands, %s", - vips_image_get_bands( image ) ), - vips_image_get_width( image ), - vips_image_get_height( image ), - VIPS_ENUM_NICK( VIPS_TYPE_BAND_FORMAT, - vips_image_get_format( image ) ), - vips_image_get_bands( image ), - VIPS_ENUM_NICK( VIPS_TYPE_INTERPRETATION, - vips_image_get_interpretation( image ) ) ); + vips_buf_appendf( buf, "%dx%d", + vips_image_get_width( image ), vips_image_get_height( image ) ); + if( vips_image_get_coding( image ) == VIPS_CODING_NONE ) { + vips_buf_appendf( buf, + ngettext( + " %s, %d band, %s", + " %s, %d bands, %s", + vips_image_get_bands( image ) ), + VIPS_ENUM_NICK( VIPS_TYPE_BAND_FORMAT, + vips_image_get_format( image ) ), + vips_image_get_bands( image ), + VIPS_ENUM_NICK( VIPS_TYPE_INTERPRETATION, + vips_image_get_interpretation( image ) ) ); + } + else { + vips_buf_appendf( buf, ", %s", + VIPS_ENUM_NICK( VIPS_TYPE_CODING, + vips_image_get_coding( image ) ) ); + } VIPS_OBJECT_CLASS( vips_image_parent_class )-> print_summary( object, buf ); diff --git a/tools/vips.c b/tools/vips.c index 678b94b7..2da386ee 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -1041,25 +1041,6 @@ main( int argc, char **argv ) break; } - /* Could be a vips7 im_function. Search here first for max - * compatibility. - */ - if( action && !handled && - (fn = im_find_function( action )) ) { - (void) add_main_group( context, NULL ); - parse_options( context, &argc, argv ); - - if( im_run_command( action, argc - 1, argv + 1 ) ) { - if( argc == 1 ) - usage( fn ); - else - error_exit( NULL ); - } - - handled = TRUE; - } - im_error_clear(); - /* Could be a vips8 VipsOperation. */ if( action && !handled && @@ -1086,6 +1067,24 @@ main( int argc, char **argv ) } im_error_clear(); + /* Could be a vips7 im_function. + */ + if( action && !handled && + (fn = im_find_function( action )) ) { + (void) add_main_group( context, NULL ); + parse_options( context, &argc, argv ); + + if( im_run_command( action, argc - 1, argv + 1 ) ) { + if( argc == 1 ) + usage( fn ); + else + error_exit( NULL ); + } + + handled = TRUE; + } + im_error_clear(); + if( action && !handled ) { printf( "%s", _( "possible actions:\n" ) ); for( i = 0; i < VIPS_NUMBER( actions ); i++ )