better saving of coded images

This commit is contained in:
John Cupitt 2012-01-12 13:39:58 +00:00
parent b43f38997d
commit 351a2ad71c
9 changed files with 83 additions and 59 deletions

View File

@ -890,11 +890,10 @@ vips_foreign_convert_saveable( VipsForeignSave *save )
*/ */
g_object_ref( in ); 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 && if( class->coding[in->Coding] ) {
class->coding == in->Coding ) {
VIPS_UNREF( save->ready ); VIPS_UNREF( save->ready );
save->ready = in; save->ready = in;
@ -1095,32 +1094,34 @@ vips_foreign_convert_saveable( VipsForeignSave *save )
in = out; in = out;
} }
/* Does this class want a coded image? The format_table[] should have /* Does this class want a coded image? Search the coding table for the
* got the format right for us. * first one.
*/ */
if( class->coding != VIPS_CODING_NONE ) { if( class->coding[VIPS_CODING_NONE] ) {
if( class->coding == VIPS_CODING_RAD ) { /* Already NONE, nothing to do.
VipsImage *out; */
}
else if( class->coding[VIPS_CODING_RAD] ) {
VipsImage *out;
if( vips_float2rad( in, &out, NULL ) ) { if( vips_float2rad( in, &out, NULL ) ) {
g_object_unref( in );
return( -1 );
}
g_object_unref( in ); g_object_unref( in );
return( -1 );
in = out;
} }
else if( class->coding == VIPS_CODING_LABQ ) { g_object_unref( in );
VipsImage *out;
if( vips_Lab2LabQ( in, &out, NULL ) ) { in = out;
g_object_unref( in ); }
return( -1 ); else if( class->coding[VIPS_CODING_LABQ] ) {
} VipsImage *out;
if( vips_Lab2LabQ( in, &out, NULL ) ) {
g_object_unref( in ); g_object_unref( in );
return( -1 );
in = out;
} }
g_object_unref( in );
in = out;
} }
VIPS_UNREF( save->ready ); VIPS_UNREF( save->ready );
@ -1147,6 +1148,8 @@ vips_foreign_save_build( VipsObject *object )
static void static void
vips_foreign_save_class_init( VipsForeignSaveClass *class ) vips_foreign_save_class_init( VipsForeignSaveClass *class )
{ {
int i;
GObjectClass *gobject_class = G_OBJECT_CLASS( class ); GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class; VipsObjectClass *object_class = (VipsObjectClass *) class;
@ -1160,7 +1163,11 @@ vips_foreign_save_class_init( VipsForeignSaveClass *class )
object_class->nickname = "filesave"; object_class->nickname = "filesave";
object_class->description = _( "file savers" ); 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, VIPS_ARG_IMAGE( class, "in", 0,
_( "Input" ), _( "Input" ),

View File

@ -112,7 +112,8 @@ vips_foreign_save_rad_class_init( VipsForeignSaveRadClass *class )
save_class->saveable = VIPS_SAVEABLE_RGB; save_class->saveable = VIPS_SAVEABLE_RGB;
save_class->format_table = bandfmt_rad; 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, VIPS_ARG_STRING( class, "filename", 1,
_( "Filename" ), _( "Filename" ),

View File

@ -163,6 +163,7 @@ vips_foreign_save_tiff_class_init( VipsForeignSaveTiffClass *class )
save_class->saveable = VIPS_SAVEABLE_ANY; save_class->saveable = VIPS_SAVEABLE_ANY;
save_class->format_table = bandfmt_tiff; save_class->format_table = bandfmt_tiff;
save_class->coding[VIPS_CODING_LABQ] = TRUE;
VIPS_ARG_STRING( class, "filename", 1, VIPS_ARG_STRING( class, "filename", 1,
_( "Filename" ), _( "Filename" ),

View File

@ -100,6 +100,8 @@ static const char *vips_suffs[] = { ".v", NULL };
static void static void
vips_foreign_save_vips_class_init( VipsForeignSaveVipsClass *class ) vips_foreign_save_vips_class_init( VipsForeignSaveVipsClass *class )
{ {
int i;
GObjectClass *gobject_class = G_OBJECT_CLASS( class ); GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class; VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsForeignClass *foreign_class = (VipsForeignClass *) 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->saveable = VIPS_SAVEABLE_ANY;
save_class->format_table = vips_bandfmt_vips; 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, VIPS_ARG_STRING( class, "filename", 1,
_( "Filename" ), _( "Filename" ),

View File

@ -266,9 +266,12 @@ typedef struct _VipsForeignSaveClass {
*/ */
VipsBandFormat *format_table; 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; } VipsForeignSaveClass;
GType vips_foreign_save_get_type( void ); GType vips_foreign_save_get_type( void );

View File

@ -208,7 +208,8 @@ typedef enum {
typedef enum { typedef enum {
VIPS_CODING_NONE = 0, VIPS_CODING_NONE = 0,
VIPS_CODING_LABQ = 2, VIPS_CODING_LABQ = 2,
VIPS_CODING_RAD = 6 VIPS_CODING_RAD = 6,
VIPS_CODING_LAST = 7
} VipsCoding; } VipsCoding;
/* Struct we keep a record of execution time in. Passed to eval signal so /* Struct we keep a record of execution time in. Passed to eval signal so

View File

@ -460,6 +460,7 @@ vips_coding_get_type( void )
{VIPS_CODING_NONE, "VIPS_CODING_NONE", "none"}, {VIPS_CODING_NONE, "VIPS_CODING_NONE", "none"},
{VIPS_CODING_LABQ, "VIPS_CODING_LABQ", "labq"}, {VIPS_CODING_LABQ, "VIPS_CODING_LABQ", "labq"},
{VIPS_CODING_RAD, "VIPS_CODING_RAD", "rad"}, {VIPS_CODING_RAD, "VIPS_CODING_RAD", "rad"},
{VIPS_CODING_LAST, "VIPS_CODING_LAST", "last"},
{0, NULL, NULL} {0, NULL, NULL}
}; };

View File

@ -386,18 +386,25 @@ vips_image_print_summary( VipsObject *object, VipsBuf *buf )
{ {
VipsImage *image = VIPS_IMAGE( object ); VipsImage *image = VIPS_IMAGE( object );
vips_buf_appendf( buf, vips_buf_appendf( buf, "%dx%d",
ngettext( vips_image_get_width( image ), vips_image_get_height( image ) );
"%dx%d %s, %d band, %s", if( vips_image_get_coding( image ) == VIPS_CODING_NONE ) {
"%dx%d %s, %d bands, %s", vips_buf_appendf( buf,
vips_image_get_bands( image ) ), ngettext(
vips_image_get_width( image ), " %s, %d band, %s",
vips_image_get_height( image ), " %s, %d bands, %s",
VIPS_ENUM_NICK( VIPS_TYPE_BAND_FORMAT, vips_image_get_bands( image ) ),
vips_image_get_format( image ) ), VIPS_ENUM_NICK( VIPS_TYPE_BAND_FORMAT,
vips_image_get_bands( image ), vips_image_get_format( image ) ),
VIPS_ENUM_NICK( VIPS_TYPE_INTERPRETATION, vips_image_get_bands( image ),
vips_image_get_interpretation( 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 )-> VIPS_OBJECT_CLASS( vips_image_parent_class )->
print_summary( object, buf ); print_summary( object, buf );

View File

@ -1041,25 +1041,6 @@ main( int argc, char **argv )
break; 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. /* Could be a vips8 VipsOperation.
*/ */
if( action && !handled && if( action && !handled &&
@ -1086,6 +1067,24 @@ main( int argc, char **argv )
} }
im_error_clear(); 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 ) { if( action && !handled ) {
printf( "%s", _( "possible actions:\n" ) ); printf( "%s", _( "possible actions:\n" ) );
for( i = 0; i < VIPS_NUMBER( actions ); i++ ) for( i = 0; i < VIPS_NUMBER( actions ); i++ )