From 01238a0fd554d765e5c1437580cf94a14e69aa55 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 21 Feb 2016 10:57:36 +0000 Subject: [PATCH] more progressive jpg changes - Remove the nocache stuff for prog jpg images. There was no saving in practice, since operations downstream could be cached. nocache is for objects that can change, not for memory saving - Call _destroy on the decompress object much earlier, it frees a huge amount of memoey for prog jpg images. --- ChangeLog | 2 +- libvips/foreign/jpeg2vips.c | 10 +++++++++- libvips/foreign/jpegload.c | 24 ------------------------ 3 files changed, 10 insertions(+), 26 deletions(-) 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,