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
|
high-frequency YUV data into the compressor), it was reproducible only once in
|
||||||
about every 25 million iterations.
|
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
|
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>
|
<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>
|
</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>
|
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">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">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>
|
<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>
|
<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>
|
</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>
|
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">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>
|
<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>
|
</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>
|
<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>
|
</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>
|
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">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>
|
<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>
|
</table>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||||
* Modified 2009-2012 by Guido Vollbeding.
|
* Modified 2009-2012 by Guido Vollbeding.
|
||||||
* libjpeg-turbo Modifications:
|
* 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.
|
* For conditions of distribution and use, see the accompanying README file.
|
||||||
*
|
*
|
||||||
* This file contains compression data destination routines for the case of
|
* 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,
|
unsigned char ** outbuffer, unsigned long * outsize,
|
||||||
boolean alloc)
|
boolean alloc)
|
||||||
{
|
{
|
||||||
|
boolean reused = FALSE;
|
||||||
my_mem_dest_ptr dest;
|
my_mem_dest_ptr dest;
|
||||||
|
|
||||||
if (outbuffer == NULL || outsize == NULL) /* sanity check */
|
if (outbuffer == NULL || outsize == NULL) /* sanity check */
|
||||||
@@ -164,12 +165,16 @@ jpeg_mem_dest_tj (j_compress_ptr cinfo,
|
|||||||
sizeof(my_mem_destination_mgr));
|
sizeof(my_mem_destination_mgr));
|
||||||
dest = (my_mem_dest_ptr) cinfo->dest;
|
dest = (my_mem_dest_ptr) cinfo->dest;
|
||||||
dest->newbuffer = NULL;
|
dest->newbuffer = NULL;
|
||||||
|
dest->outbuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest = (my_mem_dest_ptr) cinfo->dest;
|
dest = (my_mem_dest_ptr) cinfo->dest;
|
||||||
dest->pub.init_destination = init_mem_destination;
|
dest->pub.init_destination = init_mem_destination;
|
||||||
dest->pub.empty_output_buffer = empty_mem_output_buffer;
|
dest->pub.empty_output_buffer = empty_mem_output_buffer;
|
||||||
dest->pub.term_destination = term_mem_destination;
|
dest->pub.term_destination = term_mem_destination;
|
||||||
|
if (dest->outbuffer && *(dest->outbuffer) == *outbuffer &&
|
||||||
|
*outbuffer != NULL && alloc)
|
||||||
|
reused = TRUE;
|
||||||
dest->outbuffer = outbuffer;
|
dest->outbuffer = outbuffer;
|
||||||
dest->outsize = outsize;
|
dest->outsize = outsize;
|
||||||
dest->alloc = alloc;
|
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.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;
|
||||||
}
|
}
|
||||||
|
|||||||
10
tjunittest.c
10
tjunittest.c
@@ -638,7 +638,10 @@ void bufSizeTest(void)
|
|||||||
&dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
|
&dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
|
||||||
}
|
}
|
||||||
free(srcBuf); srcBuf=NULL;
|
free(srcBuf); srcBuf=NULL;
|
||||||
tjFree(dstBuf); dstBuf=NULL;
|
if(!alloc)
|
||||||
|
{
|
||||||
|
tjFree(dstBuf); dstBuf=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if((srcBuf=(unsigned char *)malloc(h*w*4))==NULL)
|
if((srcBuf=(unsigned char *)malloc(h*w*4))==NULL)
|
||||||
_throw("Memory allocation failure");
|
_throw("Memory allocation failure");
|
||||||
@@ -667,7 +670,10 @@ void bufSizeTest(void)
|
|||||||
&dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
|
&dstSize, subsamp, 100, alloc? 0:TJFLAG_NOREALLOC));
|
||||||
}
|
}
|
||||||
free(srcBuf); srcBuf=NULL;
|
free(srcBuf); srcBuf=NULL;
|
||||||
tjFree(dstBuf); dstBuf=NULL;
|
if(!alloc)
|
||||||
|
{
|
||||||
|
tjFree(dstBuf); dstBuf=NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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
|
* 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.
|
* 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
|
* 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
|
* @param jpegSubsamp the level of chrominance subsampling to be used when
|
||||||
* generating the JPEG image (see @ref TJSAMP
|
* 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
|
* 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.
|
* 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
|
* 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,
|
* @param jpegQual the image quality of the generated JPEG image (1 = worst,
|
||||||
* 100 = best)
|
* 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
|
* 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.
|
* 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
|
* 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,
|
* @param jpegQual the image quality of the generated JPEG image (1 = worst,
|
||||||
* 100 = best)
|
* 100 = best)
|
||||||
|
|||||||
Reference in New Issue
Block a user