From 037f6cd162f4a24d1448f0077210505c722684eb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 20 Nov 2014 10:07:28 +0000 Subject: [PATCH] tiles tiff write needs to cache input to keep it seq, as it promises to be --- TODO | 12 ------------ libvips/foreign/foreign.c | 4 +++- libvips/foreign/vips2tiff.c | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/TODO b/TODO index c0ddb796..6f65a300 100644 --- a/TODO +++ b/TODO @@ -1,15 +1,3 @@ -- getting an error in test_formats.sh - - $ ./test_formats.sh - testing IMG_4618.jpg v ... ok - testing IMG_4618.jpg tif ... ok - testing IMG_4618.jpg tif[compression=jpeg] ... ok - testing IMG_4618.jpg tif[compression=deflate] ... ok - testing IMG_4618.jpg tif[compression=packbits] ... ok - testing IMG_4618.jpg tif[compression=jpeg,tile] ... vips warning: linecache: - error reading tile 0x128: VipsJpeg: out of order read at line 384 - - - use vips_resize() in vipsthumbnail? should the sharpening filter be selectable? diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index aa23d3f4..404f2db3 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1337,7 +1337,9 @@ vips_foreign_save_class_init( VipsForeignSaveClass *class ) object_class->nickname = "filesave"; object_class->description = _( "file savers" ); - /* I think all savers are sequential. Hopefully. + /* All savers are seqential by definition. Things like tiled tiff + * write and interlaced png write, which are not, add extra caches + * on their input. */ operation_class->flags |= VIPS_OPERATION_SEQUENTIAL_UNBUFFERED; diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index ff69144f..e567ce84 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -138,6 +138,8 @@ * of bands, etc., see the tiff loader * 26/1/14 * - add RGB as well as YCbCr write + * 20/11/14 + * - cache input in tile write mode to keep us seqential */ /* @@ -266,6 +268,8 @@ typedef struct tiff_write { int rgbjpeg; /* True for RGB not YCbCr */ GMutex *write_lock; /* Lock TIFF*() calls with this */ + + VipsImage *cache; /* Cache a chunk of input */ } TiffWrite; /* Open TIFF for output. @@ -1229,6 +1233,7 @@ free_tiff_write( TiffWrite *tw ) VIPS_FREEF( vips_free, tw->tbuf ); VIPS_FREEF( vips_g_mutex_free, tw->write_lock ); VIPS_FREEF( free_pyramid, tw->layer ); + VIPS_UNREF( tw->cache ); VIPS_FREEF( vips_free, tw->icc_profile ); } @@ -1320,6 +1325,7 @@ make_tiff_write( VipsImage *im, const char *filename, tw->bigtiff = bigtiff; tw->rgbjpeg = rgbjpeg; tw->write_lock = NULL; + tw->cache = NULL; tw->resunit = get_resunit( resunit ); tw->xres = xres; @@ -1379,6 +1385,20 @@ make_tiff_write( VipsImage *im, const char *filename, else tw->tls = VIPS_IMAGE_SIZEOF_PEL( im ) * tw->tilew; + /* If we will be writing tiles, we need to cache tileh pixels of the + * input, since we say we're sequential. + */ + if( tw->tile ) { + if( vips_tilecache( tw->im, &tw->cache, + "tile_width", tw->im->Xsize, + "tile_height", tw->tileh, + "max_tiles", 1, + NULL ) ) + return( NULL ); + + tw->im = tw->cache; + } + return( tw ); }