new progress feedback system
This commit is contained in:
parent
a65cfcd884
commit
bc84d2ce57
@ -4,8 +4,11 @@
|
|||||||
- break im_wbuffer() out to a separate API
|
- break im_wbuffer() out to a separate API
|
||||||
- use im_wbuffer() to make im_vips2jpeg() compress in the background
|
- use im_wbuffer() to make im_vips2jpeg() compress in the background
|
||||||
- also im_vips2png(), im_vips2tiff(), im_vips2ppm()
|
- also im_vips2png(), im_vips2tiff(), im_vips2ppm()
|
||||||
- new system for propogating progress settings down pipelines unbreaks save
|
- revised evaluation progress system
|
||||||
feedback in nip2
|
- new evalstart/evalend/preclose callbacks fix over/underflow reporting
|
||||||
|
- but the meaning of evalend has changed in a non-backwards-compatible way :(
|
||||||
|
use preclose instead ito get the old behaviour
|
||||||
|
- added "--vips-progress" flag to turn on a simple eval progress tracker
|
||||||
|
|
||||||
28/9/07 started 7.13.1
|
28/9/07 started 7.13.1
|
||||||
- vips2dj can print RGB images
|
- vips2dj can print RGB images
|
||||||
|
4
TODO
4
TODO
@ -1,7 +1,9 @@
|
|||||||
- test ppm writer
|
- update docs, add pages for new cbs
|
||||||
|
|
||||||
- talk about new progress system in im_add_eval_callback()?
|
- talk about new progress system in im_add_eval_callback()?
|
||||||
|
|
||||||
|
- test ppm writer
|
||||||
|
|
||||||
- missing libstdc++ in link? what if we configure with no openexr?
|
- missing libstdc++ in link? what if we configure with no openexr?
|
||||||
|
|
||||||
added -lstdc++ to VIPS_LIBS, but will this work on solaris etc.? maybe have
|
added -lstdc++ to VIPS_LIBS, but will this work on solaris etc.? maybe have
|
||||||
|
@ -37,6 +37,21 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
|
||||||
|
/* Default tile geometry.
|
||||||
|
*/
|
||||||
|
extern int im__tile_width;
|
||||||
|
extern int im__tile_height;
|
||||||
|
extern int im__fatstrip_height;
|
||||||
|
extern int im__thinstrip_height;
|
||||||
|
|
||||||
|
/* Default n threads.
|
||||||
|
*/
|
||||||
|
extern int im__concurrency;
|
||||||
|
|
||||||
|
/* Give progress feedback.
|
||||||
|
*/
|
||||||
|
extern int im__progress;
|
||||||
|
|
||||||
typedef int (*im__fftproc_fn)( IMAGE *, IMAGE *, IMAGE * );
|
typedef int (*im__fftproc_fn)( IMAGE *, IMAGE *, IMAGE * );
|
||||||
|
|
||||||
/* iofuncs
|
/* iofuncs
|
||||||
@ -53,7 +68,9 @@ void *im__read_extension_block( IMAGE *im, int *size );
|
|||||||
int im__readhist( IMAGE *image );
|
int im__readhist( IMAGE *image );
|
||||||
int im__write_extension_block( IMAGE *im, void *buf, int size );
|
int im__write_extension_block( IMAGE *im, void *buf, int size );
|
||||||
int im__writehist( IMAGE *image );
|
int im__writehist( IMAGE *image );
|
||||||
|
int im__start_eval( IMAGE *im );
|
||||||
int im__handle_eval( IMAGE *im, int w, int h );
|
int im__handle_eval( IMAGE *im, int w, int h );
|
||||||
|
int im__end_eval( IMAGE *im );
|
||||||
int im__time_destroy( IMAGE *im );
|
int im__time_destroy( IMAGE *im );
|
||||||
|
|
||||||
extern int im__read_test;
|
extern int im__read_test;
|
||||||
|
@ -74,6 +74,10 @@ typedef void *(*im_header_map_fn)( IMAGE *, const char *, GValue *, void * );
|
|||||||
int im_init_world( const char *argv0 );
|
int im_init_world( const char *argv0 );
|
||||||
GOptionGroup *im_get_option_group( void );
|
GOptionGroup *im_get_option_group( void );
|
||||||
|
|
||||||
|
/* Turn progress feedback on and off.
|
||||||
|
*/
|
||||||
|
void im_progress_set( int progress );
|
||||||
|
|
||||||
const char *im_error_buffer( void );
|
const char *im_error_buffer( void );
|
||||||
int im_debugim( IMAGE * );
|
int im_debugim( IMAGE * );
|
||||||
int im_printlines( IMAGE * );
|
int im_printlines( IMAGE * );
|
||||||
@ -149,6 +153,8 @@ int im_ismagick( const char * );
|
|||||||
int im_isanalyze( const char *filename );
|
int im_isanalyze( const char *filename );
|
||||||
|
|
||||||
int im_add_close_callback( IMAGE *, im_callback_fn, void *, void * );
|
int im_add_close_callback( IMAGE *, im_callback_fn, void *, void * );
|
||||||
|
int im_add_preclose_callback( IMAGE *, im_callback_fn, void *, void * );
|
||||||
|
int im_add_evalstart_callback( IMAGE *, im_callback_fn, void *, void * );
|
||||||
int im_add_eval_callback( IMAGE *, im_callback_fn, void *, void * );
|
int im_add_eval_callback( IMAGE *, im_callback_fn, void *, void * );
|
||||||
int im_add_evalend_callback( IMAGE *, im_callback_fn, void *, void * );
|
int im_add_evalend_callback( IMAGE *, im_callback_fn, void *, void * );
|
||||||
|
|
||||||
|
@ -47,17 +47,6 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define IM__DEFAULT_STACK_SIZE (2 * 1024 * 1024)
|
#define IM__DEFAULT_STACK_SIZE (2 * 1024 * 1024)
|
||||||
|
|
||||||
/* Default tile geometry.
|
|
||||||
*/
|
|
||||||
extern int im__tile_width;
|
|
||||||
extern int im__tile_height;
|
|
||||||
extern int im__fatstrip_height;
|
|
||||||
extern int im__thinstrip_height;
|
|
||||||
|
|
||||||
/* Default n threads.
|
|
||||||
*/
|
|
||||||
extern int im__concurrency;
|
|
||||||
|
|
||||||
/* A work function.
|
/* A work function.
|
||||||
*/
|
*/
|
||||||
typedef int (*im__work_fn)( REGION *, void *, void *, void * );
|
typedef int (*im__work_fn)( REGION *, void *, void *, void * );
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
* - added RGB16, GREY16
|
* - added RGB16, GREY16
|
||||||
* 30/10/06
|
* 30/10/06
|
||||||
* - added im_window_t
|
* - added im_window_t
|
||||||
|
* 7/11/07
|
||||||
|
* - added preclose and evalstart callbacks
|
||||||
|
* - brought time struct in here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -236,12 +239,13 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct im__IMAGE *im; /* Image we are part of */
|
struct im__IMAGE *im; /* Image we are part of */
|
||||||
GTimer *start; /* Start time */
|
time_t unused; /* FIXME ... for compatibility */
|
||||||
int run; /* Time we have been running */
|
int run; /* Time we have been running */
|
||||||
int eta; /* Estimated seconds of computation left */
|
int eta; /* Estimated seconds of computation left */
|
||||||
gint64 tpels; /* Number of pels we expect to calculate */
|
gint64 tpels; /* Number of pels we expect to calculate */
|
||||||
gint64 npels; /* Number of pels calculated so far */
|
gint64 npels; /* Number of pels calculated so far */
|
||||||
int percent; /* Percent complete */
|
int percent; /* Percent complete */
|
||||||
|
GTimer *start; /* Start time */
|
||||||
} im_time_t;
|
} im_time_t;
|
||||||
|
|
||||||
/* Image descriptor for subroutine i/o args
|
/* Image descriptor for subroutine i/o args
|
||||||
@ -303,7 +307,7 @@ typedef struct im__IMAGE {
|
|||||||
GSList *Meta_traverse; /* Traverse order for Meta */
|
GSList *Meta_traverse; /* Traverse order for Meta */
|
||||||
|
|
||||||
/* Part of mmap() read ... the sizeof() the header we skip from the
|
/* Part of mmap() read ... the sizeof() the header we skip from the
|
||||||
* file start. Usually IM_SIZEOF_HEADER, but can be soomething else
|
* file start. Usually IM_SIZEOF_HEADER, but can be something else
|
||||||
* for binary file read.
|
* for binary file read.
|
||||||
*/
|
*/
|
||||||
int sizeof_header;
|
int sizeof_header;
|
||||||
@ -330,6 +334,11 @@ typedef struct im__IMAGE {
|
|||||||
/* The IMAGE (if any) we should signal eval progress on.
|
/* The IMAGE (if any) we should signal eval progress on.
|
||||||
*/
|
*/
|
||||||
struct im__IMAGE *progress;
|
struct im__IMAGE *progress;
|
||||||
|
|
||||||
|
/* Some more callbacks. Appended to IMAGE for binary compatibility.
|
||||||
|
*/
|
||||||
|
GSList *evalstartfns; /* list of start eval callbacks */
|
||||||
|
GSList *preclosefns; /* list of pre-close callbacks */
|
||||||
} IMAGE;
|
} IMAGE;
|
||||||
|
|
||||||
/* Only define if IM_ENABLE_DEPRECATED is set.
|
/* Only define if IM_ENABLE_DEPRECATED is set.
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
* 21/4/04 JC
|
* 21/4/04 JC
|
||||||
* - now does floor(), not rint() ... you'll need to round yourself
|
* - now does floor(), not rint() ... you'll need to round yourself
|
||||||
* before calling this if you want round-to-nearest
|
* before calling this if you want round-to-nearest
|
||||||
|
* 7/11/07
|
||||||
|
* - use new evalstart/evalend system
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -100,7 +102,18 @@ typedef struct {
|
|||||||
} Clip;
|
} Clip;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
clip_destroy( Clip *clip )
|
clip_evalstart( Clip *clip )
|
||||||
|
{
|
||||||
|
/* Reset counts.
|
||||||
|
*/
|
||||||
|
clip->overflow = 0;
|
||||||
|
clip->underflow = 0;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
clip_evalend( Clip *clip )
|
||||||
{
|
{
|
||||||
/* Print warnings, if necessary.
|
/* Print warnings, if necessary.
|
||||||
*/
|
*/
|
||||||
@ -128,8 +141,10 @@ clip_new( IMAGE *in, IMAGE *out, int ofmt )
|
|||||||
clip->underflow = 0;
|
clip->underflow = 0;
|
||||||
clip->overflow = 0;
|
clip->overflow = 0;
|
||||||
|
|
||||||
if( im_add_close_callback( out,
|
if( im_add_evalstart_callback( out,
|
||||||
(im_callback_fn) clip_destroy, clip, NULL ) )
|
(im_callback_fn) clip_evalstart, clip, NULL ) ||
|
||||||
|
im_add_evalend_callback( out,
|
||||||
|
(im_callback_fn) clip_evalend, clip, NULL ) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
return( clip );
|
return( clip );
|
||||||
|
@ -352,7 +352,7 @@ im__convert_saveable( IMAGE *in, gboolean allow_alpha )
|
|||||||
{
|
{
|
||||||
IMAGE *out;
|
IMAGE *out;
|
||||||
|
|
||||||
if( !(out = im_open( "im__convert_saveable", "p" )) )
|
if( !(out = im_open( "convert-for-save", "p" )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* If this is a IM_CODING_LABQ, we can go straight to RGB.
|
/* If this is a IM_CODING_LABQ, we can go straight to RGB.
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
* - sets Xoffset / Yoffset
|
* - sets Xoffset / Yoffset
|
||||||
* 11/11/05
|
* 11/11/05
|
||||||
* - simpler inner loop avoids gcc4 bug
|
* - simpler inner loop avoids gcc4 bug
|
||||||
|
* 7/11/07
|
||||||
|
* - new evalstart/end callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -119,19 +121,34 @@ typedef struct {
|
|||||||
} Conv;
|
} Conv;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
conv_destroy( Conv *conv )
|
conv_close( Conv *conv )
|
||||||
|
{
|
||||||
|
IM_FREEF( im_free_imask, conv->mask );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
conv_evalstart( Conv *conv )
|
||||||
|
{
|
||||||
|
/* Reset underflow/overflow count.
|
||||||
|
*/
|
||||||
|
conv->overflow = 0;
|
||||||
|
conv->underflow = 0;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
conv_evalend( Conv *conv )
|
||||||
{
|
{
|
||||||
/* Print underflow/overflow count.
|
/* Print underflow/overflow count.
|
||||||
*/
|
*/
|
||||||
if( conv->overflow || conv->underflow )
|
if( conv->overflow || conv->underflow )
|
||||||
im_warning( "im_conv: %d overflows and %d underflows detected",
|
im_warn( "im_conv",
|
||||||
|
_( "%d overflows and %d underflows detected" ),
|
||||||
conv->overflow, conv->underflow );
|
conv->overflow, conv->underflow );
|
||||||
|
|
||||||
if( conv->mask ) {
|
|
||||||
(void) im_free_imask( conv->mask );
|
|
||||||
conv->mask = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +171,11 @@ conv_new( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|||||||
conv->overflow = 0;
|
conv->overflow = 0;
|
||||||
|
|
||||||
if( im_add_close_callback( out,
|
if( im_add_close_callback( out,
|
||||||
(im_callback_fn) conv_destroy, conv, NULL ) ||
|
(im_callback_fn) conv_close, conv, NULL ) ||
|
||||||
|
im_add_close_callback( out,
|
||||||
|
(im_callback_fn) conv_evalstart, conv, NULL ) ||
|
||||||
|
im_add_close_callback( out,
|
||||||
|
(im_callback_fn) conv_evalend, conv, NULL ) ||
|
||||||
!(conv->coeff = IM_ARRAY( out, ne, int )) ||
|
!(conv->coeff = IM_ARRAY( out, ne, int )) ||
|
||||||
!(conv->mask = im_dup_imask( mask, "conv_mask" )) )
|
!(conv->mask = im_dup_imask( mask, "conv_mask" )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
@ -92,7 +92,7 @@ typedef struct {
|
|||||||
} Conv;
|
} Conv;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
conv_destroy( Conv *conv )
|
conv_close( Conv *conv )
|
||||||
{
|
{
|
||||||
if( conv->mask ) {
|
if( conv->mask ) {
|
||||||
(void) im_free_dmask( conv->mask );
|
(void) im_free_dmask( conv->mask );
|
||||||
@ -119,7 +119,7 @@ conv_new( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
|||||||
conv->coeff = NULL;
|
conv->coeff = NULL;
|
||||||
|
|
||||||
if( im_add_close_callback( out,
|
if( im_add_close_callback( out,
|
||||||
(im_callback_fn) conv_destroy, conv, NULL ) ||
|
(im_callback_fn) conv_close, conv, NULL ) ||
|
||||||
!(conv->coeff = IM_ARRAY( out, ne, double )) ||
|
!(conv->coeff = IM_ARRAY( out, ne, double )) ||
|
||||||
!(conv->mask = im_dup_dmask( mask, "conv_mask" )) )
|
!(conv->mask = im_dup_dmask( mask, "conv_mask" )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
@ -285,13 +285,14 @@ im_convf_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
|||||||
/* Check parameters.
|
/* Check parameters.
|
||||||
*/
|
*/
|
||||||
if( !in || in->Coding != IM_CODING_NONE || im_iscomplex( in ) ) {
|
if( !in || in->Coding != IM_CODING_NONE || im_iscomplex( in ) ) {
|
||||||
im_errormsg( "im_convf: input non-complex uncoded please!");
|
im_error( "im_convf",
|
||||||
|
_( "non-complex uncoded only" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
|
if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
|
||||||
mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
|
mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
|
||||||
mask->scale == 0 ) {
|
mask->scale == 0 ) {
|
||||||
im_errormsg( "im_convf: nonsense mask parameters" );
|
im_error( "im_convf", _( "nonsense mask parameters" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
if( im_piocheck( in, out ) )
|
if( im_piocheck( in, out ) )
|
||||||
@ -311,7 +312,7 @@ im_convf_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
|||||||
out->Xsize -= mask->xsize - 1;
|
out->Xsize -= mask->xsize - 1;
|
||||||
out->Ysize -= mask->ysize - 1;
|
out->Ysize -= mask->ysize - 1;
|
||||||
if( out->Xsize <= 0 || out->Ysize <= 0 ) {
|
if( out->Xsize <= 0 || out->Ysize <= 0 ) {
|
||||||
im_errormsg( "im_convf: image too small for mask" );
|
im_error( "im_convf", _( "image too small for mask" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
* 30/6/04
|
* 30/6/04
|
||||||
* - heh, 1 band image + 3 band lut + >8bit output has been broken for 9
|
* - heh, 1 band image + 3 band lut + >8bit output has been broken for 9
|
||||||
* years :-)
|
* years :-)
|
||||||
|
* 7/11/07
|
||||||
|
* - new eval start/end system
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -103,16 +105,22 @@ typedef struct {
|
|||||||
int overflow; /* Number of overflows for non-uchar lut */
|
int overflow; /* Number of overflows for non-uchar lut */
|
||||||
} LutInfo;
|
} LutInfo;
|
||||||
|
|
||||||
|
static int
|
||||||
|
lut_start( LutInfo *st )
|
||||||
|
{
|
||||||
|
st->overflow = 0;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
/* Print overflows, if any.
|
/* Print overflows, if any.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
end_lut( LutInfo *st )
|
lut_end( LutInfo *st )
|
||||||
{
|
{
|
||||||
if( st->overflow ) {
|
if( st->overflow )
|
||||||
im_warn( "im_maplut", _( "%d overflows detected" ),
|
im_warn( "im_maplut", _( "%d overflows detected" ),
|
||||||
st->overflow );
|
st->overflow );
|
||||||
st->overflow = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -139,8 +147,10 @@ build_luts( IMAGE *out, IMAGE *lut )
|
|||||||
st->clp = st->sz - 1;
|
st->clp = st->sz - 1;
|
||||||
st->overflow = 0;
|
st->overflow = 0;
|
||||||
st->table = NULL;
|
st->table = NULL;
|
||||||
if( im_add_evalend_callback( out,
|
if( im_add_evalstart_callback( out,
|
||||||
(im_callback_fn) end_lut, st, NULL ) )
|
(im_callback_fn) lut_start, st, NULL ) ||
|
||||||
|
im_add_evalend_callback( out,
|
||||||
|
(im_callback_fn) lut_end, st, NULL ) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* Attach tables.
|
/* Attach tables.
|
||||||
|
@ -80,16 +80,20 @@ add_callback( IMAGE *im, GSList **cblist, int (*fn)(), void *a, void *b )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a close callback to an IMAGE.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
im_add_close_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
im_add_close_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
||||||
{
|
{
|
||||||
return( add_callback( im, &im->closefns, fn, a, b ) );
|
return( add_callback( im, &im->closefns, fn, a, b ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_add_preclose_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
||||||
|
{
|
||||||
|
return( add_callback( im, &im->preclosefns, fn, a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
/* Add an eval callback to an IMAGE. You must call this after opening the
|
/* 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.
|
* image but before using it as an argument to an operation.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
im_add_eval_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
im_add_eval_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
||||||
@ -103,14 +107,18 @@ im_add_eval_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
|||||||
return( add_callback( im, &im->evalfns, fn, a, b ) );
|
return( add_callback( im, &im->evalfns, fn, a, b ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add an eval end callback to an IMAGE.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
im_add_evalend_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
im_add_evalend_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
||||||
{
|
{
|
||||||
return( add_callback( im, &im->evalendfns, fn, a, b ) );
|
return( add_callback( im, &im->evalendfns, fn, a, b ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_add_evalstart_callback( IMAGE *im, int (*fn)(), void *a, void *b )
|
||||||
|
{
|
||||||
|
return( add_callback( im, &im->evalstartfns, fn, a, b ) );
|
||||||
|
}
|
||||||
|
|
||||||
/* Perform a user callback.
|
/* Perform a user callback.
|
||||||
*/
|
*/
|
||||||
static void *
|
static void *
|
||||||
|
@ -52,6 +52,8 @@
|
|||||||
* - call im__writehist() to send history to XML after image data
|
* - call im__writehist() to send history to XML after image data
|
||||||
* 3/1/07
|
* 3/1/07
|
||||||
* - free history_list
|
* - free history_list
|
||||||
|
* 7/11/07
|
||||||
|
* - added preclose, removed evalend triggers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -122,7 +124,9 @@
|
|||||||
int
|
int
|
||||||
im__close( IMAGE *im )
|
im__close( IMAGE *im )
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
/* No action for NULL image.
|
/* No action for NULL image.
|
||||||
*/
|
*/
|
||||||
@ -133,6 +137,11 @@ im__close( IMAGE *im )
|
|||||||
printf( "im__close: starting for %s ..\n", im->filename );
|
printf( "im__close: starting for %s ..\n", im->filename );
|
||||||
#endif /*DEBUG_IO*/
|
#endif /*DEBUG_IO*/
|
||||||
|
|
||||||
|
/* Trigger all pre-close fns.
|
||||||
|
*/
|
||||||
|
result |= im__trigger_callbacks( im->preclosefns );
|
||||||
|
IM_FREEF( im_slist_free_all, im->preclosefns );
|
||||||
|
|
||||||
/* Free any regions defined on this image. This will, in turn, call
|
/* Free any regions defined on this image. This will, in turn, call
|
||||||
* all stop functions still running, freeing all regions we have on
|
* all stop functions still running, freeing all regions we have on
|
||||||
* other images, etc.
|
* other images, etc.
|
||||||
@ -157,9 +166,9 @@ im__close( IMAGE *im )
|
|||||||
/* Make sure all evalend functions have been called, perform all close
|
/* Make sure all evalend functions have been called, perform all close
|
||||||
* callbacks, and free eval callbacks.
|
* callbacks, and free eval callbacks.
|
||||||
*/
|
*/
|
||||||
result |= im__trigger_callbacks( im->evalendfns );
|
IM_FREEF( im_slist_free_all, im->evalstartfns );
|
||||||
IM_FREEF( im_slist_free_all, im->evalendfns );
|
|
||||||
IM_FREEF( im_slist_free_all, im->evalfns );
|
IM_FREEF( im_slist_free_all, im->evalfns );
|
||||||
|
IM_FREEF( im_slist_free_all, im->evalendfns );
|
||||||
result |= im__trigger_callbacks( im->closefns );
|
result |= im__trigger_callbacks( im->closefns );
|
||||||
IM_FREEF( im_slist_free_all, im->closefns );
|
IM_FREEF( im_slist_free_all, im->closefns );
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
* - better how-many-pixels-calculated
|
* - better how-many-pixels-calculated
|
||||||
* 27/11/06
|
* 27/11/06
|
||||||
* - merge background write stuff
|
* - merge background write stuff
|
||||||
|
* 7/11/07
|
||||||
|
* - new start/end eval callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -284,12 +286,20 @@ eval_to_memory( im_threadgroup_t *tg, REGION *or )
|
|||||||
{
|
{
|
||||||
int y, chunk;
|
int y, chunk;
|
||||||
IMAGE *im = or->im;
|
IMAGE *im = or->im;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_IO
|
#ifdef DEBUG_IO
|
||||||
int ntiles = 0;
|
int ntiles = 0;
|
||||||
printf( "eval_to_memory: partial image output to memory area\n" );
|
printf( "eval_to_memory: partial image output to memory area\n" );
|
||||||
#endif /*DEBUG_IO*/
|
#endif /*DEBUG_IO*/
|
||||||
|
|
||||||
|
/* Signal start of eval.
|
||||||
|
*/
|
||||||
|
if( im__start_eval( im ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
/* Choose a chunk size ... 1/100th of the height of the image, about.
|
/* Choose a chunk size ... 1/100th of the height of the image, about.
|
||||||
* This sets the granularity of user feedback on eval progress, but
|
* This sets the granularity of user feedback on eval progress, but
|
||||||
* does not affect mem requirements etc.
|
* does not affect mem requirements etc.
|
||||||
@ -307,24 +317,28 @@ eval_to_memory( im_threadgroup_t *tg, REGION *or )
|
|||||||
pos.top = y;
|
pos.top = y;
|
||||||
pos.width = im->Xsize;
|
pos.width = im->Xsize;
|
||||||
pos.height = chunk;
|
pos.height = chunk;
|
||||||
if( im_region_image( or, &pos ) )
|
if( (result = im_region_image( or, &pos )) )
|
||||||
return( -1 );
|
break;
|
||||||
|
|
||||||
/* Ask for evaluation of this area.
|
/* Ask for evaluation of this area.
|
||||||
*/
|
*/
|
||||||
if( eval_to_region( or, tg ) )
|
if( (result = eval_to_region( or, tg )) )
|
||||||
return( -1 );
|
break;
|
||||||
|
|
||||||
#ifdef DEBUG_IO
|
#ifdef DEBUG_IO
|
||||||
ntiles++;
|
ntiles++;
|
||||||
#endif /*DEBUG_IO*/
|
#endif /*DEBUG_IO*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Signal end of eval.
|
||||||
|
*/
|
||||||
|
result |= im__end_eval( im );
|
||||||
|
|
||||||
#ifdef DEBUG_IO
|
#ifdef DEBUG_IO
|
||||||
printf( "eval_to_memory: success! %d patches written\n", ntiles );
|
printf( "eval_to_memory: %d patches written\n", ntiles );
|
||||||
#endif /*DEBUG_IO*/
|
#endif /*DEBUG_IO*/
|
||||||
|
|
||||||
return( 0 );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A write function for VIPS images. Just write() the pixel data.
|
/* A write function for VIPS images. Just write() the pixel data.
|
||||||
@ -433,13 +447,6 @@ im_generate( IMAGE *im,
|
|||||||
im_threadgroup_free( tg );
|
im_threadgroup_free( tg );
|
||||||
im_region_free( or );
|
im_region_free( or );
|
||||||
|
|
||||||
/* Evaluation is now complete, with all sequences finished.
|
|
||||||
* Trigger evalend callbacks, then free them to make sure we
|
|
||||||
* don't trigger twice.
|
|
||||||
*/
|
|
||||||
res |= im__trigger_callbacks( im->evalendfns );
|
|
||||||
IM_FREEF( im_slist_free_all, im->evalendfns );
|
|
||||||
|
|
||||||
/* Error?
|
/* Error?
|
||||||
*/
|
*/
|
||||||
if( res )
|
if( res )
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
* 2/1/07
|
* 2/1/07
|
||||||
* - init magic
|
* - init magic
|
||||||
* - init history_list
|
* - init history_list
|
||||||
|
* 7/11/07
|
||||||
|
* - added preclose and evalstart
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -159,6 +161,9 @@ im_init( const char *filename )
|
|||||||
|
|
||||||
im->progress = NULL;
|
im->progress = NULL;
|
||||||
|
|
||||||
|
im->evalstartfns = NULL;
|
||||||
|
im->preclosefns = NULL;
|
||||||
|
|
||||||
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
||||||
im_close( im );
|
im_close( im );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
* 8/6/07
|
* 8/6/07
|
||||||
* - just warn if plugins fail to load correctly: too annoying to have
|
* - just warn if plugins fail to load correctly: too annoying to have
|
||||||
* VIPS refuse to start because of a dodgy plugin
|
* VIPS refuse to start because of a dodgy plugin
|
||||||
|
* 7/11/07
|
||||||
|
* - progress feedback option
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -190,16 +192,18 @@ im__ngettext( const char *msgid, const char *plural, unsigned long int n )
|
|||||||
static GOptionEntry option_entries[] = {
|
static GOptionEntry option_entries[] = {
|
||||||
{ "vips-concurrency", 'c', 0, G_OPTION_ARG_INT, &im__concurrency,
|
{ "vips-concurrency", 'c', 0, G_OPTION_ARG_INT, &im__concurrency,
|
||||||
N_( "evaluate with N concurrent threads" ), "N" },
|
N_( "evaluate with N concurrent threads" ), "N" },
|
||||||
{ "vips-tile-width", 'c', 0, G_OPTION_ARG_INT, &im__tile_width,
|
{ "vips-tile-width", 'w', 0, G_OPTION_ARG_INT, &im__tile_width,
|
||||||
N_( "set tile width to N (DEBUG)" ), "N" },
|
N_( "set tile width to N (DEBUG)" ), "N" },
|
||||||
{ "vips-tile-height", 'c', 0, G_OPTION_ARG_INT, &im__tile_height,
|
{ "vips-tile-height", 'h', 0, G_OPTION_ARG_INT, &im__tile_height,
|
||||||
N_( "set tile height to N (DEBUG)" ), "N" },
|
N_( "set tile height to N (DEBUG)" ), "N" },
|
||||||
{ "vips-thinstrip-height", 'c', 0,
|
{ "vips-thinstrip-height", 't', 0,
|
||||||
G_OPTION_ARG_INT, &im__thinstrip_height,
|
G_OPTION_ARG_INT, &im__thinstrip_height,
|
||||||
N_( "set thinstrip height to N (DEBUG)" ), "N" },
|
N_( "set thinstrip height to N (DEBUG)" ), "N" },
|
||||||
{ "vips-fatstrip-height", 'c', 0,
|
{ "vips-fatstrip-height", 'f', 0,
|
||||||
G_OPTION_ARG_INT, &im__fatstrip_height,
|
G_OPTION_ARG_INT, &im__fatstrip_height,
|
||||||
N_( "set fatstrip height to N (DEBUG)" ), "N" },
|
N_( "set fatstrip height to N (DEBUG)" ), "N" },
|
||||||
|
{ "vips-progress", 'p', 0, G_OPTION_ARG_NONE, &im__progress,
|
||||||
|
N_( "show progress feedback" ), NULL },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
* - read via a buffer image so we work with mmap window images
|
* - read via a buffer image so we work with mmap window images
|
||||||
* 27/11/06
|
* 27/11/06
|
||||||
* - merge threadgroup stuff
|
* - merge threadgroup stuff
|
||||||
|
* 7/11/07
|
||||||
|
* - new eval start/progress/end system
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -199,12 +201,12 @@ im_iterate( IMAGE *im,
|
|||||||
{
|
{
|
||||||
IMAGE *t;
|
IMAGE *t;
|
||||||
im_threadgroup_t *tg;
|
im_threadgroup_t *tg;
|
||||||
int res;
|
int result;
|
||||||
|
|
||||||
if( im_image_sanity( im ) )
|
if( im_image_sanity( im ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( !(t = im_open( "im_iterate_buffer", "p" )) )
|
if( !(t = im_open( "iterate", "p" )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( im_copy( im, t ) ) {
|
if( im_copy( im, t ) ) {
|
||||||
im_close( t );
|
im_close( t );
|
||||||
@ -223,10 +225,19 @@ im_iterate( IMAGE *im,
|
|||||||
im_diagnostics( "im_iterate: using %d threads", tg->nthr );
|
im_diagnostics( "im_iterate: using %d threads", tg->nthr );
|
||||||
#endif /*DEBUG_IO*/
|
#endif /*DEBUG_IO*/
|
||||||
|
|
||||||
res = iterate( tg, t, start, generate, stop, b, c );
|
/* Signal start of eval.
|
||||||
|
*/
|
||||||
|
if( im__start_eval( t ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
result = iterate( tg, t, start, generate, stop, b, c );
|
||||||
|
|
||||||
|
/* Signal end of eval.
|
||||||
|
*/
|
||||||
|
result |= im__end_eval( t );
|
||||||
|
|
||||||
im_threadgroup_free( tg );
|
im_threadgroup_free( tg );
|
||||||
im_close( t );
|
im_close( t );
|
||||||
|
|
||||||
return( res );
|
return( result );
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,9 @@ Modified:
|
|||||||
* 20/9/06
|
* 20/9/06
|
||||||
* - test for NULL filename/mode, common if you forget to check argc
|
* - test for NULL filename/mode, common if you forget to check argc
|
||||||
* (thanks bruno)
|
* (thanks bruno)
|
||||||
|
* 7/11/07
|
||||||
|
* - use preclose, not evalend, for delayed save
|
||||||
|
* - add simple cmd-line progress feedback
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -163,6 +166,16 @@ static const char *im_suffix_csv[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Progress feedback. Only really useful for testing, tbh.
|
||||||
|
*/
|
||||||
|
int im__progress = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
im_progress_set( int progress )
|
||||||
|
{
|
||||||
|
im__progress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open a VIPS image and byte-swap the image data if necessary.
|
/* Open a VIPS image and byte-swap the image data if necessary.
|
||||||
*/
|
*/
|
||||||
static IMAGE *
|
static IMAGE *
|
||||||
@ -213,7 +226,7 @@ read_vips( const char *filename )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Delayed save: if we write to TIFF or to JPEG format, actually do the write
|
/* Delayed save: if we write to TIFF or to JPEG format, actually do the write
|
||||||
* to a "p" and on evalend do im_vips2tiff() or whatever. Track save
|
* to a "p" and on preclose do im_vips2tiff() or whatever. Track save
|
||||||
* parameters here.
|
* parameters here.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -222,7 +235,7 @@ typedef struct {
|
|||||||
char *filename; /* Save args */
|
char *filename; /* Save args */
|
||||||
} SaveBlock;
|
} SaveBlock;
|
||||||
|
|
||||||
/* From evalend callback: invoke a delayed save.
|
/* From preclose callback: invoke a delayed save.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
invoke_sb( SaveBlock *sb )
|
invoke_sb( SaveBlock *sb )
|
||||||
@ -246,7 +259,7 @@ attach_sb( IMAGE *out, int (*save_fn)(), const char *filename )
|
|||||||
sb->save_fn = save_fn;
|
sb->save_fn = save_fn;
|
||||||
sb->filename = im_strdup( out, filename );
|
sb->filename = im_strdup( out, filename );
|
||||||
|
|
||||||
if( im_add_evalend_callback( out,
|
if( im_add_preclose_callback( out,
|
||||||
(im_callback_fn) invoke_sb, (void *) sb, NULL ) )
|
(im_callback_fn) invoke_sb, (void *) sb, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
@ -277,7 +290,7 @@ open_lazy_start( IMAGE *out, void *a, void *dummy )
|
|||||||
OpenLazy *lazy = (OpenLazy *) a;
|
OpenLazy *lazy = (OpenLazy *) a;
|
||||||
|
|
||||||
if( !lazy->lazy_im ) {
|
if( !lazy->lazy_im ) {
|
||||||
if( !(lazy->lazy_im = im_open_local( out, "olstart", "p" )) ||
|
if( !(lazy->lazy_im = im_open_local( out, "read", "p" )) ||
|
||||||
lazy->read_pixels( lazy->filename, lazy->lazy_im ) ) {
|
lazy->read_pixels( lazy->filename, lazy->lazy_im ) ) {
|
||||||
IM_FREEF( im_close, lazy->lazy_im );
|
IM_FREEF( im_close, lazy->lazy_im );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
@ -349,6 +362,49 @@ open_sub( OpenLazyFn read_header, OpenLazyFn read_pixels, const char *filename )
|
|||||||
return( im );
|
return( im );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Progress feedback.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* What we track during an eval.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
IMAGE *im;
|
||||||
|
|
||||||
|
int last_percent; /* The last %complete we displayed */
|
||||||
|
} Progress;
|
||||||
|
|
||||||
|
int
|
||||||
|
evalstart_cb( Progress *progress )
|
||||||
|
{
|
||||||
|
progress->last_percent = 0;
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
eval_cb( Progress *progress )
|
||||||
|
{
|
||||||
|
IMAGE *im = progress->im;
|
||||||
|
|
||||||
|
if( im->time->percent != progress->last_percent ) {
|
||||||
|
printf( "%s: %d%% complete\r",
|
||||||
|
im->filename, im->time->percent );
|
||||||
|
fflush( stdout );
|
||||||
|
|
||||||
|
progress->last_percent = im->time->percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
evalend_cb( Progress *progress )
|
||||||
|
{
|
||||||
|
printf( "\n" );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
IMAGE *
|
IMAGE *
|
||||||
im_open( const char *filename, const char *mode )
|
im_open( const char *filename, const char *mode )
|
||||||
{
|
{
|
||||||
@ -478,7 +534,7 @@ im_open( const char *filename, const char *mode )
|
|||||||
im = im_openout( filename );
|
im = im_openout( filename );
|
||||||
else if( im_filename_suffix_match( filename,
|
else if( im_filename_suffix_match( filename,
|
||||||
im_suffix_tiff ) ) {
|
im_suffix_tiff ) ) {
|
||||||
/* TIFF write. Save to a partial, and on evalend
|
/* TIFF write. Save to a partial, and on preclose
|
||||||
* im_vips2tiff from that.
|
* im_vips2tiff from that.
|
||||||
*/
|
*/
|
||||||
if( !(im = im_open( "im_open:vips2tiff:1", "p" )) )
|
if( !(im = im_open( "im_open:vips2tiff:1", "p" )) )
|
||||||
@ -550,6 +606,20 @@ im_open( const char *filename, const char *mode )
|
|||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attach progress feedback, if required.
|
||||||
|
*/
|
||||||
|
if( im__progress ) {
|
||||||
|
Progress *progress = IM_NEW( im, Progress );
|
||||||
|
|
||||||
|
progress->im = im;
|
||||||
|
im_add_evalstart_callback( im,
|
||||||
|
(im_callback_fn) evalstart_cb, progress, NULL );
|
||||||
|
im_add_eval_callback( im,
|
||||||
|
(im_callback_fn) eval_cb, progress, NULL );
|
||||||
|
im_add_evalend_callback( im,
|
||||||
|
(im_callback_fn) evalend_cb, progress, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_IO
|
#ifdef DEBUG_IO
|
||||||
printf( "im_open: success for %s (%p)\n", im->filename, im );
|
printf( "im_open: success for %s (%p)\n", im->filename, im );
|
||||||
#endif /*DEBUG_IO*/
|
#endif /*DEBUG_IO*/
|
||||||
|
@ -324,6 +324,10 @@ im_printdesc( IMAGE *image )
|
|||||||
printf( "user eval callbacks attached\n" );
|
printf( "user eval callbacks attached\n" );
|
||||||
if( image->evalendfns )
|
if( image->evalendfns )
|
||||||
printf( "user evalend callbacks attached\n" );
|
printf( "user evalend callbacks attached\n" );
|
||||||
|
if( image->evalstartfns )
|
||||||
|
printf( "user evalstart callbacks attached\n" );
|
||||||
|
if( image->preclosefns )
|
||||||
|
printf( "user preclose callbacks attached\n" );
|
||||||
if( image->regions ) {
|
if( image->regions ) {
|
||||||
printf( "%d regions present\n",
|
printf( "%d regions present\n",
|
||||||
g_slist_length( image->regions ) );
|
g_slist_length( image->regions ) );
|
||||||
|
@ -105,6 +105,7 @@ im_setupout( IMAGE *im )
|
|||||||
printf( "im_setupout: old-style output for %s\n",
|
printf( "im_setupout: old-style output for %s\n",
|
||||||
im->filename );
|
im->filename );
|
||||||
#endif /*DEBUG_IO*/
|
#endif /*DEBUG_IO*/
|
||||||
|
|
||||||
im->dtype = IM_SETBUF;
|
im->dtype = IM_SETBUF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
*
|
*
|
||||||
* 2/11/07
|
* 2/11/07
|
||||||
* - cut from im_generate
|
* - cut from im_generate
|
||||||
|
* 7/11/07
|
||||||
|
* - trigger start/end eval callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -407,19 +409,22 @@ im_wbuffer( im_threadgroup_t *tg,
|
|||||||
im_wbuffer_fn write_fn, void *a, void *b )
|
im_wbuffer_fn write_fn, void *a, void *b )
|
||||||
{
|
{
|
||||||
WriteBuffer *b1, *b2;
|
WriteBuffer *b1, *b2;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if( im__start_eval( tg->im ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
b1 = wbuffer_new( tg, write_fn, a, b );
|
b1 = wbuffer_new( tg, write_fn, a, b );
|
||||||
b2 = wbuffer_new( tg, write_fn, a, b );
|
b2 = wbuffer_new( tg, write_fn, a, b );
|
||||||
|
|
||||||
if( !b1 || !b2 || wbuffer_eval_to_file( b1, b2 ) ) {
|
if( !b1 || !b2 || wbuffer_eval_to_file( b1, b2 ) )
|
||||||
IM_FREEF( wbuffer_free, b1 );
|
result = -1;
|
||||||
IM_FREEF( wbuffer_free, b2 );
|
|
||||||
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
im__end_eval( tg->im );
|
||||||
wbuffer_free( b1 );
|
wbuffer_free( b1 );
|
||||||
wbuffer_free( b2 );
|
wbuffer_free( b2 );
|
||||||
|
|
||||||
return( 0 );
|
return( result );
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
* - better error messages
|
* - better error messages
|
||||||
* 31/10/03 JC
|
* 31/10/03 JC
|
||||||
* - stop early on kill
|
* - stop early on kill
|
||||||
|
* 7/11/07
|
||||||
|
* - add eval start/stop
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -75,39 +77,52 @@
|
|||||||
#endif /*WITH_DMALLOC*/
|
#endif /*WITH_DMALLOC*/
|
||||||
|
|
||||||
int
|
int
|
||||||
im_writeline( int ypos, IMAGE *image, PEL *linebuffer )
|
im_writeline( int ypos, IMAGE *im, PEL *linebuffer )
|
||||||
{
|
{
|
||||||
int linesize = IM_IMAGE_SIZEOF_LINE( image );
|
int linesize = IM_IMAGE_SIZEOF_LINE( im );
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
|
/* Is this the start of eval?
|
||||||
|
*/
|
||||||
|
if( ypos == 0 )
|
||||||
|
im__start_eval( im );
|
||||||
|
|
||||||
/* Possible cases for output: FILE or SETBUF.
|
/* Possible cases for output: FILE or SETBUF.
|
||||||
*/
|
*/
|
||||||
switch( image->dtype ) {
|
switch( im->dtype ) {
|
||||||
case IM_SETBUF:
|
case IM_SETBUF:
|
||||||
case IM_SETBUF_FOREIGN:
|
case IM_SETBUF_FOREIGN:
|
||||||
tmp = image->data + ypos * linesize;
|
tmp = im->data + ypos * linesize;
|
||||||
memcpy( tmp, linebuffer, linesize );
|
memcpy( tmp, linebuffer, linesize );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IM_OPENOUT:
|
case IM_OPENOUT:
|
||||||
if( im__write( image->fd, linebuffer, linesize ) )
|
/* Don't use ypos for this.
|
||||||
|
*/
|
||||||
|
if( im__write( im->fd, linebuffer, linesize ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
im_errormsg( "im_writeline: unable to output to a %s image",
|
im_error( "im_writeline",
|
||||||
im_dtype2char( image->dtype ) );
|
_( "unable to output to a %s image" ),
|
||||||
|
im_dtype2char( im->dtype ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger evaluation callbacks for this image.
|
/* Trigger evaluation callbacks for this image.
|
||||||
*/
|
*/
|
||||||
if( im__handle_eval( image, image->Xsize, 1 ) )
|
if( im__handle_eval( im, im->Xsize, 1 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( im__test_kill( image ) )
|
if( im__test_kill( im ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
/* Is this the end of eval?
|
||||||
|
*/
|
||||||
|
if( ypos == im->Ysize - 1 )
|
||||||
|
im__end_eval( im );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif /*HAVE_CONFIG_H*/
|
#endif /*HAVE_CONFIG_H*/
|
||||||
@ -50,6 +54,10 @@ int
|
|||||||
im__time_destroy( IMAGE *im )
|
im__time_destroy( IMAGE *im )
|
||||||
{
|
{
|
||||||
if( im->time ) {
|
if( im->time ) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "im__time_destroy: %s\n", im->filename );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
g_timer_destroy( im->time->start );
|
g_timer_destroy( im->time->start );
|
||||||
im_free( im->time );
|
im_free( im->time );
|
||||||
im->time = NULL;
|
im->time = NULL;
|
||||||
@ -69,6 +77,10 @@ time_add( IMAGE *im )
|
|||||||
!(time = IM_NEW( NULL, im_time_t )) )
|
!(time = IM_NEW( NULL, im_time_t )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "time_add: %s\n", im->filename );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
time->im = im;
|
time->im = im;
|
||||||
time->start = g_timer_new();
|
time->start = g_timer_new();
|
||||||
time->run = 0;
|
time->run = 0;
|
||||||
@ -98,6 +110,28 @@ update_time( im_time_t *time, int w, int h )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im__start_eval( IMAGE *im )
|
||||||
|
{
|
||||||
|
im_image_sanity( im );
|
||||||
|
|
||||||
|
if( im->progress ) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "im__start_eval: %s\n", im->filename );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
im_image_sanity( im->progress );
|
||||||
|
|
||||||
|
if( time_add( im->progress ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( im__trigger_callbacks( im->progress->evalstartfns ) )
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle eval callbacks. w and h are the size of the tile we made this time.
|
/* 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
|
* 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
|
* assume there's no geometry change between adding the feedback request and
|
||||||
@ -107,14 +141,6 @@ int
|
|||||||
im__handle_eval( IMAGE *im, int w, int h )
|
im__handle_eval( IMAGE *im, int w, int h )
|
||||||
{
|
{
|
||||||
if( im->progress ) {
|
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->progress->time, w, h ) )
|
if( update_time( im->progress->time, w, h ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
@ -124,3 +150,24 @@ im__handle_eval( IMAGE *im, int w, int h )
|
|||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im__end_eval( IMAGE *im )
|
||||||
|
{
|
||||||
|
im_image_sanity( im );
|
||||||
|
|
||||||
|
if( im->progress ) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "im__end_eval: %s\n", im->filename );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
im_image_sanity( im->progress );
|
||||||
|
|
||||||
|
if( im__trigger_callbacks( im->progress->evalendfns ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
im__time_destroy( im->progress );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
@ -974,7 +974,7 @@ local_mask( IMAGE *out, DOUBLEMASK *mask )
|
|||||||
if( !mask )
|
if( !mask )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
if( im_add_evalend_callback( out,
|
if( im_add_close_callback( out,
|
||||||
(im_callback_fn) im_free_dmask, mask, NULL ) ) {
|
(im_callback_fn) im_free_dmask, mask, NULL ) ) {
|
||||||
im_free_dmask( mask );
|
im_free_dmask( mask );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
Loading…
Reference in New Issue
Block a user