From: DRC Date: Wed, 28 Jun 2017 19:47:45 +0000 (-0500) Subject: TurboJPEG: Document xform issue w/ big marker data X-Git-Tag: 1.5.2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b0971e47d76fdb81270e93bbf11ff5558073350d;p=libjpeg-turbo TurboJPEG: Document xform issue w/ big marker data If the source image for a transform operation has a lot of EXIF or ICC data embedded in it, then it may cause the output image size to exceed the worst-case size returned by tjBufSize() (because tjTransform() transfers all markers to the output image.) This is only a problem if TJFLAG_NOREALLOC is passed to the function. Since the TurboJPEG C API doesn't require the destination image size to be set in this case, it makes the documented assumption that the calling program has allocated the destination buffer to exactly the size returned by tjBufSize(). Changing this assumption would change the API behavior and necessitate a new function name (tjTransform2().) At the moment, it's easier to just document this as a known issue, since it's easy to work around in the C API. The Java API is unfortunately a different story, since it must always use TJFLAG_NOREALLOC (because, when using the TurboJPEG Java API, all buffers are allocated on the Java heap, and thus they can't be reallocated by the C code.) There is no easy way to work around this without changing the C API as discussed above, because if the source image contains large amounts of marker data, it's virtually impossible to determine how big the output image will be. --- diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html index 9363117..8d7626d 100644 --- a/doc/html/group___turbo_j_p_e_g.html +++ b/doc/html/group___turbo_j_p_e_g.html @@ -1008,7 +1008,7 @@ Variables jpegBufaddress of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:
  1. pre-allocate the JPEG buffer with an arbitrary size using tjAlloc() and let TurboJPEG grow the buffer as needed,
  2. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  3. -
  4. 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.)
  5. +
  6. 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 that it won't be.)
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.) 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. @@ -1106,7 +1106,7 @@ If you choose option 1, *jpegSize should be set to the size of your jpegBufaddress of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:
  1. pre-allocate the JPEG buffer with an arbitrary size using tjAlloc() and let TurboJPEG grow the buffer as needed,
  2. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  3. -
  4. 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.)
  5. +
  6. 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 that it won't be.)
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.) 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. @@ -1203,7 +1203,7 @@ If you choose option 1, *jpegSize should be set to the size of your jpegBufaddress of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:
  1. pre-allocate the JPEG buffer with an arbitrary size using tjAlloc() and let TurboJPEG grow the buffer as needed,
  2. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  3. -
  4. 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.)
  5. +
  6. 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 that it won't be.)
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.) 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. @@ -2270,7 +2270,7 @@ If you choose option 1, *jpegSize should be set to the size of your dstBufspointer to an array of n image buffers. dstBufs[i] will receive a JPEG image that has been transformed using the parameters in transforms[i]. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:
  1. pre-allocate the JPEG buffer with an arbitrary size using tjAlloc() and let TurboJPEG grow the buffer as needed,
  2. set dstBufs[i] to NULL to tell TurboJPEG to allocate the buffer for you, or
  3. -
  4. pre-allocate the buffer to a "worst case" size determined by calling tjBufSize() with the transformed or cropped width and height. This should ensure that the buffer never has to be re-allocated (setting TJFLAG_NOREALLOC guarantees this.)
  5. +
  6. pre-allocate the buffer to a "worst case" size determined by calling tjBufSize() with the transformed or cropped width and height. Under normal circumstances, this should ensure that the buffer never has to be re-allocated (setting TJFLAG_NOREALLOC guarantees that it won't be.) Note, however, that there are some rare cases (such as transforming images with a large amount of embedded EXIF or ICC profile data) in which the output image will be larger than the worst-case size, and TJFLAG_NOREALLOC cannot be used in those cases.
If you choose option 1, dstSizes[i] should be set to the size of your pre-allocated buffer. In any case, unless you have set TJFLAG_NOREALLOC, you should always check dstBufs[i] upon return from this function, as it may have changed. dstSizespointer to an array of n unsigned long variables that will receive the actual sizes (in bytes) of each transformed JPEG image. If dstBufs[i] points to a pre-allocated buffer, then dstSizes[i] should be set to the size of the buffer. Upon return, dstSizes[i] will contain the size of the JPEG image (in bytes.) diff --git a/turbojpeg.h b/turbojpeg.h index aa33264..f60caf8 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -645,7 +645,7 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void); * for you, or * -# 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.) + * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.) * . * 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, @@ -713,7 +713,7 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf, * for you, or * -# 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.) + * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.) * . * 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, @@ -783,7 +783,7 @@ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle, * for you, or * -# 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.) + * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.) * . * 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, @@ -1392,9 +1392,13 @@ DLLEXPORT tjhandle DLLCALL tjInitTransform(void); * -# set dstBufs[i] to NULL to tell TurboJPEG to allocate the buffer * for you, or * -# pre-allocate the buffer to a "worst case" size determined by calling - * #tjBufSize() with the transformed or cropped width and height. This should - * ensure that the buffer never has to be re-allocated (setting - * #TJFLAG_NOREALLOC guarantees this.) + * #tjBufSize() with the transformed or cropped width and height. Under normal + * circumstances, this should ensure that the buffer never has to be + * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.) Note, + * however, that there are some rare cases (such as transforming images with a + * large amount of embedded EXIF or ICC profile data) in which the output image + * will be larger than the worst-case size, and #TJFLAG_NOREALLOC cannot be + * used in those cases. * . * If you choose option 1, dstSizes[i] should be set to the size of * your pre-allocated buffer. In any case, unless you have set