[LIBJPEG] Update to version 9d. CORE-16686

This commit is contained in:
Thomas Faber 2020-02-09 21:15:50 +01:00
parent d152519a4a
commit 1d5741919d
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
44 changed files with 2574 additions and 970 deletions

View file

@ -1,7 +1,7 @@
The Independent JPEG Group's JPEG software
==========================================
README for release 9c of 14-Jan-2018
README for release 9d of 12-Jan-2020
====================================
This distribution contains the ninth public release of the Independent JPEG
@ -10,8 +10,8 @@ to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
and other members of the Independent JPEG Group.
John Korejwa, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
Ge' Weijers, and other members of the Independent JPEG Group.
IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
(previously known as JPEG, together with ITU-T SG16).
@ -115,7 +115,7 @@ with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding.
This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
@ -152,13 +152,6 @@ The same holds for its supporting scripts (config.guess, config.sub,
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
but is also freely distributable.
The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
support has been removed altogether, and the GIF writer has been simplified
to produce "uncompressed GIFs". This technique does not use the LZW
algorithm; the resulting GIF files are larger than usual, but are readable
by all standard GIF decoders.
REFERENCES
==========
@ -246,8 +239,8 @@ ARCHIVE LOCATIONS
The "official" archive site for this software is www.ijg.org.
The most recent released version can always be found there in
directory "files". This particular version will be archived as
http://www.ijg.org/files/jpegsrc.v9c.tar.gz, and in Windows-compatible
"zip" archive format as http://www.ijg.org/files/jpegsr9c.zip.
http://www.ijg.org/files/jpegsrc.v9d.tar.gz, and in Windows-compatible
"zip" archive format as http://www.ijg.org/files/jpegsr9d.zip.
The JPEG FAQ (Frequently Asked Questions) article is a source of some
general information about JPEG.

View file

@ -1,6 +1,55 @@
CHANGE LOG for Independent JPEG Group's JPEG software
Version 9d 12-Jan-2020
-----------------------
Optimize the optimal Huffman code table generation to produce
slightly smaller files. Thank to John Korejwa for suggestion.
Note: Requires rebuild of testimgp.jpg.
Decoding Huffman: Use default tables if tables are not defined.
Thank to Simone Azzalin for report (Motion JPEG),
and to Martin Strunz for hint.
Add sanity check in optimal Huffman code table generation.
Thank to Adam Farley for suggestion.
rdtarga.c: use read_byte(), with EOF check, instead of getc()
in read_*_pixel().
Thank to Chijin Zhou for cjpeg potential vulnerability report.
jmemnobs.c: respect the max_memory_to_use setting in
jpeg_mem_available() computation. Thank to Sheng Shu and
Dongdong She for djpeg potential vulnerability report.
jdarith.c, jdhuff.c: avoid left shift of negative value
compiler warning in decode_mcu_AC_refine().
Thank to Indu Bhagat for suggestion.
Add x64 (64-bit) platform support, avoid compiler warnings.
Thank to Jonathan Potter, Feiyun Wang, and Sheng Shu for suggestion.
Adjust libjpeg version specification for pkg-config file.
Thank to Chen Chen for suggestion.
Restore GIF read and write support from libjpeg version 6a.
Thank to Wolfgang Werner (W.W.) Heinz for suggestion.
Improve consistency in raw (downsampled) image data processing mode.
Thank to Zhongyuan Zhou for hint.
Avoid out of bounds array read (AC derived table pointers)
in start pass in jdhuff.c. Thank to Peng Li for report.
Improve code sanity (jdhuff.c).
Thank to Reza Mirzazade farkhani for reports.
Add jpegtran -drop option; add options to the crop extension and wipe
to fill the extra area with content from the source image region,
instead of gray out.
Version 9c 14-Jan-2018
-----------------------

View file

@ -2,7 +2,7 @@
* djpeg.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2009-2015 by Guido Vollbeding.
* Modified 2009-2019 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.
*
@ -59,7 +59,8 @@ static const char * const cdjpeg_message_table[] = {
typedef enum {
FMT_BMP, /* BMP format (Windows flavor) */
FMT_GIF, /* GIF format */
FMT_GIF, /* GIF format (LZW compressed) */
FMT_GIF0, /* GIF format (uncompressed) */
FMT_OS2, /* BMP format (OS/2 flavor) */
FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
FMT_RLE, /* RLE format */
@ -111,8 +112,10 @@ usage (void)
(DEFAULT_FMT == FMT_BMP ? " (default)" : ""));
#endif
#ifdef GIF_SUPPORTED
fprintf(stderr, " -gif Select GIF output format%s\n",
fprintf(stderr, " -gif Select GIF output format (LZW compressed)%s\n",
(DEFAULT_FMT == FMT_GIF ? " (default)" : ""));
fprintf(stderr, " -gif0 Select GIF output format (uncompressed)%s\n",
(DEFAULT_FMT == FMT_GIF0 ? " (default)" : ""));
#endif
#ifdef BMP_SUPPORTED
fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n",
@ -195,7 +198,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
arg++; /* advance past switch marker character */
if (keymatch(arg, "bmp", 1)) {
/* BMP output format. */
/* BMP output format (Windows flavor). */
requested_fmt = FMT_BMP;
} else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) ||
@ -258,9 +261,13 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
cinfo->do_fancy_upsampling = FALSE;
} else if (keymatch(arg, "gif", 1)) {
/* GIF output format. */
/* GIF output format (LZW compressed). */
requested_fmt = FMT_GIF;
} else if (keymatch(arg, "gif0", 4)) {
/* GIF output format (uncompressed). */
requested_fmt = FMT_GIF0;
} else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) {
/* Force monochrome output. */
cinfo->out_color_space = JCS_GRAYSCALE;
@ -461,7 +468,7 @@ main (int argc, char **argv)
* APP12 is used by some digital camera makers for textual info,
* so we provide the ability to display it as text.
* If you like, additional APPn marker types can be selected for display,
* but don't try to override APP0 or APP14 this way (see libjpeg.doc).
* but don't try to override APP0 or APP14 this way (see libjpeg.txt).
*/
jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);
@ -554,7 +561,10 @@ main (int argc, char **argv)
#endif
#ifdef GIF_SUPPORTED
case FMT_GIF:
dest_mgr = jinit_write_gif(&cinfo);
dest_mgr = jinit_write_gif(&cinfo, TRUE);
break;
case FMT_GIF0:
dest_mgr = jinit_write_gif(&cinfo, FALSE);
break;
#endif
#ifdef PPM_SUPPORTED
@ -574,7 +584,6 @@ main (int argc, char **argv)
#endif
default:
ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT);
break;
}
dest_mgr->output_file = output_file;

View file

@ -1,7 +1,7 @@
/*
* jcarith.c
*
* Developed 1997-2013 by Guido Vollbeding.
* Developed 1997-2019 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.
*
@ -181,11 +181,11 @@ finish_pass (j_compress_ptr cinfo)
if (e->zc) /* output final pending zero bytes */
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte((e->c >> 19) & 0xFF, cinfo);
emit_byte((int) ((e->c >> 19) & 0xFF), cinfo);
if (((e->c >> 19) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
if (e->c & 0x7F800L) {
emit_byte((e->c >> 11) & 0xFF, cinfo);
emit_byte((int) ((e->c >> 11) & 0xFF), cinfo);
if (((e->c >> 11) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
}
@ -280,7 +280,8 @@ arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
/* Note: The 3 spacer bits in the C register guarantee
* that the new buffer byte can't be 0xFF here
* (see page 160 in the P&M JPEG book). */
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
/* New output byte, might overflow later */
e->buffer = (int) (temp & 0xFF);
} else if (temp == 0xFF) {
++e->sc; /* stack 0xFF byte (which might overflow later) */
} else {
@ -302,7 +303,8 @@ arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
emit_byte(0x00, cinfo);
} while (--e->sc);
}
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
/* New output byte (can still overflow) */
e->buffer = (int) (temp & 0xFF);
}
e->c &= 0x7FFFFL;
e->ct += 8;
@ -926,9 +928,8 @@ jinit_arith_encoder (j_compress_ptr cinfo)
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_encoder));
entropy = (arith_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(arith_entropy_encoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass;

View file

@ -2,7 +2,7 @@
* jccolor.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011-2013 by Guido Vollbeding.
* Modified 2011-2019 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.
*
@ -105,14 +105,14 @@ rgb_ycc_start (j_compress_ptr cinfo)
/* Allocate and fill in the conversion tables. */
cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(TABLE_SIZE * SIZEOF(INT32)));
TABLE_SIZE * SIZEOF(INT32));
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+R_CB_OFF] = (-FIX(0.168735892)) * i;
rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.331264108)) * i;
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.
@ -121,8 +121,8 @@ rgb_ycc_start (j_compress_ptr cinfo)
/* 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+G_CR_OFF] = (-FIX(0.418687589)) * i;
rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.081312411)) * i;
rgb_ycc_tab[i+G_CR_OFF] = (- FIX(0.418687589)) * i;
rgb_ycc_tab[i+B_CR_OFF] = (- FIX(0.081312411)) * i;
}
}
@ -131,12 +131,12 @@ rgb_ycc_start (j_compress_ptr cinfo)
* Convert some rows of samples to the JPEG colorspace.
*
* Note that we change from the application's interleaved-pixel format
* to our internal noninterleaved, one-plane-per-component format.
* The input buffer is therefore three times as wide as the output buffer.
* to our internal noninterleaved, one-plane-per-component format. The
* input buffer is therefore three times as wide as the output buffer.
*
* A starting row offset is provided only for the output buffer. The caller
* can easily adjust the passed input_buf value to accommodate any row
* offset required on that side.
* A starting row offset is provided only for the output buffer. The
* caller can easily adjust the passed input_buf value to accommodate
* any row offset required on that side.
*/
METHODDEF(void)
@ -145,8 +145,8 @@ rgb_ycc_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
@ -162,6 +162,7 @@ rgb_ycc_convert (j_compress_ptr cinfo,
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't
@ -179,7 +180,6 @@ rgb_ycc_convert (j_compress_ptr cinfo,
outptr2[col] = (JSAMPLE)
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
>> SCALEBITS);
inptr += RGB_PIXELSIZE;
}
}
}
@ -201,8 +201,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
@ -215,11 +215,11 @@ rgb_gray_convert (j_compress_ptr cinfo,
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = 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);
inptr += RGB_PIXELSIZE;
}
}
}
@ -228,8 +228,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
/*
* Convert some rows of samples to the JPEG colorspace.
* This version handles Adobe-style CMYK->YCCK conversion,
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
* conversion as above, while passing K (black) unchanged.
* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the
* same conversion as above, while passing K (black) unchanged.
* We assume rgb_ycc_start has been called.
*/
@ -239,8 +239,8 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2, outptr3;
register JDIMENSION col;
@ -259,6 +259,7 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
/* K passes through as-is */
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
inptr += 4;
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't
@ -276,7 +277,6 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
outptr2[col] = (JSAMPLE)
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
>> SCALEBITS);
inptr += 4;
}
}
}
@ -312,13 +312,13 @@ rgb_rgb1_convert (j_compress_ptr cinfo,
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
* (modulo) operator is equivalent to the bitmask operator AND.
*/
outptr0[col] = (JSAMPLE) ((r - g + CENTERJSAMPLE) & MAXJSAMPLE);
outptr1[col] = (JSAMPLE) g;
outptr2[col] = (JSAMPLE) ((b - g + CENTERJSAMPLE) & MAXJSAMPLE);
inptr += RGB_PIXELSIZE;
}
}
}
@ -335,17 +335,17 @@ grayscale_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
int instride = cinfo->input_components;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
register JDIMENSION count;
register int instride = cinfo->input_components;
JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) {
inptr = *input_buf++;
outptr = output_buf[0][output_row++];
for (col = 0; col < num_cols; col++) {
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
for (count = num_cols; count > 0; count--) {
*outptr++ = *inptr; /* don't need GETJSAMPLE() here */
inptr += instride;
}
}
@ -396,21 +396,21 @@ null_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
int ci;
register int nc = cinfo->num_components;
register JSAMPROW inptr;
register JSAMPROW outptr;
register JDIMENSION col;
register JDIMENSION count;
register int num_comps = cinfo->num_components;
JDIMENSION num_cols = cinfo->image_width;
int ci;
while (--num_rows >= 0) {
/* It seems fastest to make a separate pass for each component. */
for (ci = 0; ci < nc; ci++) {
for (ci = 0; ci < num_comps; ci++) {
inptr = input_buf[0] + ci;
outptr = output_buf[ci][output_row];
for (col = 0; col < num_cols; col++) {
for (count = num_cols; count > 0; count--) {
*outptr++ = *inptr; /* don't need GETJSAMPLE() here */
inptr += nc;
inptr += num_comps;
}
}
input_buf++;
@ -439,9 +439,8 @@ jinit_color_converter (j_compress_ptr cinfo)
{
my_cconvert_ptr cconvert;
cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_converter));
cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_converter));
cinfo->cconvert = &cconvert->pub;
/* set start_pass to null method until we find out differently */
cconvert->pub.start_pass = null_method;
@ -455,9 +454,11 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_RGB:
case JCS_BG_RGB:
#if RGB_PIXELSIZE != 3
if (cinfo->input_components != RGB_PIXELSIZE)
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
case JCS_BG_YCC:
@ -474,7 +475,6 @@ jinit_color_converter (j_compress_ptr cinfo)
default: /* JCS_UNKNOWN can be anything */
if (cinfo->input_components < 1)
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break;
}
/* Support color transform only for RGB colorspaces */
@ -507,19 +507,18 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_BG_RGB:
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == cinfo->jpeg_color_space) {
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb_rgb1_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
} else
if (cinfo->in_color_space != cinfo->jpeg_color_space)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb_rgb1_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
break;
case JCS_YCbCr:
@ -572,10 +571,9 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_CMYK:
if (cinfo->num_components != 4)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_CMYK)
cconvert->pub.color_convert = null_convert;
else
if (cinfo->in_color_space != JCS_CMYK)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
cconvert->pub.color_convert = null_convert;
break;
case JCS_YCCK:
@ -599,6 +597,5 @@ jinit_color_converter (j_compress_ptr cinfo)
cinfo->num_components != cinfo->input_components)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
cconvert->pub.color_convert = null_convert;
break;
}
}

View file

@ -2,7 +2,7 @@
* jchuff.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2006-2013 by Guido Vollbeding.
* Modified 2006-2019 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.
*
@ -178,13 +178,12 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
htbl = jpeg_std_huff_table((j_common_ptr) cinfo, isDC, tblno);
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (c_derived_tbl *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(c_derived_tbl));
*pdtbl = (c_derived_tbl *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(c_derived_tbl));
dtbl = *pdtbl;
/* Figure C.1: make table of Huffman code length for each symbol */
@ -1256,22 +1255,88 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
int codesize[257]; /* codesize[k] = code length of symbol k */
int others[257]; /* next symbol in current branch of tree */
int c1, c2;
int p, i, j;
int c1, c2, i, j;
UINT8 *p;
long v;
freq[256] = 1; /* make sure 256 has a nonzero count */
/* Including the pseudo-symbol 256 in the Huffman procedure guarantees
* that no real symbol is given code-value of all ones, because 256
* will be placed last in the largest codeword category.
* In the symbol list build procedure this element serves as sentinel
* for the zero run loop.
*/
#ifndef DONT_USE_FANCY_HUFF_OPT
/* Build list of symbols sorted in order of descending frequency */
/* This approach has several benefits (thank to John Korejwa for the idea):
* 1.
* If a codelength category is split during the length limiting procedure
* below, the feature that more frequent symbols are assigned shorter
* codewords remains valid for the adjusted code.
* 2.
* To reduce consecutive ones in a Huffman data stream (thus reducing the
* number of stuff bytes in JPEG) it is preferable to follow 0 branches
* (and avoid 1 branches) as much as possible. This is easily done by
* assigning symbols to leaves of the Huffman tree in order of decreasing
* frequency, with no secondary sort based on codelengths.
* 3.
* The symbol list can be built independently from the assignment of code
* lengths by the Huffman procedure below.
* Note: The symbol list build procedure must be performed first, because
* the Huffman procedure assigning the codelengths clobbers the frequency
* counts!
*/
/* Here we use the others array as a linked list of nonzero frequencies
* to be sorted. Already sorted elements are removed from the list.
*/
/* Building list */
/* This item does not correspond to a valid symbol frequency and is used
* as starting index.
*/
j = 256;
for (i = 0;; i++) {
if (freq[i] == 0) /* skip zero frequencies */
continue;
if (i > 255)
break;
others[j] = i; /* this symbol value */
j = i; /* previous symbol value */
}
others[j] = -1; /* mark end of list */
/* Sorting list */
p = htbl->huffval;
while ((c1 = others[256]) >= 0) {
v = freq[c1];
i = c1; /* first symbol value */
j = 256; /* pseudo symbol value for starting index */
while ((c2 = others[c1]) >= 0) {
if (freq[c2] > v) {
v = freq[c2];
i = c2; /* this symbol value */
j = c1; /* previous symbol value */
}
c1 = c2;
}
others[j] = others[i]; /* remove this symbol i from list */
*p++ = (UINT8) i;
}
#endif /* DONT_USE_FANCY_HUFF_OPT */
/* This algorithm is explained in section K.2 of the JPEG standard */
MEMZERO(bits, SIZEOF(bits));
MEMZERO(codesize, SIZEOF(codesize));
for (i = 0; i < 257; i++)
others[i] = -1; /* init links to empty */
freq[256] = 1; /* make sure 256 has a nonzero count */
/* Including the pseudo-symbol 256 in the Huffman procedure guarantees
* that no real symbol is given code-value of all ones, because 256
* will be placed last in the largest codeword category.
*/
/* Huffman's basic algorithm to assign optimal code lengths to symbols */
@ -1301,7 +1366,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
/* Done if we've merged everything into one frequency */
if (c2 < 0)
break;
/* Else merge the two counts/trees */
freq[c1] += freq[c2];
freq[c2] = 0;
@ -1312,9 +1377,9 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
c1 = others[c1];
codesize[c1]++;
}
others[c1] = c2; /* chain c2 onto c1's tree branch */
/* Increment the codesize of everything in c2's tree branch */
codesize[c2]++;
while (others[c2] >= 0) {
@ -1329,7 +1394,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
/* The JPEG standard seems to think that this can't happen, */
/* but I'm paranoid... */
if (codesize[i] > MAX_CLEN)
ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
ERREXIT(cinfo, JERR_HUFF_CLEN_OUTOFBOUNDS);
bits[codesize[i]]++;
}
@ -1345,13 +1410,16 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
* shortest nonzero BITS entry is converted into a prefix for two code words
* one bit longer.
*/
for (i = MAX_CLEN; i > 16; i--) {
while (bits[i] > 0) {
j = i - 2; /* find length of new prefix to be used */
while (bits[j] == 0)
while (bits[j] == 0) {
if (j == 0)
ERREXIT(cinfo, JERR_HUFF_CLEN_OUTOFBOUNDS);
j--;
}
bits[i] -= 2; /* remove two symbols */
bits[i-1]++; /* one goes in this length */
bits[j+1] += 2; /* two new symbols in this length */
@ -1363,24 +1431,27 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
while (bits[i] == 0) /* find largest codelength still in use */
i--;
bits[i]--;
/* Return final symbol counts (only for lengths 0..16) */
MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
#ifdef DONT_USE_FANCY_HUFF_OPT
/* Return a list of the symbols sorted by code length */
/* It's not real clear to me why we don't need to consider the codelength
* changes made above, but the JPEG spec seems to think this works.
/* Note: Due to the codelength changes made above, it can happen
* that more frequent symbols are assigned longer codewords.
*/
p = 0;
p = htbl->huffval;
for (i = 1; i <= MAX_CLEN; i++) {
for (j = 0; j <= 255; j++) {
if (codesize[j] == i) {
htbl->huffval[p] = (UINT8) j;
p++;
*p++ = (UINT8) j;
}
}
}
#endif /* DONT_USE_FANCY_HUFF_OPT */
/* Set sent_table FALSE so updated table will be written to JPEG file. */
htbl->sent_table = FALSE;
}
@ -1400,13 +1471,13 @@ finish_pass_gather (j_compress_ptr cinfo)
boolean did_dc[NUM_HUFF_TBLS];
boolean did_ac[NUM_HUFF_TBLS];
/* It's important not to apply jpeg_gen_optimal_table more than once
* per table, because it clobbers the input frequency counts!
*/
if (cinfo->progressive_mode)
/* Flush out buffered data (all we care about is counting the EOB symbol) */
emit_eobrun(entropy);
/* It's important not to apply jpeg_gen_optimal_table more than once
* per table, because it clobbers the input frequency counts!
*/
MEMZERO(did_dc, SIZEOF(did_dc));
MEMZERO(did_ac, SIZEOF(did_ac));
@ -1475,9 +1546,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
entropy->pub.encode_mcu = encode_mcu_AC_refine;
/* AC refinement needs a correction bit buffer */
if (entropy->bit_buffer == NULL)
entropy->bit_buffer = (char *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
MAX_CORR_BITS * SIZEOF(char));
entropy->bit_buffer = (char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, MAX_CORR_BITS * SIZEOF(char));
}
}
@ -1505,9 +1575,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
/* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->dc_count_ptrs[tbl] == NULL)
entropy->dc_count_ptrs[tbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
entropy->dc_count_ptrs[tbl] = (long *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, 257 * SIZEOF(long));
MEMZERO(entropy->dc_count_ptrs[tbl], 257 * SIZEOF(long));
} else {
/* Compute derived values for Huffman tables */
@ -1525,9 +1594,8 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
if (entropy->ac_count_ptrs[tbl] == NULL)
entropy->ac_count_ptrs[tbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
entropy->ac_count_ptrs[tbl] = (long *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, 257 * SIZEOF(long));
MEMZERO(entropy->ac_count_ptrs[tbl], 257 * SIZEOF(long));
} else {
jpeg_make_c_derived_tbl(cinfo, FALSE, tbl,
@ -1556,9 +1624,8 @@ jinit_huff_encoder (j_compress_ptr cinfo)
huff_entropy_ptr entropy;
int i;
entropy = (huff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(huff_entropy_encoder));
entropy = (huff_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(huff_entropy_encoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass_huff;

View file

@ -2,7 +2,7 @@
* jcmarker.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2013 by Guido Vollbeding.
* Modified 2003-2019 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.
*
@ -471,7 +471,6 @@ emit_adobe_app14 (j_compress_ptr cinfo)
break;
default:
emit_byte(cinfo, 0); /* Color transform = 0 */
break;
}
}
@ -702,9 +701,8 @@ jinit_marker_writer (j_compress_ptr cinfo)
my_marker_ptr marker;
/* Create the subobject */
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_marker_writer));
marker = (my_marker_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_marker_writer));
cinfo->marker = &marker->pub;
/* Initialize method pointers */
marker->pub.write_file_header = write_file_header;

View file

@ -2,7 +2,7 @@
* jcmaster.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2003-2017 by Guido Vollbeding.
* Modified 2003-2019 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.
*
@ -62,7 +62,7 @@ initial_setup (j_compress_ptr cinfo)
case 5: cinfo->natural_order = jpeg_natural_order5; break;
case 6: cinfo->natural_order = jpeg_natural_order6; break;
case 7: cinfo->natural_order = jpeg_natural_order7; break;
default: cinfo->natural_order = jpeg_natural_order; break;
default: cinfo->natural_order = jpeg_natural_order;
}
/* Derive lim_Se from block_size */
@ -114,20 +114,24 @@ initial_setup (j_compress_ptr cinfo)
*/
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
if (! cinfo->raw_data_in)
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
if (! cinfo->raw_data_in)
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
@ -620,9 +624,8 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
{
my_master_ptr master;
master = (my_master_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_comp_master));
master = (my_master_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_comp_master));
cinfo->master = &master->pub;
master->pub.prepare_for_pass = prepare_for_pass;
master->pub.pass_startup = pass_startup;

View file

@ -2,6 +2,7 @@
* jcomapi.c
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2019 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.
*
@ -104,3 +105,140 @@ jpeg_alloc_huff_table (j_common_ptr cinfo)
tbl->sent_table = FALSE; /* make sure this is false in any new table */
return tbl;
}
/*
* Set up the standard Huffman tables (cf. JPEG standard section K.3).
* IMPORTANT: these are only valid for 8-bit data precision!
* (Would jutils.c be a more reasonable place to put this?)
*/
GLOBAL(JHUFF_TBL *)
jpeg_std_huff_table (j_common_ptr cinfo, boolean isDC, int tblno)
{
JHUFF_TBL **htblptr, *htbl;
const UINT8 *bits, *val;
int nsymbols, len;
static const UINT8 bits_dc_luminance[17] =
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_luminance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_dc_chrominance[17] =
{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_chrominance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_ac_luminance[17] =
{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
static const UINT8 val_ac_luminance[] =
{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
static const UINT8 bits_ac_chrominance[17] =
{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
static const UINT8 val_ac_chrominance[] =
{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
if (cinfo->is_decompressor) {
if (isDC)
htblptr = ((j_decompress_ptr) cinfo)->dc_huff_tbl_ptrs;
else
htblptr = ((j_decompress_ptr) cinfo)->ac_huff_tbl_ptrs;
} else {
if (isDC)
htblptr = ((j_compress_ptr) cinfo)->dc_huff_tbl_ptrs;
else
htblptr = ((j_compress_ptr) cinfo)->ac_huff_tbl_ptrs;
}
switch (tblno) {
case 0:
if (isDC) {
bits = bits_dc_luminance;
val = val_dc_luminance;
} else {
bits = bits_ac_luminance;
val = val_ac_luminance;
}
break;
case 1:
if (isDC) {
bits = bits_dc_chrominance;
val = val_dc_chrominance;
} else {
bits = bits_ac_chrominance;
val = val_ac_chrominance;
}
break;
default:
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
return NULL; /* avoid compiler warnings for uninitialized variables */
}
if (htblptr[tblno] == NULL)
htblptr[tblno] = jpeg_alloc_huff_table(cinfo);
htbl = htblptr[tblno];
/* Copy the number-of-symbols-of-each-code-length counts */
MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
/* Validate the counts. We do this here mainly so we can copy the right
* number of symbols from the val[] array, without risking marching off
* the end of memory. jxhuff.c will do a more thorough test later.
*/
nsymbols = 0;
for (len = 1; len <= 16; len++)
nsymbols += bits[len];
if (nsymbols > 256)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
if (nsymbols > 0)
MEMCOPY(htbl->huffval, val, nsymbols * SIZEOF(UINT8));
/* Initialize sent_table FALSE so table will be written to JPEG file. */
htbl->sent_table = FALSE;
return htbl;
}

View file

@ -2,7 +2,7 @@
* jcparam.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2013 by Guido Vollbeding.
* Modified 2003-2019 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.
*
@ -162,112 +162,23 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
/*
* Huffman table setup routines
* Reset standard Huffman tables
*/
LOCAL(void)
add_huff_table (j_compress_ptr cinfo,
JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
/* Define a Huffman table */
{
int nsymbols, len;
if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
/* Copy the number-of-symbols-of-each-code-length counts */
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
/* Validate the counts. We do this here mainly so we can copy the right
* number of symbols from the val[] array, without risking marching off
* the end of memory. jchuff.c will do a more thorough test later.
*/
nsymbols = 0;
for (len = 1; len <= 16; len++)
nsymbols += bits[len];
if (nsymbols < 1 || nsymbols > 256)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
/* Initialize sent_table FALSE so table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE;
}
LOCAL(void)
std_huff_tables (j_compress_ptr cinfo)
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
/* IMPORTANT: these are only valid for 8-bit data precision! */
{
static const UINT8 bits_dc_luminance[17] =
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_luminance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_dc_chrominance[17] =
{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
static const UINT8 val_dc_chrominance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const UINT8 bits_ac_luminance[17] =
{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
static const UINT8 val_ac_luminance[] =
{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
static const UINT8 bits_ac_chrominance[17] =
{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
static const UINT8 val_ac_chrominance[] =
{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa };
add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
bits_dc_luminance, val_dc_luminance);
add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
bits_ac_luminance, val_ac_luminance);
add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
bits_dc_chrominance, val_dc_chrominance);
add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
bits_ac_chrominance, val_ac_chrominance);
if (cinfo->dc_huff_tbl_ptrs[0] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, TRUE, 0);
if (cinfo->ac_huff_tbl_ptrs[0] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, FALSE, 0);
if (cinfo->dc_huff_tbl_ptrs[1] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, TRUE, 1);
if (cinfo->ac_huff_tbl_ptrs[1] != NULL)
(void) jpeg_std_huff_table((j_common_ptr) cinfo, FALSE, 1);
}
@ -306,7 +217,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
cinfo->data_precision = BITS_IN_JSAMPLE;
/* Set up two quantization tables using default quality of 75 */
jpeg_set_quality(cinfo, 75, TRUE);
/* Set up two Huffman tables */
/* Reset standard Huffman tables */
std_huff_tables(cinfo);
/* Initialize default arithmetic coding conditioning */

View file

@ -1,7 +1,7 @@
/*
* jdarith.c
*
* Developed 1997-2015 by Guido Vollbeding.
* Developed 1997-2019 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.
*
@ -280,7 +280,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@ -370,7 +370,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@ -404,7 +404,8 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char *st;
int p1, blkn;
JCOEF p1;
int blkn;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
@ -440,7 +441,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
JCOEFPTR thiscoef;
unsigned char *st;
int tbl, k, kex;
int p1, m1;
JCOEF p1, m1;
const int * natural_order;
/* Process restart marker if needed */
@ -459,7 +460,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
m1 = -p1; /* -1 in the bit position being coded */
/* Establish EOBx (previous stage end-of-block) index */
kex = cinfo->Se;
@ -555,7 +556,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@ -612,7 +613,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
if ((m <<= 1) == (int) 0x8000U) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
@ -766,9 +767,8 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_decoder));
entropy = (arith_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(arith_entropy_decoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass;
@ -785,9 +785,9 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
if (cinfo->progressive_mode) {
/* Create progression status table */
int *coef_bit_ptr, ci;
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components*DCTSIZE2*SIZEOF(int));
cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components * DCTSIZE2 * SIZEOF(int));
coef_bit_ptr = & cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (i = 0; i < DCTSIZE2; i++)

View file

@ -2,7 +2,7 @@
* jdatadst.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2017 by Guido Vollbeding.
* Modified 2009-2019 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.
*
@ -46,7 +46,7 @@ typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
unsigned char ** outbuffer; /* target buffer */
unsigned long * outsize;
size_t * outsize;
unsigned char * newbuffer; /* newly allocated buffer */
JOCTET * buffer; /* start of buffer */
size_t bufsize;
@ -66,9 +66,8 @@ init_destination (j_compress_ptr cinfo)
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
/* Allocate the output buffer --- it will be released when done with image */
dest->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
@ -131,7 +130,7 @@ empty_mem_output_buffer (j_compress_ptr cinfo)
nextbuffer = (JOCTET *) malloc(nextsize);
if (nextbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 11);
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
@ -204,9 +203,8 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
* sizes may be different. Caveat programmer.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_destination_mgr));
cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_destination_mgr));
}
dest = (my_dest_ptr) cinfo->dest;
@ -233,7 +231,7 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
GLOBAL(void)
jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char ** outbuffer, unsigned long * outsize)
unsigned char ** outbuffer, size_t * outsize)
{
my_mem_dest_ptr dest;
@ -244,9 +242,8 @@ jpeg_mem_dest (j_compress_ptr cinfo,
* can be written to the same buffer without re-executing jpeg_mem_dest.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_mem_destination_mgr));
cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_mem_destination_mgr));
}
dest = (my_mem_dest_ptr) cinfo->dest;

View file

@ -2,7 +2,7 @@
* jdatasrc.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2015 by Guido Vollbeding.
* Modified 2009-2019 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.
*
@ -156,21 +156,23 @@ METHODDEF(void)
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
struct jpeg_source_mgr * src = cinfo->src;
size_t nbytes;
/* Just a dumb implementation for now. Could use fseek() except
* it doesn't work on pipes. Not clear that being smart is worth
* any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0) {
while (num_bytes > (long) src->bytes_in_buffer) {
num_bytes -= (long) src->bytes_in_buffer;
nbytes = (size_t) num_bytes;
while (nbytes > src->bytes_in_buffer) {
nbytes -= src->bytes_in_buffer;
(void) (*src->fill_input_buffer) (cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
}
src->next_input_byte += (size_t) num_bytes;
src->bytes_in_buffer -= (size_t) num_bytes;
src->next_input_byte += nbytes;
src->bytes_in_buffer -= nbytes;
}
}
@ -219,13 +221,11 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
* manager serially with the same JPEG object. Caveat programmer.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_source_mgr));
cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_source_mgr));
src = (my_src_ptr) cinfo->src;
src->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
INPUT_BUF_SIZE * SIZEOF(JOCTET));
src->buffer = (JOCTET *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, INPUT_BUF_SIZE * SIZEOF(JOCTET));
}
src = (my_src_ptr) cinfo->src;
@ -247,7 +247,7 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
GLOBAL(void)
jpeg_mem_src (j_decompress_ptr cinfo,
const unsigned char * inbuffer, unsigned long insize)
const unsigned char * inbuffer, size_t insize)
{
struct jpeg_source_mgr * src;
@ -259,9 +259,8 @@ jpeg_mem_src (j_decompress_ptr cinfo,
* the first one.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(struct jpeg_source_mgr));
cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(struct jpeg_source_mgr));
}
src = cinfo->src;
@ -270,6 +269,6 @@ jpeg_mem_src (j_decompress_ptr cinfo,
src->skip_input_data = skip_input_data;
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->term_source = term_source;
src->bytes_in_buffer = (size_t) insize;
src->bytes_in_buffer = insize;
src->next_input_byte = (const JOCTET *) inbuffer;
}

View file

@ -2,7 +2,7 @@
* jdcolor.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011-2017 by Guido Vollbeding.
* Modified 2011-2019 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.
*
@ -124,28 +124,22 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
cconvert->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 1.402 * x */
cconvert->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
cconvert->Cr_r_tab[i] = (int) DESCALE(FIX(1.402) * x, SCALEBITS);
/* Cb=>B value is nearest int to 1.772 * x */
cconvert->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
cconvert->Cb_b_tab[i] = (int) DESCALE(FIX(1.772) * x, SCALEBITS);
/* Cr=>G value is scaled-up -0.714136286 * x */
cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
/* Cb=>G value is scaled-up -0.344136286 * x */
@ -164,28 +158,22 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
cconvert->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 2.804 * x */
cconvert->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
cconvert->Cr_r_tab[i] = (int) DESCALE(FIX(2.804) * x, SCALEBITS);
/* Cb=>B value is nearest int to 3.544 * x */
cconvert->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
cconvert->Cb_b_tab[i] = (int) DESCALE(FIX(3.544) * x, SCALEBITS);
/* Cr=>G value is scaled-up -1.428272572 * x */
cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
/* Cb=>G value is scaled-up -0.688272572 * x */
@ -201,6 +189,7 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
* Note that we change from noninterleaved, one-plane-per-component format
* to interleaved-pixel format. The output buffer is therefore three times
* as wide as the input buffer.
*
* A starting row offset is provided only for the input buffer. The caller
* can easily adjust the passed output_buf value to accommodate any row
* offset required on that side.
@ -264,9 +253,8 @@ build_rgb_y_table (j_decompress_ptr cinfo)
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->rgb_y_tab = rgb_y_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, TABLE_SIZE * SIZEOF(INT32));
for (i = 0; i <= MAXJSAMPLE; i++) {
rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i;
@ -286,8 +274,8 @@ rgb_gray_convert (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_y_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_y_tab;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
@ -313,6 +301,7 @@ rgb_gray_convert (j_decompress_ptr cinfo,
/*
* Convert some rows of samples to the output colorspace.
* [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
* (inverse color transform).
* This can be seen as an adaption of the general YCbCr->RGB
@ -364,8 +353,8 @@ rgb1_gray_convert (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register INT32 * ctab = cconvert->rgb_y_tab;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_y_tab;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
@ -396,6 +385,7 @@ rgb1_gray_convert (j_decompress_ptr cinfo,
/*
* Convert some rows of samples to the output colorspace.
* No colorspace change, but conversion from separate-planes
* to interleaved representation.
*/
@ -430,6 +420,7 @@ rgb_convert (j_decompress_ptr cinfo,
/*
* Color conversion for no colorspace change: just copy the data,
* converting from separate-planes to interleaved representation.
* We assume out_color_components == num_components.
*/
METHODDEF(void)
@ -437,20 +428,21 @@ null_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
int ci;
register int nc = cinfo->num_components;
register JSAMPROW outptr;
register JSAMPROW inptr;
register JDIMENSION col;
register JDIMENSION count;
register int num_comps = cinfo->num_components;
JDIMENSION num_cols = cinfo->output_width;
int ci;
while (--num_rows >= 0) {
for (ci = 0; ci < nc; ci++) {
/* It seems fastest to make a separate pass for each component. */
for (ci = 0; ci < num_comps; ci++) {
inptr = input_buf[ci][input_row];
outptr = output_buf[0] + ci;
for (col = 0; col < num_cols; col++) {
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
outptr += nc;
for (count = num_cols; count > 0; count--) {
*outptr = *inptr++; /* don't need GETJSAMPLE() here */
outptr += num_comps;
}
}
input_row++;
@ -504,9 +496,10 @@ gray_rgb_convert (j_decompress_ptr cinfo,
/*
* Adobe-style YCCK->CMYK conversion.
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
* conversion as above, while passing K (black) unchanged.
* Convert some rows of samples to the output colorspace.
* This version handles Adobe-style YCCK->CMYK conversion,
* where we convert YCbCr to R=1-C, G=1-M, and B=1-Y using the
* same conversion as above, while passing K (black) unchanged.
* We assume build_ycc_rgb_table has been called.
*/
@ -577,9 +570,8 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
my_cconvert_ptr cconvert;
int ci;
cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_deconverter));
cconvert = (my_cconvert_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_color_deconverter));
cinfo->cconvert = &cconvert->pub;
cconvert->pub.start_pass = start_pass_dcolor;
@ -607,7 +599,6 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
default: /* JCS_UNKNOWN can be anything */
if (cinfo->num_components < 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
break;
}
/* Support color transform only for RGB colorspaces */
@ -684,19 +675,18 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
case JCS_BG_RGB:
cinfo->out_color_components = RGB_PIXELSIZE;
if (cinfo->jpeg_color_space == JCS_BG_RGB) {
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb1_rgb_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
} else
if (cinfo->jpeg_color_space != JCS_BG_RGB)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb1_rgb_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
break;
case JCS_CMYK:
@ -714,14 +704,12 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
}
break;
default:
/* Permit null conversion to same output space */
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
cinfo->out_color_components = cinfo->num_components;
cconvert->pub.color_convert = null_convert;
} else /* unsupported non-null conversion */
default: /* permit null conversion to same output space */
if (cinfo->out_color_space != cinfo->jpeg_color_space)
/* unsupported non-null conversion */
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
cinfo->out_color_components = cinfo->num_components;
cconvert->pub.color_convert = null_convert;
}
if (cinfo->quantize_colors)

View file

@ -2,7 +2,7 @@
* jdhuff.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2006-2016 by Guido Vollbeding.
* Modified 2006-2019 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.
*
@ -341,13 +341,12 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
htbl = jpeg_std_huff_table((j_common_ptr) cinfo, isDC, tblno);
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (d_derived_tbl *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(d_derived_tbl));
*pdtbl = (d_derived_tbl *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(d_derived_tbl));
dtbl = *pdtbl;
dtbl->pub = htbl; /* fill in back link */
@ -706,7 +705,7 @@ process_restart (j_decompress_ptr cinfo)
METHODDEF(boolean)
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int Al = cinfo->Al;
register int s, r;
@ -730,7 +729,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (! entropy->insufficient_data) {
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* Outer loop handles each block in the MCU */
@ -759,12 +758,13 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@ -777,7 +777,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
METHODDEF(boolean)
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int s, k, r;
unsigned int EOBRUN;
@ -809,7 +809,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (EOBRUN) /* if it's a band of zeroes... */
EOBRUN--; /* ...process it now (we do nothing) */
else {
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
Se = cinfo->Se;
Al = cinfo->Al;
natural_order = cinfo->natural_order;
@ -842,15 +842,16 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
}
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
}
/* Completed MCU, so update state */
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@ -864,9 +865,10 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
METHODDEF(boolean)
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int p1, blkn;
JCOEF p1;
int blkn;
BITREAD_STATE_VARS;
/* Process restart marker if needed; may have to suspend */
@ -881,7 +883,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
*/
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
@ -896,10 +898,11 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@ -911,11 +914,12 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
METHODDEF(boolean)
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int s, k, r;
unsigned int EOBRUN;
int Se, p1, m1;
int Se;
JCOEF p1, m1;
const int * natural_order;
JBLOCKROW block;
JCOEFPTR thiscoef;
@ -937,11 +941,11 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
Se = cinfo->Se;
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
m1 = -p1; /* -1 in the bit position being coded */
natural_order = cinfo->natural_order;
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
/* There is always only one block per MCU */
@ -1043,12 +1047,13 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
@ -1091,7 +1096,7 @@ decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
Se = cinfo->lim_Se;
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* Outer loop handles each block in the MCU */
@ -1178,12 +1183,13 @@ decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@ -1215,7 +1221,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (! entropy->insufficient_data) {
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
BITREAD_LOAD_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* Outer loop handles each block in the MCU */
@ -1302,12 +1308,13 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
BITREAD_SAVE_STATE(cinfo, entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
/* Account for restart interval if using restarts */
if (cinfo->restart_interval)
entropy->restarts_to_go--;
return TRUE;
}
@ -1343,11 +1350,11 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
goto bad;
}
if (cinfo->Al > 13) { /* need not check for < 0 */
/* Arguably the maximum Al value should be less than 13 for 8-bit precision,
* but the spec doesn't say so, and we try to be liberal about what we
* accept. Note: large Al values could result in out-of-range DC
* coefficients during early scans, leading to bizarre displays due to
* overflows in the IDCT math. But we won't crash.
/* Arguably the maximum Al value should be less than 13 for 8-bit
* precision, but the spec doesn't say so, and we try to be liberal
* about what we accept. Note: large Al values could result in
* out-of-range DC coefficients during early scans, leading to bizarre
* displays due to overflows in the IDCT math. But we won't crash.
*/
bad:
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
@ -1451,7 +1458,8 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
compptr = cinfo->cur_comp_info[ci];
/* Precalculate which table to use for each block */
entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
entropy->ac_cur_tbls[blkn] = /* AC needs no table when not present */
cinfo->lim_Se ? entropy->ac_derived_tbls[compptr->ac_tbl_no] : NULL;
/* Decide whether we really care about the coefficient values */
if (compptr->component_needed) {
ci = compptr->DCT_v_scaled_size;
@ -1494,7 +1502,6 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
if (ci <= 0 || ci > 8) ci = 8;
if (i <= 0 || i > 8) i = 8;
entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order[ci - 1][i - 1];
break;
}
} else {
entropy->coef_limit[blkn] = 0;
@ -1522,9 +1529,8 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
huff_entropy_ptr entropy;
int i;
entropy = (huff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(huff_entropy_decoder));
entropy = (huff_entropy_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(huff_entropy_decoder));
cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass_huff_decoder;
entropy->pub.finish_pass = finish_pass_huff;
@ -1532,9 +1538,9 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
if (cinfo->progressive_mode) {
/* Create progression status table */
int *coef_bit_ptr, ci;
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components*DCTSIZE2*SIZEOF(int));
cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components * DCTSIZE2 * SIZEOF(int));
coef_bit_ptr = & cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (i = 0; i < DCTSIZE2; i++)
@ -1545,7 +1551,7 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
entropy->derived_tbls[i] = NULL;
}
} else {
/* Mark tables unallocated */
/* Mark derived tables unallocated */
for (i = 0; i < NUM_HUFF_TBLS; i++) {
entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
}

View file

@ -2,7 +2,7 @@
* jdmarker.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2009-2013 by Guido Vollbeding.
* Modified 2009-2019 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.
*
@ -496,8 +496,6 @@ get_dht (j_decompress_ptr cinfo)
if (count > 256 || ((INT32) count) > length)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
MEMZERO(huffval, SIZEOF(huffval)); /* pre-zero array for later copy */
for (i = 0; i < count; i++)
INPUT_BYTE(cinfo, huffval[i], return FALSE);
@ -517,7 +515,8 @@ get_dht (j_decompress_ptr cinfo)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
if (count > 0)
MEMCOPY((*htblptr)->huffval, huffval, count * SIZEOF(UINT8));
}
if (length != 0)
@ -577,14 +576,14 @@ get_dqt (j_decompress_ptr cinfo)
count = DCTSIZE2;
}
switch (count) {
switch ((int) count) {
case (2*2): natural_order = jpeg_natural_order2; break;
case (3*3): natural_order = jpeg_natural_order3; break;
case (4*4): natural_order = jpeg_natural_order4; break;
case (5*5): natural_order = jpeg_natural_order5; break;
case (6*6): natural_order = jpeg_natural_order6; break;
case (7*7): natural_order = jpeg_natural_order7; break;
default: natural_order = jpeg_natural_order; break;
default: natural_order = jpeg_natural_order;
}
for (i = 0; i < count; i++) {
@ -784,7 +783,6 @@ examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
default:
TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
GETJOCTET(data[5]), (int) totallen);
break;
}
} else {
/* Start of APP0 does not match "JFIF" or "JFXX", or too short */
@ -858,7 +856,6 @@ get_interesting_appn (j_decompress_ptr cinfo)
default:
/* can't get here unless jpeg_save_markers chooses wrong processor */
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
break;
}
/* skip any remaining data -- could be lots */
@ -964,7 +961,6 @@ save_marker (j_decompress_ptr cinfo)
default:
TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
(int) (data_length + length));
break;
}
/* skip any remaining data -- could be lots */
@ -1240,7 +1236,6 @@ read_markers (j_decompress_ptr cinfo)
* ought to change!
*/
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
break;
}
/* Successfully processed marker, so reset state variable */
cinfo->unread_marker = 0;
@ -1416,9 +1411,8 @@ jinit_marker_reader (j_decompress_ptr cinfo)
int i;
/* Create subobject in permanent pool */
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_marker_reader));
marker = (my_marker_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(my_marker_reader));
cinfo->marker = &marker->pub;
/* Initialize public method pointers */
marker->pub.reset_marker_reader = reset_marker_reader;

View file

@ -2,7 +2,7 @@
* jdmaster.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2002-2017 by Guido Vollbeding.
* Modified 2002-2019 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.
*
@ -104,7 +104,7 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
*/
{
#ifdef IDCT_SCALING_SUPPORTED
int ci;
int ci, ssize;
jpeg_component_info *compptr;
#endif
@ -124,19 +124,23 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
int ssize = 1;
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
ssize = 1;
if (! cinfo->raw_data_out)
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
ssize = 1;
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
if (! cinfo->raw_data_out)
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) ==
0) {
ssize = ssize * 2;
}
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
/* We don't support IDCT ratios larger than 2. */
@ -144,13 +148,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
}
/* Recompute downsampled dimensions of components;
* application needs to know these if using raw downsampled data.
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Recompute downsampled dimensions of components;
* application needs to know these if using raw downsampled data.
*/
/* Size in samples, after IDCT scaling */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width *
@ -172,8 +173,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
break;
case JCS_RGB:
case JCS_BG_RGB:
#if RGB_PIXELSIZE != 3
cinfo->out_color_components = RGB_PIXELSIZE;
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
case JCS_BG_YCC:
cinfo->out_color_components = 3;
@ -184,7 +187,6 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
break;
default: /* else must be same colorspace as in file */
cinfo->out_color_components = cinfo->num_components;
break;
}
cinfo->output_components = (cinfo->quantize_colors ? 1 :
cinfo->out_color_components);
@ -525,9 +527,8 @@ jinit_master_decompress (j_decompress_ptr cinfo)
{
my_master_ptr master;
master = (my_master_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_decomp_master));
master = (my_master_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_decomp_master));
cinfo->master = &master->pub;
master->pub.prepare_for_output_pass = prepare_for_output_pass;
master->pub.finish_output_pass = finish_output_pass;

View file

@ -2,7 +2,7 @@
* jdmerge.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2013-2017 by Guido Vollbeding.
* Modified 2013-2019 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.
*
@ -95,28 +95,22 @@ build_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
upsample->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 1.402 * x */
upsample->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
upsample->Cr_r_tab[i] = (int) DESCALE(FIX(1.402) * x, SCALEBITS);
/* Cb=>B value is nearest int to 1.772 * x */
upsample->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
upsample->Cb_b_tab[i] = (int) DESCALE(FIX(1.772) * x, SCALEBITS);
/* Cr=>G value is scaled-up -0.714136286 * x */
upsample->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
/* Cb=>G value is scaled-up -0.344136286 * x */
@ -135,28 +129,22 @@ build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
INT32 x;
SHIFT_TEMPS
upsample->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cr_r_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cb_b_tab = (int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 2.804 * x */
upsample->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
upsample->Cr_r_tab[i] = (int) DESCALE(FIX(2.804) * x, SCALEBITS);
/* Cb=>B value is nearest int to 3.544 * x */
upsample->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
upsample->Cb_b_tab[i] = (int) DESCALE(FIX(3.544) * x, SCALEBITS);
/* Cr=>G value is scaled-up -1.428272572 * x */
upsample->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
/* Cb=>G value is scaled-up -0.688272572 * x */
@ -419,9 +407,8 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample;
upsample = (my_upsample_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_upsampler));
upsample = (my_upsample_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_upsampler));
cinfo->upsample = &upsample->pub;
upsample->pub.start_pass = start_pass_merged_upsample;
upsample->pub.need_context_rows = FALSE;
@ -432,9 +419,9 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
upsample->pub.upsample = merged_2v_upsample;
upsample->upmethod = h2v2_merged_upsample;
/* Allocate a spare row buffer */
upsample->spare_row = (JSAMPROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
upsample->spare_row = (JSAMPROW) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) upsample->out_row_width * SIZEOF(JSAMPLE));
} else {
upsample->pub.upsample = merged_1v_upsample;
upsample->upmethod = h2v1_merged_upsample;

View file

@ -2,7 +2,7 @@
* jfdctint.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modification developed 2003-2015 by Guido Vollbeding.
* Modification developed 2003-2018 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.
*
@ -3261,78 +3261,84 @@ jpeg_fdct_6x3 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
GLOBAL(void)
jpeg_fdct_4x2 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
{
INT32 tmp0, tmp1;
INT32 tmp10, tmp11;
DCTELEM *dataptr;
DCTELEM tmp0, tmp2, tmp10, tmp12, tmp4, tmp5;
INT32 tmp1, tmp3, tmp11, tmp13;
INT32 z1, z2, z3;
JSAMPROW elemptr;
int ctr;
SHIFT_TEMPS
/* Pre-zero output coefficient block. */
MEMZERO(data, SIZEOF(DCTELEM) * DCTSIZE2);
/* Pass 1: process rows.
* Note results are scaled up by sqrt(8) compared to a true DCT;
* furthermore, we scale the results by 2**PASS1_BITS.
* We must also scale the output by (8/4)*(8/2) = 2**3, which we add here.
* Note results are scaled up by sqrt(8) compared to a true DCT.
* 4-point FDCT kernel,
* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
*/
dataptr = data;
for (ctr = 0; ctr < 2; ctr++) {
elemptr = sample_data[ctr] + start_col;
/* Row 0 */
elemptr = sample_data[0] + start_col;
/* Even part */
/* Even part */
tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
tmp1 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
tmp4 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
tmp5 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
tmp10 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
tmp11 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
tmp0 = tmp4 + tmp5;
tmp2 = tmp4 - tmp5;
/* Apply unsigned->signed conversion. */
dataptr[0] = (DCTELEM)
((tmp0 + tmp1 - 4 * CENTERJSAMPLE) << (PASS1_BITS+3));
dataptr[2] = (DCTELEM) ((tmp0 - tmp1) << (PASS1_BITS+3));
/* Odd part */
/* Odd part */
z2 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
z3 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100); /* c6 */
/* Add fudge factor here for final descale. */
tmp0 += ONE << (CONST_BITS-PASS1_BITS-4);
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */
/* Add fudge factor here for final descale. */
z1 += ONE << (CONST_BITS-3-1);
tmp1 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */
tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */
dataptr[1] = (DCTELEM)
RIGHT_SHIFT(tmp0 + MULTIPLY(tmp10, FIX_0_765366865), /* c2-c6 */
CONST_BITS-PASS1_BITS-3);
dataptr[3] = (DCTELEM)
RIGHT_SHIFT(tmp0 - MULTIPLY(tmp11, FIX_1_847759065), /* c2+c6 */
CONST_BITS-PASS1_BITS-3);
/* Row 1 */
elemptr = sample_data[1] + start_col;
dataptr += DCTSIZE; /* advance pointer to next row */
}
/* Even part */
tmp4 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[3]);
tmp5 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[2]);
tmp10 = tmp4 + tmp5;
tmp12 = tmp4 - tmp5;
/* Odd part */
z2 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[3]);
z3 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[2]);
z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */
tmp11 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */
tmp13 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */
/* Pass 2: process columns.
* We remove the PASS1_BITS scaling, but leave the results scaled up
* by an overall factor of 8.
* We leave the results scaled up by an overall factor of 8.
* We must also scale the output by (8/4)*(8/2) = 2**3.
*/
dataptr = data;
for (ctr = 0; ctr < 4; ctr++) {
/* Even part */
/* Column 0 */
/* Apply unsigned->signed conversion. */
data[DCTSIZE*0] = (tmp0 + tmp10 - 8 * CENTERJSAMPLE) << 3;
data[DCTSIZE*1] = (tmp0 - tmp10) << 3;
/* Add fudge factor here for final descale. */
tmp0 = dataptr[DCTSIZE*0] + (ONE << (PASS1_BITS-1));
tmp1 = dataptr[DCTSIZE*1];
/* Column 1 */
data[DCTSIZE*0+1] = (DCTELEM) RIGHT_SHIFT(tmp1 + tmp11, CONST_BITS-3);
data[DCTSIZE*1+1] = (DCTELEM) RIGHT_SHIFT(tmp1 - tmp11, CONST_BITS-3);
dataptr[DCTSIZE*0] = (DCTELEM) RIGHT_SHIFT(tmp0 + tmp1, PASS1_BITS);
/* Column 2 */
data[DCTSIZE*0+2] = (tmp2 + tmp12) << 3;
data[DCTSIZE*1+2] = (tmp2 - tmp12) << 3;
/* Odd part */
dataptr[DCTSIZE*1] = (DCTELEM) RIGHT_SHIFT(tmp0 - tmp1, PASS1_BITS);
dataptr++; /* advance pointer to next column */
}
/* Column 3 */
data[DCTSIZE*0+3] = (DCTELEM) RIGHT_SHIFT(tmp3 + tmp13, CONST_BITS-3);
data[DCTSIZE*1+3] = (DCTELEM) RIGHT_SHIFT(tmp3 - tmp13, CONST_BITS-3);
}
@ -4312,7 +4318,6 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
/* Pass 1: process rows.
* Note results are scaled up by sqrt(8) compared to a true DCT.
* We must also scale the output by (8/2)*(8/4) = 2**3, which we add here.
*/
dataptr = data;
@ -4325,17 +4330,18 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
tmp1 = GETJSAMPLE(elemptr[1]);
/* Apply unsigned->signed conversion. */
dataptr[0] = (DCTELEM) ((tmp0 + tmp1 - 2 * CENTERJSAMPLE) << 3);
dataptr[0] = (DCTELEM) (tmp0 + tmp1 - 2 * CENTERJSAMPLE);
/* Odd part */
dataptr[1] = (DCTELEM) ((tmp0 - tmp1) << 3);
dataptr[1] = (DCTELEM) (tmp0 - tmp1);
dataptr += DCTSIZE; /* advance pointer to next row */
}
/* Pass 2: process columns.
* We leave the results scaled up by an overall factor of 8.
* We must also scale the output by (8/2)*(8/4) = 2**3.
* 4-point FDCT kernel,
* cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point FDCT].
*/
@ -4350,21 +4356,21 @@ jpeg_fdct_2x4 (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
tmp10 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*3];
tmp11 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*2];
dataptr[DCTSIZE*0] = (DCTELEM) (tmp0 + tmp1);
dataptr[DCTSIZE*2] = (DCTELEM) (tmp0 - tmp1);
dataptr[DCTSIZE*0] = (DCTELEM) ((tmp0 + tmp1) << 3);
dataptr[DCTSIZE*2] = (DCTELEM) ((tmp0 - tmp1) << 3);
/* Odd part */
tmp0 = MULTIPLY(tmp10 + tmp11, FIX_0_541196100); /* c6 */
/* Add fudge factor here for final descale. */
tmp0 += ONE << (CONST_BITS-1);
tmp0 += ONE << (CONST_BITS-3-1);
dataptr[DCTSIZE*1] = (DCTELEM)
RIGHT_SHIFT(tmp0 + MULTIPLY(tmp10, FIX_0_765366865), /* c2-c6 */
CONST_BITS);
CONST_BITS-3);
dataptr[DCTSIZE*3] = (DCTELEM)
RIGHT_SHIFT(tmp0 - MULTIPLY(tmp11, FIX_1_847759065), /* c2+c6 */
CONST_BITS);
CONST_BITS-3);
dataptr++; /* advance pointer to next column */
}

View file

@ -2,7 +2,7 @@
* jidctint.c
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modification developed 2002-2016 by Guido Vollbeding.
* Modification developed 2002-2018 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.
*
@ -1474,7 +1474,7 @@ jpeg_idct_10x10 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a 11x11 output block.
* producing an 11x11 output block.
*
* Optimized algorithm with 24 multiplications in the 1-D kernel.
* cK represents sqrt(2) * cos(K*pi/22).
@ -3675,7 +3675,7 @@ jpeg_idct_10x5 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a 8x4 output block.
* producing an 8x4 output block.
*
* 4-point IDCT in pass 1 (columns), 8-point in pass 2 (rows).
*/
@ -3835,7 +3835,7 @@ jpeg_idct_8x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a reduced-size 6x3 output block.
* producing a 6x3 output block.
*
* 3-point IDCT in pass 1 (columns), 6-point in pass 2 (rows).
*/
@ -4082,7 +4082,7 @@ jpeg_idct_2x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a 8x16 output block.
* producing an 8x16 output block.
*
* 16-point IDCT in pass 1 (columns), 8-point in pass 2 (rows).
*/
@ -5004,7 +5004,7 @@ jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a reduced-size 3x6 output block.
* producing a 3x6 output block.
*
* 6-point IDCT in pass 1 (columns), 3-point in pass 2 (rows).
*/

View file

@ -2,7 +2,7 @@
* jmemmgr.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011-2012 by Guido Vollbeding.
* Modified 2011-2019 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.
*
@ -130,7 +130,7 @@ typedef struct {
jvirt_barray_ptr virt_barray_list;
/* This counts total space obtained from jpeg_get_small/large */
long total_space_allocated;
size_t total_space_allocated;
/* alloc_sarray and alloc_barray set this value for use by virtual
* array routines.
@ -195,7 +195,7 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
* This is helpful because message parm array can't handle longs.
*/
fprintf(stderr, "Freeing pool %d, total space = %ld\n",
pool_id, mem->total_space_allocated);
pool_id, (long) mem->total_space_allocated);
for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
lhdr_ptr = lhdr_ptr->hdr.next) {
@ -260,11 +260,11 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
small_pool_ptr hdr_ptr, prev_hdr_ptr;
char * data_ptr;
size_t odd_bytes, min_request, slop;
char * data_ptr;
/* Check for unsatisfiable request (do now to ensure no overflow below) */
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
if (sizeofobject > (size_t) MAX_ALLOC_CHUNK - SIZEOF(small_pool_hdr))
out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
@ -293,8 +293,8 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
else
slop = extra_pool_slop[pool_id];
/* Don't ask for more than MAX_ALLOC_CHUNK */
if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
if (slop > (size_t) MAX_ALLOC_CHUNK - min_request)
slop = (size_t) MAX_ALLOC_CHUNK - min_request;
/* Try to get space, if fail reduce slop and try again */
for (;;) {
hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
@ -348,7 +348,7 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
size_t odd_bytes;
/* Check for unsatisfiable request (do now to ensure no overflow below) */
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
if (sizeofobject > (size_t) MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr))
out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
@ -404,7 +404,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
long ltemp;
/* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
ltemp = (MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr)) /
((long) samplesperrow * SIZEOF(JSAMPLE));
if (ltemp <= 0)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
@ -416,15 +416,14 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
/* Get space for row pointers (small object) */
result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
(size_t) (numrows * SIZEOF(JSAMPROW)));
(size_t) numrows * SIZEOF(JSAMPROW));
/* Get the rows themselves (large objects) */
currow = 0;
while (currow < numrows) {
rowsperchunk = MIN(rowsperchunk, numrows - currow);
workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
(size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
* SIZEOF(JSAMPLE)));
(size_t) rowsperchunk * (size_t) samplesperrow * SIZEOF(JSAMPLE));
for (i = rowsperchunk; i > 0; i--) {
result[currow++] = workspace;
workspace += samplesperrow;
@ -452,7 +451,7 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
long ltemp;
/* Calculate max # of rows allowed in one allocation chunk */
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
ltemp = (MAX_ALLOC_CHUNK - SIZEOF(large_pool_hdr)) /
((long) blocksperrow * SIZEOF(JBLOCK));
if (ltemp <= 0)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
@ -464,15 +463,14 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
/* Get space for row pointers (small object) */
result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
(size_t) (numrows * SIZEOF(JBLOCKROW)));
(size_t) numrows * SIZEOF(JBLOCKROW));
/* Get the rows themselves (large objects) */
currow = 0;
while (currow < numrows) {
rowsperchunk = MIN(rowsperchunk, numrows - currow);
workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
(size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
* SIZEOF(JBLOCK)));
(size_t) rowsperchunk * (size_t) blocksperrow * SIZEOF(JBLOCK));
for (i = rowsperchunk; i > 0; i--) {
result[currow++] = workspace;
workspace += blocksperrow;
@ -585,8 +583,8 @@ realize_virt_arrays (j_common_ptr cinfo)
/* Allocate the in-memory buffers for any unrealized virtual arrays */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
long space_per_minheight, maximum_space, avail_mem;
long minheights, max_minheights;
long bytesperrow, space_per_minheight, maximum_space;
long avail_mem, minheights, max_minheights;
jvirt_sarray_ptr sptr;
jvirt_barray_ptr bptr;
@ -598,18 +596,16 @@ realize_virt_arrays (j_common_ptr cinfo)
maximum_space = 0;
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
if (sptr->mem_buffer == NULL) { /* if not realized yet */
space_per_minheight += (long) sptr->maxaccess *
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
maximum_space += (long) sptr->rows_in_array *
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
bytesperrow = (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
space_per_minheight += (long) sptr->maxaccess * bytesperrow;
maximum_space += (long) sptr->rows_in_array * bytesperrow;
}
}
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
if (bptr->mem_buffer == NULL) { /* if not realized yet */
space_per_minheight += (long) bptr->maxaccess *
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
maximum_space += (long) bptr->rows_in_array *
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
bytesperrow = (long) bptr->blocksperrow * SIZEOF(JBLOCK);
space_per_minheight += (long) bptr->maxaccess * bytesperrow;
maximum_space += (long) bptr->rows_in_array * bytesperrow;
}
}
@ -618,7 +614,7 @@ realize_virt_arrays (j_common_ptr cinfo)
/* Determine amount of memory to actually use; this is system-dependent. */
avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
mem->total_space_allocated);
(long) mem->total_space_allocated);
/* If the maximum space needed is available, make all the buffers full
* height; otherwise parcel it out with the same number of minheights
@ -694,7 +690,7 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
file_offset = ptr->cur_start_row * bytesperrow;
file_offset = (long) ptr->cur_start_row * bytesperrow;
/* Loop to read or write each allocation chunk in mem_buffer */
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
/* One chunk, but check for short chunk at end of buffer */
@ -727,7 +723,7 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
file_offset = ptr->cur_start_row * bytesperrow;
file_offset = (long) ptr->cur_start_row * bytesperrow;
/* Loop to read or write each allocation chunk in mem_buffer */
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
/* One chunk, but check for short chunk at end of buffer */
@ -771,7 +767,7 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
end_row > ptr->cur_start_row + ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
@ -856,7 +852,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
end_row > ptr->cur_start_row + ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
@ -1093,7 +1089,7 @@ jinit_memory_mgr (j_common_ptr cinfo)
mem->total_space_allocated = SIZEOF(my_memory_mgr);
/* Declare ourselves open for business */
cinfo->mem = & mem->pub;
cinfo->mem = &mem->pub;
/* Check for an environment variable JPEGMEM; if found, override the
* default max_memory setting from jpeg_mem_init. Note that the

View file

@ -2,6 +2,7 @@
* jmemnobs.c
*
* Copyright (C) 1992-1996, Thomas G. Lane.
* Modified 2019 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.
*
@ -12,7 +13,7 @@
* This is very portable in the sense that it'll compile on almost anything,
* but you'd better have lots of main memory (or virtual memory) if you want
* to process big images.
* Note that the max_memory_to_use option is ignored by this implementation.
* Note that the max_memory_to_use option is respected by this implementation.
*/
#define JPEG_INTERNALS
@ -66,13 +67,16 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
/*
* This routine computes the total memory space available for allocation.
* Here we always say, "we got all you want bud!"
*/
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
if (cinfo->mem->max_memory_to_use)
return cinfo->mem->max_memory_to_use - already_allocated;
/* Here we say, "we got all you want bud!" */
return max_bytes_needed;
}

View file

@ -1,7 +1,7 @@
/*
* jpegtran.c
*
* Copyright (C) 1995-2013, Thomas G. Lane, Guido Vollbeding.
* Copyright (C) 1995-2019, 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.
*
@ -37,6 +37,7 @@
static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */
static char * dropfilename; /* for -drop switch */
static char * scaleoption; /* -scale switch */
static JCOPY_OPTION copyoption; /* -copy switch */
static jpeg_transform_info transformoption; /* image transformation options */
@ -66,6 +67,7 @@ usage (void)
fprintf(stderr, "Switches for modifying the image:\n");
#if TRANSFORMS_SUPPORTED
fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n");
fprintf(stderr, " -drop +X+Y filename Drop another image\n");
fprintf(stderr, " -flip [horizontal|vertical] Mirror image (left-right or top-bottom)\n");
fprintf(stderr, " -grayscale Reduce to grayscale (omit color data)\n");
fprintf(stderr, " -perfect Fail if there is non-transformable edge blocks\n");
@ -76,6 +78,7 @@ usage (void)
fprintf(stderr, " -transpose Transpose image\n");
fprintf(stderr, " -transverse Transverse transpose image\n");
fprintf(stderr, " -trim Drop non-transformable edge blocks\n");
fprintf(stderr, " with -drop: Requantize drop file to source file\n");
fprintf(stderr, " -wipe WxH+X+Y Wipe (gray out) a rectangular subarea\n");
#endif
fprintf(stderr, "Switches for advanced users:\n");
@ -188,7 +191,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#if TRANSFORMS_SUPPORTED
if (++argn >= argc) /* advance to next argument */
usage();
if (transformoption.crop /* reject multiple crop/wipe requests */ ||
if (transformoption.crop /* reject multiple crop/drop/wipe requests */ ||
! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
fprintf(stderr, "%s: bogus -crop argument '%s'\n",
progname, argv[argn]);
@ -198,6 +201,26 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
select_transform(JXFORM_NONE); /* force an error */
#endif
} else if (keymatch(arg, "drop", 2)) {
#if TRANSFORMS_SUPPORTED
if (++argn >= argc) /* advance to next argument */
usage();
if (transformoption.crop /* reject multiple crop/drop/wipe requests */ ||
! jtransform_parse_crop_spec(&transformoption, argv[argn]) ||
transformoption.crop_width_set != JCROP_UNSET ||
transformoption.crop_height_set != JCROP_UNSET) {
fprintf(stderr, "%s: bogus -drop argument '%s'\n",
progname, argv[argn]);
exit(EXIT_FAILURE);
}
if (++argn >= argc) /* advance to next argument */
usage();
dropfilename = argv[argn];
select_transform(JXFORM_DROP);
#else
select_transform(JXFORM_NONE); /* force an error */
#endif
} else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
/* Enable debug printouts. */
/* On first -d, print version identification */
@ -342,7 +365,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#if TRANSFORMS_SUPPORTED
if (++argn >= argc) /* advance to next argument */
usage();
if (transformoption.crop /* reject multiple crop/wipe requests */ ||
if (transformoption.crop /* reject multiple crop/drop/wipe requests */ ||
! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
fprintf(stderr, "%s: bogus -wipe argument '%s'\n",
progname, argv[argn]);
@ -386,8 +409,14 @@ int
main (int argc, char **argv)
{
struct jpeg_decompress_struct srcinfo;
struct jpeg_error_mgr jsrcerr;
#if TRANSFORMS_SUPPORTED
struct jpeg_decompress_struct dropinfo;
struct jpeg_error_mgr jdroperr;
FILE * drop_file;
#endif
struct jpeg_compress_struct dstinfo;
struct jpeg_error_mgr jsrcerr, jdsterr;
struct jpeg_error_mgr jdsterr;
#ifdef PROGRESS_REPORT
struct cdjpeg_progress_mgr progress;
#endif
@ -427,7 +456,7 @@ main (int argc, char **argv)
* values read here are mostly ignored; we will rescan the switches after
* opening the input file. Also note that most of the switches affect the
* destination JPEG object, so we parse into that and then copy over what
* needs to affects the source too.
* needs to affect the source too.
*/
file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
@ -469,6 +498,21 @@ main (int argc, char **argv)
fp = read_stdin();
}
#if TRANSFORMS_SUPPORTED
/* Open the drop file. */
if (dropfilename != NULL) {
if ((drop_file = fopen(dropfilename, READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s for reading\n", progname, dropfilename);
exit(EXIT_FAILURE);
}
dropinfo.err = jpeg_std_error(&jdroperr);
jpeg_create_decompress(&dropinfo);
jpeg_stdio_src(&dropinfo, drop_file);
} else {
drop_file = NULL;
}
#endif
#ifdef PROGRESS_REPORT
start_progress_monitor((j_common_ptr) &dstinfo, &progress);
#endif
@ -488,6 +532,17 @@ main (int argc, char **argv)
&srcinfo.scale_num, &srcinfo.scale_denom) < 1)
usage();
#if TRANSFORMS_SUPPORTED
if (dropfilename != NULL) {
(void) jpeg_read_header(&dropinfo, TRUE);
transformoption.crop_width = dropinfo.image_width;
transformoption.crop_width_set = JCROP_POS;
transformoption.crop_height = dropinfo.image_height;
transformoption.crop_height_set = JCROP_POS;
transformoption.drop_ptr = &dropinfo;
}
#endif
/* Any space needed by a transform option must be requested before
* jpeg_read_coefficients so that memory allocation will be done right.
*/
@ -503,6 +558,12 @@ main (int argc, char **argv)
/* Read source file as DCT coefficients */
src_coef_arrays = jpeg_read_coefficients(&srcinfo);
#if TRANSFORMS_SUPPORTED
if (dropfilename != NULL) {
transformoption.drop_coef_arrays = jpeg_read_coefficients(&dropinfo);
}
#endif
/* Initialize destination compression parameters from source values */
jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
@ -560,18 +621,34 @@ main (int argc, char **argv)
/* Finish compression and release memory */
jpeg_finish_compress(&dstinfo);
jpeg_destroy_compress(&dstinfo);
#if TRANSFORMS_SUPPORTED
if (dropfilename != NULL) {
(void) jpeg_finish_decompress(&dropinfo);
jpeg_destroy_decompress(&dropinfo);
}
#endif
(void) jpeg_finish_decompress(&srcinfo);
jpeg_destroy_decompress(&srcinfo);
/* Close output file, if we opened it */
if (fp != stdout)
fclose(fp);
#if TRANSFORMS_SUPPORTED
if (drop_file != NULL)
fclose(drop_file);
#endif
#ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr) &dstinfo);
#endif
/* All done. */
exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
#if TRANSFORMS_SUPPORTED
if (dropfilename != NULL)
exit(jsrcerr.num_warnings + jdroperr.num_warnings +
jdsterr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
#endif
exit(jsrcerr.num_warnings + jdsterr.num_warnings ?
EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
}

View file

@ -2,7 +2,7 @@
* jutils.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2009-2011 by Guido Vollbeding.
* Modified 2009-2019 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.
*
@ -185,7 +185,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
{
register JSAMPROW inptr, outptr;
#ifdef FMEMCOPY
register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
register size_t count = (size_t) num_cols * SIZEOF(JSAMPLE);
#else
register JDIMENSION count;
#endif
@ -213,7 +213,7 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
/* Copy a row of coefficient blocks from one place to another. */
{
#ifdef FMEMCOPY
FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
FMEMCOPY(output_row, input_row, (size_t) num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
#else
register JCOEFPTR inptr, outptr;
register long count;

View file

@ -2,7 +2,7 @@
* rdbmp.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2017 by Guido Vollbeding.
* Modified 2009-2019 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.
*
@ -33,11 +33,10 @@
typedef unsigned char U_CHAR;
#define UCH(x) ((int) (x))
#else /* !HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char U_CHAR;
#ifdef CHAR_IS_UNSIGNED
#define UCH(x) ((int) (x))
#else
typedef char U_CHAR;
#define UCH(x) ((int) (x) & 0xFF)
#endif
#endif /* HAVE_UNSIGNED_CHAR */
@ -105,7 +104,6 @@ read_colormap (bmp_source_ptr sinfo, int cmaplen, int mapentrysize)
break;
default:
ERREXIT(sinfo->cinfo, JERR_BMP_BADCMAP);
break;
}
}
@ -122,7 +120,6 @@ get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit colormap indexes */
{
bmp_source_ptr source = (bmp_source_ptr) sinfo;
JSAMPARRAY image_ptr;
register JSAMPROW inptr, outptr;
register JSAMPARRAY colormap;
register JDIMENSION col;
@ -131,12 +128,10 @@ get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* Fetch next row from virtual array */
source->source_row--;
image_ptr = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->whole_image,
source->source_row, (JDIMENSION) 1, FALSE);
inptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
source->whole_image, source->source_row, (JDIMENSION) 1, FALSE);
/* Expand the colormap indexes to real data */
inptr = image_ptr[0];
outptr = source->pub.buffer[0];
colormap = source->colormap;
cmaplen = source->cmap_length;
@ -152,26 +147,22 @@ get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
return 1;
}
METHODDEF(JDIMENSION)
get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 24-bit pixels */
{
bmp_source_ptr source = (bmp_source_ptr) sinfo;
JSAMPARRAY image_ptr;
register JSAMPROW inptr, outptr;
register JDIMENSION col;
/* Fetch next row from virtual array */
source->source_row--;
image_ptr = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->whole_image,
source->source_row, (JDIMENSION) 1, FALSE);
inptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
source->whole_image, source->source_row, (JDIMENSION) 1, FALSE);
/* Transfer data. Note source values are in BGR order
* (even though Microsoft's own documents say the opposite).
*/
inptr = image_ptr[0];
outptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */
@ -183,26 +174,22 @@ get_24bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
return 1;
}
METHODDEF(JDIMENSION)
get_32bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 32-bit pixels */
{
bmp_source_ptr source = (bmp_source_ptr) sinfo;
JSAMPARRAY image_ptr;
register JSAMPROW inptr, outptr;
register JDIMENSION col;
/* Fetch next row from virtual array */
source->source_row--;
image_ptr = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->whole_image,
source->source_row, (JDIMENSION) 1, FALSE);
inptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
source->whole_image, source->source_row, (JDIMENSION) 1, FALSE);
/* Transfer data. Note source values are in BGR order
* (even though Microsoft's own documents say the opposite).
*/
inptr = image_ptr[0];
outptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */
@ -229,7 +216,6 @@ preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
register FILE *infile = source->pub.input_file;
register int c;
register JSAMPROW out_ptr;
JSAMPARRAY image_ptr;
JDIMENSION row, col;
cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
@ -240,10 +226,8 @@ preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
progress->pub.pass_limit = (long) cinfo->image_height;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
image_ptr = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->whole_image,
row, (JDIMENSION) 1, TRUE);
out_ptr = image_ptr[0];
out_ptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
source->whole_image, row, (JDIMENSION) 1, TRUE);
for (col = source->row_width; col > 0; col--) {
/* inline copy of read_byte() for speed */
if ((c = getc(infile)) == EOF)
@ -285,12 +269,12 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
bmp_source_ptr source = (bmp_source_ptr) sinfo;
U_CHAR bmpfileheader[14];
U_CHAR bmpinfoheader[64];
#define GET_2B(array,offset) ((unsigned int) UCH(array[offset]) + \
(((unsigned int) UCH(array[offset+1])) << 8))
#define GET_4B(array,offset) ((INT32) UCH(array[offset]) + \
(((INT32) UCH(array[offset+1])) << 8) + \
(((INT32) UCH(array[offset+2])) << 16) + \
(((INT32) UCH(array[offset+3])) << 24))
#define GET_2B(array, offset) ((unsigned int) UCH(array[offset]) + \
(((unsigned int) UCH(array[offset+1])) << 8))
#define GET_4B(array, offset) ((INT32) UCH(array[offset]) + \
(((INT32) UCH(array[offset+1])) << 8) + \
(((INT32) UCH(array[offset+2])) << 16) + \
(((INT32) UCH(array[offset+3])) << 24))
INT32 bfOffBits;
INT32 headerSize;
INT32 biWidth;
@ -306,9 +290,9 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* Read and verify the bitmap file header */
if (! ReadOK(source->pub.input_file, bmpfileheader, 14))
ERREXIT(cinfo, JERR_INPUT_EOF);
if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */
if (GET_2B(bmpfileheader, 0) != 0x4D42) /* 'BM' */
ERREXIT(cinfo, JERR_BMP_NOT);
bfOffBits = GET_4B(bmpfileheader,10);
bfOffBits = GET_4B(bmpfileheader, 10);
/* We ignore the remaining fileheader fields */
/* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
@ -316,19 +300,19 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
*/
if (! ReadOK(source->pub.input_file, bmpinfoheader, 4))
ERREXIT(cinfo, JERR_INPUT_EOF);
headerSize = GET_4B(bmpinfoheader,0);
headerSize = GET_4B(bmpinfoheader, 0);
if (headerSize < 12 || headerSize > 64)
ERREXIT(cinfo, JERR_BMP_BADHEADER);
if (! ReadOK(source->pub.input_file, bmpinfoheader+4, headerSize-4))
if (! ReadOK(source->pub.input_file, bmpinfoheader + 4, headerSize - 4))
ERREXIT(cinfo, JERR_INPUT_EOF);
switch ((int) headerSize) {
case 12:
/* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */
biWidth = (INT32) GET_2B(bmpinfoheader,4);
biHeight = (INT32) GET_2B(bmpinfoheader,6);
biPlanes = GET_2B(bmpinfoheader,8);
source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10);
biWidth = (INT32) GET_2B(bmpinfoheader, 4);
biHeight = (INT32) GET_2B(bmpinfoheader, 6);
biPlanes = GET_2B(bmpinfoheader, 8);
source->bits_per_pixel = (int) GET_2B(bmpinfoheader, 10);
switch (source->bits_per_pixel) {
case 8: /* colormapped image */
@ -342,21 +326,20 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break;
default:
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
break;
}
break;
case 40:
case 64:
/* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */
/* or OS/2 2.x header, which has additional fields that we ignore */
biWidth = GET_4B(bmpinfoheader,4);
biHeight = GET_4B(bmpinfoheader,8);
biPlanes = GET_2B(bmpinfoheader,12);
source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14);
biCompression = GET_4B(bmpinfoheader,16);
biXPelsPerMeter = GET_4B(bmpinfoheader,24);
biYPelsPerMeter = GET_4B(bmpinfoheader,28);
biClrUsed = GET_4B(bmpinfoheader,32);
biWidth = GET_4B(bmpinfoheader, 4);
biHeight = GET_4B(bmpinfoheader, 8);
biPlanes = GET_2B(bmpinfoheader, 12);
source->bits_per_pixel = (int) GET_2B(bmpinfoheader, 14);
biCompression = GET_4B(bmpinfoheader, 16);
biXPelsPerMeter = GET_4B(bmpinfoheader, 24);
biYPelsPerMeter = GET_4B(bmpinfoheader, 28);
biClrUsed = GET_4B(bmpinfoheader, 32);
/* biSizeImage, biClrImportant fields are ignored */
switch (source->bits_per_pixel) {
@ -371,7 +354,6 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break;
default:
ERREXIT(cinfo, JERR_BMP_BADDEPTH);
break;
}
if (biCompression != 0)
ERREXIT(cinfo, JERR_BMP_COMPRESSED);
@ -404,9 +386,8 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
else if (biClrUsed > 256)
ERREXIT(cinfo, JERR_BMP_BADCMAP);
/* Allocate space to store the colormap */
source->colormap = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) biClrUsed, (JDIMENSION) 3);
source->colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (JDIMENSION) biClrUsed, (JDIMENSION) 3);
source->cmap_length = (int) biClrUsed;
/* and read it from the file */
read_colormap(source, (int) biClrUsed, mapentrysize);
@ -442,9 +423,8 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
/* Allocate one-row buffer for returned data */
source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (biWidth * 3), (JDIMENSION) 1);
source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (JDIMENSION) (biWidth * 3), (JDIMENSION) 1);
source->pub.buffer_height = 1;
cinfo->in_color_space = JCS_RGB;
@ -476,9 +456,8 @@ jinit_read_bmp (j_compress_ptr cinfo)
bmp_source_ptr source;
/* Create module interface object */
source = (bmp_source_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(bmp_source_struct));
source = (bmp_source_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(bmp_source_struct));
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_bmp;

View file

@ -1,28 +1,659 @@
/*
* rdgif.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2019 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.
*
* This file contains routines to read input images in GIF format.
*
*****************************************************************************
* NOTE: to avoid entanglements with Unisys' patent on LZW compression, *
* the ability to read GIF files has been removed from the IJG distribution. *
* Sorry about that. *
*****************************************************************************
*
* We are required to state that
* "The Graphics Interchange Format(c) is the Copyright property of
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
* CompuServe Incorporated."
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume input from
* an ordinary stdio stream. They further assume that reading begins
* at the start of the file; start_input may need work if the
* user interface has already read some data (e.g., to determine that
* the file is indeed GIF format).
*/
/*
* This code is loosely based on giftoppm from the PBMPLUS distribution
* of Feb. 1991. That file contains the following copyright notice:
* +-------------------------------------------------------------------+
* | Copyright 1990, David Koblas. |
* | Permission to use, copy, modify, and distribute this software |
* | and its documentation for any purpose and without fee is hereby |
* | granted, provided that the above copyright notice appear in all |
* | copies and that both that copyright notice and this permission |
* | notice appear in supporting documentation. This software is |
* | provided "as is" without express or implied warranty. |
* +-------------------------------------------------------------------+
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#ifdef GIF_SUPPORTED
/* Macros to deal with unsigned chars as efficiently as compiler allows */
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char U_CHAR;
#define UCH(x) ((int) (x))
#else /* !HAVE_UNSIGNED_CHAR */
typedef char U_CHAR;
#ifdef CHAR_IS_UNSIGNED
#define UCH(x) ((int) (x))
#else
#define UCH(x) ((int) (x) & 0xFF)
#endif
#endif /* HAVE_UNSIGNED_CHAR */
#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
#define MAXCOLORMAPSIZE 256 /* max # of colors in a GIF colormap */
#define NUMCOLORS 3 /* # of colors */
#define CM_RED 0 /* color component numbers */
#define CM_GREEN 1
#define CM_BLUE 2
#define MAX_LZW_BITS 12 /* maximum LZW code size */
#define LZW_TABLE_SIZE (1<<MAX_LZW_BITS) /* # of possible LZW symbols */
/* Macros for extracting header data --- note we assume chars may be signed */
#define LM_to_uint(array, offset) ((unsigned int) UCH(array[offset]) + \
(((unsigned int) UCH(array[offset+1])) << 8))
#define BitSet(byte, bit) ((byte) & (bit))
#define INTERLACE 0x40 /* mask for bit signifying interlaced image */
#define COLORMAPFLAG 0x80 /* mask for bit signifying colormap presence */
/*
* LZW decompression tables look like this:
* symbol_head[K] = prefix symbol of any LZW symbol K (0..LZW_TABLE_SIZE-1)
* symbol_tail[K] = suffix byte of any LZW symbol K (0..LZW_TABLE_SIZE-1)
* Note that entries 0..end_code of the above tables are not used,
* since those symbols represent raw bytes or special codes.
*
* The stack represents the not-yet-used expansion of the last LZW symbol.
* In the worst case, a symbol could expand to as many bytes as there are
* LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
* (This is conservative since that number includes the raw-byte symbols.)
*
* The tables are allocated from FAR heap space since they would use up
* rather a lot of the near data space in a PC.
*/
/* Private version of data source object */
typedef struct {
struct cjpeg_source_struct pub; /* public fields */
j_compress_ptr cinfo; /* back link saves passing separate parm */
JSAMPARRAY colormap; /* GIF colormap (converted to my format) */
/* State for GetCode and LZWReadByte */
U_CHAR code_buf[256+4]; /* current input data block */
int last_byte; /* # of bytes in code_buf */
int last_bit; /* # of bits in code_buf */
int cur_bit; /* next bit index to read */
boolean first_time; /* flags first call to GetCode */
boolean out_of_blocks; /* TRUE if hit terminator data block */
int input_code_size; /* codesize given in GIF file */
int clear_code, end_code; /* values for Clear and End codes */
int code_size; /* current actual code size */
int limit_code; /* 2^code_size */
int max_code; /* first unused code value */
/* Private state for LZWReadByte */
int oldcode; /* previous LZW symbol */
int firstcode; /* first byte of oldcode's expansion */
/* LZW symbol table and expansion stack */
UINT16 FAR *symbol_head; /* => table of prefix symbols */
UINT8 FAR *symbol_tail; /* => table of suffix bytes */
UINT8 FAR *symbol_stack; /* => stack for symbol expansions */
UINT8 FAR *sp; /* stack pointer */
/* State for interlaced image processing */
boolean is_interlaced; /* TRUE if have interlaced image */
jvirt_sarray_ptr interlaced_image; /* full image in interlaced order */
JDIMENSION cur_row_number; /* need to know actual row number */
JDIMENSION pass2_offset; /* # of pixel rows in pass 1 */
JDIMENSION pass3_offset; /* # of pixel rows in passes 1&2 */
JDIMENSION pass4_offset; /* # of pixel rows in passes 1,2,3 */
} gif_source_struct;
typedef gif_source_struct * gif_source_ptr;
/* Forward declarations */
METHODDEF(JDIMENSION) get_pixel_rows
JPP((j_compress_ptr cinfo, cjpeg_source_ptr sinfo));
METHODDEF(JDIMENSION) load_interlaced_image
JPP((j_compress_ptr cinfo, cjpeg_source_ptr sinfo));
METHODDEF(JDIMENSION) get_interlaced_row
JPP((j_compress_ptr cinfo, cjpeg_source_ptr sinfo));
LOCAL(int)
ReadByte (gif_source_ptr sinfo)
/* Read next byte from GIF file */
{
register FILE *infile = sinfo->pub.input_file;
register int c;
if ((c = getc(infile)) == EOF)
ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
return c;
}
LOCAL(int)
GetDataBlock (gif_source_ptr sinfo, U_CHAR *buf)
/* Read a GIF data block, which has a leading count byte */
/* A zero-length block marks the end of a data block sequence */
{
int count;
count = ReadByte(sinfo);
if (count > 0) {
if (! ReadOK(sinfo->pub.input_file, buf, count))
ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
}
return count;
}
LOCAL(void)
SkipDataBlocks (gif_source_ptr sinfo)
/* Skip a series of data blocks, until a block terminator is found */
{
U_CHAR buf[256];
while (GetDataBlock(sinfo, buf) > 0)
/* skip */;
}
LOCAL(void)
ReInitLZW (gif_source_ptr sinfo)
/* (Re)initialize LZW state; shared code for startup and Clear processing */
{
sinfo->code_size = sinfo->input_code_size + 1;
sinfo->limit_code = sinfo->clear_code << 1; /* 2^code_size */
sinfo->max_code = sinfo->clear_code + 2; /* first unused code value */
sinfo->sp = sinfo->symbol_stack; /* init stack to empty */
}
LOCAL(void)
InitLZWCode (gif_source_ptr sinfo)
/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
{
/* GetCode initialization */
sinfo->last_byte = 2; /* make safe to "recopy last two bytes" */
sinfo->code_buf[0] = 0;
sinfo->code_buf[1] = 0;
sinfo->last_bit = 0; /* nothing in the buffer */
sinfo->cur_bit = 0; /* force buffer load on first call */
sinfo->first_time = TRUE;
sinfo->out_of_blocks = FALSE;
/* LZWReadByte initialization: */
/* compute special code values (note that these do not change later) */
sinfo->clear_code = 1 << sinfo->input_code_size;
sinfo->end_code = sinfo->clear_code + 1;
ReInitLZW(sinfo);
}
LOCAL(int)
GetCode (gif_source_ptr sinfo)
/* Fetch the next code_size bits from the GIF data */
/* We assume code_size is less than 16 */
{
register INT32 accum;
int offs, count;
while (sinfo->cur_bit + sinfo->code_size > sinfo->last_bit) {
/* Time to reload the buffer */
/* First time, share code with Clear case */
if (sinfo->first_time) {
sinfo->first_time = FALSE;
return sinfo->clear_code;
}
if (sinfo->out_of_blocks) {
WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
return sinfo->end_code; /* fake something useful */
}
/* preserve last two bytes of what we have -- assume code_size <= 16 */
sinfo->code_buf[0] = sinfo->code_buf[sinfo->last_byte-2];
sinfo->code_buf[1] = sinfo->code_buf[sinfo->last_byte-1];
/* Load more bytes; set flag if we reach the terminator block */
if ((count = GetDataBlock(sinfo, &sinfo->code_buf[2])) == 0) {
sinfo->out_of_blocks = TRUE;
WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
return sinfo->end_code; /* fake something useful */
}
/* Reset counters */
sinfo->cur_bit = (sinfo->cur_bit - sinfo->last_bit) + 16;
sinfo->last_byte = 2 + count;
sinfo->last_bit = sinfo->last_byte * 8;
}
/* Form up next 24 bits in accum */
offs = sinfo->cur_bit >> 3; /* byte containing cur_bit */
accum = (INT32) UCH(sinfo->code_buf[offs+2]);
accum <<= 8;
accum |= (INT32) UCH(sinfo->code_buf[offs+1]);
accum <<= 8;
accum |= (INT32) UCH(sinfo->code_buf[offs]);
/* Right-align cur_bit in accum, then mask off desired number of bits */
accum >>= (sinfo->cur_bit & 7);
sinfo->cur_bit += sinfo->code_size;
return ((int) accum) & ((1 << sinfo->code_size) - 1);
}
LOCAL(int)
LZWReadByte (gif_source_ptr sinfo)
/* Read an LZW-compressed byte */
{
register int code; /* current working code */
int incode; /* saves actual input code */
/* If any codes are stacked from a previously read symbol, return them */
if (sinfo->sp > sinfo->symbol_stack)
return (int) *(-- sinfo->sp);
/* Time to read a new symbol */
code = GetCode(sinfo);
if (code == sinfo->clear_code) {
/* Reinit state, swallow any extra Clear codes, and */
/* return next code, which is expected to be a raw byte. */
ReInitLZW(sinfo);
do {
code = GetCode(sinfo);
} while (code == sinfo->clear_code);
if (code > sinfo->clear_code) { /* make sure it is a raw byte */
WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
code = 0; /* use something valid */
}
/* make firstcode, oldcode valid! */
sinfo->firstcode = sinfo->oldcode = code;
return code;
}
if (code == sinfo->end_code) {
/* Skip the rest of the image, unless GetCode already read terminator */
if (! sinfo->out_of_blocks) {
SkipDataBlocks(sinfo);
sinfo->out_of_blocks = TRUE;
}
/* Complain that there's not enough data */
WARNMS(sinfo->cinfo, JWRN_GIF_ENDCODE);
/* Pad data with 0's */
return 0; /* fake something usable */
}
/* Got normal raw byte or LZW symbol */
incode = code; /* save for a moment */
if (code >= sinfo->max_code) { /* special case for not-yet-defined symbol */
/* code == max_code is OK; anything bigger is bad data */
if (code > sinfo->max_code) {
WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
incode = 0; /* prevent creation of loops in symbol table */
}
/* this symbol will be defined as oldcode/firstcode */
*(sinfo->sp++) = (UINT8) sinfo->firstcode;
code = sinfo->oldcode;
}
/* If it's a symbol, expand it into the stack */
while (code >= sinfo->clear_code) {
*(sinfo->sp++) = sinfo->symbol_tail[code]; /* tail is a byte value */
code = sinfo->symbol_head[code]; /* head is another LZW symbol */
}
/* At this point code just represents a raw byte */
sinfo->firstcode = code; /* save for possible future use */
/* If there's room in table... */
if ((code = sinfo->max_code) < LZW_TABLE_SIZE) {
/* Define a new symbol = prev sym + head of this sym's expansion */
sinfo->symbol_head[code] = (UINT16) sinfo->oldcode;
sinfo->symbol_tail[code] = (UINT8) sinfo->firstcode;
sinfo->max_code++;
/* Is it time to increase code_size? */
if (sinfo->max_code >= sinfo->limit_code &&
sinfo->code_size < MAX_LZW_BITS) {
sinfo->code_size++;
sinfo->limit_code <<= 1; /* keep equal to 2^code_size */
}
}
sinfo->oldcode = incode; /* save last input symbol for future use */
return sinfo->firstcode; /* return first byte of symbol's expansion */
}
LOCAL(void)
ReadColorMap (gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap)
/* Read a GIF colormap */
{
int i;
for (i = 0; i < cmaplen; i++) {
#if BITS_IN_JSAMPLE == 8
#define UPSCALE(x) (x)
#else
#define UPSCALE(x) ((x) << (BITS_IN_JSAMPLE-8))
#endif
cmap[CM_RED ][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
cmap[CM_GREEN][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
cmap[CM_BLUE ][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
}
}
LOCAL(void)
DoExtension (gif_source_ptr sinfo)
/* Process an extension block */
/* Currently we ignore 'em all */
{
int extlabel;
/* Read extension label byte */
extlabel = ReadByte(sinfo);
TRACEMS1(sinfo->cinfo, 1, JTRC_GIF_EXTENSION, extlabel);
/* Skip the data block(s) associated with the extension */
SkipDataBlocks(sinfo);
}
/*
* Read the file header; return image size and component count.
*/
METHODDEF(void)
start_input_gif (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
gif_source_ptr source = (gif_source_ptr) sinfo;
U_CHAR hdrbuf[10]; /* workspace for reading control blocks */
unsigned int width, height; /* image dimensions */
int colormaplen, aspectRatio;
int c;
/* Read and verify GIF Header */
if (! ReadOK(source->pub.input_file, hdrbuf, 6))
ERREXIT(cinfo, JERR_GIF_NOT);
if (hdrbuf[0] != 'G' || hdrbuf[1] != 'I' || hdrbuf[2] != 'F')
ERREXIT(cinfo, JERR_GIF_NOT);
/* Check for expected version numbers.
* If unknown version, give warning and try to process anyway;
* this is per recommendation in GIF89a standard.
*/
if ((hdrbuf[3] != '8' || hdrbuf[4] != '7' || hdrbuf[5] != 'a') &&
(hdrbuf[3] != '8' || hdrbuf[4] != '9' || hdrbuf[5] != 'a'))
TRACEMS3(cinfo, 1, JTRC_GIF_BADVERSION, hdrbuf[3], hdrbuf[4], hdrbuf[5]);
/* Read and decipher Logical Screen Descriptor */
if (! ReadOK(source->pub.input_file, hdrbuf, 7))
ERREXIT(cinfo, JERR_INPUT_EOF);
width = LM_to_uint(hdrbuf, 0);
height = LM_to_uint(hdrbuf, 2);
/* we ignore the color resolution, sort flag, and background color index */
aspectRatio = UCH(hdrbuf[6]);
if (aspectRatio != 0 && aspectRatio != 49)
TRACEMS(cinfo, 1, JTRC_GIF_NONSQUARE);
/* Allocate space to store the colormap */
source->colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (JDIMENSION) MAXCOLORMAPSIZE, (JDIMENSION) NUMCOLORS);
colormaplen = 0; /* indicate initialization */
/* Read global colormap if header indicates it is present */
if (BitSet(hdrbuf[4], COLORMAPFLAG)) {
colormaplen = 2 << (hdrbuf[4] & 0x07);
ReadColorMap(source, colormaplen, source->colormap);
}
/* Scan until we reach start of desired image.
* We don't currently support skipping images, but could add it easily.
*/
for (;;) {
c = ReadByte(source);
if (c == ';') /* GIF terminator?? */
ERREXIT(cinfo, JERR_GIF_IMAGENOTFOUND);
if (c == '!') { /* Extension */
DoExtension(source);
continue;
}
if (c != ',') { /* Not an image separator? */
WARNMS1(cinfo, JWRN_GIF_CHAR, c);
continue;
}
/* Read and decipher Local Image Descriptor */
if (! ReadOK(source->pub.input_file, hdrbuf, 9))
ERREXIT(cinfo, JERR_INPUT_EOF);
/* we ignore top/left position info, also sort flag */
width = LM_to_uint(hdrbuf, 4);
height = LM_to_uint(hdrbuf, 6);
source->is_interlaced = (BitSet(hdrbuf[8], INTERLACE) != 0);
/* Read local colormap if header indicates it is present */
/* Note: if we wanted to support skipping images, */
/* we'd need to skip rather than read colormap for ignored images */
if (BitSet(hdrbuf[8], COLORMAPFLAG)) {
colormaplen = 2 << (hdrbuf[8] & 0x07);
ReadColorMap(source, colormaplen, source->colormap);
}
source->input_code_size = ReadByte(source); /* get min-code-size byte */
if (source->input_code_size < 2 || source->input_code_size > 8)
ERREXIT1(cinfo, JERR_GIF_CODESIZE, source->input_code_size);
/* Reached desired image, so break out of loop */
/* If we wanted to skip this image, */
/* we'd call SkipDataBlocks and then continue the loop */
break;
}
/* Prepare to read selected image: first initialize LZW decompressor */
source->symbol_head = (UINT16 FAR *) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, LZW_TABLE_SIZE * SIZEOF(UINT16));
source->symbol_tail = (UINT8 FAR *) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, LZW_TABLE_SIZE * SIZEOF(UINT8));
source->symbol_stack = (UINT8 FAR *) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, LZW_TABLE_SIZE * SIZEOF(UINT8));
InitLZWCode(source);
/*
* If image is interlaced, we read it into a full-size sample array,
* decompressing as we go; then get_interlaced_row selects rows from the
* sample array in the proper order.
*/
if (source->is_interlaced) {
/* We request the virtual array now, but can't access it until virtual
* arrays have been allocated. Hence, the actual work of reading the
* image is postponed until the first call to get_pixel_rows.
*/
source->interlaced_image = (*cinfo->mem->request_virt_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
(JDIMENSION) width, (JDIMENSION) height, (JDIMENSION) 1);
if (cinfo->progress != NULL) {
cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
progress->total_extra_passes++; /* count file input as separate pass */
}
source->pub.get_pixel_rows = load_interlaced_image;
} else {
source->pub.get_pixel_rows = get_pixel_rows;
}
/* Create compressor input buffer. */
source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (JDIMENSION) width * NUMCOLORS, (JDIMENSION) 1);
source->pub.buffer_height = 1;
/* Pad colormap for safety. */
for (c = colormaplen; c < source->clear_code; c++) {
source->colormap[CM_RED ][c] =
source->colormap[CM_GREEN][c] =
source->colormap[CM_BLUE ][c] = CENTERJSAMPLE;
}
/* Return info about the image. */
cinfo->in_color_space = JCS_RGB;
cinfo->input_components = NUMCOLORS;
cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
cinfo->image_width = width;
cinfo->image_height = height;
TRACEMS3(cinfo, 1, JTRC_GIF, width, height, colormaplen);
}
/*
* Read one row of pixels.
* This version is used for noninterlaced GIF images:
* we read directly from the GIF file.
*/
METHODDEF(JDIMENSION)
get_pixel_rows (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
gif_source_ptr source = (gif_source_ptr) sinfo;
register int c;
register JSAMPROW ptr;
register JDIMENSION col;
register JSAMPARRAY colormap = source->colormap;
ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
c = LZWReadByte(source);
*ptr++ = colormap[CM_RED ][c];
*ptr++ = colormap[CM_GREEN][c];
*ptr++ = colormap[CM_BLUE ][c];
}
return 1;
}
/*
* Read one row of pixels.
* This version is used for the first call on get_pixel_rows when
* reading an interlaced GIF file: we read the whole image into memory.
*/
METHODDEF(JDIMENSION)
load_interlaced_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
gif_source_ptr source = (gif_source_ptr) sinfo;
register JSAMPROW sptr;
register JDIMENSION col;
JDIMENSION row;
cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
/* Read the interlaced image into the virtual array we've created. */
for (row = 0; row < cinfo->image_height; row++) {
if (progress != NULL) {
progress->pub.pass_counter = (long) row;
progress->pub.pass_limit = (long) cinfo->image_height;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
sptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
source->interlaced_image, row, (JDIMENSION) 1, TRUE);
for (col = cinfo->image_width; col > 0; col--) {
*sptr++ = (JSAMPLE) LZWReadByte(source);
}
}
if (progress != NULL)
progress->completed_extra_passes++;
/* Replace method pointer so subsequent calls don't come here. */
source->pub.get_pixel_rows = get_interlaced_row;
/* Initialize for get_interlaced_row, and perform first call on it. */
source->cur_row_number = 0;
source->pass2_offset = (cinfo->image_height + 7) / 8;
source->pass3_offset = source->pass2_offset + (cinfo->image_height + 3) / 8;
source->pass4_offset = source->pass3_offset + (cinfo->image_height + 1) / 4;
return get_interlaced_row(cinfo, sinfo);
}
/*
* Read one row of pixels.
* This version is used for interlaced GIF images:
* we read from the virtual array.
*/
METHODDEF(JDIMENSION)
get_interlaced_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
gif_source_ptr source = (gif_source_ptr) sinfo;
register int c;
register JSAMPROW sptr, ptr;
register JDIMENSION col;
register JSAMPARRAY colormap = source->colormap;
JDIMENSION irow;
/* Figure out which row of interlaced image is needed, and access it. */
switch ((int) (source->cur_row_number & 7)) {
case 0: /* first-pass row */
irow = source->cur_row_number >> 3;
break;
case 4: /* second-pass row */
irow = (source->cur_row_number >> 3) + source->pass2_offset;
break;
case 2: /* third-pass row */
case 6:
irow = (source->cur_row_number >> 2) + source->pass3_offset;
break;
default: /* fourth-pass row */
irow = (source->cur_row_number >> 1) + source->pass4_offset;
}
sptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
source->interlaced_image, irow, (JDIMENSION) 1, FALSE);
/* Scan the row, expand colormap, and output */
ptr = source->pub.buffer[0];
for (col = cinfo->image_width; col > 0; col--) {
c = GETJSAMPLE(*sptr++);
*ptr++ = colormap[CM_RED ][c];
*ptr++ = colormap[CM_GREEN][c];
*ptr++ = colormap[CM_BLUE ][c];
}
source->cur_row_number++; /* for next time */
return 1;
}
/*
* Finish up at the end of the file.
*/
METHODDEF(void)
finish_input_gif (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
/* no work */
}
/*
* The module selection routine for GIF format input.
*/
@ -30,9 +661,17 @@
GLOBAL(cjpeg_source_ptr)
jinit_read_gif (j_compress_ptr cinfo)
{
fprintf(stderr, "GIF input is unsupported for legal reasons. Sorry.\n");
exit(EXIT_FAILURE);
return NULL; /* keep compiler happy */
gif_source_ptr source;
/* Create module interface object */
source = (gif_source_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(gif_source_struct));
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_gif;
source->pub.finish_input = finish_input_gif;
return &source->pub;
}
#endif /* GIF_SUPPORTED */

View file

@ -2,7 +2,7 @@
* rdppm.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2009-2017 by Bill Allombert, Guido Vollbeding.
* Modified 2009-2019 by Bill Allombert, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@ -19,11 +19,6 @@
* the file is indeed PPM format).
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#ifdef PPM_SUPPORTED
/* Portions of this code are based on the PBMPLUS library, which is:
**
** Copyright (C) 1988 by Jef Poskanzer.
@ -36,6 +31,10 @@
** implied warranty.
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#ifdef PPM_SUPPORTED
/* Macros to deal with unsigned chars as efficiently as compiler allows */
@ -43,11 +42,10 @@
typedef unsigned char U_CHAR;
#define UCH(x) ((int) (x))
#else /* !HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char U_CHAR;
#ifdef CHAR_IS_UNSIGNED
#define UCH(x) ((int) (x))
#else
typedef char U_CHAR;
#define UCH(x) ((int) (x) & 0xFF)
#endif
#endif /* HAVE_UNSIGNED_CHAR */
@ -358,7 +356,6 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break;
default:
ERREXIT(cinfo, JERR_PPM_NOT);
break;
}
/* fetch the remaining header info */
@ -449,9 +446,8 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
source->pub.buffer_height = 1;
} else {
/* Need to translate anyway, so make a separate sample buffer. */
source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1);
source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1);
source->pub.buffer_height = 1;
}
@ -461,7 +457,7 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* On 16-bit-int machines we have to be careful of maxval = 65535 */
source->rescale = (JSAMPLE *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
JPOOL_IMAGE, ((size_t) maxval + (size_t) 1) * SIZEOF(JSAMPLE));
half_maxval = maxval / 2;
for (val = 0; val <= (INT32) maxval; val++) {
/* The multiplication here must be done in 32 bits to avoid overflow */
@ -492,9 +488,8 @@ jinit_read_ppm (j_compress_ptr cinfo)
ppm_source_ptr source;
/* Create module interface object */
source = (ppm_source_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(ppm_source_struct));
source = (ppm_source_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(ppm_source_struct));
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_ppm;
source->pub.finish_input = finish_input_ppm;

View file

@ -2,6 +2,7 @@
* rdrle.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2019 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.
*
@ -68,7 +69,7 @@ typedef struct _rle_source_struct {
jvirt_sarray_ptr image; /* virtual array to hold the image */
JDIMENSION row; /* current row # in the virtual array */
rle_hdr header; /* Input file information */
rle_pixel** rle_row; /* holds a row returned by rle_getrow() */
rle_pixel **rle_row; /* holds a row returned by rle_getrow() */
} rle_source_struct;
@ -95,19 +96,14 @@ start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break;
case RLE_NOT_RLE:
ERREXIT(cinfo, JERR_RLE_NOT);
break;
case RLE_NO_SPACE:
ERREXIT(cinfo, JERR_RLE_MEM);
break;
case RLE_EMPTY:
ERREXIT(cinfo, JERR_RLE_EMPTY);
break;
case RLE_EOF:
ERREXIT(cinfo, JERR_RLE_EOF);
break;
default:
ERREXIT(cinfo, JERR_RLE_BADERROR);
break;
}
/* Figure out what we have, set private vars and return values accordingly */
@ -155,16 +151,15 @@ start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
* (GRAYSCALE scanlines don't need converting)
*/
if (source->visual != GRAYSCALE) {
source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray)
source->rle_row = (rle_pixel **) (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) width, (JDIMENSION) cinfo->input_components);
width, (JDIMENSION) cinfo->input_components);
}
/* request a virtual array to hold the image */
source->image = (*cinfo->mem->request_virt_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
(JDIMENSION) (width * source->header.ncolors),
(JDIMENSION) height, (JDIMENSION) 1);
width * (JDIMENSION) source->header.ncolors, height, (JDIMENSION) 1);
#ifdef PROGRESS_REPORT
if (progress != NULL) {
@ -242,7 +237,7 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
rle_source_ptr source = (rle_source_ptr) sinfo;
JDIMENSION row, col;
JSAMPROW scanline, red_ptr, green_ptr, blue_ptr;
JSAMPROW scanline, red_ptr, green_ptr, blue_ptr;
rle_pixel **rle_row;
rle_map *colormap;
char channel;
@ -250,9 +245,6 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
#endif
colormap = source->header.cmap;
rle_row = source->rle_row;
/* Read the RLE data into our virtual array.
* We assume here that (a) rle_pixel is represented the same as JSAMPLE,
* and (b) we are not on a machine where FAR pointers differ from regular.
@ -273,12 +265,12 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
case PSEUDOCOLOR:
for (row = 0; row < cinfo->image_height; row++) {
rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
rle_getrow(&source->header, rle_row);
#ifdef PROGRESS_REPORT
if (progress != NULL) {
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
#endif
}
@ -286,48 +278,50 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
case MAPPEDGRAY:
case TRUECOLOR:
rle_row = source->rle_row;
colormap = source->header.cmap;
for (row = 0; row < cinfo->image_height; row++) {
scanline = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
rle_row = source->rle_row;
rle_getrow(&source->header, rle_row);
scanline = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
for (col = 0; col < cinfo->image_width; col++) {
for (channel = 0; channel < source->header.ncolors; channel++) {
*scanline++ = (JSAMPLE)
(colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
}
for (channel = 0; channel < source->header.ncolors; channel++) {
*scanline++ = (JSAMPLE)
(colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
}
}
#ifdef PROGRESS_REPORT
if (progress != NULL) {
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
#endif
}
break;
case DIRECTCOLOR:
rle_row = source->rle_row;
for (row = 0; row < cinfo->image_height; row++) {
scanline = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
rle_getrow(&source->header, rle_row);
scanline = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
red_ptr = rle_row[0];
green_ptr = rle_row[1];
blue_ptr = rle_row[2];
for (col = cinfo->image_width; col > 0; col--) {
*scanline++ = *red_ptr++;
*scanline++ = *green_ptr++;
*scanline++ = *blue_ptr++;
*scanline++ = *red_ptr++;
*scanline++ = *green_ptr++;
*scanline++ = *blue_ptr++;
}
#ifdef PROGRESS_REPORT
if (progress != NULL) {
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
#endif
}
@ -373,15 +367,14 @@ jinit_read_rle (j_compress_ptr cinfo)
rle_source_ptr source;
/* Create module interface object */
source = (rle_source_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(rle_source_struct));
source = (rle_source_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(rle_source_struct));
/* Fill in method ptrs */
source->pub.start_input = start_input_rle;
source->pub.finish_input = finish_input_rle;
source->pub.get_pixel_rows = load_image;
return (cjpeg_source_ptr) source;
return &source->pub;
}
#endif /* RLE_SUPPORTED */

View file

@ -2,7 +2,7 @@
* rdswitch.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2003-2015 by Guido Vollbeding.
* Modified 2003-2019 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.
*
@ -249,9 +249,8 @@ bogus:
* NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data,
* but if you want to compress multiple images you'd want JPOOL_PERMANENT.
*/
scanptr = (jpeg_scan_info *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
scanno * SIZEOF(jpeg_scan_info));
scanptr = (jpeg_scan_info *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, scanno * SIZEOF(jpeg_scan_info));
MEMCOPY(scanptr, scans, scanno * SIZEOF(jpeg_scan_info));
cinfo->scan_info = scanptr;
cinfo->num_scans = scanno;

View file

@ -2,7 +2,7 @@
* rdtarga.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2017 by Guido Vollbeding.
* Modified 2017-2019 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.
*
@ -29,11 +29,10 @@
typedef unsigned char U_CHAR;
#define UCH(x) ((int) (x))
#else /* !HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char U_CHAR;
#ifdef CHAR_IS_UNSIGNED
#define UCH(x) ((int) (x))
#else
typedef char U_CHAR;
#define UCH(x) ((int) (x) & 0xFF)
#endif
#endif /* HAVE_UNSIGNED_CHAR */
@ -125,20 +124,17 @@ METHODDEF(void)
read_non_rle_pixel (tga_source_ptr sinfo)
/* Read one Targa pixel from the input file; no RLE expansion */
{
register FILE *infile = sinfo->pub.input_file;
register int i;
for (i = 0; i < sinfo->pixel_size; i++) {
sinfo->tga_pixel[i] = (U_CHAR) getc(infile);
sinfo->tga_pixel[i] = (U_CHAR) read_byte(sinfo);
}
}
METHODDEF(void)
read_rle_pixel (tga_source_ptr sinfo)
/* Read one Targa pixel from the input file, expanding RLE data as needed */
{
register FILE *infile = sinfo->pub.input_file;
register int i;
/* Duplicate previously read pixel? */
@ -160,7 +156,7 @@ read_rle_pixel (tga_source_ptr sinfo)
/* Read next pixel */
for (i = 0; i < sinfo->pixel_size; i++) {
sinfo->tga_pixel[i] = (U_CHAR) getc(infile);
sinfo->tga_pixel[i] = (U_CHAR) read_byte(sinfo);
}
}
@ -171,7 +167,6 @@ read_rle_pixel (tga_source_ptr sinfo)
* We provide several different versions depending on input file format.
*/
METHODDEF(JDIMENSION)
get_8bit_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit grayscale pixels */
@ -288,9 +283,8 @@ get_memory_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
source_row = cinfo->image_height - source->current_row - 1;
/* Fetch that row from virtual array */
source->pub.buffer = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->whole_image,
source_row, (JDIMENSION) 1, FALSE);
source->pub.buffer = (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
source->whole_image, source_row, (JDIMENSION) 1, FALSE);
source->current_row++;
return 1;
@ -409,7 +403,6 @@ start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break;
default:
ERREXIT(cinfo, JERR_TGA_BADPARMS);
break;
}
TRACEMS2(cinfo, 1, JTRC_TGA, width, height);
break;
@ -424,7 +417,6 @@ start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break;
default:
ERREXIT(cinfo, JERR_TGA_BADPARMS);
break;
}
if (is_bottom_up) {
@ -442,9 +434,8 @@ start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
} else {
/* Don't need a virtual array, but do need a one-row input buffer. */
source->whole_image = NULL;
source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) width * components, (JDIMENSION) 1);
source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (JDIMENSION) width * components, (JDIMENSION) 1);
source->pub.buffer_height = 1;
source->pub.get_pixel_rows = source->get_pixel_rows;
}
@ -456,8 +447,8 @@ start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
if (maplen > 256 || GET_2B(3) != 0)
ERREXIT(cinfo, JERR_TGA_BADCMAP);
/* Allocate space to store the colormap */
source->colormap = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) maplen, (JDIMENSION) 3);
source->colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (JDIMENSION) maplen, (JDIMENSION) 3);
source->cmap_length = (int) maplen;
/* and read it from the file */
read_colormap(source, (int) maplen, UCH(targaheader[7]));
@ -496,9 +487,8 @@ jinit_read_targa (j_compress_ptr cinfo)
tga_source_ptr source;
/* Create module interface object */
source = (tga_source_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(tga_source_struct));
source = (tga_source_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(tga_source_struct));
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_tga;

View file

@ -1,7 +1,7 @@
/*
* transupp.c
*
* Copyright (C) 1997-2017, Thomas G. Lane, Guido Vollbeding.
* Copyright (C) 1997-2019, 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.
*
@ -14,6 +14,8 @@
/* Although this file really shouldn't have access to the library internals,
* it's helpful to let it call jround_up() and jcopy_block_row().
* Also, the (switchable) virtual memory adaptation code for
* the drop feature has dependencies on library internals.
*/
#define JPEG_INTERNALS
@ -75,6 +77,274 @@
*/
/* Drop code may be used with or without virtual memory adaptation code.
* This code has some dependencies on internal library behavior, so you
* may choose to disable it. For example, it doesn't make a difference
* if you only use jmemnobs anyway.
*/
#ifndef DROP_REQUEST_FROM_SRC
#define DROP_REQUEST_FROM_SRC 1 /* 0 disables adaptation */
#endif
#if DROP_REQUEST_FROM_SRC
/* Force jpeg_read_coefficients to request
* the virtual coefficient arrays from
* the source decompression object.
*/
METHODDEF(jvirt_barray_ptr)
drop_request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
JDIMENSION blocksperrow, JDIMENSION numrows,
JDIMENSION maxaccess)
{
j_common_ptr srcinfo = (j_common_ptr) cinfo->client_data;
return (*srcinfo->mem->request_virt_barray)
(srcinfo, pool_id, pre_zero,
blocksperrow, numrows, maxaccess);
}
/* Force jpeg_read_coefficients to return
* after requesting and before accessing
* the virtual coefficient arrays.
*/
METHODDEF(int)
drop_consume_input (j_decompress_ptr cinfo)
{
return JPEG_SUSPENDED;
}
METHODDEF(void)
drop_start_input_pass (j_decompress_ptr cinfo)
{
cinfo->inputctl->consume_input = drop_consume_input;
}
LOCAL(void)
drop_request_from_src (j_decompress_ptr dropinfo, j_decompress_ptr srcinfo)
{
void *save_client_data;
JMETHOD(jvirt_barray_ptr, save_request_virt_barray,
(j_common_ptr cinfo, int pool_id, boolean pre_zero,
JDIMENSION blocksperrow, JDIMENSION numrows, JDIMENSION maxaccess));
JMETHOD(void, save_start_input_pass, (j_decompress_ptr cinfo));
/* Set custom method pointers, save original pointers */
save_client_data = dropinfo->client_data;
dropinfo->client_data = (void *) srcinfo;
save_request_virt_barray = dropinfo->mem->request_virt_barray;
dropinfo->mem->request_virt_barray = drop_request_virt_barray;
save_start_input_pass = dropinfo->inputctl->start_input_pass;
dropinfo->inputctl->start_input_pass = drop_start_input_pass;
/* Execute only initialization part.
* Requested coefficient arrays will be realized later by the srcinfo object.
* Next call to the same function will then do the actual data reading.
* NB: since we request the coefficient arrays from another object,
* the inherent realization call is effectively a no-op.
*/
(void) jpeg_read_coefficients(dropinfo);
/* Reset method pointers */
dropinfo->client_data = save_client_data;
dropinfo->mem->request_virt_barray = save_request_virt_barray;
dropinfo->inputctl->start_input_pass = save_start_input_pass;
/* Do input initialization for first scan now,
* which also resets the consume_input method.
*/
(*save_start_input_pass)(dropinfo);
}
#endif /* DROP_REQUEST_FROM_SRC */
LOCAL(void)
dequant_comp (j_decompress_ptr cinfo, jpeg_component_info *compptr,
jvirt_barray_ptr coef_array, JQUANT_TBL *qtblptr1)
{
JDIMENSION blk_x, blk_y;
int offset_y, k;
JQUANT_TBL *qtblptr;
JBLOCKARRAY buffer;
JBLOCKROW block;
JCOEFPTR ptr;
qtblptr = compptr->quant_table;
for (blk_y = 0; blk_y < compptr->height_in_blocks;
blk_y += compptr->v_samp_factor) {
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef_array, blk_y,
(JDIMENSION) compptr->v_samp_factor, TRUE);
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
block = buffer[offset_y];
for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
ptr = block[blk_x];
for (k = 0; k < DCTSIZE2; k++)
if (qtblptr->quantval[k] != qtblptr1->quantval[k])
ptr[k] *= qtblptr->quantval[k] / qtblptr1->quantval[k];
}
}
}
}
LOCAL(void)
requant_comp (j_decompress_ptr cinfo, jpeg_component_info *compptr,
jvirt_barray_ptr coef_array, JQUANT_TBL *qtblptr1)
{
JDIMENSION blk_x, blk_y;
int offset_y, k;
JQUANT_TBL *qtblptr;
JBLOCKARRAY buffer;
JBLOCKROW block;
JCOEFPTR ptr;
JCOEF temp, qval;
qtblptr = compptr->quant_table;
for (blk_y = 0; blk_y < compptr->height_in_blocks;
blk_y += compptr->v_samp_factor) {
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef_array, blk_y,
(JDIMENSION) compptr->v_samp_factor, TRUE);
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
block = buffer[offset_y];
for (blk_x = 0; blk_x < compptr->width_in_blocks; blk_x++) {
ptr = block[blk_x];
for (k = 0; k < DCTSIZE2; k++) {
temp = qtblptr->quantval[k];
qval = qtblptr1->quantval[k];
if (temp != qval) {
temp *= ptr[k];
/* The following quantization code is a copy from jcdctmgr.c */
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b) a /= b
#else
#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
#endif
if (temp < 0) {
temp = -temp;
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
temp = -temp;
} else {
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
}
ptr[k] = temp;
}
}
}
}
}
}
/* Calculate largest common denominator with Euclid's algorithm.
*/
LOCAL(JCOEF)
largest_common_denominator(JCOEF a, JCOEF b)
{
JCOEF c;
do {
c = a % b;
a = b;
b = c;
} while (c);
return a;
}
LOCAL(void)
adjust_quant(j_decompress_ptr srcinfo, jvirt_barray_ptr *src_coef_arrays,
j_decompress_ptr dropinfo, jvirt_barray_ptr *drop_coef_arrays,
boolean trim, j_compress_ptr dstinfo)
{
jpeg_component_info *compptr1, *compptr2;
JQUANT_TBL *qtblptr1, *qtblptr2, *qtblptr3;
int ci, k;
for (ci = 0; ci < dstinfo->num_components &&
ci < dropinfo->num_components; ci++) {
compptr1 = srcinfo->comp_info + ci;
compptr2 = dropinfo->comp_info + ci;
qtblptr1 = compptr1->quant_table;
qtblptr2 = compptr2->quant_table;
for (k = 0; k < DCTSIZE2; k++) {
if (qtblptr1->quantval[k] != qtblptr2->quantval[k]) {
if (trim)
requant_comp(dropinfo, compptr2, drop_coef_arrays[ci], qtblptr1);
else {
qtblptr3 = dstinfo->quant_tbl_ptrs[compptr1->quant_tbl_no];
for (k = 0; k < DCTSIZE2; k++)
if (qtblptr1->quantval[k] != qtblptr2->quantval[k])
qtblptr3->quantval[k] = largest_common_denominator
(qtblptr1->quantval[k], qtblptr2->quantval[k]);
dequant_comp(srcinfo, compptr1, src_coef_arrays[ci], qtblptr3);
dequant_comp(dropinfo, compptr2, drop_coef_arrays[ci], qtblptr3);
}
break;
}
}
}
}
LOCAL(void)
do_drop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
jvirt_barray_ptr *src_coef_arrays,
j_decompress_ptr dropinfo, jvirt_barray_ptr *drop_coef_arrays,
JDIMENSION drop_width, JDIMENSION drop_height)
/* Drop. If the dropinfo component number is smaller than the destination's,
* we fill in the remaining components with zero. This provides the feature
* of dropping grayscale into (arbitrarily sampled) color images.
*/
{
JDIMENSION comp_width, comp_height;
JDIMENSION blk_y, x_drop_blocks, y_drop_blocks;
int ci, offset_y;
JBLOCKARRAY src_buffer, dst_buffer;
jpeg_component_info *compptr;
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
comp_width = drop_width * compptr->h_samp_factor;
comp_height = drop_height * compptr->v_samp_factor;
x_drop_blocks = x_crop_offset * compptr->h_samp_factor;
y_drop_blocks = y_crop_offset * compptr->v_samp_factor;
for (blk_y = 0; blk_y < comp_height; blk_y += compptr->v_samp_factor) {
dst_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y + y_drop_blocks,
(JDIMENSION) compptr->v_samp_factor, TRUE);
if (ci < dropinfo->num_components) {
#if DROP_REQUEST_FROM_SRC
src_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, drop_coef_arrays[ci], blk_y,
#else
src_buffer = (*dropinfo->mem->access_virt_barray)
((j_common_ptr) dropinfo, drop_coef_arrays[ci], blk_y,
#endif
(JDIMENSION) compptr->v_samp_factor, FALSE);
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
jcopy_block_row(src_buffer[offset_y],
dst_buffer[offset_y] + x_drop_blocks,
comp_width);
}
} else {
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
FMEMZERO(dst_buffer[offset_y] + x_drop_blocks,
comp_width * SIZEOF(JBLOCK));
}
}
}
}
}
LOCAL(void)
do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
@ -114,10 +384,10 @@ do_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
LOCAL(void)
do_crop_ext (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
jvirt_barray_ptr *src_coef_arrays,
jvirt_barray_ptr *dst_coef_arrays)
do_crop_ext_zero (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
jvirt_barray_ptr *src_coef_arrays,
jvirt_barray_ptr *dst_coef_arrays)
/* Crop. This is only used when no rotate/flip is requested with the crop.
* Extension: If the destination size is larger than the source, we fill in
* the extra area with zero (neutral gray). Note we also have to zero partial
@ -148,7 +418,7 @@ do_crop_ext (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
(JDIMENSION) compptr->v_samp_factor, TRUE);
if (dstinfo->jpeg_height > srcinfo->output_height) {
if (dst_blk_y < y_crop_blocks ||
dst_blk_y >= comp_height + y_crop_blocks) {
dst_blk_y >= y_crop_blocks + comp_height) {
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
FMEMZERO(dst_buffer[offset_y],
compptr->width_in_blocks * SIZEOF(JBLOCK));
@ -174,11 +444,11 @@ do_crop_ext (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
jcopy_block_row(src_buffer[offset_y],
dst_buffer[offset_y] + x_crop_blocks,
comp_width);
if (compptr->width_in_blocks > comp_width + x_crop_blocks) {
if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
FMEMZERO(dst_buffer[offset_y] +
comp_width + x_crop_blocks,
x_crop_blocks + comp_width,
(compptr->width_in_blocks -
comp_width - x_crop_blocks) * SIZEOF(JBLOCK));
x_crop_blocks - comp_width) * SIZEOF(JBLOCK));
}
} else {
jcopy_block_row(src_buffer[offset_y] + x_crop_blocks,
@ -191,6 +461,190 @@ do_crop_ext (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
}
LOCAL(void)
do_crop_ext_flat (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
jvirt_barray_ptr *src_coef_arrays,
jvirt_barray_ptr *dst_coef_arrays)
/* Crop. This is only used when no rotate/flip is requested with the crop.
* Extension: The destination width is larger than the source and we fill in
* the extra area with the DC of the adjacent block. Note we also have to
* fill partial iMCUs at the right and bottom edge of the source image area
* in this case.
*/
{
JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height;
JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
int ci, offset_y;
JCOEF dc;
JBLOCKARRAY src_buffer, dst_buffer;
jpeg_component_info *compptr;
MCU_cols = srcinfo->output_width /
(dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
MCU_rows = srcinfo->output_height /
(dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
comp_width = MCU_cols * compptr->h_samp_factor;
comp_height = MCU_rows * compptr->v_samp_factor;
x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
dst_blk_y += compptr->v_samp_factor) {
dst_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
(JDIMENSION) compptr->v_samp_factor, TRUE);
if (dstinfo->jpeg_height > srcinfo->output_height) {
if (dst_blk_y < y_crop_blocks ||
dst_blk_y >= y_crop_blocks + comp_height) {
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
FMEMZERO(dst_buffer[offset_y],
compptr->width_in_blocks * SIZEOF(JBLOCK));
}
continue;
}
src_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, src_coef_arrays[ci],
dst_blk_y - y_crop_blocks,
(JDIMENSION) compptr->v_samp_factor, FALSE);
} else {
src_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, src_coef_arrays[ci],
dst_blk_y + y_crop_blocks,
(JDIMENSION) compptr->v_samp_factor, FALSE);
}
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
if (x_crop_blocks > 0) {
FMEMZERO(dst_buffer[offset_y],
x_crop_blocks * SIZEOF(JBLOCK));
dc = src_buffer[offset_y][0][0];
for (dst_blk_x = 0; dst_blk_x < x_crop_blocks; dst_blk_x++) {
dst_buffer[offset_y][dst_blk_x][0] = dc;
}
}
jcopy_block_row(src_buffer[offset_y],
dst_buffer[offset_y] + x_crop_blocks,
comp_width);
if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
FMEMZERO(dst_buffer[offset_y] +
x_crop_blocks + comp_width,
(compptr->width_in_blocks -
x_crop_blocks - comp_width) * SIZEOF(JBLOCK));
dc = src_buffer[offset_y][comp_width - 1][0];
for (dst_blk_x = x_crop_blocks + comp_width;
dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
dst_buffer[offset_y][dst_blk_x][0] = dc;
}
}
}
}
}
}
LOCAL(void)
do_crop_ext_reflect (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
jvirt_barray_ptr *src_coef_arrays,
jvirt_barray_ptr *dst_coef_arrays)
/* Crop. This is only used when no rotate/flip is requested with the crop.
* Extension: The destination width is larger than the source and we fill in
* the extra area with repeated reflections of the source region. Note we
* also have to fill partial iMCUs at the right and bottom edge of the source
* image area in this case.
*/
{
JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, src_blk_x;
JDIMENSION dst_blk_x, dst_blk_y, x_crop_blocks, y_crop_blocks;
int ci, k, offset_y;
JBLOCKARRAY src_buffer, dst_buffer;
JBLOCKROW src_row_ptr, dst_row_ptr;
JCOEFPTR src_ptr, dst_ptr;
jpeg_component_info *compptr;
MCU_cols = srcinfo->output_width /
(dstinfo->max_h_samp_factor * dstinfo->min_DCT_h_scaled_size);
MCU_rows = srcinfo->output_height /
(dstinfo->max_v_samp_factor * dstinfo->min_DCT_v_scaled_size);
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
comp_width = MCU_cols * compptr->h_samp_factor;
comp_height = MCU_rows * compptr->v_samp_factor;
x_crop_blocks = x_crop_offset * compptr->h_samp_factor;
y_crop_blocks = y_crop_offset * compptr->v_samp_factor;
for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
dst_blk_y += compptr->v_samp_factor) {
dst_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
(JDIMENSION) compptr->v_samp_factor, TRUE);
if (dstinfo->jpeg_height > srcinfo->output_height) {
if (dst_blk_y < y_crop_blocks ||
dst_blk_y >= y_crop_blocks + comp_height) {
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
FMEMZERO(dst_buffer[offset_y],
compptr->width_in_blocks * SIZEOF(JBLOCK));
}
continue;
}
src_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, src_coef_arrays[ci],
dst_blk_y - y_crop_blocks,
(JDIMENSION) compptr->v_samp_factor, FALSE);
} else {
src_buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, src_coef_arrays[ci],
dst_blk_y + y_crop_blocks,
(JDIMENSION) compptr->v_samp_factor, FALSE);
}
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
/* Copy source region */
jcopy_block_row(src_buffer[offset_y],
dst_buffer[offset_y] + x_crop_blocks,
comp_width);
if (x_crop_blocks > 0) {
/* Reflect to left */
dst_row_ptr = dst_buffer[offset_y] + x_crop_blocks;
for (dst_blk_x = x_crop_blocks; dst_blk_x > 0;) {
src_row_ptr = dst_row_ptr; /* (re)set axis of reflection */
for (src_blk_x = comp_width; src_blk_x > 0 && dst_blk_x > 0;
src_blk_x--, dst_blk_x--) {
dst_ptr = *--dst_row_ptr; /* destination goes left */
src_ptr = *src_row_ptr++; /* source goes right */
/* this unrolled loop doesn't need to know which row it's on... */
for (k = 0; k < DCTSIZE2; k += 2) {
*dst_ptr++ = *src_ptr++; /* copy even column */
*dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
}
}
}
}
if (compptr->width_in_blocks > x_crop_blocks + comp_width) {
/* Reflect to right */
dst_row_ptr = dst_buffer[offset_y] + x_crop_blocks + comp_width;
for (dst_blk_x = compptr->width_in_blocks - x_crop_blocks - comp_width;
dst_blk_x > 0;) {
src_row_ptr = dst_row_ptr; /* (re)set axis of reflection */
for (src_blk_x = comp_width; src_blk_x > 0 && dst_blk_x > 0;
src_blk_x--, dst_blk_x--) {
dst_ptr = *dst_row_ptr++; /* destination goes right */
src_ptr = *--src_row_ptr; /* source goes left */
/* this unrolled loop doesn't need to know which row it's on... */
for (k = 0; k < DCTSIZE2; k += 2) {
*dst_ptr++ = *src_ptr++; /* copy even column */
*dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
}
}
}
}
}
}
}
}
LOCAL(void)
do_wipe (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset, JDIMENSION y_crop_offset,
@ -274,6 +728,78 @@ do_flatten (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
}
LOCAL(void)
do_reflect (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset,
jvirt_barray_ptr *src_coef_arrays,
JDIMENSION drop_width, JDIMENSION drop_height)
/* Reflect - drop content of specified area, similar to wipe, but
* fill with repeated reflections of the outside area, instead of zero.
* NB: y_crop_offset is assumed to be zero.
*/
{
JDIMENSION x_wipe_blocks, wipe_width;
JDIMENSION y_wipe_blocks, wipe_bottom;
JDIMENSION src_blk_x, dst_blk_x;
int ci, k, offset_y;
JBLOCKARRAY buffer;
JBLOCKROW src_row_ptr, dst_row_ptr;
JCOEFPTR src_ptr, dst_ptr;
jpeg_component_info *compptr;
for (ci = 0; ci < dstinfo->num_components; ci++) {
compptr = dstinfo->comp_info + ci;
x_wipe_blocks = x_crop_offset * compptr->h_samp_factor;
wipe_width = drop_width * compptr->h_samp_factor;
wipe_bottom = drop_height * compptr->v_samp_factor;
for (y_wipe_blocks = 0; y_wipe_blocks < wipe_bottom;
y_wipe_blocks += compptr->v_samp_factor) {
buffer = (*srcinfo->mem->access_virt_barray)
((j_common_ptr) srcinfo, src_coef_arrays[ci], y_wipe_blocks,
(JDIMENSION) compptr->v_samp_factor, TRUE);
for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
if (x_wipe_blocks > 0) {
/* Reflect from left */
dst_row_ptr = buffer[offset_y] + x_wipe_blocks;
for (dst_blk_x = wipe_width; dst_blk_x > 0;) {
src_row_ptr = dst_row_ptr; /* (re)set axis of reflection */
for (src_blk_x = x_wipe_blocks;
src_blk_x > 0 && dst_blk_x > 0; src_blk_x--, dst_blk_x--) {
dst_ptr = *dst_row_ptr++; /* destination goes right */
src_ptr = *--src_row_ptr; /* source goes left */
/* this unrolled loop doesn't need to know which row it's on... */
for (k = 0; k < DCTSIZE2; k += 2) {
*dst_ptr++ = *src_ptr++; /* copy even column */
*dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
}
}
}
} else if (compptr->width_in_blocks > x_wipe_blocks + wipe_width) {
/* Reflect from right */
dst_row_ptr = buffer[offset_y] + x_wipe_blocks + wipe_width;
for (dst_blk_x = wipe_width; dst_blk_x > 0;) {
src_row_ptr = dst_row_ptr; /* (re)set axis of reflection */
src_blk_x = compptr->width_in_blocks - x_wipe_blocks - wipe_width;
for (; src_blk_x > 0 && dst_blk_x > 0; src_blk_x--, dst_blk_x--) {
dst_ptr = *--dst_row_ptr; /* destination goes left */
src_ptr = *src_row_ptr++; /* source goes right */
/* this unrolled loop doesn't need to know which row it's on... */
for (k = 0; k < DCTSIZE2; k += 2) {
*dst_ptr++ = *src_ptr++; /* copy even column */
*dst_ptr++ = - *src_ptr++; /* copy odd column with sign change */
}
}
}
} else {
FMEMZERO(buffer[offset_y] + x_wipe_blocks,
wipe_width * SIZEOF(JBLOCK));
}
}
}
}
}
LOCAL(void)
do_flip_h_no_crop (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
JDIMENSION x_crop_offset,
@ -932,7 +1458,7 @@ jt_read_integer (const char ** strptr, JDIMENSION * result)
* The routine returns TRUE if the spec string is valid, FALSE if not.
*
* The crop spec string should have the format
* <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
* <width>[{fr}]x<height>[{fr}]{+-}<xoffset>{+-}<yoffset>
* where width, height, xoffset, and yoffset are unsigned integers.
* Each of the elements can be omitted to indicate a default value.
* (A weakness of this style is that it is not possible to omit xoffset
@ -957,6 +1483,9 @@ jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
if (*spec == 'f' || *spec == 'F') {
spec++;
info->crop_width_set = JCROP_FORCE;
} else if (*spec == 'r' || *spec == 'R') {
spec++;
info->crop_width_set = JCROP_REFLECT;
} else
info->crop_width_set = JCROP_POS;
}
@ -968,6 +1497,9 @@ jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
if (*spec == 'f' || *spec == 'F') {
spec++;
info->crop_height_set = JCROP_FORCE;
} else if (*spec == 'r' || *spec == 'R') {
spec++;
info->crop_height_set = JCROP_REFLECT;
} else
info->crop_height_set = JCROP_POS;
}
@ -1042,10 +1574,10 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
jvirt_barray_ptr *coef_arrays;
boolean need_workspace, transpose_it;
jpeg_component_info *compptr;
JDIMENSION xoffset, yoffset;
JDIMENSION xoffset, yoffset, dtemp;
JDIMENSION width_in_iMCUs, height_in_iMCUs;
JDIMENSION width_in_blocks, height_in_blocks;
int ci, h_samp_factor, v_samp_factor;
int itemp, ci, h_samp_factor, v_samp_factor;
/* Determine number of components in output image */
if (info->force_grayscale &&
@ -1115,7 +1647,6 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
info->iMCU_sample_height =
srcinfo->max_v_samp_factor * srcinfo->min_DCT_v_scaled_size;
}
break;
}
/* If cropping has been requested, compute the crop area's position and
@ -1179,7 +1710,54 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
else
yoffset = info->output_height - info->crop_height - info->crop_yoffset;
/* Now adjust so that upper left corner falls at an iMCU boundary */
if (info->transform == JXFORM_WIPE) {
switch (info->transform) {
case JXFORM_DROP:
/* Ensure the effective drop region will not exceed the requested */
itemp = info->iMCU_sample_width;
dtemp = itemp - 1 - ((xoffset + itemp - 1) % itemp);
xoffset += dtemp;
if (info->crop_width <= dtemp)
info->drop_width = 0;
else if (xoffset + info->crop_width - dtemp == info->output_width)
/* Matching right edge: include partial iMCU */
info->drop_width = (info->crop_width - dtemp + itemp - 1) / itemp;
else
info->drop_width = (info->crop_width - dtemp) / itemp;
itemp = info->iMCU_sample_height;
dtemp = itemp - 1 - ((yoffset + itemp - 1) % itemp);
yoffset += dtemp;
if (info->crop_height <= dtemp)
info->drop_height = 0;
else if (yoffset + info->crop_height - dtemp == info->output_height)
/* Matching bottom edge: include partial iMCU */
info->drop_height = (info->crop_height - dtemp + itemp - 1) / itemp;
else
info->drop_height = (info->crop_height - dtemp) / itemp;
/* Check if sampling factors match for dropping */
if (info->drop_width != 0 && info->drop_height != 0)
for (ci = 0; ci < info->num_components &&
ci < info->drop_ptr->num_components; ci++) {
if (info->drop_ptr->comp_info[ci].h_samp_factor *
srcinfo->max_h_samp_factor !=
srcinfo->comp_info[ci].h_samp_factor *
info->drop_ptr->max_h_samp_factor)
ERREXIT6(srcinfo, JERR_BAD_DROP_SAMPLING, ci,
info->drop_ptr->comp_info[ci].h_samp_factor,
info->drop_ptr->max_h_samp_factor,
srcinfo->comp_info[ci].h_samp_factor,
srcinfo->max_h_samp_factor, 'h');
if (info->drop_ptr->comp_info[ci].v_samp_factor *
srcinfo->max_v_samp_factor !=
srcinfo->comp_info[ci].v_samp_factor *
info->drop_ptr->max_v_samp_factor)
ERREXIT6(srcinfo, JERR_BAD_DROP_SAMPLING, ci,
info->drop_ptr->comp_info[ci].v_samp_factor,
info->drop_ptr->max_v_samp_factor,
srcinfo->comp_info[ci].v_samp_factor,
srcinfo->max_v_samp_factor, 'v');
}
break;
case JXFORM_WIPE:
/* Ensure the effective wipe region will cover the requested */
info->drop_width = (JDIMENSION) jdiv_round_up
((long) (info->crop_width + (xoffset % info->iMCU_sample_width)),
@ -1187,7 +1765,8 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
info->drop_height = (JDIMENSION) jdiv_round_up
((long) (info->crop_height + (yoffset % info->iMCU_sample_height)),
(long) info->iMCU_sample_height);
} else {
break;
default:
/* Ensure the effective crop region will cover the requested */
if (info->crop_width_set == JCROP_FORCE ||
info->crop_width > info->output_width)
@ -1275,6 +1854,11 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
break;
case JXFORM_WIPE:
break;
case JXFORM_DROP:
#if DROP_REQUEST_FROM_SRC
drop_request_from_src(info->drop_ptr, srcinfo);
#endif
break;
}
/* Allocate workspace if needed.
@ -1282,15 +1866,13 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
* so that transform routines need not worry about missing edge blocks.
*/
if (need_workspace) {
coef_arrays = (jvirt_barray_ptr *)
(*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
SIZEOF(jvirt_barray_ptr) * info->num_components);
width_in_iMCUs = (JDIMENSION)
jdiv_round_up((long) info->output_width,
(long) info->iMCU_sample_width);
height_in_iMCUs = (JDIMENSION)
jdiv_round_up((long) info->output_height,
(long) info->iMCU_sample_height);
coef_arrays = (jvirt_barray_ptr *) (*srcinfo->mem->alloc_small)
((j_common_ptr) srcinfo, JPOOL_IMAGE,
SIZEOF(jvirt_barray_ptr) * info->num_components);
width_in_iMCUs = (JDIMENSION) jdiv_round_up
((long) info->output_width, (long) info->iMCU_sample_width);
height_in_iMCUs = (JDIMENSION) jdiv_round_up
((long) info->output_height, (long) info->iMCU_sample_height);
for (ci = 0; ci < info->num_components; ci++) {
compptr = srcinfo->comp_info + ci;
if (info->num_components == 1) {
@ -1574,7 +2156,7 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
dstinfo->jpeg_width = info->output_width;
dstinfo->jpeg_height = info->output_height;
/* Transpose destination image parameters */
/* Transpose destination image parameters, adjust quantization */
switch (info->transform) {
case JXFORM_TRANSPOSE:
case JXFORM_TRANSVERSE:
@ -1582,6 +2164,12 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
case JXFORM_ROT_270:
transpose_critical_parameters(dstinfo);
break;
case JXFORM_DROP:
if (info->drop_width != 0 && info->drop_height != 0)
adjust_quant(srcinfo, src_coef_arrays,
info->drop_ptr, info->drop_coef_arrays,
info->trim, dstinfo);
break;
default:
break;
}
@ -1637,10 +2225,22 @@ jtransform_execute_transform (j_decompress_ptr srcinfo,
switch (info->transform) {
case JXFORM_NONE:
if (info->output_width > srcinfo->output_width ||
info->output_height > srcinfo->output_height)
do_crop_ext(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
else if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
info->output_height > srcinfo->output_height) {
if (info->output_width > srcinfo->output_width &&
info->crop_width_set == JCROP_REFLECT)
do_crop_ext_reflect(srcinfo, dstinfo,
info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
else if (info->output_width > srcinfo->output_width &&
info->crop_width_set == JCROP_FORCE)
do_crop_ext_flat(srcinfo, dstinfo,
info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
else
do_crop_ext_zero(srcinfo, dstinfo,
info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
} else if (info->x_crop_offset != 0 || info->y_crop_offset != 0)
do_crop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, dst_coef_arrays);
break;
@ -1677,12 +2277,28 @@ jtransform_execute_transform (j_decompress_ptr srcinfo,
src_coef_arrays, dst_coef_arrays);
break;
case JXFORM_WIPE:
if (info->crop_width_set != JCROP_FORCE)
do_wipe(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, info->drop_width, info->drop_height);
else
if (info->crop_width_set == JCROP_REFLECT &&
info->y_crop_offset == 0 && info->drop_height ==
(JDIMENSION) jdiv_round_up
((long) info->output_height, (long) info->iMCU_sample_height) &&
(info->x_crop_offset == 0 ||
info->x_crop_offset + info->drop_width ==
(JDIMENSION) jdiv_round_up
((long) info->output_width, (long) info->iMCU_sample_width)))
do_reflect(srcinfo, dstinfo, info->x_crop_offset,
src_coef_arrays, info->drop_width, info->drop_height);
else if (info->crop_width_set == JCROP_FORCE)
do_flatten(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, info->drop_width, info->drop_height);
else
do_wipe(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, info->drop_width, info->drop_height);
break;
case JXFORM_DROP:
if (info->drop_width != 0 && info->drop_height != 0)
do_drop(srcinfo, dstinfo, info->x_crop_offset, info->y_crop_offset,
src_coef_arrays, info->drop_ptr, info->drop_coef_arrays,
info->drop_width, info->drop_height);
break;
}
}

View file

@ -2,7 +2,7 @@
* wrbmp.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2017 by Guido Vollbeding.
* Modified 2017-2019 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.
*
@ -74,22 +74,19 @@ put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
/* This version is for writing 24-bit pixels */
{
bmp_dest_ptr dest = (bmp_dest_ptr) dinfo;
JSAMPARRAY image_ptr;
register JSAMPROW inptr, outptr;
register JDIMENSION col;
int pad;
/* Access next row in virtual array */
image_ptr = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, dest->whole_image,
dest->cur_output_row, (JDIMENSION) 1, TRUE);
outptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
dest->whole_image, dest->cur_output_row, (JDIMENSION) 1, TRUE);
dest->cur_output_row++;
/* Transfer data. Note destination values must be in BGR order
* (even though Microsoft's own documents say the opposite).
*/
inptr = dest->pub.buffer[0];
outptr = image_ptr[0];
for (col = cinfo->output_width; col > 0; col--) {
outptr[2] = *inptr++; /* can omit GETJSAMPLE() safely */
outptr[1] = *inptr++;
@ -109,20 +106,17 @@ put_gray_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
/* This version is for grayscale OR quantized color output */
{
bmp_dest_ptr dest = (bmp_dest_ptr) dinfo;
JSAMPARRAY image_ptr;
register JSAMPROW inptr, outptr;
register JDIMENSION col;
int pad;
/* Access next row in virtual array */
image_ptr = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, dest->whole_image,
dest->cur_output_row, (JDIMENSION) 1, TRUE);
outptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
dest->whole_image, dest->cur_output_row, (JDIMENSION) 1, TRUE);
dest->cur_output_row++;
/* Transfer data. */
inptr = dest->pub.buffer[0];
outptr = image_ptr[0];
for (col = cinfo->output_width; col > 0; col--) {
*outptr++ = *inptr++; /* can omit GETJSAMPLE() safely */
}
@ -160,10 +154,10 @@ write_bmp_header (j_decompress_ptr cinfo, bmp_dest_ptr dest)
{
char bmpfileheader[14];
char bmpinfoheader[40];
#define PUT_2B(array,offset,value) \
#define PUT_2B(array, offset, value) \
(array[offset] = (char) ((value) & 0xFF), \
array[offset+1] = (char) (((value) >> 8) & 0xFF))
#define PUT_4B(array,offset,value) \
#define PUT_4B(array, offset, value) \
(array[offset] = (char) ((value) & 0xFF), \
array[offset+1] = (char) (((value) >> 8) & 0xFF), \
array[offset+2] = (char) (((value) >> 16) & 0xFF), \
@ -328,13 +322,13 @@ write_colormap (j_decompress_ptr cinfo, bmp_dest_ptr dest,
putc(0, outfile);
}
}
/* Pad colormap with zeros to ensure specified number of colormap entries */
/* Pad colormap to ensure specified number of colormap entries */
if (i > map_colors)
ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, i);
for (; i < map_colors; i++) {
putc(0, outfile);
putc(0, outfile);
putc(0, outfile);
putc(CENTERJSAMPLE, outfile);
putc(CENTERJSAMPLE, outfile);
putc(CENTERJSAMPLE, outfile);
if (map_entry_size == 4)
putc(0, outfile);
}
@ -346,7 +340,6 @@ finish_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
bmp_dest_ptr dest = (bmp_dest_ptr) dinfo;
register FILE * outfile = dest->pub.output_file;
JSAMPARRAY image_ptr;
register JSAMPROW data_ptr;
JDIMENSION row;
register JDIMENSION col;
@ -365,9 +358,8 @@ finish_output_bmp (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
progress->pub.pass_limit = (long) cinfo->output_height;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
image_ptr = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, dest->whole_image, row-1, (JDIMENSION) 1, FALSE);
data_ptr = image_ptr[0];
data_ptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
dest->whole_image, row - 1, (JDIMENSION) 1, FALSE);
for (col = dest->row_width; col > 0; col--) {
putc(GETJSAMPLE(*data_ptr), outfile);
data_ptr++;
@ -394,21 +386,23 @@ jinit_write_bmp (j_decompress_ptr cinfo, boolean is_os2)
JDIMENSION row_width;
/* Create module interface object, fill in method pointers */
dest = (bmp_dest_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(bmp_dest_struct));
dest = (bmp_dest_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(bmp_dest_struct));
dest->pub.start_output = start_output_bmp;
dest->pub.finish_output = finish_output_bmp;
dest->is_os2 = is_os2;
if (cinfo->out_color_space == JCS_GRAYSCALE) {
switch (cinfo->out_color_space) {
case JCS_GRAYSCALE:
dest->pub.put_pixel_rows = put_gray_rows;
} else if (cinfo->out_color_space == JCS_RGB) {
break;
case JCS_RGB:
if (cinfo->quantize_colors)
dest->pub.put_pixel_rows = put_gray_rows;
else
dest->pub.put_pixel_rows = put_pixel_rows;
} else {
break;
default:
ERREXIT(cinfo, JERR_BMP_COLORSPACE);
}

View file

@ -1,19 +1,13 @@
/*
* wrgif.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2015-2017 by Guido Vollbeding.
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2015-2019 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.
*
* This file contains routines to write output images in GIF format.
*
**************************************************************************
* NOTE: to avoid entanglements with Unisys' patent on LZW compression, *
* this code has been modified to output "uncompressed GIF" files. *
* There is no trace of the LZW algorithm in this file. *
**************************************************************************
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume output to
* an ordinary stdio stream.
@ -31,11 +25,6 @@
* copyright notice and this permission notice appear in supporting
* documentation. This software is provided "as is" without express or
* implied warranty.
*
* We are also required to state that
* "The Graphics Interchange Format(c) is the Copyright property of
* CompuServe Incorporated. GIF(sm) is a Service Mark property of
* CompuServe Incorporated."
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
@ -43,6 +32,40 @@
#ifdef GIF_SUPPORTED
#define MAX_LZW_BITS 12 /* maximum LZW code size (4096 symbols) */
typedef INT16 code_int; /* must hold -1 .. 2**MAX_LZW_BITS */
#define LZW_TABLE_SIZE ((code_int) 1 << MAX_LZW_BITS)
#define HSIZE 5003 /* hash table size for 80% occupancy */
typedef int hash_int; /* must hold -2*HSIZE..2*HSIZE */
#define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
/*
* The LZW hash table consists of two parallel arrays:
* hash_code[i] code of symbol in slot i, or 0 if empty slot
* hash_value[i] symbol's value; undefined if empty slot
* where slot values (i) range from 0 to HSIZE-1. The symbol value is
* its prefix symbol's code concatenated with its suffix character.
*
* Algorithm: use open addressing double hashing (no chaining) on the
* prefix code / suffix character combination. We do a variant of Knuth's
* algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
* secondary probe.
*
* The hash_value[] table is allocated from FAR heap space since it would
* use up rather a lot of the near data space in a PC.
*/
typedef INT32 hash_entry; /* must hold (code_int<<8) | byte */
#define HASH_ENTRY(prefix, suffix) ((((hash_entry) (prefix)) << 8) | (suffix))
/* Private version of data destination object */
typedef struct {
@ -52,14 +75,24 @@ typedef struct {
/* State for packing variable-width codes into a bitstream */
int n_bits; /* current number of bits/code */
int maxcode; /* maximum code, given n_bits */
code_int maxcode; /* maximum code, given n_bits */
int init_bits; /* initial n_bits ... restored after clear */
INT32 cur_accum; /* holds bits not yet output */
int cur_bits; /* # of bits in cur_accum */
/* LZW string construction */
code_int waiting_code; /* symbol not yet output; may be extendable */
boolean first_byte; /* if TRUE, waiting_code is not valid */
/* State for GIF code assignment */
int ClearCode; /* clear code (doesn't change) */
int EOFCode; /* EOF code (ditto) */
int code_counter; /* counts output symbols */
code_int ClearCode; /* clear code (doesn't change) */
code_int EOFCode; /* EOF code (ditto) */
code_int free_code; /* LZW: first not-yet-used symbol code */
code_int code_counter; /* not LZW: counts output symbols */
/* LZW hash table */
code_int *hash_code; /* => hash table of symbol codes */
hash_entry FAR *hash_value; /* => hash table of symbol values */
/* GIF data packet construction buffer */
int bytesinpkt; /* # of bytes in current packet */
@ -69,9 +102,6 @@ typedef struct {
typedef gif_dest_struct * gif_dest_ptr;
/* Largest value that will fit in N bits */
#define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
/*
* Routines to package finished data bytes into GIF data blocks.
@ -93,7 +123,7 @@ flush_packet (gif_dest_ptr dinfo)
/* Add a character to current packet; flush to disk if necessary */
#define CHAR_OUT(dinfo,c) \
#define CHAR_OUT(dinfo, c) \
{ (dinfo)->packetbuf[++(dinfo)->bytesinpkt] = (char) (c); \
if ((dinfo)->bytesinpkt >= 255) \
flush_packet(dinfo); \
@ -103,7 +133,7 @@ flush_packet (gif_dest_ptr dinfo)
/* Routine to convert variable-width codes into a byte stream */
LOCAL(void)
output (gif_dest_ptr dinfo, int code)
output (gif_dest_ptr dinfo, code_int code)
/* Emit a code of n_bits bits */
/* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
{
@ -115,74 +145,76 @@ output (gif_dest_ptr dinfo, int code)
dinfo->cur_accum >>= 8;
dinfo->cur_bits -= 8;
}
/*
* If the next entry is going to be too big for the code size,
* then increase it, if possible. We do this here to ensure
* that it's done in sync with the decoder's codesize increases.
*/
if (dinfo->free_code > dinfo->maxcode) {
dinfo->n_bits++;
if (dinfo->n_bits == MAX_LZW_BITS)
dinfo->maxcode = LZW_TABLE_SIZE; /* free_code will never exceed this */
else
dinfo->maxcode = MAXCODE(dinfo->n_bits);
}
}
/* The pseudo-compression algorithm.
*
* In this module we simply output each pixel value as a separate symbol;
* thus, no compression occurs. In fact, there is expansion of one bit per
* pixel, because we use a symbol width one bit wider than the pixel width.
*
* GIF ordinarily uses variable-width symbols, and the decoder will expect
* to ratchet up the symbol width after a fixed number of symbols.
* To simplify the logic and keep the expansion penalty down, we emit a
* GIF Clear code to reset the decoder just before the width would ratchet up.
* Thus, all the symbols in the output file will have the same bit width.
* Note that emitting the Clear codes at the right times is a mere matter of
* counting output symbols and is in no way dependent on the LZW patent.
*
* With a small basic pixel width (low color count), Clear codes will be
* needed very frequently, causing the file to expand even more. So this
* simplistic approach wouldn't work too well on bilevel images, for example.
* But for output of JPEG conversions the pixel width will usually be 8 bits
* (129 to 256 colors), so the overhead added by Clear symbols is only about
* one symbol in every 256.
*/
/* Compression initialization & termination */
LOCAL(void)
clear_hash (gif_dest_ptr dinfo)
/* Fill the hash table with empty entries */
{
/* It's sufficient to zero hash_code[] */
MEMZERO(dinfo->hash_code, HSIZE * SIZEOF(code_int));
}
LOCAL(void)
clear_block (gif_dest_ptr dinfo)
/* Reset compressor and issue a Clear code */
{
clear_hash(dinfo); /* delete all the symbols */
dinfo->free_code = dinfo->ClearCode + 2;
output(dinfo, dinfo->ClearCode); /* inform decoder */
dinfo->n_bits = dinfo->init_bits; /* reset code size */
dinfo->maxcode = MAXCODE(dinfo->n_bits);
}
LOCAL(void)
compress_init (gif_dest_ptr dinfo, int i_bits)
/* Initialize pseudo-compressor */
/* Initialize compressor */
{
/* init all the state variables */
dinfo->n_bits = i_bits;
dinfo->n_bits = dinfo->init_bits = i_bits;
dinfo->maxcode = MAXCODE(dinfo->n_bits);
dinfo->ClearCode = (1 << (i_bits - 1));
dinfo->ClearCode = ((code_int) 1 << (i_bits - 1));
dinfo->EOFCode = dinfo->ClearCode + 1;
dinfo->code_counter = dinfo->ClearCode + 2;
dinfo->code_counter = dinfo->free_code = dinfo->ClearCode + 2;
dinfo->first_byte = TRUE; /* no waiting symbol yet */
/* init output buffering vars */
dinfo->bytesinpkt = 0;
dinfo->cur_accum = 0;
dinfo->cur_bits = 0;
/* clear hash table */
if (dinfo->hash_code != NULL)
clear_hash(dinfo);
/* GIF specifies an initial Clear code */
output(dinfo, dinfo->ClearCode);
}
LOCAL(void)
compress_pixel (gif_dest_ptr dinfo, int c)
/* Accept and "compress" one pixel value.
* The given value must be less than n_bits wide.
*/
{
/* Output the given pixel value as a symbol. */
output(dinfo, c);
/* Issue Clear codes often enough to keep the reader from ratcheting up
* its symbol size.
*/
if (dinfo->code_counter < dinfo->maxcode) {
dinfo->code_counter++;
} else {
output(dinfo, dinfo->ClearCode);
dinfo->code_counter = dinfo->ClearCode + 2; /* reset the counter */
}
}
LOCAL(void)
compress_term (gif_dest_ptr dinfo)
/* Clean up at end */
{
/* Flush out the buffered LZW code */
if (! dinfo->first_byte)
output(dinfo, dinfo->waiting_code);
/* Send an EOF code */
output(dinfo, dinfo->EOFCode);
/* Flush the bit-packing buffer */
@ -219,7 +251,7 @@ put_3bytes (gif_dest_ptr dinfo, int val)
LOCAL(void)
emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap)
/* Output the GIF file header, including color map */
/* If colormap==NULL, synthesize a grayscale colormap */
/* If colormap == NULL, synthesize a grayscale colormap */
{
int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte;
int cshift = dinfo->cinfo->data_precision - 8;
@ -250,15 +282,15 @@ emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap)
put_word(dinfo, (unsigned int) dinfo->cinfo->output_width);
put_word(dinfo, (unsigned int) dinfo->cinfo->output_height);
FlagByte = 0x80; /* Yes, there is a global color table */
FlagByte |= (BitsPerPixel-1) << 4; /* color resolution */
FlagByte |= (BitsPerPixel-1); /* size of global color table */
FlagByte |= (BitsPerPixel - 1) << 4; /* color resolution */
FlagByte |= (BitsPerPixel - 1); /* size of global color table */
putc(FlagByte, dinfo->pub.output_file);
putc(0, dinfo->pub.output_file); /* Background color index */
putc(0, dinfo->pub.output_file); /* Reserved (aspect ratio in GIF89) */
/* Write the Global Color Map */
/* If the color map is more than 8 bits precision, */
/* we reduce it to 8 bits by shifting */
for (i=0; i < ColorMapSize; i++) {
for (i = 0; i < ColorMapSize; i++) {
if (i < num_colors) {
if (colormap != NULL) {
if (dinfo->cinfo->out_color_space == JCS_RGB) {
@ -272,11 +304,11 @@ emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap)
}
} else {
/* Create a grayscale map of num_colors values, range 0..255 */
put_3bytes(dinfo, (i * 255 + (num_colors-1)/2) / (num_colors-1));
put_3bytes(dinfo, (i * 255 + (num_colors - 1) / 2) / (num_colors - 1));
}
} else {
/* fill out the map to a power of 2 */
put_3bytes(dinfo, 0);
put_3bytes(dinfo, CENTERJSAMPLE >> cshift);
}
}
/* Write image separator and Image Descriptor */
@ -290,8 +322,8 @@ emit_header (gif_dest_ptr dinfo, int num_colors, JSAMPARRAY colormap)
/* Write Initial Code Size byte */
putc(InitCodeSize, dinfo->pub.output_file);
/* Initialize for "compression" of image data */
compress_init(dinfo, InitCodeSize+1);
/* Initialize for compression of image data */
compress_init(dinfo, InitCodeSize + 1);
}
@ -316,17 +348,139 @@ start_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
* In this module rows_supplied will always be 1.
*/
/*
* The LZW algorithm proper
*/
METHODDEF(void)
put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
put_LZW_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
{
gif_dest_ptr dest = (gif_dest_ptr) dinfo;
register JSAMPROW ptr;
register JDIMENSION col;
code_int c;
register hash_int i;
register hash_int disp;
register hash_entry probe_value;
ptr = dest->pub.buffer[0];
for (col = cinfo->output_width; col > 0; col--) {
compress_pixel(dest, GETJSAMPLE(*ptr++));
/* Accept and compress one 8-bit byte */
c = (code_int) GETJSAMPLE(*ptr++);
if (dest->first_byte) { /* need to initialize waiting_code */
dest->waiting_code = c;
dest->first_byte = FALSE;
continue;
}
/* Probe hash table to see if a symbol exists for
* waiting_code followed by c.
* If so, replace waiting_code by that symbol and continue.
*/
i = ((hash_int) c << (MAX_LZW_BITS-8)) + dest->waiting_code;
/* i is less than twice 2**MAX_LZW_BITS, therefore less than twice HSIZE */
if (i >= HSIZE)
i -= HSIZE;
probe_value = HASH_ENTRY(dest->waiting_code, c);
if (dest->hash_code[i] == 0) {
/* hit empty slot; desired symbol not in table */
output(dest, dest->waiting_code);
if (dest->free_code < LZW_TABLE_SIZE) {
dest->hash_code[i] = dest->free_code++; /* add symbol to hashtable */
dest->hash_value[i] = probe_value;
} else
clear_block(dest);
dest->waiting_code = c;
continue;
}
if (dest->hash_value[i] == probe_value) {
dest->waiting_code = dest->hash_code[i];
continue;
}
if (i == 0) /* secondary hash (after G. Knott) */
disp = 1;
else
disp = HSIZE - i;
for (;;) {
i -= disp;
if (i < 0)
i += HSIZE;
if (dest->hash_code[i] == 0) {
/* hit empty slot; desired symbol not in table */
output(dest, dest->waiting_code);
if (dest->free_code < LZW_TABLE_SIZE) {
dest->hash_code[i] = dest->free_code++; /* add symbol to hashtable */
dest->hash_value[i] = probe_value;
} else
clear_block(dest);
dest->waiting_code = c;
break;
}
if (dest->hash_value[i] == probe_value) {
dest->waiting_code = dest->hash_code[i];
break;
}
}
}
}
/*
* The pseudo-compression algorithm.
*
* In this version we simply output each pixel value as a separate symbol;
* thus, no compression occurs. In fact, there is expansion of one bit per
* pixel, because we use a symbol width one bit wider than the pixel width.
*
* GIF ordinarily uses variable-width symbols, and the decoder will expect
* to ratchet up the symbol width after a fixed number of symbols.
* To simplify the logic and keep the expansion penalty down, we emit a
* GIF Clear code to reset the decoder just before the width would ratchet up.
* Thus, all the symbols in the output file will have the same bit width.
* Note that emitting the Clear codes at the right times is a mere matter of
* counting output symbols and is in no way dependent on the LZW algorithm.
*
* With a small basic pixel width (low color count), Clear codes will be
* needed very frequently, causing the file to expand even more. So this
* simplistic approach wouldn't work too well on bilevel images, for example.
* But for output of JPEG conversions the pixel width will usually be 8 bits
* (129 to 256 colors), so the overhead added by Clear symbols is only about
* one symbol in every 256.
*/
METHODDEF(void)
put_raw_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
{
gif_dest_ptr dest = (gif_dest_ptr) dinfo;
register JSAMPROW ptr;
register JDIMENSION col;
code_int c;
ptr = dest->pub.buffer[0];
for (col = cinfo->output_width; col > 0; col--) {
c = (code_int) GETJSAMPLE(*ptr++);
/* Accept and output one pixel value.
* The given value must be less than n_bits wide.
*/
/* Output the given pixel value as a symbol. */
output(dest, c);
/* Issue Clear codes often enough to keep the reader from ratcheting up
* its symbol size.
*/
if (dest->code_counter < dest->maxcode) {
dest->code_counter++;
} else {
output(dest, dest->ClearCode);
dest->code_counter = dest->ClearCode + 2; /* reset the counter */
}
}
}
@ -340,7 +494,7 @@ finish_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
gif_dest_ptr dest = (gif_dest_ptr) dinfo;
/* Flush "compression" mechanism */
/* Flush compression mechanism */
compress_term(dest);
/* Write a zero-length data block to end the series */
putc(0, dest->pub.output_file);
@ -358,17 +512,15 @@ finish_output_gif (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
*/
GLOBAL(djpeg_dest_ptr)
jinit_write_gif (j_decompress_ptr cinfo)
jinit_write_gif (j_decompress_ptr cinfo, boolean is_lzw)
{
gif_dest_ptr dest;
/* Create module interface object, fill in method pointers */
dest = (gif_dest_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(gif_dest_struct));
dest = (gif_dest_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(gif_dest_struct));
dest->cinfo = cinfo; /* make back link for subroutines */
dest->pub.start_output = start_output_gif;
dest->pub.put_pixel_rows = put_pixel_rows;
dest->pub.finish_output = finish_output_gif;
if (cinfo->out_color_space != JCS_GRAYSCALE &&
@ -394,6 +546,20 @@ jinit_write_gif (j_decompress_ptr cinfo)
((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->output_width, (JDIMENSION) 1);
dest->pub.buffer_height = 1;
if (is_lzw) {
dest->pub.put_pixel_rows = put_LZW_pixel_rows;
/* Allocate space for hash table */
dest->hash_code = (code_int *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, HSIZE * SIZEOF(code_int));
dest->hash_value = (hash_entry FAR *) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, HSIZE * SIZEOF(hash_entry));
} else {
dest->pub.put_pixel_rows = put_raw_pixel_rows;
/* Mark tables unused */
dest->hash_code = NULL;
dest->hash_value = NULL;
}
return &dest->pub;
}

View file

@ -2,7 +2,7 @@
* wrppm.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2009-2017 by Guido Vollbeding.
* Modified 2009-2019 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.
*
@ -149,7 +149,6 @@ put_demapped_rgb (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
(void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
}
METHODDEF(void)
put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
@ -157,13 +156,13 @@ put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
ppm_dest_ptr dest = (ppm_dest_ptr) dinfo;
register char * bufferptr;
register JSAMPROW ptr;
register JSAMPROW color_map = cinfo->colormap[0];
register JSAMPROW color_map0 = cinfo->colormap[0];
register JDIMENSION col;
ptr = dest->pub.buffer[0];
bufferptr = dest->iobuffer;
for (col = cinfo->output_width; col > 0; col--) {
PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map[GETJSAMPLE(*ptr++)]));
PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[GETJSAMPLE(*ptr++)]));
}
(void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
}
@ -176,19 +175,17 @@ put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
METHODDEF(void)
start_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
ppm_dest_ptr dest = (ppm_dest_ptr) dinfo;
/* Emit file header */
switch (cinfo->out_color_space) {
case JCS_GRAYSCALE:
/* emit header for raw PGM format */
fprintf(dest->pub.output_file, "P5\n%ld %ld\n%d\n",
fprintf(dinfo->output_file, "P5\n%ld %ld\n%d\n",
(long) cinfo->output_width, (long) cinfo->output_height,
PPM_MAXVAL);
break;
case JCS_RGB:
/* emit header for raw PPM format */
fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n",
fprintf(dinfo->output_file, "P6\n%ld %ld\n%d\n",
(long) cinfo->output_width, (long) cinfo->output_height,
PPM_MAXVAL);
break;
@ -222,9 +219,8 @@ jinit_write_ppm (j_decompress_ptr cinfo)
ppm_dest_ptr dest;
/* Create module interface object, fill in method pointers */
dest = (ppm_dest_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(ppm_dest_struct));
dest = (ppm_dest_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(ppm_dest_struct));
dest->pub.start_output = start_output_ppm;
dest->pub.finish_output = finish_output_ppm;

View file

@ -2,7 +2,7 @@
* wrrle.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2017 by Guido Vollbeding.
* Modified 2017-2019 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.
*
@ -62,6 +62,7 @@ typedef struct {
typedef rle_dest_struct * rle_dest_ptr;
/* Forward declarations */
METHODDEF(void) rle_put_pixel_rows
JPP((j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
@ -79,7 +80,7 @@ start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
rle_dest_ptr dest = (rle_dest_ptr) dinfo;
size_t cmapsize;
int i, ci;
int ci, i;
#ifdef PROGRESS_REPORT
cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
#endif
@ -123,8 +124,8 @@ start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
/* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
for (ci = 0; ci < cinfo->out_color_components; ci++) {
for (i = 0; i < cinfo->actual_number_of_colors; i++) {
dest->colormap[ci * CMAPLENGTH + i] =
GETJSAMPLE(cinfo->colormap[ci][i]) << 8;
dest->colormap[ci * CMAPLENGTH + i] =
GETJSAMPLE(cinfo->colormap[ci][i]) << 8;
}
}
}
@ -163,6 +164,7 @@ rle_put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
}
}
/*
* Finish up at the end of the file.
*
@ -174,7 +176,7 @@ finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
rle_dest_ptr dest = (rle_dest_ptr) dinfo;
rle_hdr header; /* Output file information */
rle_pixel **rle_row, *red, *green, *blue;
rle_pixel **rle_row, *red_ptr, *green_ptr, *blue_ptr;
JSAMPROW output_row;
char cmapcomment[80];
int row, col;
@ -221,37 +223,37 @@ finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
#endif
if (cinfo->output_components == 1) {
for (row = cinfo->output_height-1; row >= 0; row--) {
for (row = cinfo->output_height - 1; row >= 0; row--) {
rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, dest->image,
((j_common_ptr) cinfo, dest->image,
(JDIMENSION) row, (JDIMENSION) 1, FALSE);
rle_putrow(rle_row, (int) cinfo->output_width, &header);
#ifdef PROGRESS_REPORT
if (progress != NULL) {
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
#endif
}
} else {
for (row = cinfo->output_height-1; row >= 0; row--) {
rle_row = (rle_pixel **) dest->rle_row;
for (row = cinfo->output_height - 1; row >= 0; row--) {
output_row = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, dest->image,
((j_common_ptr) cinfo, dest->image,
(JDIMENSION) row, (JDIMENSION) 1, FALSE);
red = rle_row[0];
green = rle_row[1];
blue = rle_row[2];
rle_row = dest->rle_row;
red_ptr = rle_row[0];
green_ptr = rle_row[1];
blue_ptr = rle_row[2];
for (col = cinfo->output_width; col > 0; col--) {
*red++ = GETJSAMPLE(*output_row++);
*green++ = GETJSAMPLE(*output_row++);
*blue++ = GETJSAMPLE(*output_row++);
*red_ptr++ = GETJSAMPLE(*output_row++);
*green_ptr++ = GETJSAMPLE(*output_row++);
*blue_ptr++ = GETJSAMPLE(*output_row++);
}
rle_putrow(rle_row, (int) cinfo->output_width, &header);
#ifdef PROGRESS_REPORT
if (progress != NULL) {
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
progress->pub.pass_counter++;
(*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
}
#endif
}
@ -280,9 +282,8 @@ jinit_write_rle (j_decompress_ptr cinfo)
rle_dest_ptr dest;
/* Create module interface object, fill in method pointers */
dest = (rle_dest_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(rle_dest_struct));
dest = (rle_dest_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(rle_dest_struct));
dest->pub.start_output = start_output_rle;
dest->pub.finish_output = finish_output_rle;
@ -290,14 +291,13 @@ jinit_write_rle (j_decompress_ptr cinfo)
jpeg_calc_output_dimensions(cinfo);
/* Allocate a work array for output to the RLE library. */
dest->rle_row = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->output_width, (JDIMENSION) cinfo->output_components);
dest->rle_row = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, cinfo->output_width, (JDIMENSION) cinfo->output_components);
/* Allocate a virtual array to hold the image. */
dest->image = (*cinfo->mem->request_virt_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
(JDIMENSION) (cinfo->output_width * cinfo->output_components),
cinfo->output_width * (JDIMENSION) cinfo->output_components,
cinfo->output_height, (JDIMENSION) 1);
return &dest->pub;

View file

@ -2,7 +2,7 @@
* wrtarga.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2015-2017 by Guido Vollbeding.
* Modified 2015-2019 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.
*
@ -167,19 +167,20 @@ put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
METHODDEF(void)
start_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
tga_dest_ptr dest = (tga_dest_ptr) dinfo;
int num_colors, i;
FILE *outfile;
if (cinfo->out_color_space == JCS_GRAYSCALE) {
switch (cinfo->out_color_space) {
case JCS_GRAYSCALE:
/* Targa doesn't have a mapped grayscale format, so we will */
/* demap quantized gray output. Never emit a colormap. */
write_header(cinfo, dinfo, 0);
if (cinfo->quantize_colors)
dest->pub.put_pixel_rows = put_demapped_gray;
dinfo->put_pixel_rows = put_demapped_gray;
else
dest->pub.put_pixel_rows = put_gray_rows;
} else if (cinfo->out_color_space == JCS_RGB) {
dinfo->put_pixel_rows = put_gray_rows;
break;
case JCS_RGB:
if (cinfo->quantize_colors) {
/* We only support 8-bit colormap indexes, so only 256 colors */
num_colors = cinfo->actual_number_of_colors;
@ -187,18 +188,19 @@ start_output_tga (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
ERREXIT1(cinfo, JERR_TOO_MANY_COLORS, num_colors);
write_header(cinfo, dinfo, num_colors);
/* Write the colormap. Note Targa uses BGR byte order */
outfile = dest->pub.output_file;
outfile = dinfo->output_file;
for (i = 0; i < num_colors; i++) {
putc(GETJSAMPLE(cinfo->colormap[2][i]), outfile);
putc(GETJSAMPLE(cinfo->colormap[1][i]), outfile);
putc(GETJSAMPLE(cinfo->colormap[0][i]), outfile);
}
dest->pub.put_pixel_rows = put_gray_rows;
dinfo->put_pixel_rows = put_gray_rows;
} else {
write_header(cinfo, dinfo, 0);
dest->pub.put_pixel_rows = put_pixel_rows;
dinfo->put_pixel_rows = put_pixel_rows;
}
} else {
break;
default:
ERREXIT(cinfo, JERR_TGA_COLORSPACE);
}
}
@ -228,9 +230,8 @@ jinit_write_targa (j_decompress_ptr cinfo)
tga_dest_ptr dest;
/* Create module interface object, fill in method pointers */
dest = (tga_dest_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(tga_dest_struct));
dest = (tga_dest_ptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(tga_dest_struct));
dest->pub.start_output = start_output_tga;
dest->pub.finish_output = finish_output_tga;
@ -239,13 +240,12 @@ jinit_write_targa (j_decompress_ptr cinfo)
/* Create I/O buffer. Note we make this near on a PC. */
dest->buffer_width = cinfo->output_width * cinfo->output_components;
dest->iobuffer = (char *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (dest->buffer_width * SIZEOF(char)));
dest->iobuffer = (char *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
JPOOL_IMAGE, (size_t) dest->buffer_width * SIZEOF(char));
/* Create decompressor output buffer. */
dest->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width, (JDIMENSION) 1);
dest->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
JPOOL_IMAGE, dest->buffer_width, (JDIMENSION) 1);
dest->pub.buffer_height = 1;
return &dest->pub;

View file

@ -75,7 +75,7 @@ Used Version: git commit 8765259
Website: https://github.com/win-iconv/win-iconv
Title: libjpeg
Used Version: 9c
Used Version: 9d
Website: http://www.ijg.org/
Title: libtiff

View file

@ -2,6 +2,7 @@
* cdjpeg.h
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2019 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.
*
@ -121,7 +122,8 @@ EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo,
boolean is_os2));
EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo,
boolean is_lzw));
EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo));

View file

@ -2,7 +2,7 @@
* jdct.h
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2002-2017 by Guido Vollbeding.
* Modified 2002-2019 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.
*
@ -358,13 +358,6 @@ EXTERN(void) jpeg_idct_1x2
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
/* Descale and correctly round an INT32 value that's scaled by N bits.
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
* the fudge factor is correct for either sign of X.
*/
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
* This macro is used only when the two inputs will actually be no more than
* 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a

View file

@ -2,7 +2,7 @@
* jerror.h
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 1997-2012 by Guido Vollbeding.
* Modified 1997-2018 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.
*
@ -84,7 +84,7 @@ JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
JMESSAGE(JERR_FILE_READ, "Input file read error")
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
JMESSAGE(JERR_HUFF_CLEN_OUTOFBOUNDS, "Huffman code size table out of bounds")
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")

View file

@ -2,7 +2,7 @@
* jpegint.h
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2017 by Guido Vollbeding.
* Modified 1997-2019 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.
*
@ -302,6 +302,13 @@ struct jpeg_color_quantizer {
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
#endif
/* Descale and correctly round an INT32 value that's scaled by N bits.
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
* the fudge factor is correct for either sign of X.
*/
#define DESCALE(x,n) RIGHT_SHIFT((x) + ((INT32) 1 << ((n)-1)), n)
/* Short forms of external names for systems with brain-damaged linkers. */

View file

@ -2,7 +2,7 @@
* jpeglib.h
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2002-2017 by Guido Vollbeding.
* Modified 2002-2019 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 3
#define JPEG_LIB_VERSION_MINOR 4
/* Various constants determining the sizes of things.
@ -909,6 +909,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#define jpeg_suppress_tables jSuppressTables
#define jpeg_alloc_quant_table jAlcQTable
#define jpeg_alloc_huff_table jAlcHTable
#define jpeg_std_huff_table jStdHTable
#define jpeg_start_compress jStrtCompress
#define jpeg_write_scanlines jWrtScanlines
#define jpeg_finish_compress jFinCompress
@ -977,10 +978,10 @@ EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
/* Data source and destination managers: memory buffers. */
EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo,
unsigned char ** outbuffer,
unsigned long * outsize));
size_t * outsize));
EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,
const unsigned char * inbuffer,
unsigned long insize));
size_t insize));
/* Default parameter setup for compression */
EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
@ -1005,6 +1006,8 @@ EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
boolean suppress));
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
EXTERN(JHUFF_TBL *) jpeg_std_huff_table JPP((j_common_ptr cinfo,
boolean isDC, int tblno));
/* Main entry points for compression */
EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,

View file

@ -1,7 +1,7 @@
/*
* jversion.h
*
* Copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding.
* Copyright (C) 1991-2020, 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 "9c 14-Jan-2018"
#define JVERSION "9d 12-Jan-2020"
#define JCOPYRIGHT "Copyright (C) 2018, Thomas G. Lane, Guido Vollbeding"
#define JCOPYRIGHT "Copyright (C) 2020, Thomas G. Lane, Guido Vollbeding"

View file

@ -1,7 +1,7 @@
/*
* transupp.h
*
* Copyright (C) 1997-2013, Thomas G. Lane, Guido Vollbeding.
* Copyright (C) 1997-2019, 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.
*
@ -61,6 +61,11 @@
*
* A complementary lossless-wipe option is provided to discard (gray out) data
* inside a given image region while losslessly preserving what is outside.
* Another option is lossless-drop, which replaces data at a given image
* position by another image. Both source images must have the same
* subsampling values. It is best if they also have the same quantization,
* otherwise quantization adaption occurs. The trim option can be used with
* the drop option to requantize the drop file to the source file.
*
* We also provide a lossless-resize option, which is kind of a lossless-crop
* operation in the DCT coefficient block domain - it discards higher-order
@ -106,20 +111,22 @@ typedef enum {
JXFORM_ROT_90, /* 90-degree clockwise rotation */
JXFORM_ROT_180, /* 180-degree rotation */
JXFORM_ROT_270, /* 270-degree clockwise (or 90 ccw) */
JXFORM_WIPE /* wipe */
JXFORM_WIPE, /* wipe */
JXFORM_DROP /* drop */
} JXFORM_CODE;
/*
* Codes for crop parameters, which can individually be unspecified,
* positive or negative for xoffset or yoffset,
* positive or forced for width or height.
* positive or force or reflect for width or height.
*/
typedef enum {
JCROP_UNSET,
JCROP_POS,
JCROP_NEG,
JCROP_FORCE
JCROP_UNSET,
JCROP_POS,
JCROP_NEG,
JCROP_FORCE,
JCROP_REFLECT
} JCROP_CODE;
/*
@ -134,20 +141,24 @@ typedef struct {
boolean perfect; /* if TRUE, fail if partial MCUs are requested */
boolean trim; /* if TRUE, trim partial MCUs as needed */
boolean force_grayscale; /* if TRUE, convert color image to grayscale */
boolean crop; /* if TRUE, crop or wipe source image */
boolean crop; /* if TRUE, crop or wipe source image, or drop */
/* Crop parameters: application need not set these unless crop is TRUE.
* These can be filled in by jtransform_parse_crop_spec().
*/
JDIMENSION crop_width; /* Width of selected region */
JCROP_CODE crop_width_set; /* (forced disables adjustment) */
JCROP_CODE crop_width_set; /* (force disables adjustment) */
JDIMENSION crop_height; /* Height of selected region */
JCROP_CODE crop_height_set; /* (forced disables adjustment) */
JCROP_CODE crop_height_set; /* (force disables adjustment) */
JDIMENSION crop_xoffset; /* X offset of selected region */
JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */
JDIMENSION crop_yoffset; /* Y offset of selected region */
JCROP_CODE crop_yoffset_set; /* (negative measures from bottom edge) */
/* Drop parameters: set by caller for drop request */
j_decompress_ptr drop_ptr;
jvirt_barray_ptr * drop_coef_arrays;
/* Internal workspace: caller should not touch these */
int num_components; /* # of components in workspace */
jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */