From fe80ec22752cce224c55d7b429d46503634ef034 Mon Sep 17 00:00:00 2001 From: DRC Date: Thu, 21 Aug 2014 15:51:47 +0000 Subject: [PATCH] If the output buffer in the TurboJPEG destination manager was allocated by the destination manager and is being reused from a previous compression operation, then we need to get the buffer size from the previous operation, since the calling program doesn't know the actual buffer size. git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1368 632fc199-4ca6-4c93-a231-07263d6284db --- ChangeLog.txt | 9 +++++++++ doc/html/group___turbo_j_p_e_g.html | 6 +++--- jdatadst-tj.c | 11 +++++++++-- tjunittest.c | 10 ++++++++-- turbojpeg.h | 12 +++++++++--- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6f39b0a..c31a007 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -106,6 +106,15 @@ test program specifically designed to make the bug occur (by injecting random high-frequency YUV data into the compressor), it was reproducible only once in about every 25 million iterations. +[16] Fixed an oversight in the TurboJPEG C wrapper: if any of the JPEG +compression functions was called repeatedly with the same +automatically-allocated destination buffer, then TurboJPEG would erroneously +assume that the jpegSize parameter was equal to the size of the buffer, when in +fact that parameter was probably equal to the size of the most recently +compressed JPEG image. If the size of the previous JPEG image was not as large +as the current JPEG image, then TurboJPEG would unnecessarily reallocate the +destination buffer. + 1.3.1 ===== diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html index c7b19bf..7188c7d 100644 --- a/doc/html/group___turbo_j_p_e_g.html +++ b/doc/html/group___turbo_j_p_e_g.html @@ -1011,7 +1011,7 @@ Variables
  • pre-allocate the buffer to a "worst case" size determined by calling tjBufSize(). This should ensure that the buffer never has to be re-allocated (setting TJFLAG_NOREALLOC guarantees this.)
  • If you choose option 1, *jpegSize should be set to the size of your pre-allocated buffer. In any case, unless you have set TJFLAG_NOREALLOC, you should always check *jpegBuf upon return from this function, as it may have changed. - jpegSizepointer to an unsigned long variable that holds the size of the JPEG image buffer. If *jpegBuf points to a pre-allocated buffer, then *jpegSize should be set to the size of the buffer. Upon return, *jpegSize will contain the size of the JPEG image (in bytes.) + jpegSizepointer to an unsigned long variable that holds the size of the JPEG image buffer. If *jpegBuf points to a pre-allocated buffer, then *jpegSize should be set to the size of the buffer. Upon return, *jpegSize will contain the size of the JPEG image (in bytes.) If *jpegBuf points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then *jpegSize is ignored. jpegSubsampthe level of chrominance subsampling to be used when generating the JPEG image (see Chrominance subsampling options.) jpegQualthe image quality of the generated JPEG image (1 = worst, 100 = best) flagsthe bitwise OR of one or more of the flags @@ -1109,7 +1109,7 @@ If you choose option 1, *jpegSize should be set to the size of your
  • pre-allocate the buffer to a "worst case" size determined by calling tjBufSize(). This should ensure that the buffer never has to be re-allocated (setting TJFLAG_NOREALLOC guarantees this.)
  • If you choose option 1, *jpegSize should be set to the size of your pre-allocated buffer. In any case, unless you have set TJFLAG_NOREALLOC, you should always check *jpegBuf upon return from this function, as it may have changed. - jpegSizepointer to an unsigned long variable that holds the size of the JPEG image buffer. If *jpegBuf points to a pre-allocated buffer, then *jpegSize should be set to the size of the buffer. Upon return, *jpegSize will contain the size of the JPEG image (in bytes.) + jpegSizepointer to an unsigned long variable that holds the size of the JPEG image buffer. If *jpegBuf points to a pre-allocated buffer, then *jpegSize should be set to the size of the buffer. Upon return, *jpegSize will contain the size of the JPEG image (in bytes.) If *jpegBuf points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then *jpegSize is ignored. jpegQualthe image quality of the generated JPEG image (1 = worst, 100 = best) flagsthe bitwise OR of one or more of the flags @@ -1206,7 +1206,7 @@ If you choose option 1, *jpegSize should be set to the size of your
  • pre-allocate the buffer to a "worst case" size determined by calling tjBufSize(). This should ensure that the buffer never has to be re-allocated (setting TJFLAG_NOREALLOC guarantees this.)
  • If you choose option 1, *jpegSize should be set to the size of your pre-allocated buffer. In any case, unless you have set TJFLAG_NOREALLOC, you should always check *jpegBuf upon return from this function, as it may have changed. - jpegSizepointer to an unsigned long variable that holds the size of the JPEG image buffer. If *jpegBuf points to a pre-allocated buffer, then *jpegSize should be set to the size of the buffer. Upon return, *jpegSize will contain the size of the JPEG image (in bytes.) + jpegSizepointer to an unsigned long variable that holds the size of the JPEG image buffer. If *jpegBuf points to a pre-allocated buffer, then *jpegSize should be set to the size of the buffer. Upon return, *jpegSize will contain the size of the JPEG image (in bytes.) If *jpegBuf points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then *jpegSize is ignored. jpegQualthe image quality of the generated JPEG image (1 = worst, 100 = best) flagsthe bitwise OR of one or more of the flags diff --git a/jdatadst-tj.c b/jdatadst-tj.c index bc4a35d..8289d3a 100644 --- a/jdatadst-tj.c +++ b/jdatadst-tj.c @@ -5,7 +5,7 @@ * Copyright (C) 1994-1996, Thomas G. Lane. * Modified 2009-2012 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2011, D. R. Commander. + * Copyright (C) 2011, 2014 D. R. Commander. * For conditions of distribution and use, see the accompanying README file. * * This file contains compression data destination routines for the case of @@ -150,6 +150,7 @@ jpeg_mem_dest_tj (j_compress_ptr cinfo, unsigned char ** outbuffer, unsigned long * outsize, boolean alloc) { + boolean reused = FALSE; my_mem_dest_ptr dest; if (outbuffer == NULL || outsize == NULL) /* sanity check */ @@ -164,12 +165,16 @@ jpeg_mem_dest_tj (j_compress_ptr cinfo, sizeof(my_mem_destination_mgr)); dest = (my_mem_dest_ptr) cinfo->dest; dest->newbuffer = NULL; + dest->outbuffer = NULL; } dest = (my_mem_dest_ptr) cinfo->dest; dest->pub.init_destination = init_mem_destination; dest->pub.empty_output_buffer = empty_mem_output_buffer; dest->pub.term_destination = term_mem_destination; + if (dest->outbuffer && *(dest->outbuffer) == *outbuffer && + *outbuffer != NULL && alloc) + reused = TRUE; dest->outbuffer = outbuffer; dest->outsize = outsize; dest->alloc = alloc; @@ -186,5 +191,7 @@ jpeg_mem_dest_tj (j_compress_ptr cinfo, } dest->pub.next_output_byte = dest->buffer = *outbuffer; - dest->pub.free_in_buffer = dest->bufsize = *outsize; + if (!reused) + dest->bufsize = *outsize; + dest->pub.free_in_buffer = dest->bufsize; } diff --git a/tjunittest.c b/tjunittest.c index dc84bba..9ac6626 100644 --- a/tjunittest.c +++ b/tjunittest.c @@ -638,7 +638,10 @@ void bufSizeTest(void) &dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC)); } free(srcBuf); srcBuf=NULL; - tjFree(dstBuf); dstBuf=NULL; + if(!alloc) + { + tjFree(dstBuf); dstBuf=NULL; + } if((srcBuf=(unsigned char *)malloc(h*w*4))==NULL) _throw("Memory allocation failure"); @@ -667,7 +670,10 @@ void bufSizeTest(void) &dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC)); } free(srcBuf); srcBuf=NULL; - tjFree(dstBuf); dstBuf=NULL; + if(!alloc) + { + tjFree(dstBuf); dstBuf=NULL; + } } } } diff --git a/turbojpeg.h b/turbojpeg.h index 2505100..1ada65a 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -656,7 +656,9 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void); * the JPEG image buffer. If *jpegBuf points to a pre-allocated * buffer, then *jpegSize should be set to the size of the buffer. * Upon return, *jpegSize will contain the size of the JPEG image (in - * bytes.) + * bytes.) If *jpegBuf points to a JPEG image buffer that is being + * reused from a previous call to one of the JPEG compression functions, then + * *jpegSize is ignored. * * @param jpegSubsamp the level of chrominance subsampling to be used when * generating the JPEG image (see @ref TJSAMP @@ -722,7 +724,9 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, * the JPEG image buffer. If *jpegBuf points to a pre-allocated * buffer, then *jpegSize should be set to the size of the buffer. * Upon return, *jpegSize will contain the size of the JPEG image (in - * bytes.) + * bytes.) If *jpegBuf points to a JPEG image buffer that is being + * reused from a previous call to one of the JPEG compression functions, then + * *jpegSize is ignored. * * @param jpegQual the image quality of the generated JPEG image (1 = worst, * 100 = best) @@ -790,7 +794,9 @@ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, unsigned char *srcBuf, * the JPEG image buffer. If *jpegBuf points to a pre-allocated * buffer, then *jpegSize should be set to the size of the buffer. * Upon return, *jpegSize will contain the size of the JPEG image (in - * bytes.) + * bytes.) If *jpegBuf points to a JPEG image buffer that is being + * reused from a previous call to one of the JPEG compression functions, then + * *jpegSize is ignored. * * @param jpegQual the image quality of the generated JPEG image (1 = worst, * 100 = best) -- 2.40.0