fix delayed write to foreign via "w"

also added vips_foreign_find_save_options()/
vips_foreign_find_load_options()
This commit is contained in:
John Cupitt 2012-02-02 15:08:57 +00:00
parent 2fed2f3490
commit d38e7bea57
5 changed files with 101 additions and 46 deletions

View File

@ -1,5 +1,7 @@
30/1/12 started 7.28.0
- version bump
- added vips_foreign_find_save_options()/vips_foreign_find_load_options()
- delayed write to foreign via a "w" image was not working
20/8/11 started 7.27.0
- version bump for new dev cycle

16
TODO
View File

@ -1,22 +1,6 @@
- swig is not wrapping ops which return more than one arg by reference
correctly .. eg. im_correl()
- try/bench/vips.py is broken
(gdb) run vips.py wtc_tiled_small.tif x.tif
Starting program: /usr/bin/python vips.py wtc_tiled_small.tif x.tif
[Thread debugging using libthread_db enabled]
(vips.py:28339): GLib-GObject-CRITICAL **: g_object_ref: assertion
`G_IS_OBJECT (object)' failed
Program received signal SIGSEGV, Segmentation fault.
vips_foreign_convert_saveable (save=0xeac800) at foreign.c:899
899 if( in->Coding != VIPS_CODING_NONE &&
(gdb) p in
$1 = (VipsImage *) 0x0

View File

@ -482,13 +482,13 @@ vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class,
/**
* vips_foreign_find_load:
* @filename: file to find a file for
* @filename: file to find a loader for
*
* Searches for an operation you could use to load a file.
* Searches for an operation you could use to load @filename.
*
* See also: vips_foreign_read().
*
* Returns: the nmae of an operation on success, %NULL on error
* Returns: the name of an operation on success, %NULL on error
*/
const char *
vips_foreign_find_load( const char *filename )
@ -513,6 +513,40 @@ vips_foreign_find_load( const char *filename )
return( G_OBJECT_CLASS_NAME( load_class ) );
}
/**
* vips_foreign_find_load_options:
* @filename: file to find a loader for
*
* Searches for an operation you could use to load @filename.
*
* Arguments to the loader may be embedded in the filename using the usual
* syntax.
*
* See also: vips_foreign_load().
*
* Returns: 0 on success, -1 on error
*/
const char *
vips_foreign_find_load_options( const char *filename )
{
VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_LOAD );
VipsObject *object;
const char *type_name;
/* This will use vips_foreign_load_new_from_string() to pick a loader,
* then set options from the tail of the filename. This is rather slow
* :-(
*/
if( !(object = vips_object_new_from_string( oclass, filename )) )
return( NULL );
type_name = G_OBJECT_TYPE_NAME( object );
g_object_unref( object );
return( type_name );
}
/**
* vips_foreign_is_a:
* @loader: name of loader to use for test
@ -834,9 +868,12 @@ vips_foreign_find_save_sub( VipsForeignSaveClass *save_class,
/**
* vips_foreign_find_save:
* @filename: name to find a file for
* @filename: name to find a saver for
*
* Searches for an operation you could use to save a file.
* Searches for an operation you could use to write to @filename.
*
* @filename may not contain embedded options. See
* vips_foreign_find_save_options() if your filename may have options in.
*
* See also: vips_foreign_write().
*
@ -860,6 +897,40 @@ vips_foreign_find_save( const char *filename )
return( G_OBJECT_CLASS_NAME( save_class ) );
}
/**
* vips_foreign_find_save_options:
* @filename: name to find a saver for
*
* Searches for an operation you could use to write to @filename.
*
* @filename may contain embedded options. See
* vips_foreign_find_save() if your filename does not options in.
*
* See also: vips_foreign_write().
*
* Returns: 0 on success, -1 on error
*/
const char *
vips_foreign_find_save_options( const char *filename )
{
VipsObjectClass *oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE );
VipsObject *object;
const char *type_name;
/* This will use vips_foreign_save_new_from_string() to pick a saver,
* then set options from the tail of the filename. This is rather slow
* :-(
*/
if( !(object = vips_object_new_from_string( oclass, filename )) )
return( NULL );
type_name = G_OBJECT_TYPE_NAME( object );
g_object_unref( object );
return( type_name );
}
static VipsObject *
vips_foreign_save_new_from_string( const char *string )
{
@ -1139,7 +1210,8 @@ vips_foreign_save_build( VipsObject *object )
{
VipsForeignSave *save = VIPS_FOREIGN_SAVE( object );
if( vips_foreign_convert_saveable( save ) )
if( save->in &&
vips_foreign_convert_saveable( save ) )
return( -1 );
if( VIPS_OBJECT_CLASS( vips_foreign_save_parent_class )->
@ -1222,7 +1294,8 @@ vips_foreign_load( const char *filename, VipsImage **out, ... )
* @...: %NULL-terminated list of optional named arguments
*
* Saves @in to @filename using the saver recommended by
* vips_foreign_find_save().
* vips_foreign_find_save(). Options are not in @filename but must be given
* as a NULL-terminated list of name-value pairs.
*
* See also: vips_foreign_load().
*
@ -1302,7 +1375,10 @@ vips_foreign_load_options( const char *filename, VipsImage **out )
* @filename: file to write to
*
* Saves @in to @filename using the saver recommended by
* vips_foreign_find_save().
* vips_foreign_find_save().
*
* Arguments to the saver may be embedded in the filename using the usual
* syntax.
*
* See also: vips_foreign_save().
*

View File

@ -189,6 +189,7 @@ typedef struct _VipsForeignLoadClass {
GType vips_foreign_load_get_type( void );
const char *vips_foreign_find_load( const char *filename );
const char *vips_foreign_find_load_options( const char *filename );
VipsForeignFlags vips_foreign_flags( const char *loader, const char *filename );
gboolean vips_foreign_is_a( const char *loader, const char *filename );
@ -277,6 +278,7 @@ typedef struct _VipsForeignSaveClass {
GType vips_foreign_save_get_type( void );
const char *vips_foreign_find_save( const char *filename );
const char *vips_foreign_find_save_options( const char *filename );
/* Read/write an image convenience functions.
*/

View File

@ -503,12 +503,12 @@ vips_image_rewind( VipsObject *object )
* to a "p" and on "written" do im_vips2tiff() or whatever.
*/
/* From "written" callback: invoke a delayed save by building the write object..
/* From "written" callback: save to image->filename using VipsForeign.
*/
static void
vips_image_save_cb( VipsImage *image, int *result, VipsObject *write )
vips_image_save_cb( VipsImage *image, int *result )
{
if( vips_object_build( write ) )
if( vips_foreign_save_options( image, image->filename ) )
*result = -1;
}
@ -669,36 +669,27 @@ vips_image_build( VipsObject *object )
case 'w':
{
VipsObjectClass *oclass =
g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE );
VipsObject *object;
/* This will use vips_foreign_save_new_from_string() to pick a
* saver, then set options from the tail of the filename.
*/
if( !(object = vips_object_new_from_string( oclass,
filename )) )
return( -1 );
vips_object_local( image, object );
const char *file_op;
/* Make sure the vips saver is there ... strange things will
* happen if that type is renamed or removed.
* happen if this type is renamed or removed.
*/
g_assert( g_type_from_name( "VipsForeignSaveVips" ) );
/* If this ia the vips saver, just save directly ourselves.
* Otherwise trigger a _build() and save when the image has
* been written to.
if( !(file_op = vips_foreign_find_save_options( filename )) )
return( -1 );
/* If this is the vips saver, just save directly ourselves.
* Otherwise save with VipsForeign when the image has been
* written to.
*/
if( G_TYPE_CHECK_INSTANCE_TYPE( object,
g_type_from_name( "VipsForeignSaveVips" ) ) ) {
if( strcmp( file_op, "VipsForeignSaveVips" ) == 0 )
image->dtype = VIPS_IMAGE_OPENOUT;
}
else {
image->dtype = VIPS_IMAGE_PARTIAL;
g_signal_connect( image, "written",
G_CALLBACK( vips_image_save_cb ),
object );
NULL );
}
}
break;