new-style CLI save working

This commit is contained in:
John Cupitt 2011-11-27 21:31:21 +00:00
parent d6240ac11a
commit b9db7249f4
8 changed files with 150 additions and 103 deletions

12
TODO
View File

@ -1,12 +1,6 @@
- test ref counting in vips_object_set_argument_from_string() VipsFile stuff
- make compat wrappers for old im_jpeg2vips() and im_vips2jpeg()
add path for output images, see vips_object_get_argument_to_string()
make compat wrappers for old im_jpeg2vips() and im_vips2jpeg()
make sure we are using the operation cache for jpegload
move format/* to deprecated
@ -15,7 +9,7 @@
- return missing just after read_xmp() in master?

View File

@ -876,6 +876,10 @@ input_interpolate_init( im_object *obj, char *str )
interpolate_class = vips_class_find( "VipsInterpolate", "interpolate" );
if( !(object = vips_object_new_from_string( interpolate_class, str )) )
return( -1 );
if( vips_object_build( object ) ) {
g_object_unref( object );
return( -1 );
}
*obj = object;
return( 0 );

View File

@ -547,24 +547,34 @@ vips_file_load_build( VipsObject *object )
build( object ) )
return( -1 );
/* Read header fields to init the return image. THINSTRIP since this is
* probably a disc file. We can't tell yet whether we will be opening
* to memory, sadly, so we can't suggest ANY.
/* Read the header into @out.
*/
if( class->header &&
class->header( load ) )
return( -1 );
vips_demand_hint( load->out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
/* Then 'start' creates the real image and 'gen' fetches pixels for
* 'out' from real on demand.
/* If there's no ->load() method then the header read has done
* everything. Otherwise, it's just set fields and we now must
* convert pixels on demand.
*/
if( vips_image_generate( load->out,
vips_file_load_start_cb,
vips_file_load_generate_cb,
vips_stop_one,
load, NULL ) )
return( -1 );
if( class->load ) {
/* THINSTRIP since this is probably a disc file.
* We can't tell yet whether we will be opening
* to memory, sadly, so we can't suggest ANY.
*/
vips_demand_hint( load->out,
VIPS_DEMAND_STYLE_THINSTRIP, NULL );
/* Then 'start' creates the real image and 'gen' fetches
* pixels for @out from @real on demand.
*/
if( vips_image_generate( load->out,
vips_file_load_start_cb,
vips_file_load_generate_cb,
vips_stop_one,
load, NULL ) )
return( -1 );
}
return( 0 );
}
@ -640,6 +650,69 @@ vips_file_save_print_class( VipsObjectClass *object_class, VipsBuf *buf )
VIPS_ENUM_NICK( VIPS_TYPE_SAVEABLE, class->saveable ) );
}
/* Can we write this filename with this file?
*/
static void *
vips_file_save_new_from_filename_sub( VipsFileSaveClass *save_class,
const char *filename )
{
VipsFileClass *class = VIPS_FILE_CLASS( save_class );
if( vips_filename_suffix_match( filename, class->suffs ) )
return( save_class );
return( NULL );
}
/**
* vips_file_find_save:
* @filename: name to find a file for
*
* Searches for an operation you could use to save a file.
*
* See also: vips_file_write().
*
* Returns: the name of an operation on success, %NULL on error
*/
const char *
vips_file_find_save( const char *filename )
{
VipsFileSaveClass *save_class;
if( !(save_class = (VipsFileSaveClass *) vips_file_map(
"VipsFileSave",
(VipsSListMap2Fn) vips_file_save_new_from_filename_sub,
(void *) filename, NULL )) ) {
vips_error( "VipsFileSave",
_( "\"%s\" is not a supported image file." ),
filename );
return( NULL );
}
return( G_OBJECT_CLASS_NAME( save_class ) );
}
static VipsObject *
vips_file_save_new_from_string( const char *string )
{
const char *file_op;
GType type;
VipsFileSave *save;
if( !(file_op = vips_file_find_save( string )) )
return( NULL );
type = g_type_from_name( file_op );
g_assert( type );
save = VIPS_FILE_SAVE( g_object_new( type, NULL ) );
g_object_set( save,
"filename", string,
NULL );
return( VIPS_OBJECT( save ) );
}
/* Generate the saveable image.
*/
static int
@ -864,10 +937,11 @@ vips_file_save_class_init( VipsFileSaveClass *class )
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->build = vips_file_save_build;
object_class->print_class = vips_file_save_print_class;
object_class->new_from_string = vips_file_save_new_from_string;
object_class->nickname = "filesave";
object_class->description = _( "file savers" );
object_class->print_class = vips_file_save_print_class;
object_class->build = vips_file_save_build;
VIPS_ARG_IMAGE( class, "in", 0,
_( "Input" ),
@ -881,49 +955,6 @@ vips_file_save_init( VipsFileSave *object )
{
}
/* Can we write this filename with this file?
*/
static void *
vips_file_save_new_from_filename_sub( VipsFileSaveClass *save_class,
const char *filename )
{
VipsFileClass *class = VIPS_FILE_CLASS( save_class );
if( vips_filename_suffix_match( filename, class->suffs ) )
return( save_class );
return( NULL );
}
/**
* vips_file_find_save:
* @filename: name to find a file for
*
* Searches for an operation you could use to save a file.
*
* See also: vips_file_write().
*
* Returns: the name of an operation on success, %NULL on error
*/
const char *
vips_file_find_save( const char *filename )
{
VipsFileSaveClass *save_class;
if( !(save_class = (VipsFileSaveClass *) vips_file_map(
"VipsFileSave",
(VipsSListMap2Fn) vips_file_save_new_from_filename_sub,
(void *) filename, NULL )) ) {
vips_error( "VipsFileSave",
_( "\"%s\" is not a supported image file." ),
filename );
return( NULL );
}
return( G_OBJECT_CLASS_NAME( save_class ) );
}
/**
* vips_file_read:
* @filename: file to load

View File

@ -49,16 +49,6 @@ typedef VipsFileLoadClass VipsFileLoadVipsClass;
G_DEFINE_TYPE( VipsFileLoadVips, vips_file_load_vips, VIPS_TYPE_FILE_LOAD );
static int
vips_file_load_vips_build( VipsObject *object )
{
if( VIPS_OBJECT_CLASS( vips_file_load_vips_parent_class )->
build( object ) )
return( -1 );
return( 0 );
}
static gboolean
vips_file_load_vips_is_a( const char *filename )
{
@ -86,20 +76,19 @@ static int
vips_file_load_vips_header( VipsFileLoad *load )
{
VipsFile *file = VIPS_FILE( load );
VipsImage *out;
VipsImage *out2;
if( !(load->out = vips_image_new_from_file( file->filename )) )
if( !(out2 = vips_image_new_from_file( file->filename )) )
return( -1 );
return( 0 );
}
/* Unref the @out that's there now.
*/
g_object_get( load, "out", &out, NULL );
g_object_unref( out );
g_object_unref( out );
static int
vips_file_load_vips_load( VipsFileLoad *load )
{
VipsFile *file = VIPS_FILE( load );
if( !(load->real = vips_image_new_from_file( file->filename )) )
return( -1 );
g_object_set( load, "out", out2, NULL );
return( 0 );
}
@ -115,14 +104,13 @@ vips_file_load_vips_class_init( VipsFileLoadVipsClass *class )
object_class->nickname = "vipsload";
object_class->description = _( "load vips from file" );
object_class->build = vips_file_load_vips_build;
file_class->suffs = vips_suffs;
load_class->is_a = vips_file_load_vips_is_a;
load_class->get_flags = vips_file_load_vips_get_flags;
load_class->header = vips_file_load_vips_header;
load_class->load = vips_file_load_vips_load;
load_class->load = NULL;
}
static void

View File

@ -145,11 +145,13 @@ typedef struct _VipsFileLoadClass {
*/
int (*get_flags)( VipsFileLoad * );
/* Read the header into @out.
/* Set the header fields in @out from @filename. If you can read the
* whole image as well with no performance cost (as with vipsload),
* leave ->load() NULL.
*/
int (*header)( VipsFileLoad * );
/* Read the whole image into real. It gets copied to out later.
/* Read the whole image into @real. It gets copied to @out later.
*/
int (*load)( VipsFileLoad * );

View File

@ -682,7 +682,7 @@ vips_image_generate( VipsImage *image,
*/
vips_error( "VipsImage",
_( "unable to output to a %s image" ),
VIPS_ENUM_NICK( VIPS_TYPE_DEMAND_STYLE,
VIPS_ENUM_NICK( VIPS_TYPE_IMAGE_TYPE,
image->dtype ) );
return( -1 );
}

View File

@ -1796,7 +1796,7 @@ vips_image_write_line( VipsImage *image, int ypos, PEL *linebuffer )
default:
vips_error( "VipsImage",
_( "unable to output to a %s image" ),
VIPS_ENUM_STRING( VIPS_TYPE_DEMAND_STYLE,
VIPS_ENUM_STRING( VIPS_TYPE_IMAGE_TYPE,
image->dtype ) );
return( -1 );
}

View File

@ -1236,28 +1236,33 @@ vips_object_set_argument_from_string( VipsObject *object,
VipsObject *new_object;
VipsImage *out;
/* Use VipsFile to build images, then pull 'out' from it and
* set that to set the value.
/* Use VipsFile to build images, then pull @out from it and
* use that to set the value.
*/
if( !(new_object =
vips_object_new_from_string( oclass, value )) )
return( -1 );
if( vips_object_build( new_object ) ) {
g_object_unref( new_object );
return( -1 );
}
g_object_get( new_object, "out", &out, NULL );
/* Getting 'out' will have upped it's count and we want to
/* Getting @out will have upped it's count and we want to
* hold the only ref to it.
*/
g_object_unref( out );
/* 'out' holds a ref to new_object, we can drop ours.
/* @out holds a ref to new_object, we can drop ours.
*/
g_object_unref( new_object );
g_value_init( &gvalue, VIPS_TYPE_IMAGE );
g_value_set_object( &gvalue, out );
/* Setting gvalue will have upped out's count again,
/* Setting gvalue will have upped @out's count again,
* go back to 1 so that gvalue has the only ref.
*/
g_object_unref( out );
@ -1270,6 +1275,11 @@ vips_object_set_argument_from_string( VipsObject *object,
vips_object_new_from_string( oclass, value )) )
return( -1 );
if( vips_object_build( new_object ) ) {
g_object_unref( new_object );
return( -1 );
}
g_value_init( &gvalue, G_TYPE_OBJECT );
g_value_set_object( &gvalue, new_object );
@ -1407,7 +1417,30 @@ vips_object_get_argument_to_string( VipsObject *object,
g_assert( argument_class->flags & VIPS_ARGUMENT_OUTPUT );
if( g_type_is_a( otype, VIPS_TYPE_OBJECT ) &&
if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) &&
(oclass = g_type_class_ref( VIPS_TYPE_FILE_SAVE )) ) {
VipsObject *new_object;
VipsImage *in;
/* Use VipsFile to make a saver, set 'in' on that and run
* build to make it write.
*/
if( !(new_object =
vips_object_new_from_string( oclass, arg )) )
return( -1 );
g_object_get( object, name, &in, NULL );
g_object_set( new_object, "in", in, NULL );
g_object_unref( in );
if( vips_object_build( new_object ) ) {
g_object_unref( new_object );
return( -1 );
}
g_object_unref( new_object );
}
else if( g_type_is_a( otype, VIPS_TYPE_OBJECT ) &&
(oclass = g_type_class_ref( otype )) &&
oclass->output_to_arg ) {
VipsObject *value;
@ -1570,11 +1603,6 @@ vips_object_new_from_string( VipsObjectClass *object_class, const char *p )
}
}
if( vips_object_build( object ) ) {
g_object_unref( object );
return( NULL );
}
return( object );
}