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 );
/* 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" ),

View File

@ -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" ),

View File

@ -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" ),

View File

@ -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" ),

View File

@ -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 );

View File

@ -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

View File

@ -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}
};

View File

@ -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 );

View File

@ -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++ )