]> granicus.if.org Git - libjpeg-turbo/commitdiff
If the output buffer in the TurboJPEG destination manager was allocated by the destin...
authorDRC <dcommander@users.sourceforge.net>
Thu, 21 Aug 2014 15:51:47 +0000 (15:51 +0000)
committerDRC <dcommander@users.sourceforge.net>
Thu, 21 Aug 2014 15:51:47 +0000 (15:51 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1368 632fc199-4ca6-4c93-a231-07263d6284db

ChangeLog.txt
doc/html/group___turbo_j_p_e_g.html
jdatadst-tj.c
tjunittest.c
turbojpeg.h

index 6f39b0a2d6c98c0e678586178998a1968e591a12..c31a00751162cdedb4bab953e5f9b5f3eab1ca97 100644 (file)
@@ -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
 =====
index c7b19bf43e98b063b55e73b9225212d6dc7eac19..7188c7d663e399e6e9d515904d119d07298d56bc 100644 (file)
@@ -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>
index bc4a35dd7d3a1b86815ef3afbb8b951f74163d55..8289d3a48185a656406b11601098ab2ba1f6ce79 100644 (file)
@@ -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;
 }
index dc84bbaa41ccbb757d3b3a85d3eba1eece656b7b..9ac6626c5c5b981cb7ebdffe315cc9bda59b1d91 100644 (file)
@@ -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;
+                               }
                        }
                }
        }
index 2505100c7b21ded44912c90f1bc209a7a3757376..1ada65a2174250fecb9e031694b159e17201cff2 100644 (file)
@@ -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)