diff --git a/ChangeLog b/ChangeLog index 747c3b65..e10b543b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,7 +6,7 @@ - vipsthumbnail knows about pdfload and svgload - added @page param to magickload - matload is more specific (thanks bithive) -- don't cache progressive jpg images +- lower mem use for progressive jpg decode 27/1/16 started 8.2.3 - fix a crash with SPARC byte-order labq vips images diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index b776f3a3..dab23237 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -69,6 +69,9 @@ * fd during jpg read, handy for large numbers of input images * 15/7/15 * - save exif tags using @name, not @title ... @title is subject to i18n + * 21/2/16 + * - _destroy the decompress object as soon as we can, frees loads of + * memory for progressive jpg files */ /* @@ -977,6 +980,12 @@ read_jpeg_generate( VipsRegion *or, jpeg->y_pos += 1; } + /* Progressive images can have a lot of memory in the decompress + * object, destroy as soon as we can. Safe to call many times. + */ + if( jpeg->y_pos >= or->im->Ysize ) + jpeg_destroy_decompress( &jpeg->cinfo ); + VIPS_GATE_STOP( "read_jpeg_generate: work" ); return( 0 ); @@ -1083,7 +1092,6 @@ vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only ) } #endif /*DEBUG*/ - /* Convert! */ if( header_only ) { diff --git a/libvips/foreign/jpegload.c b/libvips/foreign/jpegload.c index 58f0aec7..2e81077e 100644 --- a/libvips/foreign/jpegload.c +++ b/libvips/foreign/jpegload.c @@ -4,8 +4,6 @@ * - wrap a class around the jpeg writer * 29/11/11 * - split to make load, load from buffer and load from file - * 18/2/16 - * - don't cache progressive jpgs, they take too much mem */ /* @@ -94,25 +92,6 @@ typedef VipsForeignLoadClass VipsForeignLoadJpegClass; G_DEFINE_ABSTRACT_TYPE( VipsForeignLoadJpeg, vips_foreign_load_jpeg, VIPS_TYPE_FOREIGN_LOAD ); -static VipsOperationFlags -vips_foreign_load_jpeg_operation_get_flags( VipsOperation *operation ) -{ - VipsForeignLoad *load = VIPS_FOREIGN_LOAD( operation ); - - VipsOperationFlags flags; - int multiscan; - - flags = VIPS_OPERATION_CLASS( vips_foreign_load_jpeg_parent_class )-> - get_flags( operation ); - if( load->out && - !vips_image_get_int( load->out, - "jpeg-multiscan", &multiscan ) && - multiscan ) - flags |= VIPS_OPERATION_NOCACHE; - - return( flags ); -} - static VipsForeignFlags vips_foreign_load_jpeg_get_flags( VipsForeignLoad *load ) { @@ -147,7 +126,6 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class ) { GObjectClass *gobject_class = G_OBJECT_CLASS( class ); VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsOperationClass *operation_class = (VipsOperationClass *) class; VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class; gobject_class->set_property = vips_object_set_property; @@ -157,8 +135,6 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class ) object_class->description = _( "load jpeg" ); object_class->build = vips_foreign_load_jpeg_build; - operation_class->get_flags = vips_foreign_load_jpeg_operation_get_flags; - load_class->get_flags = vips_foreign_load_jpeg_get_flags; VIPS_ARG_INT( class, "shrink", 10,