diff --git a/ChangeLog b/ChangeLog index 9fb8816e..d46e5290 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,6 +50,7 @@ - update C++/Python binding - oop, bool constants are always (int) now, so (^-1) works for unsigned types, thanks Nicolas +- much lower memuse for im_cache() in complex pipelines 12/5/10 started 7.22.2 - the conditional image of ifthenelse can be any format, a (!=0) is added if diff --git a/TODO b/TODO index f7a15709..d05a00a9 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,6 @@ + + + - see Haida's mail re. cfitsio and higher dimensions diff --git a/libvips/iofuncs/debug.c b/libvips/iofuncs/debug.c index d9ed1fa0..57bedeef 100644 --- a/libvips/iofuncs/debug.c +++ b/libvips/iofuncs/debug.c @@ -229,16 +229,15 @@ im_demand_type im_char2dhint( const char *str ) { return( char2enum( &enumdhint, str ) ); } static void * -print_one_line_region( REGION *r, int *n2, gint64 *total ) +add_unique( REGION *r, gint64 *total, GSList **seen ) { - if( r->type == IM_REGION_BUFFER && r->buffer ) { - printf( "\t*** %d) %zd malloced bytes\n", - *n2, r->buffer->bsize ); + if( r->type == IM_REGION_BUFFER && + r->buffer && + !g_slist_find( *seen, r->buffer ) ) { + *seen = g_slist_prepend( *seen, r->buffer ); *total += r->buffer->bsize; } - *n2 += 1; - return( NULL ); } @@ -247,36 +246,37 @@ print_one_line_region( REGION *r, int *n2, gint64 *total ) static void * print_one_line( IMAGE *im, int *n, gint64 *total ) { - printf( "%2d) %p, %s, %s: %dx%d, %d bands, %s\n", + gint64 size; + + printf( "%d, %p, %s, %s, %d, %d, %d, %s, ", *n, im, - im_dtype2char( im->dtype ), im->filename, + im_dtype2char( im->dtype ), + im->filename, im->Xsize, im->Ysize, im->Bands, im_BandFmt2char( im->BandFmt ) ); *n += 1; + size = 0; if( im->dtype == IM_SETBUF && im->data ) { - gint64 size = (gint64) IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize; - - printf( "\t*** %" G_GINT64_FORMAT " malloced bytes\n", size ); - *total += size; + size = (gint64) IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize; } + *total += size; + printf( "%" G_GINT64_FORMAT ", ", size ); + printf( "%d, ", g_slist_length( im->regions ) ); + + size = 0; if( im->regions ) { - int n2; - gint64 total2; + GSList *seen; - printf( "\t%d regions\n", g_slist_length( im->regions ) ); - - n2 = 0; - total2 = 0; + seen = NULL; (void) im_slist_map2( im->regions, - (VSListMap2Fn) print_one_line_region, &n2, &total2 ); - if( total2 ) - printf( "\t*** using total of %" G_GINT64_FORMAT - " bytes\n", total2 ); - *total += total2; + (VSListMap2Fn) add_unique, &size, &seen ); + g_slist_free( seen ); } + *total += size; + printf( "%" G_GINT64_FORMAT "\n", size ); return( NULL ); } @@ -295,11 +295,13 @@ void im__print_all( void ) { if( im__open_images ) { - int n = 0; - gint64 total = 0; + int n; + gint64 total; + n = 0; total = 0; - printf( "%d images\n", g_slist_length( im__open_images ) ); + printf( "n, p, dtype, file, xsize, ysize, bands, fmt, " ); + printf( "isize, nreg, rsize\n" ); (void) im_slist_map2( im__open_images, (VSListMap2Fn) print_one_line, &n, &total ); if( total ) diff --git a/libvips/iofuncs/sinkscreen.c b/libvips/iofuncs/sinkscreen.c index 67f333a0..ebbd8e1a 100644 --- a/libvips/iofuncs/sinkscreen.c +++ b/libvips/iofuncs/sinkscreen.c @@ -2,6 +2,9 @@ * * 1/1/10 * - from im_render.c + * 25/11/10 + * - in synchronous mode, use a single region for input and save huge + * mem use */ /* @@ -141,6 +144,11 @@ typedef struct _Render { /* Hash of tiles with positions. Tiles can be dirty or painted. */ GHashTable *tiles; + + /* In synchronous mode (notify == NULL), generate tiles with this + * REGION. + */ + REGION *synchronous_reg; } Render; /* Our per-thread state. @@ -237,6 +245,7 @@ render_free( Render *render ) render->ntiles = 0; IM_FREEF( g_slist_free, render->dirty ); IM_FREEF( g_hash_table_destroy, render->tiles ); + IM_FREEF( im_region_free, render->synchronous_reg ); im_free( render ); @@ -615,6 +624,8 @@ render_new( VipsImage *in, VipsImage *out, VipsImage *mask, render->tiles = g_hash_table_new( tile_hash, tile_equal ); + render->synchronous_reg = NULL; + render->dirty = NULL; /* Both out and mask must close before we can free the render. @@ -635,6 +646,13 @@ render_new( VipsImage *in, VipsImage *out, VipsImage *mask, render_ref( render ); } + /* In synchronous mode we need a region to generate pixels with. + */ + if( !notify ) { + if( !(render->synchronous_reg = im_region_create( in )) ) + return( NULL ); + } + VIPS_DEBUG_MSG_AMBER( "render_new: %p\n", render ); #ifdef VIPS_DEBUG_AMBER @@ -770,7 +788,8 @@ tile_queue( Tile *tile ) "painting tile %p %dx%d synchronously\n", tile, tile->area.left, tile->area.top ); - if( im_prepare( tile->region, &tile->area ) ) + if( im_prepare_to( render->synchronous_reg, tile->region, + &tile->area, tile->area.left, tile->area.top ) ) VIPS_DEBUG_MSG_RED( "tile_queue: prepare failed\n" ); tile->painted = TRUE;