From 73a8c068047ca766493903b1d4924beb6f69c653 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 17 Feb 2024 18:33:56 +0100 Subject: [PATCH] jpeg: Import upstream release 9f. --- libs/jpeg/jccoefct.c | 8 +- libs/jpeg/jccolor.c | 35 +++--- libs/jpeg/jchuff.c | 284 +++++++++++++++++++++++-------------------- libs/jpeg/jdcolor.c | 93 +++++++------- libs/jpeg/jdct.h | 4 +- libs/jpeg/jdmerge.c | 31 +++-- libs/jpeg/jinclude.h | 66 +++++++++- libs/jpeg/jmorecfg.h | 31 +++-- libs/jpeg/jpeglib.h | 4 +- libs/jpeg/jversion.h | 6 +- 10 files changed, 318 insertions(+), 244 deletions(-) diff --git a/libs/jpeg/jccoefct.c b/libs/jpeg/jccoefct.c index 77851f390e1..494aa22988e 100644 --- a/libs/jpeg/jccoefct.c +++ b/libs/jpeg/jccoefct.c @@ -2,7 +2,7 @@ * jccoefct.c * * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 2003-2020 by Guido Vollbeding. + * Modified 2003-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -41,9 +41,9 @@ typedef struct { int MCU_rows_per_iMCU_row; /* number of such rows needed */ /* For single-pass compression, it's sufficient to buffer just one MCU - * (although this may prove a bit slow in practice). We append a - * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it - * for each MCU constructed and sent. + * (although this may prove a bit slow in practice). + * We append a workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, + * and reuse it for each MCU constructed and sent. * In multi-pass modes, this array points to the current MCU's blocks * within the virtual arrays. */ diff --git a/libs/jpeg/jccolor.c b/libs/jpeg/jccolor.c index db2ca429e8f..c028dd9db30 100644 --- a/libs/jpeg/jccolor.c +++ b/libs/jpeg/jccolor.c @@ -2,7 +2,7 @@ * jccolor.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2011-2019 by Guido Vollbeding. + * Modified 2011-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -40,10 +40,10 @@ typedef my_color_converter * my_cconvert_ptr; * Note that the derived conversion coefficients given in some of these * documents are imprecise. The general conversion equations are * Y = Kr * R + (1 - Kr - Kb) * G + Kb * B - * Cb = 0.5 * (B - Y) / (1 - Kb) - * Cr = 0.5 * (R - Y) / (1 - Kr) + * Cb = (B - Y) / (1 - Kb) / K + * Cr = (R - Y) / (1 - Kr) / K * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993 - * from the 1953 FCC NTSC primaries and CIE Illuminant C), + * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC, * the conversion equations to be implemented are therefore * Y = 0.299 * R + 0.587 * G + 0.114 * B * Cb = -0.168735892 * R - 0.331264108 * G + 0.5 * B + CENTERJSAMPLE @@ -62,8 +62,8 @@ typedef my_color_converter * my_cconvert_ptr; * by precalculating the constants times R,G,B for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); * for 9-bit to 12-bit samples it is still acceptable. It's not very - * reasonable for 16-bit samples, but if you want lossless storage you - * shouldn't be changing colorspace anyway. + * reasonable for 16-bit samples, but if you want lossless storage + * you shouldn't be changing colorspace anyway. * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included * in the tables to save adding them separately in the inner loop. */ @@ -110,16 +110,16 @@ rgb_ycc_start (j_compress_ptr cinfo) for (i = 0; i <= MAXJSAMPLE; i++) { rgb_ycc_tab[i+R_Y_OFF] = FIX(0.299) * i; rgb_ycc_tab[i+G_Y_OFF] = FIX(0.587) * i; - rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; + rgb_ycc_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; rgb_ycc_tab[i+R_CB_OFF] = (- FIX(0.168735892)) * i; rgb_ycc_tab[i+G_CB_OFF] = (- FIX(0.331264108)) * i; /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. * This ensures that the maximum output will round to MAXJSAMPLE * not MAXJSAMPLE+1, and thus that we don't have to range-limit. */ - rgb_ycc_tab[i+B_CB_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1; + rgb_ycc_tab[i+B_CB_OFF] = (i << (SCALEBITS-1)) + CBCR_OFFSET + ONE_HALF-1; /* B=>Cb and R=>Cr tables are the same - rgb_ycc_tab[i+R_CR_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1; + rgb_ycc_tab[i+R_CR_OFF] = (i << (SCALEBITS-1)) + CBCR_OFFSET + ONE_HALF-1; */ rgb_ycc_tab[i+G_CR_OFF] = (- FIX(0.418687589)) * i; rgb_ycc_tab[i+B_CR_OFF] = (- FIX(0.081312411)) * i; @@ -190,8 +190,8 @@ rgb_ycc_convert (j_compress_ptr cinfo, /* * Convert some rows of samples to the JPEG colorspace. - * This version handles RGB->grayscale conversion, which is the same - * as the RGB->Y portion of RGB->YCbCr. + * This version handles RGB->grayscale conversion, + * which is the same as the RGB->Y portion of RGB->YCbCr. * We assume rgb_ycc_start has been called (we only use the Y tables). */ @@ -201,7 +201,7 @@ rgb_gray_convert (j_compress_ptr cinfo, JDIMENSION output_row, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; + register INT32 y; register INT32 * ctab = cconvert->rgb_ycc_tab; register JSAMPROW inptr; register JSAMPROW outptr; @@ -212,14 +212,11 @@ rgb_gray_convert (j_compress_ptr cinfo, inptr = *input_buf++; outptr = output_buf[0][output_row++]; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr[RGB_RED]); - g = GETJSAMPLE(inptr[RGB_GREEN]); - b = GETJSAMPLE(inptr[RGB_BLUE]); + y = ctab[R_Y_OFF + GETJSAMPLE(inptr[RGB_RED])]; + y += ctab[G_Y_OFF + GETJSAMPLE(inptr[RGB_GREEN])]; + y += ctab[B_Y_OFF + GETJSAMPLE(inptr[RGB_BLUE])]; inptr += RGB_PIXELSIZE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } diff --git a/libs/jpeg/jchuff.c b/libs/jpeg/jchuff.c index f3272c9fa64..1f527b2182d 100644 --- a/libs/jpeg/jchuff.c +++ b/libs/jpeg/jchuff.c @@ -2,7 +2,7 @@ * jchuff.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2006-2020 by Guido Vollbeding. + * Modified 2006-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -26,17 +26,11 @@ /* The legal range of a DCT coefficient is - * -1024 .. +1023 for 8-bit data; - * -16384 .. +16383 for 12-bit data. - * Hence the magnitude should always fit in 10 or 14 bits respectively. + * -1024 .. +1023 for 8-bit sample data precision; + * -16384 .. +16383 for 12-bit sample data precision. + * Hence the magnitude should always fit in sample data precision + 2 bits. */ -#if BITS_IN_JSAMPLE == 8 -#define MAX_COEF_BITS 10 -#else -#define MAX_COEF_BITS 14 -#endif - /* Derived data constructed for each Huffman table */ typedef struct { @@ -547,6 +541,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; register int temp, temp2; register int nbits; + int max_coef_bits; int blkn, ci, tbl; ISHIFT_TEMPS @@ -558,6 +553,9 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) if (entropy->restarts_to_go == 0) emit_restart_e(entropy, entropy->next_restart_num); + /* Since we're encoding a difference, the range limit is twice as much. */ + max_coef_bits = cinfo->data_precision + 3; + /* Encode the MCU data blocks */ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { ci = cinfo->MCU_membership[blkn]; @@ -569,12 +567,17 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) temp = IRIGHT_SHIFT((int) (MCU_data[blkn][0][0]), cinfo->Al); /* DC differences are figured on the point-transformed values. */ - temp2 = temp - entropy->saved.last_dc_val[ci]; + if ((temp2 = temp - entropy->saved.last_dc_val[ci]) == 0) { + /* Count/emit the Huffman-coded symbol for the number of bits */ + emit_dc_symbol(entropy, tbl, 0); + + continue; + } + entropy->saved.last_dc_val[ci] = temp; /* Encode the DC coefficient difference per section G.1.2.1 */ - temp = temp2; - if (temp < 0) { + if ((temp = temp2) < 0) { temp = -temp; /* temp is abs value of input */ /* For a negative input, want temp2 = bitwise complement of abs(input) */ /* This code assumes we are on a two's complement machine */ @@ -583,14 +586,10 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) /* Find the number of bits needed for the magnitude of the coefficient */ nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values */ + if (nbits > max_coef_bits) ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit the Huffman-coded symbol for the number of bits */ @@ -598,8 +597,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ - emit_bits_e(entropy, (unsigned int) temp2, nbits); + emit_bits_e(entropy, (unsigned int) temp2, nbits); } cinfo->dest->next_output_byte = entropy->next_output_byte; @@ -633,7 +631,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) register int temp, temp2; register int nbits; register int r, k; - int Se, Al; + int Se, Al, max_coef_bits; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; @@ -646,6 +644,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) Se = cinfo->Se; Al = cinfo->Al; natural_order = cinfo->natural_order; + max_coef_bits = cinfo->data_precision + 2; /* Encode the MCU data block */ block = MCU_data[0]; @@ -666,18 +665,23 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) */ if (temp < 0) { temp = -temp; /* temp is abs value of input */ - temp >>= Al; /* apply the point transform */ + /* Apply the point transform, and watch out for case */ + /* that nonzero coef is zero after point transform. */ + if ((temp >>= Al) == 0) { + r++; + continue; + } /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ temp2 = ~temp; } else { - temp >>= Al; /* apply the point transform */ + /* Apply the point transform, and watch out for case */ + /* that nonzero coef is zero after point transform. */ + if ((temp >>= Al) == 0) { + r++; + continue; + } temp2 = temp; } - /* Watch out for case that nonzero coef is zero after point transform */ - if (temp == 0) { - r++; - continue; - } /* Emit any pending EOBRUN */ if (entropy->EOBRUN > 0) @@ -689,11 +693,11 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKARRAY MCU_data) } /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) + if (nbits > max_coef_bits) ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit Huffman symbol for run length / number of bits */ @@ -916,83 +920,89 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, register int nbits; register int r, k; int Se = state->cinfo->lim_Se; + int max_coef_bits = state->cinfo->data_precision + 3; const int * natural_order = state->cinfo->natural_order; /* Encode the DC coefficient difference per section F.1.2.1 */ - temp = temp2 = block[0] - last_dc_val; + if ((temp = block[0] - last_dc_val) == 0) { + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits_s(state, dctbl->ehufco[0], dctbl->ehufsi[0])) + return FALSE; + } else { + if ((temp2 = temp) < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* For a negative input, want temp2 = bitwise complement of abs(input) */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > max_coef_bits) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits_s(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; - /* Emit the Huffman-coded symbol for the number of bits */ - if (! emit_bits_s(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ if (! emit_bits_s(state, (unsigned int) temp2, nbits)) return FALSE; + } /* Encode the AC coefficients per section F.1.2.2 */ r = 0; /* r = run length of zeros */ for (k = 1; k <= Se; k++) { - if ((temp2 = block[natural_order[k]]) == 0) { + if ((temp = block[natural_order[k]]) == 0) { r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - if (! emit_bits_s(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) - return FALSE; - r -= 16; - } - - temp = temp2; - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - - /* Emit Huffman symbol for run length / number of bits */ - temp = (r << 4) + nbits; - if (! emit_bits_s(state, actbl->ehufco[temp], actbl->ehufsi[temp])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (! emit_bits_s(state, (unsigned int) temp2, nbits)) - return FALSE; - - r = 0; + continue; } + + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits_s(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + if ((temp2 = temp) < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Use ">=" instead of ">" so can use the + * same one larger limit from DC check here. + */ + if (nbits >= max_coef_bits) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit Huffman symbol for run length / number of bits */ + temp = (r << 4) + nbits; + if (! emit_bits_s(state, actbl->ehufco[temp], actbl->ehufsi[temp])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits_s(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; /* reset zero run length */ } /* If the last coef(s) were zero, emit an end-of-block code */ @@ -1122,28 +1132,31 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, register int nbits; register int r, k; int Se = cinfo->lim_Se; + int max_coef_bits = cinfo->data_precision + 3; const int * natural_order = cinfo->natural_order; /* Encode the DC coefficient difference per section F.1.2.1 */ - temp = block[0] - last_dc_val; - if (temp < 0) - temp = -temp; + if ((temp = block[0] - last_dc_val) == 0) { + /* Count the Huffman symbol for the number of bits */ + dc_counts[0]++; + } else { + if (temp < 0) + temp = -temp; /* temp is abs value of input */ - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > max_coef_bits) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count the Huffman symbol for the number of bits */ - dc_counts[nbits]++; /* Encode the AC coefficients per section F.1.2.2 */ @@ -1152,30 +1165,33 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, for (k = 1; k <= Se; k++) { if ((temp = block[natural_order[k]]) == 0) { r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - ac_counts[0xF0]++; - r -= 16; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - if (temp < 0) - temp = -temp; - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count Huffman symbol for run length / number of bits */ - ac_counts[(r << 4) + nbits]++; - - r = 0; + continue; } + + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + if (temp < 0) + temp = -temp; /* temp is abs value of input */ + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + do nbits++; /* there must be at least one 1 bit */ + while ((temp >>= 1)); + /* Check for out-of-range coefficient values. + * Use ">=" instead of ">" so can use the + * same one larger limit from DC check here. + */ + if (nbits >= max_coef_bits) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; /* reset zero run length */ } /* If the last coef(s) were zero, emit an end-of-block code */ diff --git a/libs/jpeg/jdcolor.c b/libs/jpeg/jdcolor.c index 7750df125a7..6b40fb53404 100644 --- a/libs/jpeg/jdcolor.c +++ b/libs/jpeg/jdcolor.c @@ -2,7 +2,7 @@ * jdcolor.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2011-2020 by Guido Vollbeding. + * Modified 2011-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -32,7 +32,9 @@ typedef struct { INT32 * Cb_g_tab; /* => table for Cb to G conversion */ /* Private state for RGB->Y conversion */ - INT32 * rgb_y_tab; /* => table for RGB to Y conversion */ + INT32 * R_y_tab; /* => table for R to Y conversion */ + INT32 * G_y_tab; /* => table for G to Y conversion */ + INT32 * B_y_tab; /* => table for B to Y conversion */ } my_color_deconverter; typedef my_color_deconverter * my_cconvert_ptr; @@ -87,29 +89,17 @@ typedef my_color_deconverter * my_cconvert_ptr; * by precalculating the constants times Cb and Cr for all possible values. * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); * for 9-bit to 12-bit samples it is still acceptable. It's not very - * reasonable for 16-bit samples, but if you want lossless storage you - * shouldn't be changing colorspace anyway. - * The Cr=>R and Cb=>B values can be rounded to integers in advance; the - * values for the G calculation are left scaled up, since we must add them - * together before rounding. + * reasonable for 16-bit samples, but if you want lossless storage + * you shouldn't be changing colorspace anyway. + * The Cr=>R and Cb=>B values can be rounded to integers in advance; + * the values for the G calculation are left scaled up, + * since we must add them together before rounding. */ #define SCALEBITS 16 /* speediest right-shift on some machines */ #define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) #define FIX(x) ((INT32) ((x) * (1L<Y conversion and divide it up into - * three parts, instead of doing three alloc_small requests. This lets us - * use a single table base address, which can be held in a register in the - * inner loops on many machines (more than can hold all three addresses, - * anyway). - */ - -#define R_Y_OFF 0 /* offset to R => Y section */ -#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ -#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ -#define TABLE_SIZE (3*(MAXJSAMPLE+1)) - /* * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion. @@ -249,17 +239,19 @@ LOCAL(void) build_rgb_y_table (j_decompress_ptr cinfo) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - INT32 * rgb_y_tab; INT32 i; - /* Allocate and fill in the conversion tables. */ - cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, TABLE_SIZE * SIZEOF(INT32)); + cconvert->R_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->G_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); + cconvert->B_y_tab = (INT32 *) (*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32)); for (i = 0; i <= MAXJSAMPLE; i++) { - rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i; - rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i; - rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; + cconvert->R_y_tab[i] = FIX(0.299) * i; + cconvert->G_y_tab[i] = FIX(0.587) * i; + cconvert->B_y_tab[i] = FIX(0.114) * i + ONE_HALF; } } @@ -274,8 +266,10 @@ rgb_gray_convert (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; @@ -288,13 +282,10 @@ rgb_gray_convert (j_decompress_ptr cinfo, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr0[col]); - g = GETJSAMPLE(inptr1[col]); - b = GETJSAMPLE(inptr2[col]); - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[GETJSAMPLE(inptr0[col])]; + y += Gytab[GETJSAMPLE(inptr1[col])]; + y += Bytab[GETJSAMPLE(inptr2[col])]; + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } @@ -354,7 +345,10 @@ rgb1_gray_convert (j_decompress_ptr cinfo, { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2; register JDIMENSION col; @@ -373,12 +367,10 @@ rgb1_gray_convert (j_decompress_ptr cinfo, /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD * (modulo) operator is equivalent to the bitmask operator AND. */ - r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE; - b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[(r + g - CENTERJSAMPLE) & MAXJSAMPLE]; + y += Gytab[g]; + y += Bytab[(b + g - CENTERJSAMPLE) & MAXJSAMPLE]; + outptr[col] = (JSAMPLE) (y >> SCALEBITS); } } } @@ -565,8 +557,10 @@ cmyk_yk_convert (j_decompress_ptr cinfo, JSAMPARRAY output_buf, int num_rows) { my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int r, g, b; - register INT32 * ctab = cconvert->rgb_y_tab; + register INT32 y; + register INT32 * Rytab = cconvert->R_y_tab; + register INT32 * Gytab = cconvert->G_y_tab; + register INT32 * Bytab = cconvert->B_y_tab; register JSAMPROW outptr; register JSAMPROW inptr0, inptr1, inptr2, inptr3; register JDIMENSION col; @@ -580,13 +574,10 @@ cmyk_yk_convert (j_decompress_ptr cinfo, input_row++; outptr = *output_buf++; for (col = 0; col < num_cols; col++) { - r = MAXJSAMPLE - GETJSAMPLE(inptr0[col]); - g = MAXJSAMPLE - GETJSAMPLE(inptr1[col]); - b = MAXJSAMPLE - GETJSAMPLE(inptr2[col]); - /* Y */ - outptr[0] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); + y = Rytab[MAXJSAMPLE - GETJSAMPLE(inptr0[col])]; + y += Gytab[MAXJSAMPLE - GETJSAMPLE(inptr1[col])]; + y += Bytab[MAXJSAMPLE - GETJSAMPLE(inptr2[col])]; + outptr[0] = (JSAMPLE) (y >> SCALEBITS); /* K passes through unchanged */ outptr[1] = inptr3[col]; /* don't need GETJSAMPLE here */ outptr += 2; diff --git a/libs/jpeg/jdct.h b/libs/jpeg/jdct.h index c8ec6cd90e9..0f251590c49 100644 --- a/libs/jpeg/jdct.h +++ b/libs/jpeg/jdct.h @@ -2,7 +2,7 @@ * jdct.h * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2019 by Guido Vollbeding. + * Modified 2002-2023 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -158,7 +158,7 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ #define jpeg_idct_6x12 jRD6x12 #define jpeg_idct_5x10 jRD5x10 #define jpeg_idct_4x8 jRD4x8 -#define jpeg_idct_3x6 jRD3x8 +#define jpeg_idct_3x6 jRD3x6 #define jpeg_idct_2x4 jRD2x4 #define jpeg_idct_1x2 jRD1x2 #endif /* NEED_SHORT_EXTERNAL_NAMES */ diff --git a/libs/jpeg/jdmerge.c b/libs/jpeg/jdmerge.c index 8ff13143af2..0d16821bedf 100644 --- a/libs/jpeg/jdmerge.c +++ b/libs/jpeg/jdmerge.c @@ -2,7 +2,7 @@ * jdmerge.c * * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2013-2020 by Guido Vollbeding. + * Modified 2013-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -20,17 +20,17 @@ * B = Y + K4 * Cb * only the Y term varies among the group of pixels corresponding to a pair * of chroma samples, so the rest of the terms can be calculated just once. - * At typical sampling ratios, this eliminates half or three-quarters of the - * multiplications needed for color conversion. + * At typical sampling ratios, this eliminates half or three-quarters + * of the multiplications needed for color conversion. * * This file currently provides implementations for the following cases: * YCC => RGB color conversion only (YCbCr or BG_YCC). * Sampling ratios of 2h1v or 2h2v. * No scaling needed at upsample time. * Corner-aligned (non-CCIR601) sampling alignment. - * Other special cases could be added, but in most applications these are - * the only common cases. (For uncommon cases we fall back on the more - * general code in jdsample.c and jdcolor.c.) + * Other special cases could be added, but in most applications these + * are the only common cases. (For uncommon cases we fall back on + * the more general code in jdsample.c and jdcolor.c.) */ #define JPEG_INTERNALS @@ -286,9 +286,9 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, /* Do the chroma part of the calculation */ cb = GETJSAMPLE(*inptr1++); cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; /* Fetch 2 Y values and emit 2 pixels */ y = GETJSAMPLE(*inptr0++); outptr[RGB_RED] = range_limit[y + cred]; @@ -303,15 +303,14 @@ h2v1_merged_upsample (j_decompress_ptr cinfo, } /* If image width is odd, do the last output column separately */ if (cinfo->output_width & 1) { + y = GETJSAMPLE(*inptr0); cb = GETJSAMPLE(*inptr1); cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; + outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; + outptr[RGB_GREEN] = range_limit[y + + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], + SCALEBITS))]; + outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; } } @@ -350,9 +349,9 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, /* Do the chroma part of the calculation */ cb = GETJSAMPLE(*inptr1++); cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; /* Fetch 4 Y values and emit 4 pixels */ y = GETJSAMPLE(*inptr00++); outptr0[RGB_RED] = range_limit[y + cred]; @@ -379,9 +378,9 @@ h2v2_merged_upsample (j_decompress_ptr cinfo, if (cinfo->output_width & 1) { cb = GETJSAMPLE(*inptr1); cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); cblue = Cbbtab[cb]; + cred = Crrtab[cr]; y = GETJSAMPLE(*inptr00); outptr0[RGB_RED] = range_limit[y + cred]; outptr0[RGB_GREEN] = range_limit[y + cgreen]; diff --git a/libs/jpeg/jinclude.h b/libs/jpeg/jinclude.h index 20ed4ef11f8..12ea8cd2fdf 100644 --- a/libs/jpeg/jinclude.h +++ b/libs/jpeg/jinclude.h @@ -2,7 +2,7 @@ * jinclude.h * * Copyright (C) 1991-1994, Thomas G. Lane. - * Modified 2017 by Guido Vollbeding. + * Modified 2017-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -11,8 +11,8 @@ * care of by the standard jconfig symbols, but on really weird systems * you may have to edit this file.) * - * NOTE: this file is NOT intended to be included by applications using the - * JPEG library. Most applications need only include jpeglib.h. + * NOTE: this file is NOT intended to be included by applications using + * the JPEG library. Most applications need only include jpeglib.h. */ @@ -87,11 +87,71 @@ * * Furthermore, macros are provided for fflush() and ferror() in order * to facilitate adaption by applications using an own FILE class. + * + * You can define your own custom file I/O functions in jconfig.h and + * #define JPEG_HAVE_FILE_IO_CUSTOM there to prevent redefinition here. + * + * You can #define JPEG_USE_FILE_IO_CUSTOM in jconfig.h to use custom file + * I/O functions implemented in Delphi VCL (Visual Component Library) + * in Vcl.Imaging.jpeg.pas for the TJPEGImage component utilizing + * the Delphi RTL (Run-Time Library) TMemoryStream component: + * + * procedure jpeg_stdio_src(var cinfo: jpeg_decompress_struct; + * input_file: TStream); external; + * + * procedure jpeg_stdio_dest(var cinfo: jpeg_compress_struct; + * output_file: TStream); external; + * + * function jfread(var buf; recsize, reccount: Integer; S: TStream): Integer; + * begin + * Result := S.Read(buf, recsize * reccount); + * end; + * + * function jfwrite(const buf; recsize, reccount: Integer; S: TStream): Integer; + * begin + * Result := S.Write(buf, recsize * reccount); + * end; + * + * function jfflush(S: TStream): Integer; + * begin + * Result := 0; + * end; + * + * function jferror(S: TStream): Integer; + * begin + * Result := 0; + * end; + * + * TMemoryStream of Delphi RTL has the distinctive feature to provide dynamic + * memory buffer management with a file/stream-based interface, particularly for + * the write (output) operation, which is easier to apply compared with direct + * implementations as given in jdatadst.c for memory destination. Those direct + * implementations of dynamic memory write tend to be more difficult to use, + * so providing an option like TMemoryStream may be a useful alternative. + * + * The CFile/CMemFile classes of the Microsoft Foundation Class (MFC) Library + * may be used in a similar fashion. */ +#ifndef JPEG_HAVE_FILE_IO_CUSTOM +#ifdef JPEG_USE_FILE_IO_CUSTOM +extern size_t jfread(void * __ptr, size_t __size, size_t __n, FILE * __stream); +extern size_t jfwrite(const void * __ptr, size_t __size, size_t __n, FILE * __stream); +extern int jfflush(FILE * __stream); +extern int jferror(FILE * __fp); + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) jfread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) jfwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFFLUSH(file) jfflush(file) +#define JFERROR(file) jferror(file) +#else #define JFREAD(file,buf,sizeofbuf) \ ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) #define JFWRITE(file,buf,sizeofbuf) \ ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) #define JFFLUSH(file) fflush(file) #define JFERROR(file) ferror(file) +#endif +#endif diff --git a/libs/jpeg/jmorecfg.h b/libs/jpeg/jmorecfg.h index 679d68bdc54..4638d6af2d2 100644 --- a/libs/jpeg/jmorecfg.h +++ b/libs/jpeg/jmorecfg.h @@ -2,7 +2,7 @@ * jmorecfg.h * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 1997-2013 by Guido Vollbeding. + * Modified 1997-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -351,8 +351,8 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; #define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN) */ +#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW) */ #define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ /* Note: if you selected more than 8-bit data precision, it is dangerous to * turn off ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only @@ -369,8 +369,8 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; #define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW) */ #define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ #define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ #undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ @@ -384,20 +384,31 @@ typedef enum { FALSE = 0, TRUE = 1 } boolean; /* * Ordering of RGB data in scanlines passed to or from the application. * If your application wants to deal with data in the order B,G,R, just - * change these macros. You can also deal with formats such as R,G,B,X - * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing - * the offsets will also change the order in which colormap data is organized. + * #define JPEG_USE_RGB_CUSTOM in jconfig.h, or define your own custom + * order in jconfig.h and #define JPEG_HAVE_RGB_CUSTOM. + * You can also deal with formats such as R,G,B,X (one extra byte per pixel) + * by changing RGB_PIXELSIZE. + * Note that changing the offsets will also change + * the order in which colormap data is organized. * RESTRICTIONS: * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. * 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE - * is not 3 (they don't understand about dummy color components!). So you - * can't use color quantization if you change that value. + * is not 3 (they don't understand about dummy color components!). + * So you can't use color quantization if you change that value. */ +#ifndef JPEG_HAVE_RGB_CUSTOM +#ifdef JPEG_USE_RGB_CUSTOM +#define RGB_RED 2 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 0 /* Offset of Blue */ +#else #define RGB_RED 0 /* Offset of Red in an RGB scanline element */ #define RGB_GREEN 1 /* Offset of Green */ #define RGB_BLUE 2 /* Offset of Blue */ +#endif #define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ +#endif /* Definitions for speed-related optimizations. */ diff --git a/libs/jpeg/jpeglib.h b/libs/jpeg/jpeglib.h index b1fa8ea9ad5..e7e15ab2cd4 100644 --- a/libs/jpeg/jpeglib.h +++ b/libs/jpeg/jpeglib.h @@ -2,7 +2,7 @@ * jpeglib.h * * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2002-2020 by Guido Vollbeding. + * Modified 2002-2022 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -39,7 +39,7 @@ extern "C" { #define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */ #define JPEG_LIB_VERSION_MAJOR 9 -#define JPEG_LIB_VERSION_MINOR 5 +#define JPEG_LIB_VERSION_MINOR 6 /* Various constants determining the sizes of things. diff --git a/libs/jpeg/jversion.h b/libs/jpeg/jversion.h index 17134b7a5ba..df53ef5e55b 100644 --- a/libs/jpeg/jversion.h +++ b/libs/jpeg/jversion.h @@ -1,7 +1,7 @@ /* * jversion.h * - * Copyright (C) 1991-2022, Thomas G. Lane, Guido Vollbeding. + * Copyright (C) 1991-2024, Thomas G. Lane, Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -9,6 +9,6 @@ */ -#define JVERSION "9e 16-Jan-2022" +#define JVERSION "9f 14-Jan-2024" -#define JCOPYRIGHT "Copyright (C) 2022, Thomas G. Lane, Guido Vollbeding" +#define JCOPYRIGHT "Copyright (C) 2024, Thomas G. Lane, Guido Vollbeding"