rewind is an object method

make rewind a method on object, image uses it to preserve filename and
mode across rewind
This commit is contained in:
John Cupitt 2011-03-10 23:44:38 +00:00
parent e180c9ec52
commit 939ce4fd51
5 changed files with 73 additions and 28 deletions

12
TODO
View File

@ -1,15 +1,7 @@
- rewind is not removing arg instance flags
- on rewind, we junk filename, argh
VIPS-WARNING **: object.c:567: VipsImage can only assign 'nickname' once
I guess we need to save and restore it
VipsArgumentInstance *argument_instance =
vips__argument_get_instance( argument_class, object );
how do we find and junk these?
vips_object_dispose_argument(
runs, but perhaps does not trash instance storage? where is this released?

View File

@ -349,6 +349,8 @@ double vips_image_get_xres( VipsImage *image );
double vips_image_get_yres( VipsImage *image );
int vips_image_get_xoffset( VipsImage *image );
int vips_image_get_yoffset( VipsImage *image );
const char *vips_image_get_filename( VipsImage *image );
const char *vips_image_get_mode( VipsImage *image );
size_t vips_image_size( VipsImage *image );
void vips_image_written( VipsImage *image );

View File

@ -217,6 +217,11 @@ struct _VipsObjectClass {
*/
void (*sanity)( VipsObject *, VipsBuf * );
/* Rewind. Save and restore any stuff that needs to survive a
* dispose().
*/
void (*rewind)( VipsObject * );
/* Just before close, everything is still alive.
*/
void (*preclose)( VipsObject * );

View File

@ -506,6 +506,27 @@ vips_image_sanity( VipsObject *object, VipsBuf *buf )
VIPS_OBJECT_CLASS( vips_image_parent_class )->sanity( object, buf );
}
static void
vips_image_rewind( VipsObject *object )
{
VipsImage *image = VIPS_IMAGE( object );
char *filename;
char *mode;
/* The old values for filename and mode become the new defaults.
*/
filename = g_strdup( vips_image_get_filename( image ) );
mode = g_strdup( vips_image_get_mode( image ) );
VIPS_OBJECT_CLASS( vips_image_parent_class )->rewind( object );
g_assert( image->filename == NULL );
g_assert( image->mode == NULL );
image->filename = filename;
image->mode = mode;
}
static gboolean
vips_format_is_vips( VipsFormatClass *format )
{
@ -1042,6 +1063,7 @@ vips_image_class_init( VipsImageClass *class )
vobject_class->print = vips_image_print;
vobject_class->sanity = vips_image_sanity;
vobject_class->rewind = vips_image_rewind;
vobject_class->build = vips_image_build;
class->invalidate = vips_image_real_invalidate;
@ -1261,6 +1283,12 @@ vips_image_get_yoffset( VipsImage *image )
return( image->Yoffset );
}
const char *
vips_image_get_filename( VipsImage *image )
{
return( image->filename );
}
size_t
vips_image_size( VipsImage *image )
{

View File

@ -172,6 +172,20 @@ vips_object_sanity( VipsObject *object )
return( TRUE );
}
/* On a rewind, we dispose the old contents of the object and
* reconstruct. This is used in things like im_pincheck() where a "w"
* image has to be rewound and become a "p" image.
*
* Override in subclasses if you want to preserve some fields, see image.c.
*/
void
vips_object_rewind( VipsObject *object )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
class->rewind( object );
}
/* Extra stuff we track for properties to do our argument handling.
*/
@ -180,6 +194,8 @@ vips_object_sanity( VipsObject *object )
static void
vips_argument_instance_free( VipsArgumentInstance *argument_instance )
{
printf( "vips_argument_instance_free\n" );
if( argument_instance->destroy_id ) {
g_signal_handler_disconnect( argument_instance->object,
argument_instance->destroy_id );
@ -368,10 +384,10 @@ vips_object_dispose_argument( VipsObject *object, GParamSpec *pspec,
void *a, void *b )
{
#ifdef DEBUG
#endif /*DEBUG*/
printf( "vips_object_dispose_argument: " );
vips_object_print( object );
printf( ".%s\n", pspec->name );
#endif /*DEBUG*/
g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
g_assert( ((VipsArgument *) argument_instance)->pspec == pspec );
@ -404,9 +420,9 @@ vips_object_dispose( GObject *gobject )
VipsObject *object = VIPS_OBJECT( gobject );
#ifdef DEBUG
#endif /*DEBUG*/
printf( "vips_object_dispose: " );
vips_object_print( object );
#endif /*DEBUG*/
/* Our subclasses should have already called this. Run it again, just
* in case.
@ -423,6 +439,7 @@ vips_object_dispose( GObject *gobject )
/* Clear all our arguments: they may be holding refs we should drop.
*/
vips_argument_map( object, vips_object_dispose_argument, NULL, NULL );
VIPS_FREEF( vips_argument_table_destroy, object->argument_table );
G_OBJECT_CLASS( vips_object_parent_class )->dispose( gobject );
}
@ -440,7 +457,6 @@ vips_object_finalize( GObject *gobject )
vips_object_close( object );
g_hash_table_remove( vips_object_all, object );
VIPS_FREEF( vips_argument_table_destroy, object->argument_table );
G_OBJECT_CLASS( vips_object_parent_class )->finalize( gobject );
@ -792,6 +808,22 @@ vips_object_real_sanity( VipsObject *object, VipsBuf *buf )
{
}
static void
vips_object_real_rewind( VipsObject *object )
{
#ifdef DEBUG
#endif /*DEBUG*/
printf( "vips_object_rewind\n" );
vips_object_print( object );
g_object_run_dispose( G_OBJECT( object ) );
object->constructed = FALSE;
object->preclose = FALSE;
object->close = FALSE;
object->postclose = FALSE;
}
static void
transform_string_double( const GValue *src_value, GValue *dest_value )
{
@ -819,6 +851,7 @@ vips_object_class_init( VipsObjectClass *class )
class->print_class = vips_object_real_print_class;
class->print = vips_object_real_print;
class->sanity = vips_object_real_sanity;
class->rewind = vips_object_real_rewind;
class->nickname = "object";
class->description = _( "VIPS base class" );
@ -1244,18 +1277,3 @@ vips_object_sanity_all( void )
{
vips_object_map( (VSListMap2Fn) vips_object_sanity_all_cb, NULL, NULL );
}
/* On a rewind, we dispose the old contents of the object and
* reconstruct. This is used in things like im_pincheck() where a "w"
* image has to be rewound and become a "p" image.
*/
void
vips_object_rewind( VipsObject *object )
{
g_object_run_dispose( G_OBJECT( object ) );
object->constructed = FALSE;
object->preclose = FALSE;
object->close = FALSE;
object->postclose = FALSE;
}