written callbacks can fail

written callbacks now take a status return argument, so we can error for
"vips im_copy fred.jpg /jim.jpg", phew
This commit is contained in:
John Cupitt 2011-03-24 11:21:24 +00:00
parent 9e62bf3b36
commit 5e8121321d
5 changed files with 48 additions and 46 deletions

5
TODO
View File

@ -1,8 +1,3 @@
- vips_attach_save() in image.c has problems if save fails ... there's no way
for the result of the "written" callback to propogate the error
_written() should take a &status argument?
- add MATLAB write

View File

@ -286,8 +286,9 @@ typedef struct _VipsImageClass {
/* An image has been written to.
* Used by eg. im_open("x.jpg", "w") to do the final write to jpeg.
* Set *result to non-zero to indicate an error on write.
*/
void (*written)( VipsImage *image );
void (*written)( VipsImage *image, int *result );
/* An image has been modified in some way and caches all
* need dropping.
@ -341,7 +342,7 @@ extern const size_t vips__image_sizeof_bandformat[];
(X) * VIPS_IMAGE_SIZEOF_PEL( I ))
#endif /*VIPS_DEBUG*/
void vips_image_written( VipsImage *image );
int vips_image_written( VipsImage *image );
void vips_image_invalidate_all( VipsImage *image );
void vips_image_preeval( VipsImage *image );
void vips_image_eval( VipsImage *image, int w, int h );

View File

@ -451,7 +451,8 @@ im_generate( IMAGE *im,
return( -1 );
}
vips_image_written( im );
if( vips_image_written( im ) )
return( -1 );
return( 0 );
}

View File

@ -806,12 +806,10 @@ typedef struct {
/* From "written" callback: invoke a delayed save.
*/
static void
vips_image_save_cb( VipsImage *image, SaveBlock *sb )
vips_image_save_cb( VipsImage *image, int *result, SaveBlock *sb )
{
/* FIXME ... what can we do with this error return?
*/
if( sb->save_fn( image, sb->filename ) )
;
*result = -1;
}
static void
@ -985,8 +983,7 @@ vips_image_build( VipsObject *object )
/* Check parameters.
*/
if( image->sizeof_header < 0 ) {
vips_error( "vips_image_open_raw",
"%s", _( "bad parameters" ) );
vips_error( "VipsImage", "%s", _( "bad parameters" ) );
return( -1 );
}
@ -1012,7 +1009,7 @@ vips_image_build( VipsObject *object )
*/
if( image->file_length < VIPS_IMAGE_SIZEOF_IMAGE( image ) ) {
vips_error( "VipsImage",
_( "unable to open %s: file too short" ),
_( "unable to open \"%s\", file too short" ),
image->filename );
return( -1 );
}
@ -1207,30 +1204,34 @@ vips_image_class_init( VipsImageClass *class )
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( VipsImageClass, preeval ),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0 );
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER );
vips_image_signals[SIG_EVAL] = g_signal_new( "eval",
G_TYPE_FROM_CLASS( class ),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( VipsImageClass, eval ),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0 );
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER );
vips_image_signals[SIG_POSTEVAL] = g_signal_new( "posteval",
G_TYPE_FROM_CLASS( class ),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET( VipsImageClass, posteval ),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0 );
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER );
vips_image_signals[SIG_WRITTEN] = g_signal_new( "written",
G_TYPE_FROM_CLASS( class ),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET( VipsImageClass, written ),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0 );
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER );
vips_image_signals[SIG_INVALIDATE] = g_signal_new( "invalidate",
G_TYPE_FROM_CLASS( class ),
@ -1257,15 +1258,20 @@ vips_image_init( VipsImage *image )
image->sizeof_header = IM_SIZEOF_HEADER;
}
void
int
vips_image_written( VipsImage *image )
{
int result;
#ifdef VIPS_DEBUG
printf( "vips_image_written: " );
vips_object_print( VIPS_OBJECT( image ) );
#endif /*VIPS_DEBUG*/
g_signal_emit( image, vips_image_signals[SIG_WRITTEN], 0 );
result = 0;
g_signal_emit( image, vips_image_signals[SIG_WRITTEN], 0, &result );
return( result );
}
void
@ -1398,7 +1404,7 @@ vips_image_get_kill( VipsImage *image )
/* Has kill been set for this image? If yes, abort evaluation.
*/
if( image->kill )
vips_error( "vips_image_test_kill",
vips_error( "VipsImage",
_( "killed for image \"%s\"" ), image->filename );
return( image->kill );
@ -1818,8 +1824,7 @@ vips__image_write_prepare( VipsImage *image )
break;
default:
vips_error( "im_setupout",
"%s", _( "bad image descriptor" ) );
vips_error( "VipsImage", "%s", _( "bad image descriptor" ) );
return( -1 );
}
@ -1869,7 +1874,7 @@ vips_image_write_line( VipsImage *image, int ypos, PEL *linebuffer )
break;
default:
vips_error( "im_writeline",
vips_error( "VipsImage",
_( "unable to output to a %s image" ),
VIPS_ENUM_STRING( VIPS_TYPE_DEMAND_STYLE,
image->dtype ) );
@ -1886,7 +1891,8 @@ vips_image_write_line( VipsImage *image, int ypos, PEL *linebuffer )
*/
if( ypos == image->Ysize - 1 ) {
vips_image_posteval( image );
vips_image_written( image );
if( vips_image_written( image ) )
return( -1 );
}
return( 0 );

View File

@ -137,7 +137,7 @@ vips__open_image_read( const char *filename )
/* Open read-write failed. Fall back to open read-only.
*/
if( (fd = open( filename, MODE_READONLY )) == -1 ) {
vips_error_system( errno, "vips__open_image_read",
vips_error_system( errno, "VipsImage",
_( "unable to open \"%s\"" ), filename );
return( -1 );
}
@ -326,7 +326,7 @@ read_chunk( int fd, gint64 offset, size_t length )
return( NULL );
if( read( fd, buf, length ) != (ssize_t) length ) {
im_free( buf );
vips_error( "im_readhist", "%s", _( "unable to read history" ) );
vips_error( "VipsImage", "%s", _( "unable to read history" ) );
return( NULL );
}
buf[length] = '\0';
@ -358,7 +358,7 @@ im__read_extension_block( IMAGE *im, int *size )
psize = im__image_pixel_length( im );
g_assert( im->file_length > 0 );
if( im->file_length - psize > 10 * 1024 * 1024 ) {
vips_error( "im_readhist",
vips_error( "VipsImage",
"%s", _( "more than a 10 megabytes of XML? "
"sufferin' succotash!" ) );
return( NULL );
@ -406,7 +406,7 @@ read_xml( IMAGE *im )
if( !(node = xmlDocGetRootElement( doc )) ||
!node->nsDef ||
!im_isprefix( NAMESPACE, (char *) node->nsDef->href ) ) {
vips_error( "im__readhist",
vips_error( "VipsImage",
"%s", _( "incorrect namespace in XML" ) );
xmlFreeDoc( doc );
return( NULL );
@ -530,7 +530,7 @@ rebuild_header_meta( IMAGE *im, xmlNode *i )
g_value_init( &value, gtype );
if( !g_value_transform( &save_value, &value ) ) {
g_value_unset( &save_value );
vips_error( "im__readhist",
vips_error( "VipsImage",
"%s", _( "error transforming from "
"save format" ) );
return( -1 );
@ -639,7 +639,7 @@ set_prop( xmlNode *node, const char *name, const char *fmt, ... )
va_end( ap );
if( !xmlSetProp( node, (xmlChar *) name, (xmlChar *) value ) ) {
vips_error( "im_writehist", _( "unable to set property \"%s\" "
vips_error( "VipsImage", _( "unable to set property \"%s\" "
"to value \"%s\"." ),
name, value );
return( -1 );
@ -686,7 +686,7 @@ save_fields_meta( Meta *meta, xmlNode *node )
g_value_init( &save_value, IM_TYPE_SAVE_STRING );
if( !g_value_transform( &meta->value, &save_value ) ) {
vips_error( "im__writehist", "%s",
vips_error( "VipsImage", "%s",
_( "error transforming to save format" ) );
return( node );
}
@ -734,8 +734,7 @@ im__write_extension_block( IMAGE *im, void *buf, int size )
if( (length = im_file_length( im->fd )) == -1 )
return( -1 );
if( length - psize < 0 ) {
vips_error( "im__write_extension_block",
"%s", _( "file has been truncated" ) );
vips_error( "VipsImage", "%s", _( "file has been truncated" ) );
return( -1 );
}
@ -849,7 +848,7 @@ im__writehist( IMAGE *im )
NULL, (xmlChar *) "root", NULL )) ||
set_sprop( doc->children, "xmlns", namespace ) ||
save_fields( im, doc->children ) ) {
vips_error( "im__writehist", "%s", _( "xml save error" ) );
vips_error( "VipsImage", "%s", _( "xml save error" ) );
xmlFreeDoc( doc );
return( -1 );
}
@ -858,7 +857,7 @@ im__writehist( IMAGE *im )
*/
xmlDocDumpMemory( doc, (xmlChar **) ((char *) &dump), &dump_size );
if( !dump ) {
vips_error( "im__writehist", "%s", _( "xml save error" ) );
vips_error( "VipsImage", "%s", _( "xml save error" ) );
xmlFreeDoc( doc );
return( -1 );
}
@ -881,7 +880,7 @@ im__writehist( IMAGE *im )
xmlDocDumpMemory( doc, (xmlChar **) &dump2, &dump_size2 );
if( !dump2 ) {
vips_error( "im__writehist", "%s", _( "xml save error" ) );
vips_error( "VipsImage", "%s", _( "xml save error" ) );
xmlFreeDoc( doc );
xmlFree( dump );
return( -1 );
@ -916,7 +915,7 @@ vips_image_open_input( VipsImage *image )
return( -1 );
if( read( image->fd, header, IM_SIZEOF_HEADER ) != IM_SIZEOF_HEADER ||
im__read_header_bytes( image, header ) ) {
vips_error_system( errno, "vips_open_input",
vips_error_system( errno, "VipsImage",
_( "unable to read header for \"%s\"" ),
image->filename );
return( -1 );
@ -929,7 +928,7 @@ vips_image_open_input( VipsImage *image )
return( -1 );
image->file_length = rsize;
if( psize > rsize )
vips_warn( "vips_open_input",
vips_warn( "VipsImage",
_( "unable to read data for \"%s\", %s" ),
image->filename, _( "file has been truncated" ) );
@ -942,7 +941,7 @@ vips_image_open_input( VipsImage *image )
* harmless.
*/
if( im__readhist( image ) ) {
vips_warn( "vips_open_input", _( "error reading XML: %s" ),
vips_warn( "VipsImage", _( "error reading XML: %s" ),
vips_error_buffer() );
vips_error_clear();
}
@ -961,7 +960,7 @@ vips_image_open_output( VipsImage *image )
if( (image->fd = open( image->filename,
MODE_WRITE, 0666 )) < 0 ) {
vips_error_system( errno, "vips_image_open_output",
vips_error_system( errno, "VipsImage",
_( "unable to write to \"%s\"" ),
image->filename );
return( -1 );