Update bundled libjpeg-turbo to version 3.0.1

[ChangeLog][Third-Party Code] libjpeg-turbo was updated to version 3.0.1

Fixes: QTBUG-117804
Pick-to: 6.5 6.2 5.15
Change-Id: Ia6cdb02eb9c590fe024bdf75566976756c6e13c6
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit 071291a0d465e3a2241af017a84fa4911acb486a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Eirik Aavitsland 2023-10-18 11:51:50 +02:00 committed by Qt Cherry-pick Bot
parent 9f971deb06
commit 6173f053a0
6 changed files with 107 additions and 43 deletions

View File

@ -7,8 +7,8 @@
"Description": "The Independent JPEG Group's JPEG software", "Description": "The Independent JPEG Group's JPEG software",
"Homepage": "http://libjpeg-turbo.virtualgl.org/", "Homepage": "http://libjpeg-turbo.virtualgl.org/",
"Version": "3.0.0", "Version": "3.0.1",
"DownloadLocation": "https://sourceforge.net/projects/libjpeg-turbo/files/3.0.0/libjpeg-turbo-3.0.0.tar.gz", "DownloadLocation": "https://sourceforge.net/projects/libjpeg-turbo/files/3.0.1/libjpeg-turbo-3.0.1.tar.gz",
"License": "Independent JPEG Group License and BSD 3-Clause \"New\" or \"Revised\" License and zlib License", "License": "Independent JPEG Group License and BSD 3-Clause \"New\" or \"Revised\" License and zlib License",
"LicenseId": "IJG AND BSD-3-Clause AND Zlib", "LicenseId": "IJG AND BSD-3-Clause AND Zlib",

View File

@ -1,3 +1,24 @@
3.0.1
=====
### Significant changes relative to 3.0.0:
1. The x86-64 SIMD functions now use a standard stack frame, prologue, and
epilogue so that debuggers and profilers can reliably capture backtraces from
within the functions.
2. Fixed two minor issues in the interblock smoothing algorithm that caused
mathematical (but not necessarily perceptible) edge block errors when
decompressing progressive JPEG images exactly two MCU blocks in width or that
use vertical chrominance subsampling.
3. Fixed a regression introduced by 3.0 beta2[6] that, in rare cases, caused
the C Huffman encoder (which is not used by default on x86 and Arm CPUs) to
generate incorrect results if the Neon SIMD extensions were explicitly disabled
at build time (by setting the `WITH_SIMD` CMake variable to `0`) in an AArch64
build of libjpeg-turbo.
3.0.0 3.0.0
===== =====
@ -398,9 +419,9 @@ transform a specially-crafted malformed JPEG image.
### Significant changes relative to 2.1 beta1: ### Significant changes relative to 2.1 beta1:
1. Fixed a regression introduced by 2.1 beta1[6(b)] whereby attempting to 1. Fixed a regression (CVE-2021-29390) introduced by 2.1 beta1[6(b)] whereby
decompress certain progressive JPEG images with one or more component planes of attempting to decompress certain progressive JPEG images with one or more
width 8 or less caused a buffer overrun. component planes of width 8 or less caused a buffer overrun.
2. Fixed a regression introduced by 2.1 beta1[6(b)] whereby attempting to 2. Fixed a regression introduced by 2.1 beta1[6(b)] whereby attempting to
decompress a specially-crafted malformed progressive JPEG image caused the decompress a specially-crafted malformed progressive JPEG image caused the

View File

@ -21,11 +21,28 @@ derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and
VirtualGL projects made numerous enhancements to the codec in 2009, and in VirtualGL projects made numerous enhancements to the codec in 2009, and in
early 2010, libjpeg-turbo spun off into an independent project, with the goal early 2010, libjpeg-turbo spun off into an independent project, with the goal
of making high-speed JPEG compression/decompression technology available to a of making high-speed JPEG compression/decompression technology available to a
broader range of users and developers. broader range of users and developers. libjpeg-turbo is an ISO/IEC and ITU-T
reference implementation of the JPEG standard.
More information about libjpeg-turbo can be found at More information about libjpeg-turbo can be found at
<https://libjpeg-turbo.org>. <https://libjpeg-turbo.org>.
Funding
=======
libjpeg-turbo is an independent open source project, but we rely on patronage
and funded development in order to maintain that independence. The easiest way
to ensure that libjpeg-turbo remains community-focused and free of any one
organization's agenda is to
[sponsor our project through GitHub](https://github.com/sponsors/libjpeg-turbo).
All sponsorship money goes directly toward funding the labor necessary to
maintain libjpeg-turbo, support the user community, and implement bug fixes and
strategically important features.
[![Sponsor libjpeg-turbo](https://img.shields.io/github/sponsors/libjpeg-turbo?label=Sponsor&logo=GitHub)](https://github.com/sponsors/libjpeg-turbo)
License License
======= =======
@ -266,30 +283,35 @@ Mathematical Compatibility
========================== ==========================
For the most part, libjpeg-turbo should produce identical output to libjpeg For the most part, libjpeg-turbo should produce identical output to libjpeg
v6b. The one exception to this is when using the floating point DCT/IDCT, in v6b. There are two exceptions:
which case the outputs of libjpeg v6b and libjpeg-turbo can differ for the
following reasons:
- The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever so 1. When decompressing a JPEG image that uses 4:4:0 chrominance subsampling, the
slightly more accurate than the implementation in libjpeg v6b, but not by outputs of libjpeg v6b and libjpeg-turbo can differ because libjpeg-turbo
any amount perceptible to human vision (generally in the range of 0.01 to implements a "fancy" (smooth) 4:4:0 upsampling algorithm and libjpeg did not.
0.08 dB gain in PNSR.)
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate 2. When using the floating point DCT/IDCT, the outputs of libjpeg v6b and
(and slightly faster) floating point IDCT algorithm introduced in libjpeg libjpeg-turbo can differ for the following reasons:
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the floating
point IDCT in line with the accuracy of the accurate integer IDCT. The
floating point DCT/IDCT algorithms are mainly a legacy feature, and they do
not produce significantly more accuracy than the accurate integer algorithms
(to put numbers on this, the typical difference in PNSR between the two
algorithms is less than 0.10 dB, whereas changing the quality level by 1 in
the upper range of the quality scale is typically more like a 1.0 dB
difference.)
- If the floating point algorithms in libjpeg-turbo are not implemented using - The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever
SIMD instructions on a particular platform, then the accuracy of the so slightly more accurate than the implementation in libjpeg v6b, but not
floating point DCT/IDCT can depend on the compiler settings. by any amount perceptible to human vision (generally in the range of 0.01
to 0.08 dB gain in PNSR.)
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate
(and slightly faster) floating point IDCT algorithm introduced in libjpeg
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the
floating point IDCT in line with the accuracy of the accurate integer
IDCT. The floating point DCT/IDCT algorithms are mainly a legacy
feature, and they do not produce significantly more accuracy than the
accurate integer algorithms. (To put numbers on this, the typical
difference in PNSR between the two algorithms is less than 0.10 dB,
whereas changing the quality level by 1 in the upper range of the quality
scale is typically more like a 1.0 dB difference.)
- If the floating point algorithms in libjpeg-turbo are not implemented
using SIMD instructions on a particular platform, then the accuracy of
the floating point DCT/IDCT can depend on the compiler settings.
While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is
still using the same algorithms as libjpeg v6b, so there are several specific still using the same algorithms as libjpeg v6b, so there are several specific

View File

@ -108,7 +108,9 @@ typedef bit_buf_type simd_bit_buf_type;
typedef struct { typedef struct {
union { union {
bit_buf_type c; bit_buf_type c;
#ifdef WITH_SIMD
simd_bit_buf_type simd; simd_bit_buf_type simd;
#endif
} put_buffer; /* current bit accumulation buffer */ } put_buffer; /* current bit accumulation buffer */
int free_bits; /* # of bits available in it */ int free_bits; /* # of bits available in it */
/* (Neon GAS: # of bits now in it) */ /* (Neon GAS: # of bits now in it) */
@ -133,7 +135,9 @@ typedef struct {
long *ac_count_ptrs[NUM_HUFF_TBLS]; long *ac_count_ptrs[NUM_HUFF_TBLS];
#endif #endif
#ifdef WITH_SIMD
int simd; int simd;
#endif
} huff_entropy_encoder; } huff_entropy_encoder;
typedef huff_entropy_encoder *huff_entropy_ptr; typedef huff_entropy_encoder *huff_entropy_ptr;
@ -147,7 +151,9 @@ typedef struct {
size_t free_in_buffer; /* # of byte spaces remaining in buffer */ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
savable_state cur; /* Current bit buffer & DC state */ savable_state cur; /* Current bit buffer & DC state */
j_compress_ptr cinfo; /* dump_buffer needs access to this */ j_compress_ptr cinfo; /* dump_buffer needs access to this */
#ifdef WITH_SIMD
int simd; int simd;
#endif
} working_state; } working_state;
@ -511,6 +517,7 @@ flush_bits(working_state *state)
simd_bit_buf_type put_buffer; int put_bits; simd_bit_buf_type put_buffer; int put_bits;
int localbuf = 0; int localbuf = 0;
#ifdef WITH_SIMD
if (state->simd) { if (state->simd) {
#if defined(__aarch64__) && !defined(NEON_INTRINSICS) #if defined(__aarch64__) && !defined(NEON_INTRINSICS)
put_bits = state->cur.free_bits; put_bits = state->cur.free_bits;
@ -518,7 +525,9 @@ flush_bits(working_state *state)
put_bits = SIMD_BIT_BUF_SIZE - state->cur.free_bits; put_bits = SIMD_BIT_BUF_SIZE - state->cur.free_bits;
#endif #endif
put_buffer = state->cur.put_buffer.simd; put_buffer = state->cur.put_buffer.simd;
} else { } else
#endif
{
put_bits = BIT_BUF_SIZE - state->cur.free_bits; put_bits = BIT_BUF_SIZE - state->cur.free_bits;
put_buffer = state->cur.put_buffer.c; put_buffer = state->cur.put_buffer.c;
} }
@ -536,6 +545,7 @@ flush_bits(working_state *state)
EMIT_BYTE(temp) EMIT_BYTE(temp)
} }
#ifdef WITH_SIMD
if (state->simd) { /* and reset bit buffer to empty */ if (state->simd) { /* and reset bit buffer to empty */
state->cur.put_buffer.simd = 0; state->cur.put_buffer.simd = 0;
#if defined(__aarch64__) && !defined(NEON_INTRINSICS) #if defined(__aarch64__) && !defined(NEON_INTRINSICS)
@ -543,7 +553,9 @@ flush_bits(working_state *state)
#else #else
state->cur.free_bits = SIMD_BIT_BUF_SIZE; state->cur.free_bits = SIMD_BIT_BUF_SIZE;
#endif #endif
} else { } else
#endif
{
state->cur.put_buffer.c = 0; state->cur.put_buffer.c = 0;
state->cur.free_bits = BIT_BUF_SIZE; state->cur.free_bits = BIT_BUF_SIZE;
} }
@ -719,7 +731,9 @@ encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
state.free_in_buffer = cinfo->dest->free_in_buffer; state.free_in_buffer = cinfo->dest->free_in_buffer;
state.cur = entropy->saved; state.cur = entropy->saved;
state.cinfo = cinfo; state.cinfo = cinfo;
#ifdef WITH_SIMD
state.simd = entropy->simd; state.simd = entropy->simd;
#endif
/* Emit restart marker if needed */ /* Emit restart marker if needed */
if (cinfo->restart_interval) { if (cinfo->restart_interval) {
@ -792,7 +806,9 @@ finish_pass_huff(j_compress_ptr cinfo)
state.free_in_buffer = cinfo->dest->free_in_buffer; state.free_in_buffer = cinfo->dest->free_in_buffer;
state.cur = entropy->saved; state.cur = entropy->saved;
state.cinfo = cinfo; state.cinfo = cinfo;
#ifdef WITH_SIMD
state.simd = entropy->simd; state.simd = entropy->simd;
#endif
/* Flush out the last data */ /* Flush out the last data */
if (!flush_bits(&state)) if (!flush_bits(&state))

View File

@ -5,7 +5,7 @@
* Copyright (C) 1994-1997, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2010, 2015-2016, 2019-2020, 2022, D. R. Commander. * Copyright (C) 2010, 2015-2016, 2019-2020, 2022-2023, D. R. Commander.
* Copyright (C) 2015, 2020, Google, Inc. * Copyright (C) 2015, 2020, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
@ -431,7 +431,8 @@ decompress_smooth_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
my_coef_ptr coef = (my_coef_ptr)cinfo->coef; my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
JDIMENSION block_num, last_block_column; JDIMENSION block_num, last_block_column;
int ci, block_row, block_rows, access_rows; int ci, block_row, block_rows, access_rows, image_block_row,
image_block_rows;
JBLOCKARRAY buffer; JBLOCKARRAY buffer;
JBLOCKROW buffer_ptr, prev_prev_block_row, prev_block_row; JBLOCKROW buffer_ptr, prev_prev_block_row, prev_block_row;
JBLOCKROW next_block_row, next_next_block_row; JBLOCKROW next_block_row, next_next_block_row;
@ -497,6 +498,7 @@ decompress_smooth_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
(JDIMENSION)access_rows, FALSE); (JDIMENSION)access_rows, FALSE);
buffer += 2 * compptr->v_samp_factor; /* point to current iMCU row */ buffer += 2 * compptr->v_samp_factor; /* point to current iMCU row */
} else if (cinfo->output_iMCU_row > 0) { } else if (cinfo->output_iMCU_row > 0) {
access_rows += compptr->v_samp_factor; /* prior iMCU row too */
buffer = (*cinfo->mem->access_virt_barray) buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr)cinfo, coef->whole_image[ci], ((j_common_ptr)cinfo, coef->whole_image[ci],
(cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
@ -539,29 +541,30 @@ decompress_smooth_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
inverse_DCT = cinfo->idct->_inverse_DCT[ci]; inverse_DCT = cinfo->idct->_inverse_DCT[ci];
output_ptr = output_buf[ci]; output_ptr = output_buf[ci];
/* Loop over all DCT blocks to be processed. */ /* Loop over all DCT blocks to be processed. */
image_block_rows = block_rows * cinfo->total_iMCU_rows;
for (block_row = 0; block_row < block_rows; block_row++) { for (block_row = 0; block_row < block_rows; block_row++) {
image_block_row = cinfo->output_iMCU_row * block_rows + block_row;
buffer_ptr = buffer[block_row] + cinfo->master->first_MCU_col[ci]; buffer_ptr = buffer[block_row] + cinfo->master->first_MCU_col[ci];
if (block_row > 0 || cinfo->output_iMCU_row > 0) if (image_block_row > 0)
prev_block_row = prev_block_row =
buffer[block_row - 1] + cinfo->master->first_MCU_col[ci]; buffer[block_row - 1] + cinfo->master->first_MCU_col[ci];
else else
prev_block_row = buffer_ptr; prev_block_row = buffer_ptr;
if (block_row > 1 || cinfo->output_iMCU_row > 1) if (image_block_row > 1)
prev_prev_block_row = prev_prev_block_row =
buffer[block_row - 2] + cinfo->master->first_MCU_col[ci]; buffer[block_row - 2] + cinfo->master->first_MCU_col[ci];
else else
prev_prev_block_row = prev_block_row; prev_prev_block_row = prev_block_row;
if (block_row < block_rows - 1 || cinfo->output_iMCU_row < last_iMCU_row) if (image_block_row < image_block_rows - 1)
next_block_row = next_block_row =
buffer[block_row + 1] + cinfo->master->first_MCU_col[ci]; buffer[block_row + 1] + cinfo->master->first_MCU_col[ci];
else else
next_block_row = buffer_ptr; next_block_row = buffer_ptr;
if (block_row < block_rows - 2 || if (image_block_row < image_block_rows - 2)
cinfo->output_iMCU_row + 1 < last_iMCU_row)
next_next_block_row = next_next_block_row =
buffer[block_row + 2] + cinfo->master->first_MCU_col[ci]; buffer[block_row + 2] + cinfo->master->first_MCU_col[ci];
else else
@ -584,11 +587,11 @@ decompress_smooth_data(j_decompress_ptr cinfo, _JSAMPIMAGE output_buf)
/* Update DC values */ /* Update DC values */
if (block_num == cinfo->master->first_MCU_col[ci] && if (block_num == cinfo->master->first_MCU_col[ci] &&
block_num < last_block_column) { block_num < last_block_column) {
DC04 = (int)prev_prev_block_row[1][0]; DC04 = DC05 = (int)prev_prev_block_row[1][0];
DC09 = (int)prev_block_row[1][0]; DC09 = DC10 = (int)prev_block_row[1][0];
DC14 = (int)buffer_ptr[1][0]; DC14 = DC15 = (int)buffer_ptr[1][0];
DC19 = (int)next_block_row[1][0]; DC19 = DC20 = (int)next_block_row[1][0];
DC24 = (int)next_next_block_row[1][0]; DC24 = DC25 = (int)next_next_block_row[1][0];
} }
if (block_num + 1 < last_block_column) { if (block_num + 1 < last_block_column) {
DC05 = (int)prev_prev_block_row[2][0]; DC05 = (int)prev_prev_block_row[2][0];

View File

@ -7,7 +7,8 @@
* Lossless JPEG Modifications: * Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison. * Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, 2022, D. R. Commander. * Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, 2022-2023,
D. R. Commander.
* Copyright (C) 2015, Google, Inc. * Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
@ -270,7 +271,8 @@ typedef enum {
JCS_EXT_BGRA, /* blue/green/red/alpha */ JCS_EXT_BGRA, /* blue/green/red/alpha */
JCS_EXT_ABGR, /* alpha/blue/green/red */ JCS_EXT_ABGR, /* alpha/blue/green/red */
JCS_EXT_ARGB, /* alpha/red/green/blue */ JCS_EXT_ARGB, /* alpha/red/green/blue */
JCS_RGB565 /* 5-bit red/6-bit green/5-bit blue */ JCS_RGB565 /* 5-bit red/6-bit green/5-bit blue
[decompression only] */
} J_COLOR_SPACE; } J_COLOR_SPACE;
/* DCT/IDCT algorithm options. */ /* DCT/IDCT algorithm options. */