diff --git a/ChangeLog b/ChangeLog index 3c2ea093..069101f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ - cast to unsigned int now removes <0 values - vips7 interface to openslide now supports :,level,associated options - make vips8 cache smaller +- more accurate progress reporting 13/3/12 started 7.28.2 - xres/yres tiffsave args were broken diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index cd5e1d44..e93d3e3c 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -476,7 +476,7 @@ 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 ); +void vips_image_eval( VipsImage *image, guint64 processed ); void vips_image_posteval( VipsImage *image ); void vips_image_set_progress( VipsImage *image, gboolean progress ); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 0f40aa79..de8c2f99 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -1092,8 +1092,8 @@ vips_progress_add( VipsImage *image ) return( 0 ); } -void -vips_progress_update( VipsProgress *progress, int w, int h ) +static void +vips_progress_update( VipsProgress *progress, guint64 processed ) { float prop; @@ -1102,11 +1102,11 @@ vips_progress_update( VipsProgress *progress, int w, int h ) g_assert( progress ); progress->run = g_timer_elapsed( progress->start, NULL ); - progress->npels += w * h; + progress->npels = processed; prop = (float) progress->npels / (float) progress->tpels; progress->percent = 100 * prop; - /* Don't estiomate eta until we are 10% in. + /* Don't estimate eta until we are 10% in. */ if( prop > 0.1 ) progress->eta = (1.0 / prop) * progress->run - progress->run; @@ -1135,10 +1135,10 @@ vips_image_preeval( VipsImage *image ) } } -/* Another w * h pixels have been processed. +/* Updated the number of pixels that have been processed. */ void -vips_image_eval( VipsImage *image, int w, int h ) +vips_image_eval( VipsImage *image, guint64 processed ) { if( image->progress_signal ) { VIPS_DEBUG_MSG( "vips_image_eval: %p\n", image ); @@ -1146,7 +1146,7 @@ vips_image_eval( VipsImage *image, int w, int h ) g_assert( vips_object_sanity( VIPS_OBJECT( image->progress_signal ) ) ); - vips_progress_update( image->time, w, h ); + vips_progress_update( image->time, processed ); /* For vips7 compat, update the ->time on the signalling image * too, even though it may have a different width/height to @@ -1154,7 +1154,7 @@ vips_image_eval( VipsImage *image, int w, int h ) */ if( image->progress_signal->time != image->time ) vips_progress_update( image->progress_signal->time, - w, h ); + processed ); g_signal_emit( image->progress_signal, vips_image_signals[SIG_EVAL], 0, image->time ); @@ -1878,7 +1878,7 @@ vips_image_write_line( VipsImage *image, int ypos, VipsPel *linebuffer ) /* Trigger evaluation callbacks for this image. */ - vips_image_eval( image, image->Xsize, 1 ); + vips_image_eval( image, ypos * image->Xsize ); if( vips_image_get_kill( image ) ) return( -1 ); diff --git a/libvips/iofuncs/sink.c b/libvips/iofuncs/sink.c index 1f05ed91..b34e90dd 100644 --- a/libvips/iofuncs/sink.c +++ b/libvips/iofuncs/sink.c @@ -211,6 +211,8 @@ vips_sink_base_init( SinkBase *sink_base, VipsImage *image ) vips_get_tile_size( image, &sink_base->tile_width, &sink_base->tile_height, &sink_base->nlines ); + + sink_base->processed = 0; } static int @@ -283,6 +285,10 @@ vips_sink_base_allocate( VipsThreadState *state, void *a, gboolean *stop ) */ sink_base->x += sink_base->tile_width; + /* Add the number of pixels we've just allocated to progress. + */ + sink_base->processed += state->pos.width * state->pos.height; + return( 0 ); } @@ -305,14 +311,12 @@ vips_sink_base_progress( void *a ) { SinkBase *sink_base = (SinkBase *) a; - VIPS_DEBUG_MSG( "vips_sink_base_progress: %d x %d\n", - sink_base->tile_width, sink_base->tile_height ); + VIPS_DEBUG_MSG( "vips_sink_base_progress:\n" ); /* Trigger any eval callbacks on our source image and * check for errors. */ - vips_image_eval( sink_base->im, - sink_base->tile_width, sink_base->tile_height ); + vips_image_eval( sink_base->im, sink_base->processed ); if( vips_image_get_kill( sink_base->im ) ) return( -1 ); diff --git a/libvips/iofuncs/sink.h b/libvips/iofuncs/sink.h index e520fc0c..38843506 100644 --- a/libvips/iofuncs/sink.h +++ b/libvips/iofuncs/sink.h @@ -56,6 +56,10 @@ typedef struct _SinkBase { int tile_height; int nlines; + /* The number of pixels allocate has allocated. Used for progress + * feedback. + */ + guint64 processed; } SinkBase; /* Some function we can share. diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index 432a0992..a8bda0b7 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -396,6 +396,10 @@ wbuffer_allocate_fn( VipsThreadState *state, void *a, gboolean *stop ) */ sink_base->x += sink_base->tile_width; + /* Add the number of pixels we've just allocated to progress. + */ + sink_base->processed += state->pos.width * state->pos.height; + return( 0 ); } diff --git a/libvips/iofuncs/sinkmemory.c b/libvips/iofuncs/sinkmemory.c index 375d5916..3b55d690 100644 --- a/libvips/iofuncs/sinkmemory.c +++ b/libvips/iofuncs/sinkmemory.c @@ -240,6 +240,10 @@ sink_memory_area_allocate_fn( VipsThreadState *state, void *a, gboolean *stop ) */ sink_base->x += sink_base->tile_width; + /* Add the number of pixels we've just allocated to progress. + */ + sink_base->processed += state->pos.width * state->pos.height; + return( 0 ); }