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
This commit is contained in:
@@ -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
|
||||
=====
|
||||
|
||||
@@ -1011,7 +1011,7 @@ Variables</h2></td></tr>
|
||||
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees this.)</li>
|
||||
</ol>
|
||||
If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
|
||||
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
|
||||
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
|
||||
<tr><td class="paramname">jpegSubsamp</td><td>the level of chrominance subsampling to be used when generating the JPEG image (see <a class="el" href="group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074">Chrominance subsampling options</a>.)</td></tr>
|
||||
<tr><td class="paramname">jpegQual</td><td>the image quality of the generated JPEG image (1 = worst, 100 = best)</td></tr>
|
||||
<tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">flags</a></td></tr>
|
||||
@@ -1109,7 +1109,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
|
||||
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees this.)</li>
|
||||
</ol>
|
||||
If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
|
||||
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
|
||||
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
|
||||
<tr><td class="paramname">jpegQual</td><td>the image quality of the generated JPEG image (1 = worst, 100 = best)</td></tr>
|
||||
<tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">flags</a></td></tr>
|
||||
</table>
|
||||
@@ -1206,7 +1206,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
|
||||
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees this.)</li>
|
||||
</ol>
|
||||
If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
|
||||
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
|
||||
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
|
||||
<tr><td class="paramname">jpegQual</td><td>the image quality of the generated JPEG image (1 = worst, 100 = best)</td></tr>
|
||||
<tr><td class="paramname">flags</td><td>the bitwise OR of one or more of the <a class="el" href="group___turbo_j_p_e_g.html#ga72ecf4ebe6eb702d3c6f5ca27455e1ec">flags</a></td></tr>
|
||||
</table>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -638,7 +638,10 @@ void bufSizeTest(void)
|
||||
&dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
|
||||
}
|
||||
free(srcBuf); srcBuf=NULL;
|
||||
if(!alloc)
|
||||
{
|
||||
tjFree(dstBuf); dstBuf=NULL;
|
||||
}
|
||||
|
||||
if((srcBuf=(unsigned char *)malloc(h*w*4))==NULL)
|
||||
_throw("Memory allocation failure");
|
||||
@@ -667,10 +670,13 @@ void bufSizeTest(void)
|
||||
&dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
|
||||
}
|
||||
free(srcBuf); srcBuf=NULL;
|
||||
if(!alloc)
|
||||
{
|
||||
tjFree(dstBuf); dstBuf=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("Done. \n");
|
||||
|
||||
bailout:
|
||||
|
||||
12
turbojpeg.h
12
turbojpeg.h
@@ -656,7 +656,9 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
|
||||
* the JPEG image buffer. If <tt>*jpegBuf</tt> points to a pre-allocated
|
||||
* buffer, then <tt>*jpegSize</tt> should be set to the size of the buffer.
|
||||
* Upon return, <tt>*jpegSize</tt> will contain the size of the JPEG image (in
|
||||
* bytes.)
|
||||
* bytes.) If <tt>*jpegBuf</tt> points to a JPEG image buffer that is being
|
||||
* reused from a previous call to one of the JPEG compression functions, then
|
||||
* <tt>*jpegSize</tt> 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 <tt>*jpegBuf</tt> points to a pre-allocated
|
||||
* buffer, then <tt>*jpegSize</tt> should be set to the size of the buffer.
|
||||
* Upon return, <tt>*jpegSize</tt> will contain the size of the JPEG image (in
|
||||
* bytes.)
|
||||
* bytes.) If <tt>*jpegBuf</tt> points to a JPEG image buffer that is being
|
||||
* reused from a previous call to one of the JPEG compression functions, then
|
||||
* <tt>*jpegSize</tt> 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 <tt>*jpegBuf</tt> points to a pre-allocated
|
||||
* buffer, then <tt>*jpegSize</tt> should be set to the size of the buffer.
|
||||
* Upon return, <tt>*jpegSize</tt> will contain the size of the JPEG image (in
|
||||
* bytes.)
|
||||
* bytes.) If <tt>*jpegBuf</tt> points to a JPEG image buffer that is being
|
||||
* reused from a previous call to one of the JPEG compression functions, then
|
||||
* <tt>*jpegSize</tt> is ignored.
|
||||
*
|
||||
* @param jpegQual the image quality of the generated JPEG image (1 = worst,
|
||||
* 100 = best)
|
||||
|
||||
Reference in New Issue
Block a user