From 67e7cdc4d6171d38b1a421ebcfb15171e5a4b390 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 2 Nov 2007 19:05:00 +0000 Subject: [PATCH] propogate progress feedback down pipelines --- ChangeLog | 2 ++ TODO | 5 +++-- include/vips/vips.h | 4 ++++ libsrc/conversion/im_vips2png.c | 3 +-- libsrc/iofuncs/buffer.c | 5 +++++ libsrc/iofuncs/callback.c | 11 +++++++++-- libsrc/iofuncs/im_cp_desc.c | 2 +- libsrc/iofuncs/im_init.c | 2 ++ libsrc/iofuncs/time.c | 18 +++++++++++++----- 9 files changed, 40 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index cf626f52..21b86f90 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ - break im_wbuffer() out to a separate API - use im_wbuffer() to make im_vips2jpeg() compress in the background - also im_vips2png() +- new system for propogating progress settings down pipelines unbreaks save + feedback in nip2 28/9/07 started 7.13.1 - vips2dj can print RGB images diff --git a/TODO b/TODO index d404c051..bdf1103b 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,6 @@ -- wrap API around the double-buffered write stuff and get - jpeg/tiff/png/ppm/etc. all writing double-buffered as well +- im__convert_saveable() is not propogating 'progress' for wtc2.jpg + +- done jpeg, png ... make others dbl-buf writes too - missing libstdc++ in link? what if we configure with no openexr? diff --git a/include/vips/vips.h b/include/vips/vips.h index 72ccaa50..dbf36932 100644 --- a/include/vips/vips.h +++ b/include/vips/vips.h @@ -326,6 +326,10 @@ typedef struct im__IMAGE { * efficiently. */ GSList *history_list; + + /* The IMAGE (if any) we should signal eval progress on. + */ + struct im__IMAGE *progress; } IMAGE; /* Only define if IM_ENABLE_DEPRECATED is set. diff --git a/libsrc/conversion/im_vips2png.c b/libsrc/conversion/im_vips2png.c index 1e3728c1..86ddc636 100644 --- a/libsrc/conversion/im_vips2png.c +++ b/libsrc/conversion/im_vips2png.c @@ -195,8 +195,7 @@ write_vips( Write *write, int compress, int interlace ) { IMAGE *in = write->in; - Rect area; - int j, y, i, nb_passes; + int i, nb_passes; assert( in->BandFmt == IM_BANDFMT_UCHAR ); assert( in->Coding == IM_CODING_NONE ); diff --git a/libsrc/iofuncs/buffer.c b/libsrc/iofuncs/buffer.c index 03dd439a..202f58d9 100644 --- a/libsrc/iofuncs/buffer.c +++ b/libsrc/iofuncs/buffer.c @@ -475,6 +475,11 @@ im__link_make( IMAGE *parent, IMAGE *child ) parent->children = g_slist_prepend( parent->children, child ); child->parents = g_slist_prepend( child->parents, parent ); + + /* Propogate the progress indicator. + */ + if( !child->progress && parent->progress ) + child->progress = parent->progress; } /* Break link. diff --git a/libsrc/iofuncs/callback.c b/libsrc/iofuncs/callback.c index 8e3d82c1..eec3f88b 100644 --- a/libsrc/iofuncs/callback.c +++ b/libsrc/iofuncs/callback.c @@ -88,11 +88,18 @@ im_add_close_callback( IMAGE *im, int (*fn)(), void *a, void *b ) return( add_callback( im, &im->closefns, fn, a, b ) ); } -/* Add an eval callback to an IMAGE. +/* Add an eval callback to an IMAGE. You must call this after opening the + * image, but before using it as an argument to an operation. */ int im_add_eval_callback( IMAGE *im, int (*fn)(), void *a, void *b ) -{ +{ + /* Mark this image as needing progress feedback. im__link_make() + * propogates this value to our children as we build a pipeline. + * im__handle_eval() looks up the IMAGE it should signal on. + */ + im->progress = im; + return( add_callback( im, &im->evalfns, fn, a, b ) ); } diff --git a/libsrc/iofuncs/im_cp_desc.c b/libsrc/iofuncs/im_cp_desc.c index c18536b9..addd7320 100644 --- a/libsrc/iofuncs/im_cp_desc.c +++ b/libsrc/iofuncs/im_cp_desc.c @@ -59,7 +59,7 @@ */ #ifdef HAVE_CONFIG_H -#include +#include #endif /*HAVE_CONFIG_H*/ #include diff --git a/libsrc/iofuncs/im_init.c b/libsrc/iofuncs/im_init.c index 65271879..384acbb3 100644 --- a/libsrc/iofuncs/im_init.c +++ b/libsrc/iofuncs/im_init.c @@ -157,6 +157,8 @@ im_init( const char *filename ) im->history_list = NULL; + im->progress = NULL; + if( !(im->filename = im_strdup( NULL, filename )) ) { im_close( im ); return( NULL ); diff --git a/libsrc/iofuncs/time.c b/libsrc/iofuncs/time.c index 387e800f..bae9f1ab 100644 --- a/libsrc/iofuncs/time.c +++ b/libsrc/iofuncs/time.c @@ -99,18 +99,26 @@ update_time( im_time_t *time, int w, int h ) } /* Handle eval callbacks. w and h are the size of the tile we made this time. + * We signal progress on the ->progress IMAGE, see im_add_eval_callback(). We + * assume there's no geometry change between adding the feedback request and + * evaling the image. */ int im__handle_eval( IMAGE *im, int w, int h ) { - if( im->evalfns ) { - if( !im->time ) - if( time_add( im ) ) + if( im->progress ) { + if( !im->progress->time ) { + /* So we just check sanity first time around. + */ + im_image_sanity( im->progress ); + + if( time_add( im->progress ) ) return( -1 ); - if( update_time( im->time, w, h ) ) + } + if( update_time( im->progress->time, w, h ) ) return( -1 ); - if( im__trigger_callbacks( im->evalfns ) ) + if( im__trigger_callbacks( im->progress->evalfns ) ) return( -1 ); }