From ba22c0f76d88f596e157b6c546c599e21ebbaf64 Mon Sep 17 00:00:00 2001 From: DRC Date: Fri, 24 Jun 2022 14:03:03 -0500 Subject: [PATCH] tjDecompressHeader3(): Accept tables-only streams Inspired by: https://github.com/amyspark/libjpeg-turbo/commit/b3b15cfe74cf07914122e26cf1e408a9a9cf3135 Closes #604 Closes #605 --- ChangeLog.md | 6 +++++ doc/html/annotated.html | 2 +- doc/html/classes.html | 2 +- doc/html/functions.html | 2 +- doc/html/functions_vars.html | 2 +- doc/html/group___turbo_j_p_e_g.html | 18 ++++++------- doc/html/index.html | 2 +- doc/html/modules.html | 2 +- doc/html/structtjregion.html | 2 +- doc/html/structtjscalingfactor.html | 2 +- doc/html/structtjtransform.html | 2 +- doxygen.config | 2 +- java/doc/index-all.html | 3 ++- .../turbojpeg/TJDecompressor.html | 20 +++++++++++---- .../turbojpeg/TJDecompressor.java | 19 ++++++++++---- turbojpeg.c | 8 +++++- turbojpeg.h | 25 +++++++++++++------ 17 files changed, 81 insertions(+), 38 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 62a9b0cf..a00651ac 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -6,6 +6,12 @@ 1. Fixed a regression introduced in 2.1.3 that caused build failures with Visual Studio 2010. +2. The `tjDecompressHeader3()` function in the TurboJPEG C API and the +`TJDecompressor.setSourceImage()` method in the TurboJPEG Java API now accept +"abbreviated table specification" (AKA "tables-only") datastreams, which can be +used to prime the decompressor with quantization and Huffman tables that can be +used when decompressing subsequent "abbreviated image" datastreams. + 2.1.3 ===== diff --git a/doc/html/annotated.html b/doc/html/annotated.html index b7773dd4..c735a5a7 100644 --- a/doc/html/annotated.html +++ b/doc/html/annotated.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/classes.html b/doc/html/classes.html index bfcf32a9..42f38f6b 100644 --- a/doc/html/classes.html +++ b/doc/html/classes.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/functions.html b/doc/html/functions.html index 055b876f..5de4c6fb 100644 --- a/doc/html/functions.html +++ b/doc/html/functions.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/functions_vars.html b/doc/html/functions_vars.html index 540b3e44..2b010f40 100644 --- a/doc/html/functions_vars.html +++ b/doc/html/functions_vars.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html index bf100736..63d47910 100644 --- a/doc/html/group___turbo_j_p_e_g.html +++ b/doc/html/group___turbo_j_p_e_g.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
@@ -273,7 +273,7 @@ Functions  Create a TurboJPEG decompressor instance. More...
  DLLEXPORT int tjDecompressHeader3 (tjhandle handle, const unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, int *jpegSubsamp, int *jpegColorspace) - Retrieve information about a JPEG image without decompressing it. More...
+ Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quantization and Huffman tables. More...
  DLLEXPORT tjscalingfactortjGetScalingFactors (int *numscalingfactors)  Returns a list of fractional scaling factors that the JPEG decompressor in this implementation of TurboJPEG supports. More...
@@ -1725,16 +1725,16 @@ If you choose option 1, *jpegSize should be set to the size of your
-

Retrieve information about a JPEG image without decompressing it.

+

Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quantization and Huffman tables.

Parameters
- - - - - - + + + + + +
handlea handle to a TurboJPEG decompressor or transformer instance
jpegBufpointer to a buffer containing a JPEG image
jpegSizesize of the JPEG image (in bytes)
widthpointer to an integer variable that will receive the width (in pixels) of the JPEG image
heightpointer to an integer variable that will receive the height (in pixels) of the JPEG image
jpegSubsamppointer to an integer variable that will receive the level of chrominance subsampling used when the JPEG image was compressed (see Chrominance subsampling options.)
jpegColorspacepointer to an integer variable that will receive one of the JPEG colorspace constants, indicating the colorspace of the JPEG image (see JPEG colorspaces.)
jpegBufpointer to a buffer containing a JPEG image or an "abbreviated table specification" (AKA "tables-only") datastream. Passing a tables-only datastream to this function primes the decompressor with quantization and Huffman tables that can be used when decompressing subsequent "abbreviated image" datastreams. This is useful, for instance, when decompressing video streams in which all frames share the same quantization and Huffman tables.
jpegSizesize of the JPEG image or tables-only datastream (in bytes)
widthpointer to an integer variable that will receive the width (in pixels) of the JPEG image. If jpegBuf points to a tables-only datastream, then width is ignored.
heightpointer to an integer variable that will receive the height (in pixels) of the JPEG image. If jpegBuf points to a tables-only datastream, then height is ignored.
jpegSubsamppointer to an integer variable that will receive the level of chrominance subsampling used when the JPEG image was compressed (see Chrominance subsampling options.) If jpegBuf points to a tables-only datastream, then jpegSubsamp is ignored.
jpegColorspacepointer to an integer variable that will receive one of the JPEG colorspace constants, indicating the colorspace of the JPEG image (see JPEG colorspaces.) If jpegBuf points to a tables-only datastream, then jpegColorspace is ignored.
diff --git a/doc/html/index.html b/doc/html/index.html index 165a589f..a6f272a3 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/modules.html b/doc/html/modules.html index b3fa1c06..d48980a4 100644 --- a/doc/html/modules.html +++ b/doc/html/modules.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/structtjregion.html b/doc/html/structtjregion.html index daa206aa..72d49d27 100644 --- a/doc/html/structtjregion.html +++ b/doc/html/structtjregion.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/structtjscalingfactor.html b/doc/html/structtjscalingfactor.html index 021a36f0..1606a02c 100644 --- a/doc/html/structtjscalingfactor.html +++ b/doc/html/structtjscalingfactor.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doc/html/structtjtransform.html b/doc/html/structtjtransform.html index 92aa3fa3..ba78980e 100644 --- a/doc/html/structtjtransform.html +++ b/doc/html/structtjtransform.html @@ -23,7 +23,7 @@
TurboJPEG -  2.1 +  2.1.4
diff --git a/doxygen.config b/doxygen.config index 6deb064e..16708b03 100644 --- a/doxygen.config +++ b/doxygen.config @@ -1,5 +1,5 @@ PROJECT_NAME = TurboJPEG -PROJECT_NUMBER = 2.1 +PROJECT_NUMBER = 2.1.4 OUTPUT_DIRECTORY = doc/ USE_WINDOWS_ENCODING = NO OPTIMIZE_OUTPUT_FOR_C = YES diff --git a/java/doc/index-all.html b/java/doc/index-all.html index 3a49818e..5def53ee 100644 --- a/java/doc/index-all.html +++ b/java/doc/index-all.html @@ -792,7 +792,8 @@
setSourceImage(byte[], int) - Method in class org.libjpegturbo.turbojpeg.TJDecompressor
-
Associate the JPEG image of length imageSize bytes stored in +
Associate the JPEG image or "abbreviated table specification" (AKA + "tables-only") datastream of length imageSize bytes stored in jpegImage with this decompressor instance.
setSourceImage(YUVImage) - Method in class org.libjpegturbo.turbojpeg.TJDecompressor
diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html index b281e327..6666e4e1 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html @@ -418,7 +418,8 @@ implements java.io.Closeable void setSourceImage(byte[] jpegImage, int imageSize) -
Associate the JPEG image of length imageSize bytes stored in +
Associate the JPEG image or "abbreviated table specification" (AKA + "tables-only") datastream of length imageSize bytes stored in jpegImage with this decompressor instance.
@@ -611,10 +612,19 @@ implements java.io.Closeable
public void setSourceImage(byte[] jpegImage,
                   int imageSize)
                     throws TJException
-
Associate the JPEG image of length imageSize bytes stored in - jpegImage with this decompressor instance. This image will - be used as the source image for subsequent decompress operations.
-
Parameters:
jpegImage - JPEG image buffer. This buffer is not modified.
imageSize - size of the JPEG image (in bytes)
+
Associate the JPEG image or "abbreviated table specification" (AKA + "tables-only") datastream of length imageSize bytes stored in + jpegImage with this decompressor instance. If + jpegImage contains a JPEG image, then this image will be used + as the source image for subsequent decompress operations. Passing a + tables-only datastream to this method primes the decompressor with + quantization and Huffman tables that can be used when decompressing + subsequent "abbreviated image" datastreams. This is useful, for instance, + when decompressing video streams in which all frames share the same + quantization and Huffman tables.
+
Parameters:
jpegImage - buffer containing a JPEG image or an "abbreviated table + specification" (AKA "tables-only") datastream. This buffer is not + modified.
imageSize - size of the JPEG image (in bytes)
Throws:
TJException
diff --git a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java index cba9ff03..aba390b1 100644 --- a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2015, 2018 D. R. Commander. All Rights Reserved. + * Copyright (C)2011-2015, 2018, 2022 D. R. Commander. All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,11 +89,20 @@ public class TJDecompressor implements Closeable { } /** - * Associate the JPEG image of length imageSize bytes stored in - * jpegImage with this decompressor instance. This image will - * be used as the source image for subsequent decompress operations. + * Associate the JPEG image or "abbreviated table specification" (AKA + * "tables-only") datastream of length imageSize bytes stored in + * jpegImage with this decompressor instance. If + * jpegImage contains a JPEG image, then this image will be used + * as the source image for subsequent decompress operations. Passing a + * tables-only datastream to this method primes the decompressor with + * quantization and Huffman tables that can be used when decompressing + * subsequent "abbreviated image" datastreams. This is useful, for instance, + * when decompressing video streams in which all frames share the same + * quantization and Huffman tables. * - * @param jpegImage JPEG image buffer. This buffer is not modified. + * @param jpegImage buffer containing a JPEG image or an "abbreviated table + * specification" (AKA "tables-only") datastream. This buffer is not + * modified. * * @param imageSize size of the JPEG image (in bytes) */ diff --git a/turbojpeg.c b/turbojpeg.c index 32394cca..a1544f24 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -1225,7 +1225,13 @@ DLLEXPORT int tjDecompressHeader3(tjhandle handle, } jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); - jpeg_read_header(dinfo, TRUE); + + /* jpeg_read_header() calls jpeg_abort() and returns JPEG_HEADER_TABLES_ONLY + if the datastream is a tables-only datastream. Since we aren't using a + suspending data source, the only other value it can return is + JPEG_HEADER_OK. */ + if (jpeg_read_header(dinfo, FALSE) == JPEG_HEADER_TABLES_ONLY) + return 0; *width = dinfo->image_width; *height = dinfo->image_height; diff --git a/turbojpeg.h b/turbojpeg.h index 5b33ad84..02b54ca9 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -1129,27 +1129,38 @@ DLLEXPORT tjhandle tjInitDecompress(void); /** - * Retrieve information about a JPEG image without decompressing it. + * Retrieve information about a JPEG image without decompressing it, or prime + * the decompressor with quantization and Huffman tables. * * @param handle a handle to a TurboJPEG decompressor or transformer instance * - * @param jpegBuf pointer to a buffer containing a JPEG image + * @param jpegBuf pointer to a buffer containing a JPEG image or an + * "abbreviated table specification" (AKA "tables-only") datastream. Passing a + * tables-only datastream to this function primes the decompressor with + * quantization and Huffman tables that can be used when decompressing + * subsequent "abbreviated image" datastreams. This is useful, for instance, + * when decompressing video streams in which all frames share the same + * quantization and Huffman tables. * - * @param jpegSize size of the JPEG image (in bytes) + * @param jpegSize size of the JPEG image or tables-only datastream (in bytes) * * @param width pointer to an integer variable that will receive the width (in - * pixels) of the JPEG image + * pixels) of the JPEG image. If jpegBuf points to a tables-only + * datastream, then width is ignored. * * @param height pointer to an integer variable that will receive the height - * (in pixels) of the JPEG image + * (in pixels) of the JPEG image. If jpegBuf points to a tables-only + * datastream, then height is ignored. * * @param jpegSubsamp pointer to an integer variable that will receive the * level of chrominance subsampling used when the JPEG image was compressed - * (see @ref TJSAMP "Chrominance subsampling options".) + * (see @ref TJSAMP "Chrominance subsampling options".) If jpegBuf + * points to a tables-only datastream, then jpegSubsamp is ignored. * * @param jpegColorspace pointer to an integer variable that will receive one * of the JPEG colorspace constants, indicating the colorspace of the JPEG - * image (see @ref TJCS "JPEG colorspaces".) + * image (see @ref TJCS "JPEG colorspaces".) If jpegBuf + * points to a tables-only datastream, then jpegColorspace is ignored. * * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr2() * and #tjGetErrorCode().)