[LIBJPEG]

* Sync to v9.
* Brought to you by Ivan Di Francesco.
CORE-6819 #resolve #comment Committed in r58400. Grazie ;)

svn path=/trunk/; revision=58400
This commit is contained in:
Amine Khaldi 2013-03-02 17:14:06 +00:00
parent 61f00085f4
commit 65caa5d13b
36 changed files with 1997 additions and 479 deletions

View file

@ -1,10 +1,10 @@
The Independent JPEG Group's JPEG software The Independent JPEG Group's JPEG software
========================================== ==========================================
README for release 8b of 16-May-2010 README for release 9 of 13-Jan-2013
==================================== ===================================
This distribution contains the eighth public release of the Independent JPEG This distribution contains the ninth public release of the Independent JPEG
Group's free JPEG software. You are welcome to redistribute this software and Group's free JPEG software. You are welcome to redistribute this software and
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
@ -13,7 +13,8 @@ Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
and other members of the Independent JPEG Group. and other members of the Independent JPEG Group.
IJG is not affiliated with the official ISO JPEG standards committee. IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
(also known as JPEG, together with ITU-T SG16).
DOCUMENTATION ROADMAP DOCUMENTATION ROADMAP
@ -114,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, 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. its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding. This software is copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below. All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this Permission is hereby granted to use, copy, modify, and distribute this
@ -145,15 +146,6 @@ commercial products, provided that all warranty or liability claims are
assumed by the product vendor. assumed by the product vendor.
ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
ansi2knr.c is NOT covered by the above copyright and conditions, but instead
by the usual distribution terms of the Free Software Foundation; principally,
that you must include source code if you redistribute it. (See the file
ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
of any program generated from the IJG code, this does not limit you more than
the foregoing paragraphs do.
The Unix configuration script "configure" was produced with GNU Autoconf. The Unix configuration script "configure" was produced with GNU Autoconf.
It is copyright by the Free Software Foundation but is freely distributable. It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub, The same holds for its supporting scripts (config.guess, config.sub,
@ -221,10 +213,16 @@ Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of 10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
Continuous-tone Still Images, Part 2: Compliance testing" and has document Continuous-tone Still Images, Part 2: Compliance testing" and has document
numbers ISO/IEC IS 10918-2, ITU-T T.83. numbers ISO/IEC IS 10918-2, ITU-T T.83.
IJG JPEG 8 introduces an implementation of the JPEG SmartScale extension IJG JPEG 8 introduced an implementation of the JPEG SmartScale extension
which is specified in a contributed document at ITU and ISO with title "ITU-T which is specified in two documents: A contributed document at ITU and ISO
JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced Image Coding", April with title "ITU-T JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced
2006, Geneva, Switzerland. The latest version of the document is Revision 3. Image Coding", April 2006, Geneva, Switzerland. The latest version of this
document is Revision 3. And a contributed document ISO/IEC JTC1/SC29/WG1 N
5799 with title "Evolution of JPEG", June/July 2011, Berlin, Germany.
IJG JPEG 9 introduces a reversible color transform for improved lossless
compression which is described in a contributed document ISO/IEC JTC1/SC29/
WG1 N 6080 with title "JPEG 9 Lossless Coding", June/July 2012, Paris,
France.
The JPEG standard does not specify all details of an interchangeable file The JPEG standard does not specify all details of an interchangeable file
format. For the omitted details we follow the "JFIF" conventions, revision format. For the omitted details we follow the "JFIF" conventions, revision
@ -254,8 +252,8 @@ ARCHIVE LOCATIONS
The "official" archive site for this software is www.ijg.org. The "official" archive site for this software is www.ijg.org.
The most recent released version can always be found there in The most recent released version can always be found there in
directory "files". This particular version will be archived as directory "files". This particular version will be archived as
http://www.ijg.org/files/jpegsrc.v8b.tar.gz, and in Windows-compatible http://www.ijg.org/files/jpegsrc.v9.tar.gz, and in Windows-compatible
"zip" archive format as http://www.ijg.org/files/jpegsr8b.zip. "zip" archive format as http://www.ijg.org/files/jpegsr9.zip.
The JPEG FAQ (Frequently Asked Questions) article is a source of some The JPEG FAQ (Frequently Asked Questions) article is a source of some
general information about JPEG. general information about JPEG.
@ -281,12 +279,16 @@ ITU JPEG (Study Group 16) meeting in Geneva, Switzerland.
Thank to Thomas Wiegand and Gary Sullivan for inviting me to the Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland. Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
Thank to Thomas Richter and Daniel Lee for inviting me to the
ISO/IEC JTC1/SC29/WG1 (also known as JPEG, together with ITU-T SG16)
meeting in Berlin, Germany.
Thank to John Korejwa and Massimo Ballerini for inviting me to Thank to John Korejwa and Massimo Ballerini for inviting me to
fruitful consultations in Boston, MA and Milan, Italy. fruitful consultations in Boston, MA and Milan, Italy.
Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther
Maier-Gerber, Walter Stoeber, and Fred Schmitz for corresponding Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel
business development. for corresponding business development.
Thank to Nico Zschach and Dirk Stelling of the technical support team Thank to Nico Zschach and Dirk Stelling of the technical support team
at the Digital Images company in Halle for providing me with extra at the Digital Images company in Halle for providing me with extra
@ -304,23 +306,45 @@ design and development of this singular software package.
FILE FORMAT WARS FILE FORMAT WARS
================ ================
The ISO JPEG standards committee actually promotes different formats like The ISO/IEC JTC1/SC29/WG1 standards committee (also known as JPEG, together
"JPEG 2000" or "JPEG XR" which are incompatible with original DCT-based with ITU-T SG16) currently promotes different formats containing the name
JPEG and which are based on faulty technologies. IJG therefore does not "JPEG" which is misleading because these formats are incompatible with
and will not support such momentary mistakes (see REFERENCES). original DCT-based JPEG and are based on faulty technologies.
We have little or no sympathy for the promotion of these formats. Indeed, IJG therefore does not and will not support such momentary mistakes
one of the original reasons for developing this free software was to help (see REFERENCES).
force convergence on common, interoperable format standards for JPEG files. There exist also distributions under the name "OpenJPEG" promoting such
kind of formats which is misleading because they don't support original
JPEG images.
We have no sympathy for the promotion of inferior formats. Indeed, one of
the original reasons for developing this free software was to help force
convergence on common, interoperable format standards for JPEG files.
Don't use an incompatible file format! Don't use an incompatible file format!
(In any case, our decoder will remain capable of reading existing JPEG (In any case, our decoder will remain capable of reading existing JPEG
image files indefinitely.) image files indefinitely.)
Furthermore, the ISO committee pretends to be "responsible for the popular
JPEG" in their public reports which is not true because they don't respond to
actual requirements for the maintenance of the original JPEG specification.
There are currently different distributions in circulation containing the
name "libjpeg" which is misleading because they don't have the features and
are incompatible with formats supported by actual IJG libjpeg distributions.
One of those fakes is released by members of the ISO committee and just uses
the name of libjpeg for misdirection of people, similar to the abuse of the
name JPEG as described above, while having nothing in common with actual IJG
libjpeg distributions.
The other one claims to be a "derivative" or "fork" of the original libjpeg
and violates the license conditions as described under LEGAL ISSUES above.
We have no sympathy for the release of misleading and illegal distributions
derived from obsolete code bases.
Don't use an obsolete code base!
TO DO TO DO
===== =====
Version 8 is the first release of a new generation JPEG standard Version 9 is the second release of a new generation JPEG standard
to overcome the limitations of the original JPEG specification. to overcome the limitations of the original JPEG specification.
More features are being prepared for coming releases... More features are being prepared for coming releases...
Please send bug reports, offers of help, etc. to jpeg-info@uc.ag. Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org.

View file

@ -1,6 +1,62 @@
CHANGE LOG for Independent JPEG Group's JPEG software CHANGE LOG for Independent JPEG Group's JPEG software
Version 9 13-Jan-2013
----------------------
Add cjpeg -rgb1 option to create an RGB JPEG file, and insert
a simple reversible color transform into the processing which
significantly improves the compression.
The recommended command for lossless coding of RGB images is now
cjpeg -rgb1 -block 1 -arithmetic.
As said, this option improves the compression significantly, but
the files are not compatible with JPEG decoders prior to IJG v9
due to the included color transform.
The used color transform and marker signaling is compatible with
other JPEG standards (e.g., JPEG-LS part 2).
Remove the automatic de-ANSI-fication support (Automake 1.12).
Thank also to Nitin A Kamble for suggestion.
Add remark for jpeg_mem_dest() in jdatadst.c.
Thank to Elie-Gregoire Khoury for the hint.
Support files with invalid component identifiers (created
by Adobe PDF). Thank to Robin Watts for the suggestion.
Adapt full buffer case in jcmainct.c for use with scaled DCT.
Thank to Sergii Biloshytskyi for the suggestion.
Add type identifier for declaration of noreturn functions.
Thank to Brett L. Moore for the suggestion.
Correct argument type in format string, avoid compiler warnings.
Thank to Vincent Torri for hint.
Add missing #include directives in configuration checks, avoid
configuration errors. Thank to John Spencer for the hint.
Version 8d 15-Jan-2012
-----------------------
Add cjpeg -rgb option to create RGB JPEG files.
Using this switch suppresses the conversion from RGB
colorspace input to the default YCbCr JPEG colorspace.
This feature allows true lossless JPEG coding of RGB color images.
The recommended command for this purpose is currently
cjpeg -rgb -block 1 -arithmetic.
SmartScale capable decoder (introduced with IJG JPEG 8) required.
Thank to Michael Koch for the initial suggestion.
Add option to disable the region adjustment in the transupp crop code.
Thank to Jeffrey Friedl for the suggestion.
Thank to Richard Jones and Edd Dawson for various minor corrections.
Thank to Akim Demaille for configure.ac cleanup.
Version 8c 16-Jan-2011 Version 8c 16-Jan-2011
----------------------- -----------------------

View file

@ -2,7 +2,7 @@
* cjpeg.c * cjpeg.c
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding. * Modified 2003-2013 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -152,6 +152,7 @@ usage (void)
fprintf(stderr, "Switches (names may be abbreviated):\n"); fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is useful range)\n"); fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is useful range)\n");
fprintf(stderr, " -grayscale Create monochrome JPEG file\n"); fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
fprintf(stderr, " -rgb Create RGB JPEG file\n");
#ifdef ENTROPY_OPT_SUPPORTED #ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n"); fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
#endif #endif
@ -165,9 +166,15 @@ usage (void)
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n"); fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
#endif #endif
fprintf(stderr, "Switches for advanced users:\n"); fprintf(stderr, "Switches for advanced users:\n");
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
#ifdef DCT_SCALING_SUPPORTED #ifdef DCT_SCALING_SUPPORTED
fprintf(stderr, " -block N DCT block size (1..16; default is 8)\n"); fprintf(stderr, " -block N DCT block size (1..16; default is 8)\n");
#endif #endif
#if JPEG_LIB_VERSION_MAJOR >= 9
fprintf(stderr, " -rgb1 Create RGB JPEG file with reversible color transform\n");
#endif
#ifdef DCT_ISLOW_SUPPORTED #ifdef DCT_ISLOW_SUPPORTED
fprintf(stderr, " -dct int Use integer DCT method%s\n", fprintf(stderr, " -dct int Use integer DCT method%s\n",
(JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
@ -189,9 +196,6 @@ usage (void)
fprintf(stderr, " -outfile name Specify name for output file\n"); fprintf(stderr, " -outfile name Specify name for output file\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n"); fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, "Switches for wizards:\n"); fprintf(stderr, "Switches for wizards:\n");
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
fprintf(stderr, " -baseline Force baseline quantization tables\n"); fprintf(stderr, " -baseline Force baseline quantization tables\n");
fprintf(stderr, " -qtables file Use quantization tables given in file\n"); fprintf(stderr, " -qtables file Use quantization tables given in file\n");
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n"); fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
@ -263,9 +267,8 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "block", 2)) { } else if (keymatch(arg, "block", 2)) {
/* Set DCT block size. */ /* Set DCT block size. */
#if defined(DCT_SCALING_SUPPORTED) && defined(JPEG_LIB_VERSION_MAJOR) && \ #if defined DCT_SCALING_SUPPORTED && JPEG_LIB_VERSION_MAJOR >= 8 && \
(JPEG_LIB_VERSION_MAJOR > 8 || (JPEG_LIB_VERSION_MAJOR == 8 && \ (JPEG_LIB_VERSION_MAJOR > 8 || JPEG_LIB_VERSION_MINOR >= 3)
defined(JPEG_LIB_VERSION_MINOR) && JPEG_LIB_VERSION_MINOR >= 3))
int val; int val;
if (++argn >= argc) /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
@ -310,6 +313,16 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Force a monochrome JPEG file to be generated. */ /* Force a monochrome JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
} else if (keymatch(arg, "rgb", 3) || keymatch(arg, "rgb1", 4)) {
/* Force an RGB JPEG file to be generated. */
#if JPEG_LIB_VERSION_MAJOR >= 9
/* Note: Entropy table assignment in jpeg_set_colorspace depends
* on color_transform.
*/
cinfo->color_transform = arg[3] ? JCT_SUBTRACT_GREEN : JCT_NONE;
#endif
jpeg_set_colorspace(cinfo, JCS_RGB);
} else if (keymatch(arg, "maxmemory", 3)) { } else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */ /* Maximum memory in Kb (or Mb with 'm'). */
long lval; long lval;
@ -324,7 +337,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
cinfo->mem->max_memory_to_use = lval * 1000L; cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "nosmooth", 3)) { } else if (keymatch(arg, "nosmooth", 3)) {
/* Suppress fancy downsampling */ /* Suppress fancy downsampling. */
cinfo->do_fancy_downsampling = FALSE; cinfo->do_fancy_downsampling = FALSE;
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
@ -410,7 +423,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Scale the image by a fraction M/N. */ /* Scale the image by a fraction M/N. */
if (++argn >= argc) /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
usage(); usage();
if (sscanf(argv[argn], "%d/%d", if (sscanf(argv[argn], "%u/%u",
&cinfo->scale_num, &cinfo->scale_denom) != 2) &cinfo->scale_num, &cinfo->scale_denom) != 2)
usage(); usage();

View file

@ -2,7 +2,7 @@
* djpeg.c * djpeg.c
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding. * Modified 2009-2013 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -298,7 +298,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
cinfo->mem->max_memory_to_use = lval * 1000L; cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "nosmooth", 3)) { } else if (keymatch(arg, "nosmooth", 3)) {
/* Suppress fancy upsampling */ /* Suppress fancy upsampling. */
cinfo->do_fancy_upsampling = FALSE; cinfo->do_fancy_upsampling = FALSE;
} else if (keymatch(arg, "onepass", 3)) { } else if (keymatch(arg, "onepass", 3)) {
@ -327,7 +327,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
/* Scale the output image by a fraction M/N. */ /* Scale the output image by a fraction M/N. */
if (++argn >= argc) /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
usage(); usage();
if (sscanf(argv[argn], "%d/%d", if (sscanf(argv[argn], "%u/%u",
&cinfo->scale_num, &cinfo->scale_denom) < 1) &cinfo->scale_num, &cinfo->scale_denom) < 1)
usage(); usage();

View file

@ -1,16 +1,16 @@
/* /*
* jaricom.c * jaricom.c
* *
* Developed 1997-2009 by Guido Vollbeding. * Developed 1997-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
* This file contains probability estimation tables for common use in * This file contains probability estimation tables for common use in
* arithmetic entropy encoding and decoding routines. * arithmetic entropy encoding and decoding routines.
* *
* This data represents Table D.2 in the JPEG spec (ISO/IEC IS 10918-1 * This data represents Table D.3 in the JPEG spec (D.2 in the draft),
* and CCITT Recommendation ITU-T T.81) and Table 24 in the JBIG spec * ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81, and Table 24
* (ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82). * in the JBIG spec, ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82.
*/ */
#define JPEG_INTERNALS #define JPEG_INTERNALS
@ -147,7 +147,7 @@ const INT32 jpeg_aritab[113+1] = {
V( 112, 0x59eb, 112, 111, 1 ), V( 112, 0x59eb, 112, 111, 1 ),
/* /*
* This last entry is used for fixed probability estimate of 0.5 * This last entry is used for fixed probability estimate of 0.5
* as recommended in Section 10.3 Table 5 of ITU-T Rec. T.851. * as suggested in Section 10.3 Table 5 of ITU-T Rec. T.851.
*/ */
V( 113, 0x5a1d, 113, 113, 0 ) V( 113, 0x5a1d, 113, 113, 0 )
}; };

View file

@ -1,7 +1,7 @@
/* /*
* jcarith.c * jcarith.c
* *
* Developed 1997-2009 by Guido Vollbeding. * Developed 1997-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -223,7 +223,7 @@ arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
register INT32 qe, temp; register INT32 qe, temp;
register int sv; register int sv;
/* Fetch values from our compact representation of Table D.2: /* Fetch values from our compact representation of Table D.3(D.2):
* Qe values and probability estimation state machine * Qe values and probability estimation state machine
*/ */
sv = *st; sv = *st;
@ -479,7 +479,8 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */ /* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */ /* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--) ke = cinfo->Se;
do {
/* We must apply the point transform by Al. For AC coefficients this /* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably * is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value. * in C, we shift after obtaining the absolute value.
@ -490,13 +491,14 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
v = -v; v = -v;
if (v >>= cinfo->Al) break; if (v >>= cinfo->Al) break;
} }
} while (--ke);
/* Figure F.5: Encode_AC_Coefficients */ /* Figure F.5: Encode_AC_Coefficients */
for (k = cinfo->Ss; k <= ke; k++) { for (k = cinfo->Ss - 1; k < ke;) {
st = entropy->ac_stats[tbl] + 3 * (k - 1); st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 0); /* EOB decision */ arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) { for (;;) {
if ((v = (*block)[natural_order[k]]) >= 0) { if ((v = (*block)[natural_order[++k]]) >= 0) {
if (v >>= cinfo->Al) { if (v >>= cinfo->Al) {
arith_encode(cinfo, st + 1, 1); arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 0); arith_encode(cinfo, entropy->fixed_bin, 0);
@ -510,7 +512,8 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
break; break;
} }
} }
arith_encode(cinfo, st + 1, 0); st += 3; k++; arith_encode(cinfo, st + 1, 0);
st += 3;
} }
st += 2; st += 2;
/* Figure F.8: Encoding the magnitude category of v */ /* Figure F.8: Encoding the magnitude category of v */
@ -537,9 +540,9 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
while (m >>= 1) while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0); arith_encode(cinfo, st, (m & v) ? 1 : 0);
} }
/* Encode EOB decision only if k <= cinfo->Se */ /* Encode EOB decision only if k < cinfo->Se */
if (k <= cinfo->Se) { if (k < cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1); st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 1); arith_encode(cinfo, st, 1);
} }
@ -616,7 +619,8 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* Section G.1.3.3: Encoding of AC coefficients */ /* Section G.1.3.3: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */ /* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--) ke = cinfo->Se;
do {
/* We must apply the point transform by Al. For AC coefficients this /* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably * is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value. * in C, we shift after obtaining the absolute value.
@ -627,6 +631,7 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
v = -v; v = -v;
if (v >>= cinfo->Al) break; if (v >>= cinfo->Al) break;
} }
} while (--ke);
/* Establish EOBx (previous stage end-of-block) index */ /* Establish EOBx (previous stage end-of-block) index */
for (kex = ke; kex > 0; kex--) for (kex = ke; kex > 0; kex--)
@ -638,12 +643,12 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
} }
/* Figure G.10: Encode_AC_Coefficients_SA */ /* Figure G.10: Encode_AC_Coefficients_SA */
for (k = cinfo->Ss; k <= ke; k++) { for (k = cinfo->Ss - 1; k < ke;) {
st = entropy->ac_stats[tbl] + 3 * (k - 1); st = entropy->ac_stats[tbl] + 3 * k;
if (k > kex) if (k >= kex)
arith_encode(cinfo, st, 0); /* EOB decision */ arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) { for (;;) {
if ((v = (*block)[natural_order[k]]) >= 0) { if ((v = (*block)[natural_order[++k]]) >= 0) {
if (v >>= cinfo->Al) { if (v >>= cinfo->Al) {
if (v >> 1) /* previously nonzero coef */ if (v >> 1) /* previously nonzero coef */
arith_encode(cinfo, st + 2, (v & 1)); arith_encode(cinfo, st + 2, (v & 1));
@ -665,12 +670,13 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
break; break;
} }
} }
arith_encode(cinfo, st + 1, 0); st += 3; k++; arith_encode(cinfo, st + 1, 0);
st += 3;
} }
} }
/* Encode EOB decision only if k <= cinfo->Se */ /* Encode EOB decision only if k < cinfo->Se */
if (k <= cinfo->Se) { if (k < cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1); st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 1); arith_encode(cinfo, st, 1);
} }
@ -765,18 +771,21 @@ encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */ /* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
if ((ke = cinfo->lim_Se) == 0) continue;
tbl = compptr->ac_tbl_no; tbl = compptr->ac_tbl_no;
/* Establish EOB (end-of-block) index */ /* Establish EOB (end-of-block) index */
for (ke = cinfo->lim_Se; ke > 0; ke--) do {
if ((*block)[natural_order[ke]]) break; if ((*block)[natural_order[ke]]) break;
} while (--ke);
/* Figure F.5: Encode_AC_Coefficients */ /* Figure F.5: Encode_AC_Coefficients */
for (k = 1; k <= ke; k++) { for (k = 0; k < ke;) {
st = entropy->ac_stats[tbl] + 3 * (k - 1); st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 0); /* EOB decision */ arith_encode(cinfo, st, 0); /* EOB decision */
while ((v = (*block)[natural_order[k]]) == 0) { while ((v = (*block)[natural_order[++k]]) == 0) {
arith_encode(cinfo, st + 1, 0); st += 3; k++; arith_encode(cinfo, st + 1, 0);
st += 3;
} }
arith_encode(cinfo, st + 1, 1); arith_encode(cinfo, st + 1, 1);
/* Figure F.6: Encoding nonzero value v */ /* Figure F.6: Encoding nonzero value v */
@ -812,9 +821,9 @@ encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
while (m >>= 1) while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0); arith_encode(cinfo, st, (m & v) ? 1 : 0);
} }
/* Encode EOB decision only if k <= cinfo->lim_Se */ /* Encode EOB decision only if k < cinfo->lim_Se */
if (k <= cinfo->lim_Se) { if (k < cinfo->lim_Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1); st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 1); arith_encode(cinfo, st, 1);
} }
} }
@ -919,7 +928,7 @@ jinit_arith_encoder (j_compress_ptr cinfo)
entropy = (arith_entropy_ptr) entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_encoder)); SIZEOF(arith_entropy_encoder));
cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass; entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass; entropy->pub.finish_pass = finish_pass;

View file

@ -2,6 +2,7 @@
* jccoefct.c * jccoefct.c
* *
* Copyright (C) 1994-1997, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -183,16 +184,16 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
ypos, xpos, (JDIMENSION) blockcnt); ypos, xpos, (JDIMENSION) blockcnt);
if (blockcnt < compptr->MCU_width) { if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */ /* Create some dummy blocks at the right edge of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], FMEMZERO((void FAR *) coef->MCU_buffer[blkn + blockcnt],
(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
for (bi = blockcnt; bi < compptr->MCU_width; bi++) { for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
} }
} }
} else { } else {
/* Create a row of dummy blocks at the bottom of the image. */ /* Create a row of dummy blocks at the bottom of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn], FMEMZERO((void FAR *) coef->MCU_buffer[blkn],
compptr->MCU_width * SIZEOF(JBLOCK)); compptr->MCU_width * SIZEOF(JBLOCK));
for (bi = 0; bi < compptr->MCU_width; bi++) { for (bi = 0; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
} }
@ -290,7 +291,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
if (ndummy > 0) { if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */ /* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */ thisblockrow += blocks_across; /* => first dummy block */
jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK)); FMEMZERO((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
lastDC = thisblockrow[-1][0]; lastDC = thisblockrow[-1][0];
for (bi = 0; bi < ndummy; bi++) { for (bi = 0; bi < ndummy; bi++) {
thisblockrow[bi][0] = lastDC; thisblockrow[bi][0] = lastDC;
@ -309,8 +310,8 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
block_row++) { block_row++) {
thisblockrow = buffer[block_row]; thisblockrow = buffer[block_row];
lastblockrow = buffer[block_row-1]; lastblockrow = buffer[block_row-1];
jzero_far((void FAR *) thisblockrow, FMEMZERO((void FAR *) thisblockrow,
(size_t) (blocks_across * SIZEOF(JBLOCK))); (size_t) (blocks_across * SIZEOF(JBLOCK)));
for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
lastDC = lastblockrow[h_samp_factor-1][0]; lastDC = lastblockrow[h_samp_factor-1][0];
for (bi = 0; bi < h_samp_factor; bi++) { for (bi = 0; bi < h_samp_factor; bi++) {

View file

@ -2,6 +2,7 @@
* jccolor.c * jccolor.c
* *
* Copyright (C) 1991-1996, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -132,8 +133,8 @@ rgb_ycc_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab; register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register JSAMPROW inptr; register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2; register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col; register JDIMENSION col;
@ -149,7 +150,6 @@ rgb_ycc_convert (j_compress_ptr cinfo,
r = GETJSAMPLE(inptr[RGB_RED]); r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]); g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]); b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation. * must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't * Hence the value being shifted is never negative, and we don't
@ -167,6 +167,7 @@ rgb_ycc_convert (j_compress_ptr cinfo,
outptr2[col] = (JSAMPLE) outptr2[col] = (JSAMPLE)
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
>> SCALEBITS); >> SCALEBITS);
inptr += RGB_PIXELSIZE;
} }
} }
} }
@ -188,8 +189,8 @@ rgb_gray_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab; register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register JSAMPROW inptr; register JSAMPROW inptr;
register JSAMPROW outptr; register JSAMPROW outptr;
register JDIMENSION col; register JDIMENSION col;
@ -197,17 +198,16 @@ rgb_gray_convert (j_compress_ptr cinfo,
while (--num_rows >= 0) { while (--num_rows >= 0) {
inptr = *input_buf++; inptr = *input_buf++;
outptr = output_buf[0][output_row]; outptr = output_buf[0][output_row++];
output_row++;
for (col = 0; col < num_cols; col++) { for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr[RGB_RED]); r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]); g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]); b = GETJSAMPLE(inptr[RGB_BLUE]);
inptr += RGB_PIXELSIZE;
/* Y */ /* Y */
outptr[col] = (JSAMPLE) outptr[col] = (JSAMPLE)
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
>> SCALEBITS); >> SCALEBITS);
inptr += RGB_PIXELSIZE;
} }
} }
} }
@ -227,8 +227,8 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_ycc_tab; register INT32 * ctab = cconvert->rgb_ycc_tab;
register int r, g, b;
register JSAMPROW inptr; register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2, outptr3; register JSAMPROW outptr0, outptr1, outptr2, outptr3;
register JDIMENSION col; register JDIMENSION col;
@ -247,7 +247,6 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
b = MAXJSAMPLE - GETJSAMPLE(inptr[2]); b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
/* K passes through as-is */ /* K passes through as-is */
outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */ outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
inptr += 4;
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; we do not need an explicit range-limiting operation. * must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't * Hence the value being shifted is never negative, and we don't
@ -265,6 +264,46 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
outptr2[col] = (JSAMPLE) outptr2[col] = (JSAMPLE)
((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
>> SCALEBITS); >> SCALEBITS);
inptr += 4;
}
}
}
/*
* Convert some rows of samples to the JPEG colorspace.
* [R,G,B] to [R-G,G,B-G] conversion with modulo calculation
* (forward reversible color transform).
*/
METHODDEF(void)
rgb_rgb1_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
register int r, g, b;
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) {
inptr = *input_buf++;
outptr0 = output_buf[0][output_row];
outptr1 = output_buf[1][output_row];
outptr2 = output_buf[2][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr[RGB_RED]);
g = GETJSAMPLE(inptr[RGB_GREEN]);
b = GETJSAMPLE(inptr[RGB_BLUE]);
/* 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;
} }
} }
} }
@ -281,16 +320,15 @@ grayscale_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
int instride = cinfo->input_components;
register JSAMPROW inptr; register JSAMPROW inptr;
register JSAMPROW outptr; register JSAMPROW outptr;
register JDIMENSION col; register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width; JDIMENSION num_cols = cinfo->image_width;
int instride = cinfo->input_components;
while (--num_rows >= 0) { while (--num_rows >= 0) {
inptr = *input_buf++; inptr = *input_buf++;
outptr = output_buf[0][output_row]; outptr = output_buf[0][output_row++];
output_row++;
for (col = 0; col < num_cols; col++) { for (col = 0; col < num_cols; col++) {
outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */ outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
inptr += instride; inptr += instride;
@ -299,6 +337,39 @@ grayscale_convert (j_compress_ptr cinfo,
} }
/*
* Convert some rows of samples to the JPEG colorspace.
* No colorspace conversion, but change from interleaved
* to separate-planes representation.
*/
METHODDEF(void)
rgb_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) {
inptr = *input_buf++;
outptr0 = output_buf[0][output_row];
outptr1 = output_buf[1][output_row];
outptr2 = output_buf[2][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr0[col] = inptr[RGB_RED];
outptr1[col] = inptr[RGB_GREEN];
outptr2[col] = inptr[RGB_BLUE];
inptr += RGB_PIXELSIZE;
}
}
}
/* /*
* Convert some rows of samples to the JPEG colorspace. * Convert some rows of samples to the JPEG colorspace.
* This version handles multi-component colorspaces without conversion. * This version handles multi-component colorspaces without conversion.
@ -310,20 +381,20 @@ null_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
int ci;
register int nc = cinfo->num_components;
register JSAMPROW inptr; register JSAMPROW inptr;
register JSAMPROW outptr; register JSAMPROW outptr;
register JDIMENSION col; register JDIMENSION col;
register int ci;
int nc = cinfo->num_components;
JDIMENSION num_cols = cinfo->image_width; JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) { while (--num_rows >= 0) {
/* It seems fastest to make a separate pass for each component. */ /* It seems fastest to make a separate pass for each component. */
for (ci = 0; ci < nc; ci++) { for (ci = 0; ci < nc; ci++) {
inptr = *input_buf; inptr = input_buf[0] + ci;
outptr = output_buf[ci][output_row]; outptr = output_buf[ci][output_row];
for (col = 0; col < num_cols; col++) { for (col = 0; col < num_cols; col++) {
outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */ *outptr++ = *inptr; /* don't need GETJSAMPLE() here */
inptr += nc; inptr += nc;
} }
} }
@ -356,7 +427,7 @@ jinit_color_converter (j_compress_ptr cinfo)
cconvert = (my_cconvert_ptr) cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_converter)); SIZEOF(my_color_converter));
cinfo->cconvert = (struct jpeg_color_converter *) cconvert; cinfo->cconvert = &cconvert->pub;
/* set start_pass to null method until we find out differently */ /* set start_pass to null method until we find out differently */
cconvert->pub.start_pass = null_method; cconvert->pub.start_pass = null_method;
@ -368,11 +439,9 @@ jinit_color_converter (j_compress_ptr cinfo)
break; break;
case JCS_RGB: case JCS_RGB:
#if RGB_PIXELSIZE != 3
if (cinfo->input_components != RGB_PIXELSIZE) if (cinfo->input_components != RGB_PIXELSIZE)
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break; break;
#endif /* else share code with YCbCr */
case JCS_YCbCr: case JCS_YCbCr:
if (cinfo->input_components != 3) if (cinfo->input_components != 3)
@ -391,28 +460,41 @@ jinit_color_converter (j_compress_ptr cinfo)
break; break;
} }
/* Support color transform only for RGB colorspace */
if (cinfo->color_transform && cinfo->jpeg_color_space != JCS_RGB)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
/* Check num_components, set conversion method based on requested space */ /* Check num_components, set conversion method based on requested space */
switch (cinfo->jpeg_color_space) { switch (cinfo->jpeg_color_space) {
case JCS_GRAYSCALE: case JCS_GRAYSCALE:
if (cinfo->num_components != 1) if (cinfo->num_components != 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_GRAYSCALE) if (cinfo->in_color_space == JCS_GRAYSCALE ||
cinfo->in_color_space == JCS_YCbCr)
cconvert->pub.color_convert = grayscale_convert; cconvert->pub.color_convert = grayscale_convert;
else if (cinfo->in_color_space == JCS_RGB) { else if (cinfo->in_color_space == JCS_RGB) {
cconvert->pub.start_pass = rgb_ycc_start; cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub.color_convert = rgb_gray_convert; cconvert->pub.color_convert = rgb_gray_convert;
} else if (cinfo->in_color_space == JCS_YCbCr) } else
cconvert->pub.color_convert = grayscale_convert;
else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break; break;
case JCS_RGB: case JCS_RGB:
if (cinfo->num_components != 3) if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3) if (cinfo->in_color_space == JCS_RGB) {
cconvert->pub.color_convert = null_convert; switch (cinfo->color_transform) {
else 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;
}
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break; break;

View file

@ -2,6 +2,7 @@
* jcmainct.c * jcmainct.c
* *
* Copyright (C) 1994-1996, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2003-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -68,32 +69,32 @@ METHODDEF(void) process_data_buffer_main
METHODDEF(void) METHODDEF(void)
start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
/* Do nothing in raw-data mode. */ /* Do nothing in raw-data mode. */
if (cinfo->raw_data_in) if (cinfo->raw_data_in)
return; return;
main->cur_iMCU_row = 0; /* initialize counters */ mainp->cur_iMCU_row = 0; /* initialize counters */
main->rowgroup_ctr = 0; mainp->rowgroup_ctr = 0;
main->suspended = FALSE; mainp->suspended = FALSE;
main->pass_mode = pass_mode; /* save mode for use by process_data */ mainp->pass_mode = pass_mode; /* save mode for use by process_data */
switch (pass_mode) { switch (pass_mode) {
case JBUF_PASS_THRU: case JBUF_PASS_THRU:
#ifdef FULL_MAIN_BUFFER_SUPPORTED #ifdef FULL_MAIN_BUFFER_SUPPORTED
if (main->whole_image[0] != NULL) if (mainp->whole_image[0] != NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
#endif #endif
main->pub.process_data = process_data_simple_main; mainp->pub.process_data = process_data_simple_main;
break; break;
#ifdef FULL_MAIN_BUFFER_SUPPORTED #ifdef FULL_MAIN_BUFFER_SUPPORTED
case JBUF_SAVE_SOURCE: case JBUF_SAVE_SOURCE:
case JBUF_CRANK_DEST: case JBUF_CRANK_DEST:
case JBUF_SAVE_AND_PASS: case JBUF_SAVE_AND_PASS:
if (main->whole_image[0] == NULL) if (mainp->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
main->pub.process_data = process_data_buffer_main; mainp->pub.process_data = process_data_buffer_main;
break; break;
#endif #endif
default: default:
@ -114,46 +115,46 @@ process_data_simple_main (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail) JDIMENSION in_rows_avail)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { while (mainp->cur_iMCU_row < cinfo->total_iMCU_rows) {
/* Read input data if we haven't filled the main buffer yet */ /* Read input data if we haven't filled the main buffer yet */
if (main->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size) if (mainp->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
(*cinfo->prep->pre_process_data) (cinfo, (*cinfo->prep->pre_process_data) (cinfo,
input_buf, in_row_ctr, in_rows_avail, input_buf, in_row_ctr, in_rows_avail,
main->buffer, &main->rowgroup_ctr, mainp->buffer, &mainp->rowgroup_ctr,
(JDIMENSION) cinfo->min_DCT_v_scaled_size); (JDIMENSION) cinfo->min_DCT_v_scaled_size);
/* If we don't have a full iMCU row buffered, return to application for /* If we don't have a full iMCU row buffered, return to application for
* more data. Note that preprocessor will always pad to fill the iMCU row * more data. Note that preprocessor will always pad to fill the iMCU row
* at the bottom of the image. * at the bottom of the image.
*/ */
if (main->rowgroup_ctr != (JDIMENSION) cinfo->min_DCT_v_scaled_size) if (mainp->rowgroup_ctr != (JDIMENSION) cinfo->min_DCT_v_scaled_size)
return; return;
/* Send the completed row to the compressor */ /* Send the completed row to the compressor */
if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { if (! (*cinfo->coef->compress_data) (cinfo, mainp->buffer)) {
/* If compressor did not consume the whole row, then we must need to /* If compressor did not consume the whole row, then we must need to
* suspend processing and return to the application. In this situation * suspend processing and return to the application. In this situation
* we pretend we didn't yet consume the last input row; otherwise, if * we pretend we didn't yet consume the last input row; otherwise, if
* it happened to be the last row of the image, the application would * it happened to be the last row of the image, the application would
* think we were done. * think we were done.
*/ */
if (! main->suspended) { if (! mainp->suspended) {
(*in_row_ctr)--; (*in_row_ctr)--;
main->suspended = TRUE; mainp->suspended = TRUE;
} }
return; return;
} }
/* We did finish the row. Undo our little suspension hack if a previous /* We did finish the row. Undo our little suspension hack if a previous
* call suspended; then mark the main buffer empty. * call suspended; then mark the main buffer empty.
*/ */
if (main->suspended) { if (mainp->suspended) {
(*in_row_ctr)++; (*in_row_ctr)++;
main->suspended = FALSE; mainp->suspended = FALSE;
} }
main->rowgroup_ctr = 0; mainp->rowgroup_ctr = 0;
main->cur_iMCU_row++; mainp->cur_iMCU_row++;
} }
} }
@ -170,25 +171,27 @@ process_data_buffer_main (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail) JDIMENSION in_rows_avail)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
int ci; int ci;
jpeg_component_info *compptr; jpeg_component_info *compptr;
boolean writing = (main->pass_mode != JBUF_CRANK_DEST); boolean writing = (mainp->pass_mode != JBUF_CRANK_DEST);
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { while (mainp->cur_iMCU_row < cinfo->total_iMCU_rows) {
/* Realign the virtual buffers if at the start of an iMCU row. */ /* Realign the virtual buffers if at the start of an iMCU row. */
if (main->rowgroup_ctr == 0) { if (mainp->rowgroup_ctr == 0) {
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
main->buffer[ci] = (*cinfo->mem->access_virt_sarray) mainp->buffer[ci] = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, main->whole_image[ci], ((j_common_ptr) cinfo, mainp->whole_image[ci], mainp->cur_iMCU_row *
main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), ((JDIMENSION) (compptr->v_samp_factor * cinfo->min_DCT_v_scaled_size)),
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); (JDIMENSION) (compptr->v_samp_factor * cinfo->min_DCT_v_scaled_size),
writing);
} }
/* In a read pass, pretend we just read some source data. */ /* In a read pass, pretend we just read some source data. */
if (! writing) { if (! writing) {
*in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; *in_row_ctr += (JDIMENSION)
main->rowgroup_ctr = DCTSIZE; (cinfo->max_v_samp_factor * cinfo->min_DCT_v_scaled_size);
mainp->rowgroup_ctr = (JDIMENSION) cinfo->min_DCT_v_scaled_size;
} }
} }
@ -197,40 +200,40 @@ process_data_buffer_main (j_compress_ptr cinfo,
if (writing) { if (writing) {
(*cinfo->prep->pre_process_data) (cinfo, (*cinfo->prep->pre_process_data) (cinfo,
input_buf, in_row_ctr, in_rows_avail, input_buf, in_row_ctr, in_rows_avail,
main->buffer, &main->rowgroup_ctr, mainp->buffer, &mainp->rowgroup_ctr,
(JDIMENSION) DCTSIZE); (JDIMENSION) cinfo->min_DCT_v_scaled_size);
/* Return to application if we need more data to fill the iMCU row. */ /* Return to application if we need more data to fill the iMCU row. */
if (main->rowgroup_ctr < DCTSIZE) if (mainp->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
return; return;
} }
/* Emit data, unless this is a sink-only pass. */ /* Emit data, unless this is a sink-only pass. */
if (main->pass_mode != JBUF_SAVE_SOURCE) { if (mainp->pass_mode != JBUF_SAVE_SOURCE) {
if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { if (! (*cinfo->coef->compress_data) (cinfo, mainp->buffer)) {
/* If compressor did not consume the whole row, then we must need to /* If compressor did not consume the whole row, then we must need to
* suspend processing and return to the application. In this situation * suspend processing and return to the application. In this situation
* we pretend we didn't yet consume the last input row; otherwise, if * we pretend we didn't yet consume the last input row; otherwise, if
* it happened to be the last row of the image, the application would * it happened to be the last row of the image, the application would
* think we were done. * think we were done.
*/ */
if (! main->suspended) { if (! mainp->suspended) {
(*in_row_ctr)--; (*in_row_ctr)--;
main->suspended = TRUE; mainp->suspended = TRUE;
} }
return; return;
} }
/* We did finish the row. Undo our little suspension hack if a previous /* We did finish the row. Undo our little suspension hack if a previous
* call suspended; then mark the main buffer empty. * call suspended; then mark the main buffer empty.
*/ */
if (main->suspended) { if (mainp->suspended) {
(*in_row_ctr)++; (*in_row_ctr)++;
main->suspended = FALSE; mainp->suspended = FALSE;
} }
} }
/* If get here, we are done with this iMCU row. Mark buffer empty. */ /* If get here, we are done with this iMCU row. Mark buffer empty. */
main->rowgroup_ctr = 0; mainp->rowgroup_ctr = 0;
main->cur_iMCU_row++; mainp->cur_iMCU_row++;
} }
} }
@ -244,15 +247,15 @@ process_data_buffer_main (j_compress_ptr cinfo,
GLOBAL(void) GLOBAL(void)
jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{ {
my_main_ptr main; my_main_ptr mainp;
int ci; int ci;
jpeg_component_info *compptr; jpeg_component_info *compptr;
main = (my_main_ptr) mainp = (my_main_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_main_controller)); SIZEOF(my_main_controller));
cinfo->main = (struct jpeg_c_main_controller *) main; cinfo->main = &mainp->pub;
main->pub.start_pass = start_pass_main; mainp->pub.start_pass = start_pass_main;
/* We don't need to create a buffer in raw-data mode. */ /* We don't need to create a buffer in raw-data mode. */
if (cinfo->raw_data_in) if (cinfo->raw_data_in)
@ -267,11 +270,12 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
/* Note we pad the bottom to a multiple of the iMCU height */ /* Note we pad the bottom to a multiple of the iMCU height */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) mainp->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
compptr->width_in_blocks * compptr->DCT_h_scaled_size, compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size),
(JDIMENSION) jround_up((long) compptr->height_in_blocks, ((JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor) * DCTSIZE, (long) compptr->v_samp_factor)) *
((JDIMENSION) cinfo->min_DCT_v_scaled_size),
(JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size)); (JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
} }
#else #else
@ -279,14 +283,14 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
#endif #endif
} else { } else {
#ifdef FULL_MAIN_BUFFER_SUPPORTED #ifdef FULL_MAIN_BUFFER_SUPPORTED
main->whole_image[0] = NULL; /* flag for no virtual arrays */ mainp->whole_image[0] = NULL; /* flag for no virtual arrays */
#endif #endif
/* Allocate a strip buffer for each component */ /* Allocate a strip buffer for each component */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
main->buffer[ci] = (*cinfo->mem->alloc_sarray) mainp->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, ((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * compptr->DCT_h_scaled_size, compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size),
(JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size)); (JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
} }
} }

View file

@ -2,7 +2,7 @@
* jcmarker.c * jcmarker.c
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding. * Modified 2003-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -19,24 +19,24 @@ typedef enum { /* JPEG marker codes */
M_SOF1 = 0xc1, M_SOF1 = 0xc1,
M_SOF2 = 0xc2, M_SOF2 = 0xc2,
M_SOF3 = 0xc3, M_SOF3 = 0xc3,
M_SOF5 = 0xc5, M_SOF5 = 0xc5,
M_SOF6 = 0xc6, M_SOF6 = 0xc6,
M_SOF7 = 0xc7, M_SOF7 = 0xc7,
M_JPG = 0xc8, M_JPG = 0xc8,
M_SOF9 = 0xc9, M_SOF9 = 0xc9,
M_SOF10 = 0xca, M_SOF10 = 0xca,
M_SOF11 = 0xcb, M_SOF11 = 0xcb,
M_SOF13 = 0xcd, M_SOF13 = 0xcd,
M_SOF14 = 0xce, M_SOF14 = 0xce,
M_SOF15 = 0xcf, M_SOF15 = 0xcf,
M_DHT = 0xc4, M_DHT = 0xc4,
M_DAC = 0xcc, M_DAC = 0xcc,
M_RST0 = 0xd0, M_RST0 = 0xd0,
M_RST1 = 0xd1, M_RST1 = 0xd1,
M_RST2 = 0xd2, M_RST2 = 0xd2,
@ -45,7 +45,7 @@ typedef enum { /* JPEG marker codes */
M_RST5 = 0xd5, M_RST5 = 0xd5,
M_RST6 = 0xd6, M_RST6 = 0xd6,
M_RST7 = 0xd7, M_RST7 = 0xd7,
M_SOI = 0xd8, M_SOI = 0xd8,
M_EOI = 0xd9, M_EOI = 0xd9,
M_SOS = 0xda, M_SOS = 0xda,
@ -54,7 +54,7 @@ typedef enum { /* JPEG marker codes */
M_DRI = 0xdd, M_DRI = 0xdd,
M_DHP = 0xde, M_DHP = 0xde,
M_EXP = 0xdf, M_EXP = 0xdf,
M_APP0 = 0xe0, M_APP0 = 0xe0,
M_APP1 = 0xe1, M_APP1 = 0xe1,
M_APP2 = 0xe2, M_APP2 = 0xe2,
@ -71,13 +71,14 @@ typedef enum { /* JPEG marker codes */
M_APP13 = 0xed, M_APP13 = 0xed,
M_APP14 = 0xee, M_APP14 = 0xee,
M_APP15 = 0xef, M_APP15 = 0xef,
M_JPG0 = 0xf0, M_JPG0 = 0xf0,
M_JPG8 = 0xf8,
M_JPG13 = 0xfd, M_JPG13 = 0xfd,
M_COM = 0xfe, M_COM = 0xfe,
M_TEM = 0x01, M_TEM = 0x01,
M_ERROR = 0x100 M_ERROR = 0x100
} JPEG_MARKER; } JPEG_MARKER;
@ -281,6 +282,37 @@ emit_dri (j_compress_ptr cinfo)
} }
LOCAL(void)
emit_lse_ict (j_compress_ptr cinfo)
/* Emit an LSE inverse color transform specification marker */
{
/* Support only 1 transform */
if (cinfo->color_transform != JCT_SUBTRACT_GREEN ||
cinfo->num_components < 3)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
emit_marker(cinfo, M_JPG8);
emit_2bytes(cinfo, 24); /* fixed length */
emit_byte(cinfo, 0x0D); /* ID inverse transform specification */
emit_2bytes(cinfo, MAXJSAMPLE); /* MAXTRANS */
emit_byte(cinfo, 3); /* Nt=3 */
emit_byte(cinfo, cinfo->comp_info[1].component_id);
emit_byte(cinfo, cinfo->comp_info[0].component_id);
emit_byte(cinfo, cinfo->comp_info[2].component_id);
emit_byte(cinfo, 0x80); /* F1: CENTER1=1, NORM1=0 */
emit_2bytes(cinfo, 0); /* A(1,1)=0 */
emit_2bytes(cinfo, 0); /* A(1,2)=0 */
emit_byte(cinfo, 0); /* F2: CENTER2=0, NORM2=0 */
emit_2bytes(cinfo, 1); /* A(2,1)=1 */
emit_2bytes(cinfo, 0); /* A(2,2)=0 */
emit_byte(cinfo, 0); /* F3: CENTER3=0, NORM3=0 */
emit_2bytes(cinfo, 1); /* A(3,1)=1 */
emit_2bytes(cinfo, 0); /* A(3,2)=0 */
}
LOCAL(void) LOCAL(void)
emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
/* Emit a SOF marker */ /* Emit a SOF marker */
@ -502,7 +534,8 @@ write_file_header (j_compress_ptr cinfo)
/* /*
* Write frame header. * Write frame header.
* This consists of DQT and SOFn markers, and a conditional pseudo SOS marker. * This consists of DQT and SOFn markers,
* a conditional LSE marker and a conditional pseudo SOS marker.
* Note that we do not emit the SOF until we have emitted the DQT(s). * Note that we do not emit the SOF until we have emitted the DQT(s).
* This avoids compatibility problems with incorrect implementations that * This avoids compatibility problems with incorrect implementations that
* try to error-check the quant table numbers as soon as they see the SOF. * try to error-check the quant table numbers as soon as they see the SOF.
@ -560,6 +593,10 @@ write_frame_header (j_compress_ptr cinfo)
emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
} }
/* Check to emit LSE inverse color transform specification marker */
if (cinfo->color_transform)
emit_lse_ict(cinfo);
/* Check to emit pseudo SOS marker */ /* Check to emit pseudo SOS marker */
if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE) if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE)
emit_pseudo_sos(cinfo); emit_pseudo_sos(cinfo);
@ -668,7 +705,7 @@ jinit_marker_writer (j_compress_ptr cinfo)
marker = (my_marker_ptr) marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_marker_writer)); SIZEOF(my_marker_writer));
cinfo->marker = (struct jpeg_marker_writer *) marker; cinfo->marker = &marker->pub;
/* Initialize method pointers */ /* Initialize method pointers */
marker->pub.write_file_header = write_file_header; marker->pub.write_file_header = write_file_header;
marker->pub.write_frame_header = write_frame_header; marker->pub.write_frame_header = write_frame_header;

View file

@ -2,7 +2,7 @@
* jcparam.c * jcparam.c
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2008 by Guido Vollbeding. * Modified 2003-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -150,7 +150,7 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables. /* Set or change the 'quality' (quantization) setting, using default tables.
* This is the standard quality-adjusting entry point for typical user * This is the standard quality-adjusting entry point for typical user
* interfaces; only those who want detailed control over quantization tables * interfaces; only those who want detailed control over quantization tables
* would use the preceding three routines directly. * would use the preceding routines directly.
*/ */
{ {
/* Convert user 0-100 rating to percentage scaling */ /* Convert user 0-100 rating to percentage scaling */
@ -367,6 +367,9 @@ jpeg_set_defaults (j_compress_ptr cinfo)
cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
cinfo->Y_density = 1; cinfo->Y_density = 1;
/* No color transform */
cinfo->color_transform = JCT_NONE;
/* Choose JPEG colorspace based on input space, set defaults accordingly */ /* Choose JPEG colorspace based on input space, set defaults accordingly */
jpeg_default_colorspace(cinfo); jpeg_default_colorspace(cinfo);
@ -448,7 +451,9 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */ cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
cinfo->num_components = 3; cinfo->num_components = 3;
SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0); SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0); SET_COMP(1, 0x47 /* 'G' */, 1,1, 0,
cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0,
cinfo->color_transform == JCT_SUBTRACT_GREEN ? 1 : 0);
SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0); SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
break; break;
case JCS_YCbCr: case JCS_YCbCr:

View file

@ -2,7 +2,7 @@
* jctrans.c * jctrans.c
* *
* Copyright (C) 1995-1998, Thomas G. Lane. * Copyright (C) 1995-1998, Thomas G. Lane.
* Modified 2000-2009 by Guido Vollbeding. * Modified 2000-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -85,7 +85,10 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
jpeg_set_defaults(dstinfo); jpeg_set_defaults(dstinfo);
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
* Fix it to get the right header markers for the image colorspace. * Fix it to get the right header markers for the image colorspace.
* Note: Entropy table assignment in jpeg_set_colorspace depends
* on color_transform.
*/ */
dstinfo->color_transform = srcinfo->color_transform;
jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
dstinfo->data_precision = srcinfo->data_precision; dstinfo->data_precision = srcinfo->data_precision;
dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
@ -130,7 +133,7 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
} }
} }
/* Note: we do not copy the source's Huffman table assignments; /* Note: we do not copy the source's entropy table assignments;
* instead we rely on jpeg_set_colorspace to have made a suitable choice. * instead we rely on jpeg_set_colorspace to have made a suitable choice.
*/ */
} }
@ -364,7 +367,7 @@ transencode_coef_controller (j_compress_ptr cinfo,
coef = (my_coef_ptr) coef = (my_coef_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_coef_controller)); SIZEOF(my_coef_controller));
cinfo->coef = (struct jpeg_c_coef_controller *) coef; cinfo->coef = &coef->pub;
coef->pub.start_pass = start_pass_coef; coef->pub.start_pass = start_pass_coef;
coef->pub.compress_data = compress_output; coef->pub.compress_data = compress_output;
@ -375,7 +378,7 @@ transencode_coef_controller (j_compress_ptr cinfo,
buffer = (JBLOCKROW) buffer = (JBLOCKROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); FMEMZERO((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
coef->dummy_buffer[i] = buffer + i; coef->dummy_buffer[i] = buffer + i;
} }

View file

@ -1,7 +1,7 @@
/* /*
* jdarith.c * jdarith.c
* *
* Developed 1997-2009 by Guido Vollbeding. * Developed 1997-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -145,7 +145,7 @@ arith_decode (j_decompress_ptr cinfo, unsigned char *st)
e->a <<= 1; e->a <<= 1;
} }
/* Fetch values from our compact representation of Table D.2: /* Fetch values from our compact representation of Table D.3(D.2):
* Qe values and probability estimation state machine * Qe values and probability estimation state machine
*/ */
sv = *st; sv = *st;
@ -345,12 +345,15 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */ /* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
/* Figure F.20: Decode_AC_coefficients */ /* Figure F.20: Decode_AC_coefficients */
for (k = cinfo->Ss; k <= cinfo->Se; k++) { k = cinfo->Ss - 1;
st = entropy->ac_stats[tbl] + 3 * (k - 1); do {
st = entropy->ac_stats[tbl] + 3 * k;
if (arith_decode(cinfo, st)) break; /* EOB flag */ if (arith_decode(cinfo, st)) break; /* EOB flag */
while (arith_decode(cinfo, st + 1) == 0) { for (;;) {
st += 3; k++; k++;
if (k > cinfo->Se) { if (arith_decode(cinfo, st + 1)) break;
st += 3;
if (k >= cinfo->Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE); WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */ entropy->ct = -1; /* spectral overflow */
return TRUE; return TRUE;
@ -384,7 +387,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
v += 1; if (sign) v = -v; v += 1; if (sign) v = -v;
/* Scale and output coefficient in natural (dezigzagged) order */ /* Scale and output coefficient in natural (dezigzagged) order */
(*block)[natural_order[k]] = (JCOEF) (v << cinfo->Al); (*block)[natural_order[k]] = (JCOEF) (v << cinfo->Al);
} } while (k < cinfo->Se);
return TRUE; return TRUE;
} }
@ -457,15 +460,18 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
/* Establish EOBx (previous stage end-of-block) index */ /* Establish EOBx (previous stage end-of-block) index */
for (kex = cinfo->Se; kex > 0; kex--) kex = cinfo->Se;
do {
if ((*block)[natural_order[kex]]) break; if ((*block)[natural_order[kex]]) break;
} while (--kex);
for (k = cinfo->Ss; k <= cinfo->Se; k++) { k = cinfo->Ss - 1;
st = entropy->ac_stats[tbl] + 3 * (k - 1); do {
if (k > kex) st = entropy->ac_stats[tbl] + 3 * k;
if (k >= kex)
if (arith_decode(cinfo, st)) break; /* EOB flag */ if (arith_decode(cinfo, st)) break; /* EOB flag */
for (;;) { for (;;) {
thiscoef = *block + natural_order[k]; thiscoef = *block + natural_order[++k];
if (*thiscoef) { /* previously nonzero coef */ if (*thiscoef) { /* previously nonzero coef */
if (arith_decode(cinfo, st + 2)) { if (arith_decode(cinfo, st + 2)) {
if (*thiscoef < 0) if (*thiscoef < 0)
@ -482,14 +488,14 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
*thiscoef = p1; *thiscoef = p1;
break; break;
} }
st += 3; k++; st += 3;
if (k > cinfo->Se) { if (k >= cinfo->Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE); WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */ entropy->ct = -1; /* spectral overflow */
return TRUE; return TRUE;
} }
} }
} } while (k < cinfo->Se);
return TRUE; return TRUE;
} }
@ -575,15 +581,19 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */ /* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
if (cinfo->lim_Se == 0) continue;
tbl = compptr->ac_tbl_no; tbl = compptr->ac_tbl_no;
k = 0;
/* Figure F.20: Decode_AC_coefficients */ /* Figure F.20: Decode_AC_coefficients */
for (k = 1; k <= cinfo->lim_Se; k++) { do {
st = entropy->ac_stats[tbl] + 3 * (k - 1); st = entropy->ac_stats[tbl] + 3 * k;
if (arith_decode(cinfo, st)) break; /* EOB flag */ if (arith_decode(cinfo, st)) break; /* EOB flag */
while (arith_decode(cinfo, st + 1) == 0) { for (;;) {
st += 3; k++; k++;
if (k > cinfo->lim_Se) { if (arith_decode(cinfo, st + 1)) break;
st += 3;
if (k >= cinfo->lim_Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE); WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */ entropy->ct = -1; /* spectral overflow */
return TRUE; return TRUE;
@ -616,7 +626,7 @@ decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (arith_decode(cinfo, st)) v |= m; if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v; v += 1; if (sign) v = -v;
(*block)[natural_order[k]] = (JCOEF) v; (*block)[natural_order[k]] = (JCOEF) v;
} } while (k < cinfo->lim_Se);
} }
return TRUE; return TRUE;
@ -746,7 +756,7 @@ jinit_arith_decoder (j_decompress_ptr cinfo)
entropy = (arith_entropy_ptr) entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_decoder)); SIZEOF(arith_entropy_decoder));
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass; entropy->pub.start_pass = start_pass;
/* Mark tables unallocated */ /* Mark tables unallocated */

View file

@ -2,7 +2,7 @@
* jdatadst.c * jdatadst.c
* *
* Copyright (C) 1994-1996, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding. * Modified 2009-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -128,7 +128,7 @@ empty_mem_output_buffer (j_compress_ptr cinfo)
/* Try to allocate new buffer with double size */ /* Try to allocate new buffer with double size */
nextsize = dest->bufsize * 2; nextsize = dest->bufsize * 2;
nextbuffer = malloc(nextsize); nextbuffer = (JOCTET *) malloc(nextsize);
if (nextbuffer == NULL) if (nextbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
@ -226,6 +226,9 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
* larger memory, so the buffer is available to the application after * larger memory, so the buffer is available to the application after
* finishing compression, and then the application is responsible for * finishing compression, and then the application is responsible for
* freeing the requested memory. * freeing the requested memory.
* Note: An initial buffer supplied by the caller is expected to be
* managed by the application. The library does not free such buffer
* when allocating a larger buffer.
*/ */
GLOBAL(void) GLOBAL(void)
@ -256,7 +259,7 @@ jpeg_mem_dest (j_compress_ptr cinfo,
if (*outbuffer == NULL || *outsize == 0) { if (*outbuffer == NULL || *outsize == 0) {
/* Allocate initial buffer */ /* Allocate initial buffer */
dest->newbuffer = *outbuffer = malloc(OUTPUT_BUF_SIZE); dest->newbuffer = *outbuffer = (unsigned char *) malloc(OUTPUT_BUF_SIZE);
if (dest->newbuffer == NULL) if (dest->newbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
*outsize = OUTPUT_BUF_SIZE; *outsize = OUTPUT_BUF_SIZE;

View file

@ -2,7 +2,7 @@
* jdatasrc.c * jdatasrc.c
* *
* Copyright (C) 1994-1996, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2010 by Guido Vollbeding. * Modified 2009-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -121,16 +121,17 @@ fill_input_buffer (j_decompress_ptr cinfo)
METHODDEF(boolean) METHODDEF(boolean)
fill_mem_input_buffer (j_decompress_ptr cinfo) fill_mem_input_buffer (j_decompress_ptr cinfo)
{ {
static JOCTET mybuffer[4]; static const JOCTET mybuffer[4] = {
(JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
};
/* The whole JPEG data is expected to reside in the supplied memory /* The whole JPEG data is expected to reside in the supplied memory
* buffer, so any request for more data beyond the given buffer size * buffer, so any request for more data beyond the given buffer size
* is treated as an error. * is treated as an error.
*/ */
WARNMS(cinfo, JWRN_JPEG_EOF); WARNMS(cinfo, JWRN_JPEG_EOF);
/* Insert a fake EOI marker */ /* Insert a fake EOI marker */
mybuffer[0] = (JOCTET) 0xFF;
mybuffer[1] = (JOCTET) JPEG_EOI;
cinfo->src->next_input_byte = mybuffer; cinfo->src->next_input_byte = mybuffer;
cinfo->src->bytes_in_buffer = 2; cinfo->src->bytes_in_buffer = 2;

View file

@ -2,6 +2,7 @@
* jdcoefct.c * jdcoefct.c
* *
* Copyright (C) 1994-1997, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2002-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -162,8 +163,9 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
MCU_col_num++) { MCU_col_num++) {
/* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
jzero_far((void FAR *) coef->MCU_buffer[0], if (cinfo->lim_Se) /* can bypass in DC only case */
(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); FMEMZERO((void FAR *) coef->MCU_buffer[0],
(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
/* Suspension forced; update state counters and exit */ /* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset; coef->MCU_vert_offset = yoffset;
@ -729,6 +731,9 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
coef->MCU_buffer[i] = buffer + i; coef->MCU_buffer[i] = buffer + i;
} }
if (cinfo->lim_Se == 0) /* DC only case: want to bypass later */
FMEMZERO((void FAR *) buffer,
(size_t) (D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)));
coef->pub.consume_data = dummy_consume_data; coef->pub.consume_data = dummy_consume_data;
coef->pub.decompress_data = decompress_onepass; coef->pub.decompress_data = decompress_onepass;
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */

View file

@ -2,6 +2,7 @@
* jdcolor.c * jdcolor.c
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -23,20 +24,28 @@ typedef struct {
int * Cb_b_tab; /* => table for Cb to B conversion */ int * Cb_b_tab; /* => table for Cb to B conversion */
INT32 * Cr_g_tab; /* => table for Cr to G conversion */ INT32 * Cr_g_tab; /* => table for Cr to G conversion */
INT32 * Cb_g_tab; /* => table for Cb to G conversion */ INT32 * Cb_g_tab; /* => table for Cb to G conversion */
/* Private state for RGB->Y conversion */
INT32 * rgb_y_tab; /* => table for RGB to Y conversion */
} my_color_deconverter; } my_color_deconverter;
typedef my_color_deconverter * my_cconvert_ptr; typedef my_color_deconverter * my_cconvert_ptr;
/**************** YCbCr -> RGB conversion: most common case **************/ /**************** YCbCr -> RGB conversion: most common case **************/
/**************** RGB -> Y conversion: less common case **************/
/* /*
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
* The conversion equations to be implemented are therefore * The conversion equations to be implemented are therefore
*
* R = Y + 1.40200 * Cr * R = Y + 1.40200 * Cr
* G = Y - 0.34414 * Cb - 0.71414 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr
* B = Y + 1.77200 * Cb * B = Y + 1.77200 * Cb
*
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
*
* where Cb and Cr represent the incoming values less CENTERJSAMPLE. * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
* *
@ -61,6 +70,18 @@ typedef my_color_deconverter * my_cconvert_ptr;
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
/* We allocate one big table for RGB->Y conversion and divide it up into
* three parts, instead of doing three alloc_small requests. This lets us
* use a single table base address, which can be held in a register in the
* inner loops on many machines (more than can hold all three addresses,
* anyway).
*/
#define R_Y_OFF 0 /* offset to R => Y section */
#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
#define TABLE_SIZE (3*(MAXJSAMPLE+1))
/* /*
* Initialize tables for YCC->RGB colorspace conversion. * Initialize tables for YCC->RGB colorspace conversion.
@ -160,6 +181,178 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
/**************** Cases other than YCbCr -> RGB **************/ /**************** Cases other than YCbCr -> RGB **************/
/*
* Initialize for RGB->grayscale colorspace conversion.
*/
LOCAL(void)
build_rgb_y_table (j_decompress_ptr cinfo)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
INT32 * rgb_y_tab;
INT32 i;
/* Allocate and fill in the conversion tables. */
cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(TABLE_SIZE * SIZEOF(INT32)));
for (i = 0; i <= MAXJSAMPLE; i++) {
rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i;
rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;
rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
}
}
/*
* Convert RGB to grayscale.
*/
METHODDEF(void)
rgb_gray_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
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 JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr0[col]);
g = GETJSAMPLE(inptr1[col]);
b = GETJSAMPLE(inptr2[col]);
/* Y */
outptr[col] = (JSAMPLE)
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
>> SCALEBITS);
}
}
}
/*
* [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
* (inverse color transform).
*/
METHODDEF(void)
rgb1_rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register int r, g, b;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr0[col]);
g = GETJSAMPLE(inptr1[col]);
b = GETJSAMPLE(inptr2[col]);
/* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
* (modulo) operator is equivalent to the bitmask operator AND.
*/
outptr[RGB_RED] = (JSAMPLE) ((r + g - CENTERJSAMPLE) & MAXJSAMPLE);
outptr[RGB_GREEN] = (JSAMPLE) g;
outptr[RGB_BLUE] = (JSAMPLE) ((b + g - CENTERJSAMPLE) & MAXJSAMPLE);
outptr += RGB_PIXELSIZE;
}
}
}
/*
* [R-G,G,B-G] to grayscale conversion with modulo calculation
* (inverse color transform).
*/
METHODDEF(void)
rgb1_gray_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
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 JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr0[col]);
g = GETJSAMPLE(inptr1[col]);
b = GETJSAMPLE(inptr2[col]);
/* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
* (modulo) operator is equivalent to the bitmask operator AND.
*/
r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE;
b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE;
/* Y */
outptr[col] = (JSAMPLE)
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
>> SCALEBITS);
}
}
}
/*
* No colorspace change, but conversion from separate-planes
* to interleaved representation.
*/
METHODDEF(void)
rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr[RGB_RED] = inptr0[col];
outptr[RGB_GREEN] = inptr1[col];
outptr[RGB_BLUE] = inptr2[col];
outptr += RGB_PIXELSIZE;
}
}
}
/* /*
* Color conversion for no colorspace change: just copy the data, * Color conversion for no colorspace change: just copy the data,
* converting from separate-planes to interleaved representation. * converting from separate-planes to interleaved representation.
@ -170,19 +363,20 @@ null_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
{ {
register JSAMPROW inptr, outptr;
register JDIMENSION count;
register int num_components = cinfo->num_components;
JDIMENSION num_cols = cinfo->output_width;
int ci; int ci;
register int nc = cinfo->num_components;
register JSAMPROW outptr;
register JSAMPROW inptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) { while (--num_rows >= 0) {
for (ci = 0; ci < num_components; ci++) { for (ci = 0; ci < nc; ci++) {
inptr = input_buf[ci][input_row]; inptr = input_buf[ci][input_row];
outptr = output_buf[0] + ci; outptr = output_buf[0] + ci;
for (count = num_cols; count > 0; count--) { for (col = 0; col < num_cols; col++) {
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
outptr += num_components; outptr += nc;
} }
} }
input_row++; input_row++;
@ -218,7 +412,8 @@ gray_rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row, JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows) JSAMPARRAY output_buf, int num_rows)
{ {
register JSAMPROW inptr, outptr; register JSAMPROW outptr;
register JSAMPROW inptr;
register JDIMENSION col; register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width; JDIMENSION num_cols = cinfo->output_width;
@ -309,7 +504,7 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
cconvert = (my_cconvert_ptr) cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_deconverter)); SIZEOF(my_color_deconverter));
cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; cinfo->cconvert = &cconvert->pub;
cconvert->pub.start_pass = start_pass_dcolor; cconvert->pub.start_pass = start_pass_dcolor;
/* Make sure num_components agrees with jpeg_color_space */ /* Make sure num_components agrees with jpeg_color_space */
@ -337,6 +532,10 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
break; break;
} }
/* Support color transform only for RGB colorspace */
if (cinfo->color_transform && cinfo->jpeg_color_space != JCS_RGB)
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
/* Set out_color_components and conversion method based on requested space. /* Set out_color_components and conversion method based on requested space.
* Also clear the component_needed flags for any unused components, * Also clear the component_needed flags for any unused components,
* so that earlier pipeline stages can avoid useless computation. * so that earlier pipeline stages can avoid useless computation.
@ -351,6 +550,19 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
/* For color->grayscale conversion, only the Y (0) component is needed */ /* For color->grayscale conversion, only the Y (0) component is needed */
for (ci = 1; ci < cinfo->num_components; ci++) for (ci = 1; ci < cinfo->num_components; ci++)
cinfo->comp_info[ci].component_needed = FALSE; cinfo->comp_info[ci].component_needed = FALSE;
} else if (cinfo->jpeg_color_space == JCS_RGB) {
switch (cinfo->color_transform) {
case JCT_NONE:
cconvert->pub.color_convert = rgb_gray_convert;
break;
case JCT_SUBTRACT_GREEN:
cconvert->pub.color_convert = rgb1_gray_convert;
break;
default:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
}
build_rgb_y_table(cinfo);
} else } else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break; break;
@ -362,8 +574,18 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
build_ycc_rgb_table(cinfo); build_ycc_rgb_table(cinfo);
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
cconvert->pub.color_convert = gray_rgb_convert; cconvert->pub.color_convert = gray_rgb_convert;
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) { } else if (cinfo->jpeg_color_space == JCS_RGB) {
cconvert->pub.color_convert = null_convert; 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;
}
} else } else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break; break;

View file

@ -2,7 +2,7 @@
* jdhuff.c * jdhuff.c
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2006-2009 by Guido Vollbeding. * Modified 2006-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -797,7 +797,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* There is always only one block per MCU */ /* There is always only one block per MCU */
if (EOBRUN > 0) /* if it's a band of zeroes... */ if (EOBRUN) /* if it's a band of zeroes... */
EOBRUN--; /* ...process it now (we do nothing) */ EOBRUN--; /* ...process it now (we do nothing) */
else { else {
BITREAD_LOAD_STATE(cinfo,entropy->bitstate); BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
@ -816,18 +816,17 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Scale and output coefficient in natural (dezigzagged) order */ /* Scale and output coefficient in natural (dezigzagged) order */
(*block)[natural_order[k]] = (JCOEF) (s << Al); (*block)[natural_order[k]] = (JCOEF) (s << Al);
} else { } else {
if (r == 15) { /* ZRL */ if (r != 15) { /* EOBr, run length is 2^r + appended bits */
k += 15; /* skip 15 zeroes in band */
} else { /* EOBr, run length is 2^r + appended bits */
EOBRUN = 1 << r;
if (r) { /* EOBr, r > 0 */ if (r) { /* EOBr, r > 0 */
EOBRUN = 1 << r;
CHECK_BIT_BUFFER(br_state, r, return FALSE); CHECK_BIT_BUFFER(br_state, r, return FALSE);
r = GET_BITS(r); r = GET_BITS(r);
EOBRUN += r; EOBRUN += r;
EOBRUN--; /* this band is processed at this moment */
} }
EOBRUN--; /* this band is processed at this moment */
break; /* force end-of-band */ break; /* force end-of-band */
} }
k += 15; /* ZRL: skip 15 zeroes in band */
} }
} }
@ -951,7 +950,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
k = cinfo->Ss; k = cinfo->Ss;
if (EOBRUN == 0) { if (EOBRUN == 0) {
for (; k <= Se; k++) { do {
HUFF_DECODE(s, br_state, tbl, goto undoit, label3); HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
r = s >> 4; r = s >> 4;
s &= 15; s &= 15;
@ -981,7 +980,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
*/ */
do { do {
thiscoef = *block + natural_order[k]; thiscoef = *block + natural_order[k];
if (*thiscoef != 0) { if (*thiscoef) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit); CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1)) { if (GET_BITS(1)) {
if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
@ -1004,18 +1003,19 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
/* Remember its position in case we have to suspend */ /* Remember its position in case we have to suspend */
newnz_pos[num_newnz++] = pos; newnz_pos[num_newnz++] = pos;
} }
} k++;
} while (k <= Se);
} }
if (EOBRUN > 0) { if (EOBRUN) {
/* Scan any remaining coefficient positions after the end-of-band /* Scan any remaining coefficient positions after the end-of-band
* (the last newly nonzero coefficient, if any). Append a correction * (the last newly nonzero coefficient, if any). Append a correction
* bit to each already-nonzero coefficient. A correction bit is 1 * bit to each already-nonzero coefficient. A correction bit is 1
* if the absolute value of the coefficient must be increased. * if the absolute value of the coefficient must be increased.
*/ */
for (; k <= Se; k++) { do {
thiscoef = *block + natural_order[k]; thiscoef = *block + natural_order[k];
if (*thiscoef != 0) { if (*thiscoef) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit); CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1)) { if (GET_BITS(1)) {
if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
@ -1026,7 +1026,8 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
} }
} }
} }
} k++;
} while (k <= Se);
/* Count one block completed in EOB run */ /* Count one block completed in EOB run */
EOBRUN--; EOBRUN--;
} }
@ -1043,7 +1044,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
undoit: undoit:
/* Re-zero any output coefficients that we made newly nonzero */ /* Re-zero any output coefficients that we made newly nonzero */
while (num_newnz > 0) while (num_newnz)
(*block)[newnz_pos[--num_newnz]] = 0; (*block)[newnz_pos[--num_newnz]] = 0;
return FALSE; return FALSE;
@ -1514,7 +1515,7 @@ jinit_huff_decoder (j_decompress_ptr cinfo)
entropy = (huff_entropy_ptr) entropy = (huff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(huff_entropy_decoder)); SIZEOF(huff_entropy_decoder));
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; cinfo->entropy = &entropy->pub;
entropy->pub.start_pass = start_pass_huff_decoder; entropy->pub.start_pass = start_pass_huff_decoder;
if (cinfo->progressive_mode) { if (cinfo->progressive_mode) {

View file

@ -2,6 +2,7 @@
* jdmainct.c * jdmainct.c
* *
* Copyright (C) 1994-1996, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2002-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -159,7 +160,7 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
* This is done only once, not once per pass. * This is done only once, not once per pass.
*/ */
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
int ci, rgroup; int ci, rgroup;
int M = cinfo->min_DCT_v_scaled_size; int M = cinfo->min_DCT_v_scaled_size;
jpeg_component_info *compptr; jpeg_component_info *compptr;
@ -168,10 +169,10 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
/* Get top-level space for component array pointers. /* Get top-level space for component array pointers.
* We alloc both arrays with one call to save a few cycles. * We alloc both arrays with one call to save a few cycles.
*/ */
main->xbuffer[0] = (JSAMPIMAGE) mainp->xbuffer[0] = (JSAMPIMAGE)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components; mainp->xbuffer[1] = mainp->xbuffer[0] + cinfo->num_components;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
@ -184,9 +185,9 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
xbuf += rgroup; /* want one row group at negative offsets */ xbuf += rgroup; /* want one row group at negative offsets */
main->xbuffer[0][ci] = xbuf; mainp->xbuffer[0][ci] = xbuf;
xbuf += rgroup * (M + 4); xbuf += rgroup * (M + 4);
main->xbuffer[1][ci] = xbuf; mainp->xbuffer[1][ci] = xbuf;
} }
} }
@ -200,7 +201,7 @@ make_funny_pointers (j_decompress_ptr cinfo)
* This will be repeated at the beginning of each pass. * This will be repeated at the beginning of each pass.
*/ */
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
int ci, i, rgroup; int ci, i, rgroup;
int M = cinfo->min_DCT_v_scaled_size; int M = cinfo->min_DCT_v_scaled_size;
jpeg_component_info *compptr; jpeg_component_info *compptr;
@ -210,10 +211,10 @@ make_funny_pointers (j_decompress_ptr cinfo)
ci++, compptr++) { ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
xbuf0 = main->xbuffer[0][ci]; xbuf0 = mainp->xbuffer[0][ci];
xbuf1 = main->xbuffer[1][ci]; xbuf1 = mainp->xbuffer[1][ci];
/* First copy the workspace pointers as-is */ /* First copy the workspace pointers as-is */
buf = main->buffer[ci]; buf = mainp->buffer[ci];
for (i = 0; i < rgroup * (M + 2); i++) { for (i = 0; i < rgroup * (M + 2); i++) {
xbuf0[i] = xbuf1[i] = buf[i]; xbuf0[i] = xbuf1[i] = buf[i];
} }
@ -240,7 +241,7 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
* This changes the pointer list state from top-of-image to the normal state. * This changes the pointer list state from top-of-image to the normal state.
*/ */
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
int ci, i, rgroup; int ci, i, rgroup;
int M = cinfo->min_DCT_v_scaled_size; int M = cinfo->min_DCT_v_scaled_size;
jpeg_component_info *compptr; jpeg_component_info *compptr;
@ -250,8 +251,8 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
ci++, compptr++) { ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
xbuf0 = main->xbuffer[0][ci]; xbuf0 = mainp->xbuffer[0][ci];
xbuf1 = main->xbuffer[1][ci]; xbuf1 = mainp->xbuffer[1][ci];
for (i = 0; i < rgroup; i++) { for (i = 0; i < rgroup; i++) {
xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
@ -269,7 +270,7 @@ set_bottom_pointers (j_decompress_ptr cinfo)
* Also sets rowgroups_avail to indicate number of nondummy row groups in row. * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
*/ */
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
int ci, i, rgroup, iMCUheight, rows_left; int ci, i, rgroup, iMCUheight, rows_left;
jpeg_component_info *compptr; jpeg_component_info *compptr;
JSAMPARRAY xbuf; JSAMPARRAY xbuf;
@ -286,12 +287,12 @@ set_bottom_pointers (j_decompress_ptr cinfo)
* so we need only do it once. * so we need only do it once.
*/ */
if (ci == 0) { if (ci == 0) {
main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); mainp->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
} }
/* Duplicate the last real sample row rgroup*2 times; this pads out the /* Duplicate the last real sample row rgroup*2 times; this pads out the
* last partial rowgroup and ensures at least one full rowgroup of context. * last partial rowgroup and ensures at least one full rowgroup of context.
*/ */
xbuf = main->xbuffer[main->whichptr][ci]; xbuf = mainp->xbuffer[mainp->whichptr][ci];
for (i = 0; i < rgroup * 2; i++) { for (i = 0; i < rgroup * 2; i++) {
xbuf[rows_left + i] = xbuf[rows_left-1]; xbuf[rows_left + i] = xbuf[rows_left-1];
} }
@ -306,27 +307,27 @@ set_bottom_pointers (j_decompress_ptr cinfo)
METHODDEF(void) METHODDEF(void)
start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
switch (pass_mode) { switch (pass_mode) {
case JBUF_PASS_THRU: case JBUF_PASS_THRU:
if (cinfo->upsample->need_context_rows) { if (cinfo->upsample->need_context_rows) {
main->pub.process_data = process_data_context_main; mainp->pub.process_data = process_data_context_main;
make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ mainp->whichptr = 0; /* Read first iMCU row into xbuffer[0] */
main->context_state = CTX_PREPARE_FOR_IMCU; mainp->context_state = CTX_PREPARE_FOR_IMCU;
main->iMCU_row_ctr = 0; mainp->iMCU_row_ctr = 0;
} else { } else {
/* Simple case with no context needed */ /* Simple case with no context needed */
main->pub.process_data = process_data_simple_main; mainp->pub.process_data = process_data_simple_main;
} }
main->buffer_full = FALSE; /* Mark buffer empty */ mainp->buffer_full = FALSE; /* Mark buffer empty */
main->rowgroup_ctr = 0; mainp->rowgroup_ctr = 0;
break; break;
#ifdef QUANT_2PASS_SUPPORTED #ifdef QUANT_2PASS_SUPPORTED
case JBUF_CRANK_DEST: case JBUF_CRANK_DEST:
/* For last pass of 2-pass quantization, just crank the postprocessor */ /* For last pass of 2-pass quantization, just crank the postprocessor */
main->pub.process_data = process_data_crank_post; mainp->pub.process_data = process_data_crank_post;
break; break;
#endif #endif
default: default:
@ -346,14 +347,14 @@ process_data_simple_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail) JDIMENSION out_rows_avail)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
JDIMENSION rowgroups_avail; JDIMENSION rowgroups_avail;
/* Read input data if we haven't filled the main buffer yet */ /* Read input data if we haven't filled the main buffer yet */
if (! main->buffer_full) { if (! mainp->buffer_full) {
if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer)) if (! (*cinfo->coef->decompress_data) (cinfo, mainp->buffer))
return; /* suspension forced, can do nothing more */ return; /* suspension forced, can do nothing more */
main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ mainp->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
} }
/* There are always min_DCT_scaled_size row groups in an iMCU row. */ /* There are always min_DCT_scaled_size row groups in an iMCU row. */
@ -364,14 +365,14 @@ process_data_simple_main (j_decompress_ptr cinfo,
*/ */
/* Feed the postprocessor */ /* Feed the postprocessor */
(*cinfo->post->post_process_data) (cinfo, main->buffer, (*cinfo->post->post_process_data) (cinfo, mainp->buffer,
&main->rowgroup_ctr, rowgroups_avail, &mainp->rowgroup_ctr, rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail); output_buf, out_row_ctr, out_rows_avail);
/* Has postprocessor consumed all the data yet? If so, mark buffer empty */ /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
if (main->rowgroup_ctr >= rowgroups_avail) { if (mainp->rowgroup_ctr >= rowgroups_avail) {
main->buffer_full = FALSE; mainp->buffer_full = FALSE;
main->rowgroup_ctr = 0; mainp->rowgroup_ctr = 0;
} }
} }
@ -386,15 +387,15 @@ process_data_context_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail) JDIMENSION out_rows_avail)
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr mainp = (my_main_ptr) cinfo->main;
/* Read input data if we haven't filled the main buffer yet */ /* Read input data if we haven't filled the main buffer yet */
if (! main->buffer_full) { if (! mainp->buffer_full) {
if (! (*cinfo->coef->decompress_data) (cinfo, if (! (*cinfo->coef->decompress_data) (cinfo,
main->xbuffer[main->whichptr])) mainp->xbuffer[mainp->whichptr]))
return; /* suspension forced, can do nothing more */ return; /* suspension forced, can do nothing more */
main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ mainp->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
main->iMCU_row_ctr++; /* count rows received */ mainp->iMCU_row_ctr++; /* count rows received */
} }
/* Postprocessor typically will not swallow all the input data it is handed /* Postprocessor typically will not swallow all the input data it is handed
@ -402,47 +403,47 @@ process_data_context_main (j_decompress_ptr cinfo,
* to exit and restart. This switch lets us keep track of how far we got. * to exit and restart. This switch lets us keep track of how far we got.
* Note that each case falls through to the next on successful completion. * Note that each case falls through to the next on successful completion.
*/ */
switch (main->context_state) { switch (mainp->context_state) {
case CTX_POSTPONED_ROW: case CTX_POSTPONED_ROW:
/* Call postprocessor using previously set pointers for postponed row */ /* Call postprocessor using previously set pointers for postponed row */
(*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
&main->rowgroup_ctr, main->rowgroups_avail, &mainp->rowgroup_ctr, mainp->rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail); output_buf, out_row_ctr, out_rows_avail);
if (main->rowgroup_ctr < main->rowgroups_avail) if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
return; /* Need to suspend */ return; /* Need to suspend */
main->context_state = CTX_PREPARE_FOR_IMCU; mainp->context_state = CTX_PREPARE_FOR_IMCU;
if (*out_row_ctr >= out_rows_avail) if (*out_row_ctr >= out_rows_avail)
return; /* Postprocessor exactly filled output buf */ return; /* Postprocessor exactly filled output buf */
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case CTX_PREPARE_FOR_IMCU: case CTX_PREPARE_FOR_IMCU:
/* Prepare to process first M-1 row groups of this iMCU row */ /* Prepare to process first M-1 row groups of this iMCU row */
main->rowgroup_ctr = 0; mainp->rowgroup_ctr = 0;
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1); mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1);
/* Check for bottom of image: if so, tweak pointers to "duplicate" /* Check for bottom of image: if so, tweak pointers to "duplicate"
* the last sample row, and adjust rowgroups_avail to ignore padding rows. * the last sample row, and adjust rowgroups_avail to ignore padding rows.
*/ */
if (main->iMCU_row_ctr == cinfo->total_iMCU_rows) if (mainp->iMCU_row_ctr == cinfo->total_iMCU_rows)
set_bottom_pointers(cinfo); set_bottom_pointers(cinfo);
main->context_state = CTX_PROCESS_IMCU; mainp->context_state = CTX_PROCESS_IMCU;
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case CTX_PROCESS_IMCU: case CTX_PROCESS_IMCU:
/* Call postprocessor using previously set pointers */ /* Call postprocessor using previously set pointers */
(*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
&main->rowgroup_ctr, main->rowgroups_avail, &mainp->rowgroup_ctr, mainp->rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail); output_buf, out_row_ctr, out_rows_avail);
if (main->rowgroup_ctr < main->rowgroups_avail) if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
return; /* Need to suspend */ return; /* Need to suspend */
/* After the first iMCU, change wraparound pointers to normal state */ /* After the first iMCU, change wraparound pointers to normal state */
if (main->iMCU_row_ctr == 1) if (mainp->iMCU_row_ctr == 1)
set_wraparound_pointers(cinfo); set_wraparound_pointers(cinfo);
/* Prepare to load new iMCU row using other xbuffer list */ /* Prepare to load new iMCU row using other xbuffer list */
main->whichptr ^= 1; /* 0=>1 or 1=>0 */ mainp->whichptr ^= 1; /* 0=>1 or 1=>0 */
main->buffer_full = FALSE; mainp->buffer_full = FALSE;
/* Still need to process last row group of this iMCU row, */ /* Still need to process last row group of this iMCU row, */
/* which is saved at index M+1 of the other xbuffer */ /* which is saved at index M+1 of the other xbuffer */
main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1); mainp->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1);
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2); mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2);
main->context_state = CTX_POSTPONED_ROW; mainp->context_state = CTX_POSTPONED_ROW;
} }
} }
@ -475,15 +476,15 @@ process_data_crank_post (j_decompress_ptr cinfo,
GLOBAL(void) GLOBAL(void)
jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{ {
my_main_ptr main; my_main_ptr mainp;
int ci, rgroup, ngroups; int ci, rgroup, ngroups;
jpeg_component_info *compptr; jpeg_component_info *compptr;
main = (my_main_ptr) mainp = (my_main_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_main_controller)); SIZEOF(my_main_controller));
cinfo->main = (struct jpeg_d_main_controller *) main; cinfo->main = &mainp->pub;
main->pub.start_pass = start_pass_main; mainp->pub.start_pass = start_pass_main;
if (need_full_buffer) /* shouldn't happen */ if (need_full_buffer) /* shouldn't happen */
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
@ -504,9 +505,9 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
ci++, compptr++) { ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
main->buffer[ci] = (*cinfo->mem->alloc_sarray) mainp->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, ((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * compptr->DCT_h_scaled_size, compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size),
(JDIMENSION) (rgroup * ngroups)); (JDIMENSION) (rgroup * ngroups));
} }
} }

View file

@ -2,7 +2,7 @@
* jdmarker.c * jdmarker.c
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding. * Modified 2009-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -23,24 +23,24 @@ typedef enum { /* JPEG marker codes */
M_SOF1 = 0xc1, M_SOF1 = 0xc1,
M_SOF2 = 0xc2, M_SOF2 = 0xc2,
M_SOF3 = 0xc3, M_SOF3 = 0xc3,
M_SOF5 = 0xc5, M_SOF5 = 0xc5,
M_SOF6 = 0xc6, M_SOF6 = 0xc6,
M_SOF7 = 0xc7, M_SOF7 = 0xc7,
M_JPG = 0xc8, M_JPG = 0xc8,
M_SOF9 = 0xc9, M_SOF9 = 0xc9,
M_SOF10 = 0xca, M_SOF10 = 0xca,
M_SOF11 = 0xcb, M_SOF11 = 0xcb,
M_SOF13 = 0xcd, M_SOF13 = 0xcd,
M_SOF14 = 0xce, M_SOF14 = 0xce,
M_SOF15 = 0xcf, M_SOF15 = 0xcf,
M_DHT = 0xc4, M_DHT = 0xc4,
M_DAC = 0xcc, M_DAC = 0xcc,
M_RST0 = 0xd0, M_RST0 = 0xd0,
M_RST1 = 0xd1, M_RST1 = 0xd1,
M_RST2 = 0xd2, M_RST2 = 0xd2,
@ -49,7 +49,7 @@ typedef enum { /* JPEG marker codes */
M_RST5 = 0xd5, M_RST5 = 0xd5,
M_RST6 = 0xd6, M_RST6 = 0xd6,
M_RST7 = 0xd7, M_RST7 = 0xd7,
M_SOI = 0xd8, M_SOI = 0xd8,
M_EOI = 0xd9, M_EOI = 0xd9,
M_SOS = 0xda, M_SOS = 0xda,
@ -58,7 +58,7 @@ typedef enum { /* JPEG marker codes */
M_DRI = 0xdd, M_DRI = 0xdd,
M_DHP = 0xde, M_DHP = 0xde,
M_EXP = 0xdf, M_EXP = 0xdf,
M_APP0 = 0xe0, M_APP0 = 0xe0,
M_APP1 = 0xe1, M_APP1 = 0xe1,
M_APP2 = 0xe2, M_APP2 = 0xe2,
@ -75,13 +75,14 @@ typedef enum { /* JPEG marker codes */
M_APP13 = 0xed, M_APP13 = 0xed,
M_APP14 = 0xee, M_APP14 = 0xee,
M_APP15 = 0xef, M_APP15 = 0xef,
M_JPG0 = 0xf0, M_JPG0 = 0xf0,
M_JPG8 = 0xf8,
M_JPG13 = 0xfd, M_JPG13 = 0xfd,
M_COM = 0xfe, M_COM = 0xfe,
M_TEM = 0x01, M_TEM = 0x01,
M_ERROR = 0x100 M_ERROR = 0x100
} JPEG_MARKER; } JPEG_MARKER;
@ -217,6 +218,7 @@ get_soi (j_decompress_ptr cinfo)
/* Set initial assumptions for colorspace etc */ /* Set initial assumptions for colorspace etc */
cinfo->jpeg_color_space = JCS_UNKNOWN; cinfo->jpeg_color_space = JCS_UNKNOWN;
cinfo->color_transform = JCT_NONE;
cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
cinfo->saw_JFIF_marker = FALSE; cinfo->saw_JFIF_marker = FALSE;
@ -240,7 +242,7 @@ get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog,
/* Process a SOFn marker */ /* Process a SOFn marker */
{ {
INT32 length; INT32 length;
int c, ci; int c, ci, i;
jpeg_component_info * compptr; jpeg_component_info * compptr;
INPUT_VARS(cinfo); INPUT_VARS(cinfo);
@ -278,11 +280,27 @@ get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog,
cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components * SIZEOF(jpeg_component_info)); cinfo->num_components * SIZEOF(jpeg_component_info));
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0; ci < cinfo->num_components; ci++) {
ci++, compptr++) { INPUT_BYTE(cinfo, c, return FALSE);
/* Check to see whether component id has already been seen */
/* (in violation of the spec, but unfortunately seen in some */
/* files). If so, create "fake" component id equal to the */
/* max id seen so far + 1. */
for (i = 0, compptr = cinfo->comp_info; i < ci; i++, compptr++) {
if (c == compptr->component_id) {
compptr = cinfo->comp_info;
c = compptr->component_id;
compptr++;
for (i = 1; i < ci; i++, compptr++) {
if (compptr->component_id > c) c = compptr->component_id;
}
c++;
break;
}
}
compptr->component_id = c;
compptr->component_index = ci; compptr->component_index = ci;
INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
INPUT_BYTE(cinfo, c, return FALSE); INPUT_BYTE(cinfo, c, return FALSE);
compptr->h_samp_factor = (c >> 4) & 15; compptr->h_samp_factor = (c >> 4) & 15;
compptr->v_samp_factor = (c ) & 15; compptr->v_samp_factor = (c ) & 15;
@ -305,12 +323,12 @@ get_sos (j_decompress_ptr cinfo)
/* Process a SOS marker */ /* Process a SOS marker */
{ {
INT32 length; INT32 length;
int i, ci, n, c, cc; int c, ci, i, n;
jpeg_component_info * compptr; jpeg_component_info * compptr;
INPUT_VARS(cinfo); INPUT_VARS(cinfo);
if (! cinfo->marker->saw_SOF) if (! cinfo->marker->saw_SOF)
ERREXIT(cinfo, JERR_SOS_NO_SOF); ERREXITS(cinfo, JERR_SOF_BEFORE, "SOS");
INPUT_2BYTES(cinfo, length, return FALSE); INPUT_2BYTES(cinfo, length, return FALSE);
@ -328,24 +346,38 @@ get_sos (j_decompress_ptr cinfo)
/* Collect the component-spec parameters */ /* Collect the component-spec parameters */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
INPUT_BYTE(cinfo, cc, return FALSE);
INPUT_BYTE(cinfo, c, return FALSE); INPUT_BYTE(cinfo, c, return FALSE);
/* Detect the case where component id's are not unique, and, if so, */
/* create a fake component id using the same logic as in get_sof. */
for (ci = 0; ci < i; ci++) {
if (c == cinfo->cur_comp_info[ci]->component_id) {
c = cinfo->cur_comp_info[0]->component_id;
for (ci = 1; ci < i; ci++) {
compptr = cinfo->cur_comp_info[ci];
if (compptr->component_id > c) c = compptr->component_id;
}
c++;
break;
}
}
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
if (cc == compptr->component_id) if (c == compptr->component_id)
goto id_found; goto id_found;
} }
ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, c);
id_found: id_found:
cinfo->cur_comp_info[i] = compptr; cinfo->cur_comp_info[i] = compptr;
INPUT_BYTE(cinfo, c, return FALSE);
compptr->dc_tbl_no = (c >> 4) & 15; compptr->dc_tbl_no = (c >> 4) & 15;
compptr->ac_tbl_no = (c ) & 15; compptr->ac_tbl_no = (c ) & 15;
TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, compptr->component_id,
compptr->dc_tbl_no, compptr->ac_tbl_no); compptr->dc_tbl_no, compptr->ac_tbl_no);
} }
@ -605,6 +637,68 @@ get_dri (j_decompress_ptr cinfo)
} }
LOCAL(boolean)
get_lse (j_decompress_ptr cinfo)
/* Process an LSE marker */
{
INT32 length;
unsigned int tmp;
int cid;
INPUT_VARS(cinfo);
if (! cinfo->marker->saw_SOF)
ERREXITS(cinfo, JERR_SOF_BEFORE, "LSE");
if (cinfo->num_components < 3) goto bad;
INPUT_2BYTES(cinfo, length, return FALSE);
if (length != 24)
ERREXIT(cinfo, JERR_BAD_LENGTH);
INPUT_BYTE(cinfo, tmp, return FALSE);
if (tmp != 0x0D) /* ID inverse transform specification */
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
INPUT_2BYTES(cinfo, tmp, return FALSE);
if (tmp != MAXJSAMPLE) goto bad; /* MAXTRANS */
INPUT_BYTE(cinfo, tmp, return FALSE);
if (tmp != 3) goto bad; /* Nt=3 */
INPUT_BYTE(cinfo, cid, return FALSE);
if (cid != cinfo->comp_info[1].component_id) goto bad;
INPUT_BYTE(cinfo, cid, return FALSE);
if (cid != cinfo->comp_info[0].component_id) goto bad;
INPUT_BYTE(cinfo, cid, return FALSE);
if (cid != cinfo->comp_info[2].component_id) goto bad;
INPUT_BYTE(cinfo, tmp, return FALSE);
if (tmp != 0x80) goto bad; /* F1: CENTER1=1, NORM1=0 */
INPUT_2BYTES(cinfo, tmp, return FALSE);
if (tmp != 0) goto bad; /* A(1,1)=0 */
INPUT_2BYTES(cinfo, tmp, return FALSE);
if (tmp != 0) goto bad; /* A(1,2)=0 */
INPUT_BYTE(cinfo, tmp, return FALSE);
if (tmp != 0) goto bad; /* F2: CENTER2=0, NORM2=0 */
INPUT_2BYTES(cinfo, tmp, return FALSE);
if (tmp != 1) goto bad; /* A(2,1)=1 */
INPUT_2BYTES(cinfo, tmp, return FALSE);
if (tmp != 0) goto bad; /* A(2,2)=0 */
INPUT_BYTE(cinfo, tmp, return FALSE);
if (tmp != 0) goto bad; /* F3: CENTER3=0, NORM3=0 */
INPUT_2BYTES(cinfo, tmp, return FALSE);
if (tmp != 1) goto bad; /* A(3,1)=1 */
INPUT_2BYTES(cinfo, tmp, return FALSE);
if (tmp != 0) { /* A(3,2)=0 */
bad:
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
}
/* OK, valid transform that we can handle. */
cinfo->color_transform = JCT_SUBTRACT_GREEN;
INPUT_SYNC(cinfo);
return TRUE;
}
/* /*
* Routines for processing APPn and COM markers. * Routines for processing APPn and COM markers.
* These are either saved in memory or discarded, per application request. * These are either saved in memory or discarded, per application request.
@ -1059,32 +1153,37 @@ read_markers (j_decompress_ptr cinfo)
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
cinfo->unread_marker = 0; /* processed the marker */ cinfo->unread_marker = 0; /* processed the marker */
return JPEG_REACHED_SOS; return JPEG_REACHED_SOS;
case M_EOI: case M_EOI:
TRACEMS(cinfo, 1, JTRC_EOI); TRACEMS(cinfo, 1, JTRC_EOI);
cinfo->unread_marker = 0; /* processed the marker */ cinfo->unread_marker = 0; /* processed the marker */
return JPEG_REACHED_EOI; return JPEG_REACHED_EOI;
case M_DAC: case M_DAC:
if (! get_dac(cinfo)) if (! get_dac(cinfo))
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
break; break;
case M_DHT: case M_DHT:
if (! get_dht(cinfo)) if (! get_dht(cinfo))
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
break; break;
case M_DQT: case M_DQT:
if (! get_dqt(cinfo)) if (! get_dqt(cinfo))
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
break; break;
case M_DRI: case M_DRI:
if (! get_dri(cinfo)) if (! get_dri(cinfo))
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
break; break;
case M_JPG8:
if (! get_lse(cinfo))
return JPEG_SUSPENDED;
break;
case M_APP0: case M_APP0:
case M_APP1: case M_APP1:
case M_APP2: case M_APP2:
@ -1105,7 +1204,7 @@ read_markers (j_decompress_ptr cinfo)
cinfo->unread_marker - (int) M_APP0]) (cinfo)) cinfo->unread_marker - (int) M_APP0]) (cinfo))
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
break; break;
case M_COM: case M_COM:
if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo)) if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
return JPEG_SUSPENDED; return JPEG_SUSPENDED;
@ -1314,7 +1413,7 @@ jinit_marker_reader (j_decompress_ptr cinfo)
marker = (my_marker_ptr) marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_marker_reader)); SIZEOF(my_marker_reader));
cinfo->marker = (struct jpeg_marker_reader *) marker; cinfo->marker = &marker->pub;
/* Initialize public method pointers */ /* Initialize public method pointers */
marker->pub.reset_marker_reader = reset_marker_reader; marker->pub.reset_marker_reader = reset_marker_reader;
marker->pub.read_markers = read_markers; marker->pub.read_markers = read_markers;

View file

@ -2,7 +2,7 @@
* jdmaster.c * jdmaster.c
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2002-2009 by Guido Vollbeding. * Modified 2002-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -158,10 +158,8 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
cinfo->out_color_components = 1; cinfo->out_color_components = 1;
break; break;
case JCS_RGB: case JCS_RGB:
#if RGB_PIXELSIZE != 3
cinfo->out_color_components = RGB_PIXELSIZE; cinfo->out_color_components = RGB_PIXELSIZE;
break; break;
#endif /* else share code with YCbCr */
case JCS_YCbCr: case JCS_YCbCr:
cinfo->out_color_components = 3; cinfo->out_color_components = 3;
break; break;

View file

@ -2,6 +2,7 @@
* jerror.c * jerror.c
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -25,8 +26,6 @@
#include "jerror.h" #include "jerror.h"
#ifdef USE_WINDOWS_MESSAGEBOX #ifdef USE_WINDOWS_MESSAGEBOX
#define WIN32_NO_STATUS
#define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#endif #endif
@ -68,7 +67,7 @@ const char * const jpeg_std_message_table[] = {
* or jpeg_destroy) at some point. * or jpeg_destroy) at some point.
*/ */
METHODDEF(void) METHODDEF(noreturn_t)
error_exit (j_common_ptr cinfo) error_exit (j_common_ptr cinfo)
{ {
/* Always display the message */ /* Always display the message */

638
reactos/dll/3rdparty/libjpeg/jmemdos.c vendored Normal file
View file

@ -0,0 +1,638 @@
/*
* jmemdos.c
*
* Copyright (C) 1992-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides an MS-DOS-compatible implementation of the system-
* dependent portion of the JPEG memory manager. Temporary data can be
* stored in extended or expanded memory as well as in regular DOS files.
*
* If you use this file, you must be sure that NEED_FAR_POINTERS is defined
* if you compile in a small-data memory model; it should NOT be defined if
* you use a large-data memory model. This file is not recommended if you
* are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
* Also, this code will NOT work if struct fields are aligned on greater than
* 2-byte boundaries.
*
* Based on code contributed by Ge' Weijers.
*/
/*
* If you have both extended and expanded memory, you may want to change the
* order in which they are tried in jopen_backing_store. On a 286 machine
* expanded memory is usually faster, since extended memory access involves
* an expensive protected-mode-and-back switch. On 386 and better, extended
* memory is usually faster. As distributed, the code tries extended memory
* first (what? not everyone has a 386? :-).
*
* You can disable use of extended/expanded memory entirely by altering these
* definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
*/
#ifndef XMS_SUPPORTED
#define XMS_SUPPORTED 1
#endif
#ifndef EMS_SUPPORTED
#define EMS_SUPPORTED 1
#endif
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h" /* import the system-dependent declarations */
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare these */
extern void * malloc JPP((size_t size));
extern void free JPP((void *ptr));
extern char * getenv JPP((const char * name));
#endif
#ifdef NEED_FAR_POINTERS
#ifdef __TURBOC__
/* These definitions work for Borland C (Turbo C) */
#include <alloc.h> /* need farmalloc(), farfree() */
#define far_malloc(x) farmalloc(x)
#define far_free(x) farfree(x)
#else
/* These definitions work for Microsoft C and compatible compilers */
#include <malloc.h> /* need _fmalloc(), _ffree() */
#define far_malloc(x) _fmalloc(x)
#define far_free(x) _ffree(x)
#endif
#else /* not NEED_FAR_POINTERS */
#define far_malloc(x) malloc(x)
#define far_free(x) free(x)
#endif /* NEED_FAR_POINTERS */
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#else
#define READ_BINARY "rb"
#endif
#ifndef USE_MSDOS_MEMMGR /* make sure user got configuration right */
You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */
#endif
#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */
MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */
#endif
/*
* Declarations for assembly-language support routines (see jmemdosa.asm).
*
* The functions are declared "far" as are all their pointer arguments;
* this ensures the assembly source code will work regardless of the
* compiler memory model. We assume "short" is 16 bits, "long" is 32.
*/
typedef void far * XMSDRIVER; /* actually a pointer to code */
typedef struct { /* registers for calling XMS driver */
unsigned short ax, dx, bx;
void far * ds_si;
} XMScontext;
typedef struct { /* registers for calling EMS driver */
unsigned short ax, dx, bx;
void far * ds_si;
} EMScontext;
extern short far jdos_open JPP((short far * handle, char far * filename));
extern short far jdos_close JPP((short handle));
extern short far jdos_seek JPP((short handle, long offset));
extern short far jdos_read JPP((short handle, void far * buffer,
unsigned short count));
extern short far jdos_write JPP((short handle, void far * buffer,
unsigned short count));
extern void far jxms_getdriver JPP((XMSDRIVER far *));
extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
extern short far jems_available JPP((void));
extern void far jems_calldriver JPP((EMScontext far *));
/*
* Selection of a file name for a temporary file.
* This is highly system-dependent, and you may want to customize it.
*/
static int next_file_num; /* to distinguish among several temp files */
LOCAL(void)
select_file_name (char * fname)
{
const char * env;
char * ptr;
FILE * tfile;
/* Keep generating file names till we find one that's not in use */
for (;;) {
/* Get temp directory name from environment TMP or TEMP variable;
* if none, use "."
*/
if ((env = (const char *) getenv("TMP")) == NULL)
if ((env = (const char *) getenv("TEMP")) == NULL)
env = ".";
if (*env == '\0') /* null string means "." */
env = ".";
ptr = fname; /* copy name to fname */
while (*env != '\0')
*ptr++ = *env++;
if (ptr[-1] != '\\' && ptr[-1] != '/')
*ptr++ = '\\'; /* append backslash if not in env variable */
/* Append a suitable file name */
next_file_num++; /* advance counter */
sprintf(ptr, "JPG%03d.TMP", next_file_num);
/* Probe to see if file name is already in use */
if ((tfile = fopen(fname, READ_BINARY)) == NULL)
break;
fclose(tfile); /* oops, it's there; close tfile & try again */
}
}
/*
* Near-memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
}
/*
* "Large" objects are allocated in far memory, if possible
*/
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) far_malloc(sizeofobject);
}
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
far_free(object);
}
/*
* This routine computes the total memory space available for allocation.
* It's impossible to do this in a portable way; our current solution is
* to make the user tell us (with a default value set at compile time).
* If you can actually get the available space, it's a good idea to subtract
* a slop factor of 5% or so.
*/
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */
#endif
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
return cinfo->mem->max_memory_to_use - already_allocated;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jpeg_mem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
/*
* For MS-DOS we support three types of backing storage:
* 1. Conventional DOS files. We access these by direct DOS calls rather
* than via the stdio package. This provides a bit better performance,
* but the real reason is that the buffers to be read or written are FAR.
* The stdio library for small-data memory models can't cope with that.
* 2. Extended memory, accessed per the XMS V2.0 specification.
* 3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
* You'll need copies of those specs to make sense of the related code.
* The specs are available by Internet FTP from the SIMTEL archives
* (oak.oakland.edu and its various mirror sites). See files
* pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip.
*/
/*
* Access methods for a DOS file.
*/
METHODDEF(void)
read_file_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (jdos_seek(info->handle.file_handle, file_offset))
ERREXIT(cinfo, JERR_TFILE_SEEK);
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
if (byte_count > 65535L) /* safety check */
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
if (jdos_read(info->handle.file_handle, buffer_address,
(unsigned short) byte_count))
ERREXIT(cinfo, JERR_TFILE_READ);
}
METHODDEF(void)
write_file_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
if (jdos_seek(info->handle.file_handle, file_offset))
ERREXIT(cinfo, JERR_TFILE_SEEK);
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
if (byte_count > 65535L) /* safety check */
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
if (jdos_write(info->handle.file_handle, buffer_address,
(unsigned short) byte_count))
ERREXIT(cinfo, JERR_TFILE_WRITE);
}
METHODDEF(void)
close_file_store (j_common_ptr cinfo, backing_store_ptr info)
{
jdos_close(info->handle.file_handle); /* close the file */
remove(info->temp_name); /* delete the file */
/* If your system doesn't have remove(), try unlink() instead.
* remove() is the ANSI-standard name for this function, but
* unlink() was more common in pre-ANSI systems.
*/
TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
}
LOCAL(boolean)
open_file_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
short handle;
select_file_name(info->temp_name);
if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
/* might as well exit since jpeg_open_backing_store will fail anyway */
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
return FALSE;
}
info->handle.file_handle = handle;
info->read_backing_store = read_file_store;
info->write_backing_store = write_file_store;
info->close_backing_store = close_file_store;
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
return TRUE; /* succeeded */
}
/*
* Access methods for extended memory.
*/
#if XMS_SUPPORTED
static XMSDRIVER xms_driver; /* saved address of XMS driver */
typedef union { /* either long offset or real-mode pointer */
long offset;
void far * ptr;
} XMSPTR;
typedef struct { /* XMS move specification structure */
long length;
XMSH src_handle;
XMSPTR src;
XMSH dst_handle;
XMSPTR dst;
} XMSspec;
#define ODD(X) (((X) & 1L) != 0)
METHODDEF(void)
read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
XMScontext ctx;
XMSspec spec;
char endbuffer[2];
/* The XMS driver can't cope with an odd length, so handle the last byte
* specially if byte_count is odd. We don't expect this to be common.
*/
spec.length = byte_count & (~ 1L);
spec.src_handle = info->handle.xms_handle;
spec.src.offset = file_offset;
spec.dst_handle = 0;
spec.dst.ptr = buffer_address;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x0b00; /* EMB move */
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
ERREXIT(cinfo, JERR_XMS_READ);
if (ODD(byte_count)) {
read_xms_store(cinfo, info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
}
}
METHODDEF(void)
write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
XMScontext ctx;
XMSspec spec;
char endbuffer[2];
/* The XMS driver can't cope with an odd length, so handle the last byte
* specially if byte_count is odd. We don't expect this to be common.
*/
spec.length = byte_count & (~ 1L);
spec.src_handle = 0;
spec.src.ptr = buffer_address;
spec.dst_handle = info->handle.xms_handle;
spec.dst.offset = file_offset;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x0b00; /* EMB move */
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
ERREXIT(cinfo, JERR_XMS_WRITE);
if (ODD(byte_count)) {
read_xms_store(cinfo, info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
write_xms_store(cinfo, info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
}
}
METHODDEF(void)
close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
{
XMScontext ctx;
ctx.dx = info->handle.xms_handle;
ctx.ax = 0x0a00;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
/* we ignore any error return from the driver */
}
LOCAL(boolean)
open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
XMScontext ctx;
/* Get address of XMS driver */
jxms_getdriver((XMSDRIVER far *) & xms_driver);
if (xms_driver == NULL)
return FALSE; /* no driver to be had */
/* Get version number, must be >= 2.00 */
ctx.ax = 0x0000;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax < (unsigned short) 0x0200)
return FALSE;
/* Try to get space (expressed in kilobytes) */
ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
ctx.ax = 0x0900;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
return FALSE;
/* Succeeded, save the handle and away we go */
info->handle.xms_handle = ctx.dx;
info->read_backing_store = read_xms_store;
info->write_backing_store = write_xms_store;
info->close_backing_store = close_xms_store;
TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
return TRUE; /* succeeded */
}
#endif /* XMS_SUPPORTED */
/*
* Access methods for expanded memory.
*/
#if EMS_SUPPORTED
/* The EMS move specification structure requires word and long fields aligned
* at odd byte boundaries. Some compilers will align struct fields at even
* byte boundaries. While it's usually possible to force byte alignment,
* that causes an overall performance penalty and may pose problems in merging
* JPEG into a larger application. Instead we accept some rather dirty code
* here. Note this code would fail if the hardware did not allow odd-byte
* word & long accesses, but all 80x86 CPUs do.
*/
typedef void far * EMSPTR;
typedef union { /* EMS move specification structure */
long length; /* It's easy to access first 4 bytes */
char bytes[18]; /* Misaligned fields in here! */
} EMSspec;
/* Macros for accessing misaligned fields */
#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset])))
#define SRC_TYPE(spec) FIELD_AT(spec,4,char)
#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH)
#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short)
#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short)
#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR)
#define DST_TYPE(spec) FIELD_AT(spec,11,char)
#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH)
#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short)
#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short)
#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR)
#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */
#define HIBYTE(W) (((W) >> 8) & 0xFF)
#define LOBYTE(W) ((W) & 0xFF)
METHODDEF(void)
read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
EMScontext ctx;
EMSspec spec;
spec.length = byte_count;
SRC_TYPE(spec) = 1;
SRC_HANDLE(spec) = info->handle.ems_handle;
SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
DST_TYPE(spec) = 0;
DST_HANDLE(spec) = 0;
DST_PTR(spec) = buffer_address;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x5700; /* move memory region */
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
ERREXIT(cinfo, JERR_EMS_READ);
}
METHODDEF(void)
write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
EMScontext ctx;
EMSspec spec;
spec.length = byte_count;
SRC_TYPE(spec) = 0;
SRC_HANDLE(spec) = 0;
SRC_PTR(spec) = buffer_address;
DST_TYPE(spec) = 1;
DST_HANDLE(spec) = info->handle.ems_handle;
DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x5700; /* move memory region */
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
ERREXIT(cinfo, JERR_EMS_WRITE);
}
METHODDEF(void)
close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
{
EMScontext ctx;
ctx.ax = 0x4500;
ctx.dx = info->handle.ems_handle;
jems_calldriver((EMScontext far *) & ctx);
TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
/* we ignore any error return from the driver */
}
LOCAL(boolean)
open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
EMScontext ctx;
/* Is EMS driver there? */
if (! jems_available())
return FALSE;
/* Get status, make sure EMS is OK */
ctx.ax = 0x4000;
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
return FALSE;
/* Get version, must be >= 4.0 */
ctx.ax = 0x4600;
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
return FALSE;
/* Try to allocate requested space */
ctx.ax = 0x4300;
ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
return FALSE;
/* Succeeded, save the handle and away we go */
info->handle.ems_handle = ctx.dx;
info->read_backing_store = read_ems_store;
info->write_backing_store = write_ems_store;
info->close_backing_store = close_ems_store;
TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
return TRUE; /* succeeded */
}
#endif /* EMS_SUPPORTED */
/*
* Initial opening of a backing-store object.
*/
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
/* Try extended memory, then expanded memory, then regular file. */
#if XMS_SUPPORTED
if (open_xms_store(cinfo, info, total_bytes_needed))
return;
#endif
#if EMS_SUPPORTED
if (open_ems_store(cinfo, info, total_bytes_needed))
return;
#endif
if (open_file_store(cinfo, info, total_bytes_needed))
return;
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required.
*/
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
next_file_num = 0; /* initialize temp file name generator */
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
}
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* Microsoft C, at least in v6.00A, will not successfully reclaim freed
* blocks of size > 32Kbytes unless we give it a kick in the rear, like so:
*/
#ifdef NEED_FHEAPMIN
_fheapmin();
#endif
}

289
reactos/dll/3rdparty/libjpeg/jmemmac.c vendored Normal file
View file

@ -0,0 +1,289 @@
/*
* jmemmac.c
*
* Copyright (C) 1992-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* jmemmac.c provides an Apple Macintosh implementation of the system-
* dependent portion of the JPEG memory manager.
*
* If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the
* JPEG_INTERNALS part of jconfig.h.
*
* jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr
* instead of malloc and free. It accurately determines the amount of
* memory available by using CompactMem. Notice that if left to its
* own devices, this code can chew up all available space in the
* application's zone, with the exception of the rather small "slop"
* factor computed in jpeg_mem_available(). The application can ensure
* that more space is left over by reducing max_memory_to_use.
*
* Large images are swapped to disk using temporary files and System 7.0+'s
* temporary folder functionality.
*
* Note that jmemmac.c depends on two features of MacOS that were first
* introduced in System 7: FindFolder and the FSSpec-based calls.
* If your application uses jmemmac.c and is run under System 6 or earlier,
* and the jpeg library decides it needs a temporary file, it will abort,
* printing error messages about requiring System 7. (If no temporary files
* are created, it will run fine.)
*
* If you want to use jmemmac.c in an application that might be used with
* System 6 or earlier, then you should remove dependencies on FindFolder
* and the FSSpec calls. You will need to replace FindFolder with some
* other mechanism for finding a place to put temporary files, and you
* should replace the FSSpec calls with their HFS equivalents:
*
* FSpDelete -> HDelete
* FSpGetFInfo -> HGetFInfo
* FSpCreate -> HCreate
* FSpOpenDF -> HOpen *** Note: not HOpenDF ***
* FSMakeFSSpec -> (fill in spec by hand.)
*
* (Use HOpen instead of HOpenDF. HOpen is just a glue-interface to PBHOpen,
* which is on all HFS macs. HOpenDF is a System 7 addition which avoids the
* ages-old problem of names starting with a period.)
*
* Contributed by Sam Bushell (jsam@iagu.on.net) and
* Dan Gildor (gyld@in-touch.com).
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h" /* import the system-dependent declarations */
#ifndef USE_MAC_MEMMGR /* make sure user got configuration right */
You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */
#endif
#include <Memory.h> /* we use the MacOS memory manager */
#include <Files.h> /* we use the MacOS File stuff */
#include <Folders.h> /* we use the MacOS HFS stuff */
#include <Script.h> /* for smSystemScript */
#include <Gestalt.h> /* we use Gestalt to test for specific functionality */
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
#define TEMP_FILE_NAME "JPG%03d.TMP"
#endif
static int next_file_num; /* to distinguish among several temp files */
/*
* Memory allocation and freeing are controlled by the MacOS library
* routines NewPtr() and DisposePtr(), which allocate fixed-address
* storage. Unfortunately, the IJG library isn't smart enough to cope
* with relocatable storage.
*/
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) NewPtr(sizeofobject);
}
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
DisposePtr((Ptr) object);
}
/*
* "Large" objects are treated the same as "small" ones.
* NB: we include FAR keywords in the routine declarations simply for
* consistency with the rest of the IJG code; FAR should expand to empty
* on rational architectures like the Mac.
*/
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) NewPtr(sizeofobject);
}
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
DisposePtr((Ptr) object);
}
/*
* This routine computes the total memory space available for allocation.
*/
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
long limit = cinfo->mem->max_memory_to_use - already_allocated;
long slop, mem;
/* Don't ask for more than what application has told us we may use */
if (max_bytes_needed > limit && limit > 0)
max_bytes_needed = limit;
/* Find whether there's a big enough free block in the heap.
* CompactMem tries to create a contiguous block of the requested size,
* and then returns the size of the largest free block (which could be
* much more or much less than we asked for).
* We add some slop to ensure we don't use up all available memory.
*/
slop = max_bytes_needed / 16 + 32768L;
mem = CompactMem(max_bytes_needed + slop) - slop;
if (mem < 0)
mem = 0; /* sigh, couldn't even get the slop */
/* Don't take more than the application says we can have */
if (mem > limit && limit > 0)
mem = limit;
return mem;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jpeg_mem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
METHODDEF(void)
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
long bytes = byte_count;
long retVal;
if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
ERREXIT(cinfo, JERR_TFILE_SEEK);
retVal = FSRead ( info->temp_file, &bytes,
(unsigned char *) buffer_address );
if ( retVal != noErr || bytes != byte_count )
ERREXIT(cinfo, JERR_TFILE_READ);
}
METHODDEF(void)
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
{
long bytes = byte_count;
long retVal;
if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
ERREXIT(cinfo, JERR_TFILE_SEEK);
retVal = FSWrite ( info->temp_file, &bytes,
(unsigned char *) buffer_address );
if ( retVal != noErr || bytes != byte_count )
ERREXIT(cinfo, JERR_TFILE_WRITE);
}
METHODDEF(void)
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
{
FSClose ( info->temp_file );
FSpDelete ( &(info->tempSpec) );
}
/*
* Initial opening of a backing-store object.
*
* This version uses FindFolder to find the Temporary Items folder,
* and puts the temporary file in there.
*/
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
short tmpRef, vRefNum;
long dirID;
FInfo finderInfo;
FSSpec theSpec;
Str255 fName;
OSErr osErr;
long gestaltResponse = 0;
/* Check that FSSpec calls are available. */
osErr = Gestalt( gestaltFSAttr, &gestaltResponse );
if ( ( osErr != noErr )
|| !( gestaltResponse & (1<<gestaltHasFSSpecCalls) ) )
ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required");
/* TO DO: add a proper error message to jerror.h. */
/* Check that FindFolder is available. */
osErr = Gestalt( gestaltFindFolderAttr, &gestaltResponse );
if ( ( osErr != noErr )
|| !( gestaltResponse & (1<<gestaltFindFolderPresent) ) )
ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required.");
/* TO DO: add a proper error message to jerror.h. */
osErr = FindFolder ( kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
&vRefNum, &dirID );
if ( osErr != noErr )
ERREXITS(cinfo, JERR_TFILE_CREATE, "- temporary items folder unavailable");
/* TO DO: Try putting the temp files somewhere else. */
/* Keep generating file names till we find one that's not in use */
for (;;) {
next_file_num++; /* advance counter */
sprintf(info->temp_name, TEMP_FILE_NAME, next_file_num);
strcpy ( (Ptr)fName+1, info->temp_name );
*fName = strlen (info->temp_name);
osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec );
if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr )
break;
}
osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript );
if ( osErr != noErr )
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) );
if ( osErr != noErr )
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
info->tempSpec = theSpec;
info->read_backing_store = read_backing_store;
info->write_backing_store = write_backing_store;
info->close_backing_store = close_backing_store;
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required.
*/
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
next_file_num = 0;
/* max_memory_to_use will be initialized to FreeMem()'s result;
* the calling application might later reduce it, for example
* to leave room to invoke multiple JPEG objects.
* Note that FreeMem returns the total number of free bytes;
* it may not be possible to allocate a single block of this size.
*/
return FreeMem();
}
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* no work */
}

View file

@ -2,6 +2,7 @@
* jmemmgr.c * jmemmgr.c
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -213,7 +214,7 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
#endif /* MEM_STATS */ #endif /* MEM_STATS */
LOCAL(void) LOCAL(noreturn_t)
out_of_memory (j_common_ptr cinfo, int which) out_of_memory (j_common_ptr cinfo, int which)
/* Report an out-of-memory error and stop execution */ /* Report an out-of-memory error and stop execution */
/* If we compiled MEM_STATS support, report alloc requests before dying */ /* If we compiled MEM_STATS support, report alloc requests before dying */
@ -821,7 +822,7 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
end_row -= ptr->cur_start_row; end_row -= ptr->cur_start_row;
while (undef_row < end_row) { while (undef_row < end_row) {
jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
undef_row++; undef_row++;
} }
} else { } else {
@ -906,7 +907,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
end_row -= ptr->cur_start_row; end_row -= ptr->cur_start_row;
while (undef_row < end_row) { while (undef_row < end_row) {
jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
undef_row++; undef_row++;
} }
} else { } else {

View file

@ -1,7 +1,7 @@
/* /*
* jpegtran.c * jpegtran.c
* *
* Copyright (C) 1995-2010, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1995-2012, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -78,14 +78,14 @@ usage (void)
fprintf(stderr, " -trim Drop non-transformable edge blocks\n"); fprintf(stderr, " -trim Drop non-transformable edge blocks\n");
#endif #endif
fprintf(stderr, "Switches for advanced users:\n"); fprintf(stderr, "Switches for advanced users:\n");
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
fprintf(stderr, " -outfile name Specify name for output file\n"); fprintf(stderr, " -outfile name Specify name for output file\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n"); fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, "Switches for wizards:\n"); fprintf(stderr, "Switches for wizards:\n");
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n");
#endif #endif
@ -467,7 +467,7 @@ main (int argc, char **argv)
/* Adjust default decompression parameters */ /* Adjust default decompression parameters */
if (scaleoption != NULL) if (scaleoption != NULL)
if (sscanf(scaleoption, "%d/%d", if (sscanf(scaleoption, "%u/%u",
&srcinfo.scale_num, &srcinfo.scale_denom) < 1) &srcinfo.scale_num, &srcinfo.scale_denom) < 1)
usage(); usage();

View file

@ -2,6 +2,7 @@
* jquant1.c * jquant1.c
* *
* Copyright (C) 1991-1996, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -530,8 +531,8 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
/* Initialize output values to 0 so can process components separately */ /* Initialize output values to 0 so can process components separately */
jzero_far((void FAR *) output_buf[row], FMEMZERO((void FAR *) output_buf[row],
(size_t) (width * SIZEOF(JSAMPLE))); (size_t) (width * SIZEOF(JSAMPLE)));
row_index = cquantize->row_index; row_index = cquantize->row_index;
for (ci = 0; ci < nc; ci++) { for (ci = 0; ci < nc; ci++) {
input_ptr = input_buf[row] + ci; input_ptr = input_buf[row] + ci;
@ -635,8 +636,8 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
/* Initialize output values to 0 so can process components separately */ /* Initialize output values to 0 so can process components separately */
jzero_far((void FAR *) output_buf[row], FMEMZERO((void FAR *) output_buf[row],
(size_t) (width * SIZEOF(JSAMPLE))); (size_t) (width * SIZEOF(JSAMPLE)));
for (ci = 0; ci < nc; ci++) { for (ci = 0; ci < nc; ci++) {
input_ptr = input_buf[row] + ci; input_ptr = input_buf[row] + ci;
output_ptr = output_buf[row]; output_ptr = output_buf[row];
@ -781,7 +782,7 @@ start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
/* Initialize the propagated errors to zero. */ /* Initialize the propagated errors to zero. */
arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
for (i = 0; i < cinfo->out_color_components; i++) for (i = 0; i < cinfo->out_color_components; i++)
jzero_far((void FAR *) cquantize->fserrors[i], arraysize); FMEMZERO((void FAR *) cquantize->fserrors[i], arraysize);
break; break;
default: default:
ERREXIT(cinfo, JERR_NOT_COMPILED); ERREXIT(cinfo, JERR_NOT_COMPILED);

View file

@ -2,6 +2,7 @@
* jquant2.c * jquant2.c
* *
* Copyright (C) 1991-1996, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -1203,7 +1204,7 @@ start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
/* Initialize the propagated errors to zero. */ /* Initialize the propagated errors to zero. */
jzero_far((void FAR *) cquantize->fserrors, arraysize); FMEMZERO((void FAR *) cquantize->fserrors, arraysize);
/* Make the error-limit table if we didn't already. */ /* Make the error-limit table if we didn't already. */
if (cquantize->error_limiter == NULL) if (cquantize->error_limiter == NULL)
init_error_limit(cinfo); init_error_limit(cinfo);
@ -1214,8 +1215,8 @@ start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
/* Zero the histogram or inverse color map, if necessary */ /* Zero the histogram or inverse color map, if necessary */
if (cquantize->needs_zeroed) { if (cquantize->needs_zeroed) {
for (i = 0; i < HIST_C0_ELEMS; i++) { for (i = 0; i < HIST_C0_ELEMS; i++) {
jzero_far((void FAR *) histogram[i], FMEMZERO((void FAR *) histogram[i],
HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
} }
cquantize->needs_zeroed = FALSE; cquantize->needs_zeroed = FALSE;
} }

View file

@ -2,7 +2,7 @@
* jutils.c * jutils.c
* *
* Copyright (C) 1991-1996, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding. * Modified 2009-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -148,13 +148,27 @@ jround_up (long a, long b)
* is not all that great, because these routines aren't very heavily used.) * is not all that great, because these routines aren't very heavily used.)
*/ */
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ #ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */
#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) #define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
#define FMEMZERO(target,size) MEMZERO(target,size)
#else /* 80x86 case, define if we can */ #else /* 80x86 case, define if we can */
#ifdef USE_FMEM #ifdef USE_FMEM
#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) #define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) #else
/* This function is for use by the FMEMZERO macro defined in jpegint.h.
* Do not call this function directly, use the FMEMZERO macro instead.
*/
GLOBAL(void)
jzero_far (void FAR * target, size_t bytestozero)
/* Zero out a chunk of FAR memory. */
/* This might be sample-array data, block-array data, or alloc_large data. */
{
register char FAR * ptr = (char FAR *) target;
register size_t count;
for (count = bytestozero; count > 0; count--) {
*ptr++ = 0;
}
}
#endif #endif
#endif #endif
@ -211,21 +225,3 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
} }
#endif #endif
} }
GLOBAL(void)
jzero_far (void FAR * target, size_t bytestozero)
/* Zero out a chunk of FAR memory. */
/* This might be sample-array data, block-array data, or alloc_large data. */
{
#ifdef FMEMZERO
FMEMZERO(target, bytestozero);
#else
register char FAR * ptr = (char FAR *) target;
register size_t count;
for (count = bytestozero; count > 0; count--) {
*ptr++ = 0;
}
#endif
}

View file

@ -1,7 +1,7 @@
/* /*
* transupp.c * transupp.c
* *
* Copyright (C) 1997-2009, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1997-2012, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -771,7 +771,7 @@ jt_read_integer (const char ** strptr, JDIMENSION * result)
* The routine returns TRUE if the spec string is valid, FALSE if not. * The routine returns TRUE if the spec string is valid, FALSE if not.
* *
* The crop spec string should have the format * The crop spec string should have the format
* <width>x<height>{+-}<xoffset>{+-}<yoffset> * <width>[f]x<height>[f]{+-}<xoffset>{+-}<yoffset>
* where width, height, xoffset, and yoffset are unsigned integers. * where width, height, xoffset, and yoffset are unsigned integers.
* Each of the elements can be omitted to indicate a default value. * 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 * (A weakness of this style is that it is not possible to omit xoffset
@ -793,14 +793,22 @@ jtransform_parse_crop_spec (jpeg_transform_info *info, const char *spec)
/* fetch width */ /* fetch width */
if (! jt_read_integer(&spec, &info->crop_width)) if (! jt_read_integer(&spec, &info->crop_width))
return FALSE; return FALSE;
info->crop_width_set = JCROP_POS; if (*spec == 'f' || *spec == 'F') {
spec++;
info->crop_width_set = JCROP_FORCE;
} else
info->crop_width_set = JCROP_POS;
} }
if (*spec == 'x' || *spec == 'X') { if (*spec == 'x' || *spec == 'X') {
/* fetch height */ /* fetch height */
spec++; spec++;
if (! jt_read_integer(&spec, &info->crop_height)) if (! jt_read_integer(&spec, &info->crop_height))
return FALSE; return FALSE;
info->crop_height_set = JCROP_POS; if (*spec == 'f' || *spec == 'F') {
spec++;
info->crop_height_set = JCROP_FORCE;
} else
info->crop_height_set = JCROP_POS;
} }
if (*spec == '+' || *spec == '-') { if (*spec == '+' || *spec == '-') {
/* fetch xoffset */ /* fetch xoffset */
@ -980,10 +988,16 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
else else
yoffset = info->crop_yoffset; yoffset = info->crop_yoffset;
/* Now adjust so that upper left corner falls at an iMCU boundary */ /* Now adjust so that upper left corner falls at an iMCU boundary */
info->output_width = if (info->crop_width_set == JCROP_FORCE)
info->crop_width + (xoffset % info->iMCU_sample_width); info->output_width = info->crop_width;
info->output_height = else
info->crop_height + (yoffset % info->iMCU_sample_height); info->output_width =
info->crop_width + (xoffset % info->iMCU_sample_width);
if (info->crop_height_set == JCROP_FORCE)
info->output_height = info->crop_height;
else
info->output_height =
info->crop_height + (yoffset % info->iMCU_sample_height);
/* Save x/y offsets measured in iMCUs */ /* Save x/y offsets measured in iMCUs */
info->x_crop_offset = xoffset / info->iMCU_sample_width; info->x_crop_offset = xoffset / info->iMCU_sample_width;
info->y_crop_offset = yoffset / info->iMCU_sample_height; info->y_crop_offset = yoffset / info->iMCU_sample_height;
@ -1062,7 +1076,7 @@ jtransform_request_workspace (j_decompress_ptr srcinfo,
if (need_workspace) { if (need_workspace) {
coef_arrays = (jvirt_barray_ptr *) coef_arrays = (jvirt_barray_ptr *)
(*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE, (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
SIZEOF(jvirt_barray_ptr) * info->num_components); SIZEOF(jvirt_barray_ptr) * info->num_components);
width_in_iMCUs = (JDIMENSION) width_in_iMCUs = (JDIMENSION)
jdiv_round_up((long) info->output_width, jdiv_round_up((long) info->output_width,
(long) info->iMCU_sample_width); (long) info->iMCU_sample_width);

View file

@ -2,7 +2,7 @@
* jerror.h * jerror.h
* *
* Copyright (C) 1994-1997, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding. * Modified 1997-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -106,11 +106,11 @@ JMESSAGE(JERR_QUANT_COMPONENTS,
"Cannot quantize more than %d color components") "Cannot quantize more than %d color components")
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
JMESSAGE(JERR_SOF_BEFORE, "Invalid JPEG file structure: %s before SOF")
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")

View file

@ -2,7 +2,7 @@
* jmorecfg.h * jmorecfg.h
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding. * Modified 1997-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -187,63 +187,14 @@ typedef unsigned int JDIMENSION;
* or code profilers that require it. * or code profilers that require it.
*/ */
#ifdef _WIN32
# if defined(ALL_STATIC)
# if defined(JPEG_DLL)
# undef JPEG_DLL
# endif
# if !defined(JPEG_STATIC)
# define JPEG_STATIC
# endif
# endif
# if defined(JPEG_DLL)
# if defined(JPEG_STATIC)
# undef JPEG_STATIC
# endif
# endif
# if defined(JPEG_DLL)
/* building a DLL */
# define JPEG_IMPEXP __declspec(dllexport)
# elif defined(JPEG_STATIC)
/* building or linking to a static library */
# define JPEG_IMPEXP
# else
/* linking to the DLL */
# define JPEG_IMPEXP __declspec(dllimport)
# endif
# if !defined(JPEG_API)
# define JPEG_API __cdecl
# endif
/* The only remaining magic that is necessary for cygwin */
#elif defined(__CYGWIN__)
# if !defined(JPEG_IMPEXP)
# define JPEG_IMPEXP
# endif
# if !defined(JPEG_API)
# define JPEG_API __cdecl
# endif
#endif
/* Ensure our magic doesn't hurt other platforms */
#if !defined(JPEG_IMPEXP)
# define JPEG_IMPEXP
#endif
#if !defined(JPEG_API)
# define JPEG_API
#endif
/* a function called through method pointers: */ /* a function called through method pointers: */
#define METHODDEF(type) static type #define METHODDEF(type) static type
/* a function used only in its module: */ /* a function used only in its module: */
#define LOCAL(type) static type #define LOCAL(type) static type
/* a function referenced thru EXTERNs: */ /* a function referenced thru EXTERNs: */
#define GLOBAL(type) type JPEG_API #define GLOBAL(type) type
/* a reference to a GLOBAL function: */ /* a reference to a GLOBAL function: */
#ifndef EXTERN #define EXTERN(type) extern type
# define EXTERN(type) extern JPEG_IMPEXP type JPEG_API
/* a reference to a "GLOBAL" function exported by sourcefiles of utility progs */
#endif /* EXTERN */
#define EXTERN_1(type) extern type JPEG_API
/* This macro is used to declare a "method", that is, a function pointer. /* This macro is used to declare a "method", that is, a function pointer.
@ -259,6 +210,26 @@ typedef unsigned int JDIMENSION;
#endif #endif
/* The noreturn type identifier is used to declare functions
* which cannot return.
* Compilers can thus create more optimized code and perform
* better checks for warnings and errors.
* Static analyzer tools can make improved inferences about
* execution paths and are prevented from giving false alerts.
*
* Unfortunately, the proposed specifications of corresponding
* extensions in the Dec 2011 ISO C standard revision (C11),
* GCC, MSVC, etc. are not viable.
* Thus we introduce a user defined type to declare noreturn
* functions at least for clarity. A proper compiler would
* have a suitable noreturn type to match in place of void.
*/
#ifndef HAVE_NORETURN_T
typedef void noreturn_t;
#endif
/* Here is the pseudo-keyword for declaring pointers that must be "far" /* Here is the pseudo-keyword for declaring pointers that must be "far"
* on 80x86 machines. Most of the specialized coding for 80x86 is handled * on 80x86 machines. Most of the specialized coding for 80x86 is handled
* by just saying "FAR *" where such a pointer is needed. In a few places * by just saying "FAR *" where such a pointer is needed. In a few places
@ -281,15 +252,16 @@ typedef unsigned int JDIMENSION;
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work. * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
*/ */
#ifndef HAVE_BOOLEAN #ifdef HAVE_BOOLEAN
typedef int boolean;
#endif
#ifndef FALSE /* in case these macros already exist */ #ifndef FALSE /* in case these macros already exist */
#define FALSE 0 /* values of boolean */ #define FALSE 0 /* values of boolean */
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
#endif #endif
#else
typedef enum { FALSE = 0, TRUE = 1 } boolean;
#endif
/* /*
@ -361,9 +333,7 @@ typedef int boolean;
* the offsets will also change the order in which colormap data is organized. * the offsets will also change the order in which colormap data is organized.
* RESTRICTIONS: * RESTRICTIONS:
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
* 2. These macros only affect RGB<=>YCbCr color conversion, so they are not * 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* useful if you are using JPEG color spaces other than YCbCr or grayscale.
* 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* is not 3 (they don't understand about dummy color components!). So you * is not 3 (they don't understand about dummy color components!). So you
* can't use color quantization if you change that value. * can't use color quantization if you change that value.
*/ */

View file

@ -2,7 +2,7 @@
* jpegint.h * jpegint.h
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding. * Modified 1997-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -321,21 +321,41 @@ struct jpeg_color_quantizer {
#define jinit_memory_mgr jIMemMgr #define jinit_memory_mgr jIMemMgr
#define jdiv_round_up jDivRound #define jdiv_round_up jDivRound
#define jround_up jRound #define jround_up jRound
#define jzero_far jZeroFar
#define jcopy_sample_rows jCopySamples #define jcopy_sample_rows jCopySamples
#define jcopy_block_row jCopyBlocks #define jcopy_block_row jCopyBlocks
#define jzero_far jZeroFar
#define jpeg_zigzag_order jZIGTable #define jpeg_zigzag_order jZIGTable
#define jpeg_natural_order jZAGTable #define jpeg_natural_order jZAGTable
#define jpeg_natural_order7 jZAGTable7 #define jpeg_natural_order7 jZAG7Table
#define jpeg_natural_order6 jZAGTable6 #define jpeg_natural_order6 jZAG6Table
#define jpeg_natural_order5 jZAGTable5 #define jpeg_natural_order5 jZAG5Table
#define jpeg_natural_order4 jZAGTable4 #define jpeg_natural_order4 jZAG4Table
#define jpeg_natural_order3 jZAGTable3 #define jpeg_natural_order3 jZAG3Table
#define jpeg_natural_order2 jZAGTable2 #define jpeg_natural_order2 jZAG2Table
#define jpeg_aritab jAriTab #define jpeg_aritab jAriTab
#endif /* NEED_SHORT_EXTERNAL_NAMES */ #endif /* NEED_SHORT_EXTERNAL_NAMES */
/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
* and coefficient-block arrays. This won't work on 80x86 because the arrays
* are FAR and we're assuming a small-pointer memory model. However, some
* DOS compilers provide far-pointer versions of memcpy() and memset() even
* in the small-model libraries. These will be used if USE_FMEM is defined.
* Otherwise, the routines in jutils.c do it the hard way.
*/
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */
#define FMEMZERO(target,size) MEMZERO(target,size)
#else /* 80x86 case */
#ifdef USE_FMEM
#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
#else
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
#define FMEMZERO(target,size) jzero_far(target, size)
#endif
#endif
/* Compression module initialization routines */ /* Compression module initialization routines */
EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
@ -381,7 +401,6 @@ EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
int num_rows, JDIMENSION num_cols)); int num_rows, JDIMENSION num_cols));
EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
JDIMENSION num_blocks)); JDIMENSION num_blocks));
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
/* Constant tables in jutils.c */ /* Constant tables in jutils.c */
#if 0 /* This table is not actually needed in v6a */ #if 0 /* This table is not actually needed in v6a */
extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */

View file

@ -2,7 +2,7 @@
* jpeglib.h * jpeglib.h
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2002-2010 by Guido Vollbeding. * Modified 2002-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -34,12 +34,12 @@ extern "C" {
#endif #endif
/* Version IDs for the JPEG library. /* Version IDs for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 80". * Might be useful for tests like "#if JPEG_LIB_VERSION >= 90".
*/ */
#define JPEG_LIB_VERSION 80 /* Compatibility version 8.0 */ #define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */
#define JPEG_LIB_VERSION_MAJOR 8 #define JPEG_LIB_VERSION_MAJOR 9
#define JPEG_LIB_VERSION_MINOR 3 #define JPEG_LIB_VERSION_MINOR 0
/* Various constants determining the sizes of things. /* Various constants determining the sizes of things.
@ -47,7 +47,7 @@ extern "C" {
* if you want to be compatible. * if you want to be compatible.
*/ */
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ #define DCTSIZE 8 /* The basic DCT block is 8x8 coefficients */
#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ #define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ #define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ #define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
@ -221,6 +221,13 @@ typedef enum {
JCS_YCCK /* Y/Cb/Cr/K */ JCS_YCCK /* Y/Cb/Cr/K */
} J_COLOR_SPACE; } J_COLOR_SPACE;
/* Supported color transforms. */
typedef enum {
JCT_NONE = 0,
JCT_SUBTRACT_GREEN = 1
} J_COLOR_TRANSFORM;
/* DCT/IDCT algorithm options. */ /* DCT/IDCT algorithm options. */
typedef enum { typedef enum {
@ -369,7 +376,10 @@ struct jpeg_compress_struct {
UINT16 X_density; /* Horizontal pixel density */ UINT16 X_density; /* Horizontal pixel density */
UINT16 Y_density; /* Vertical pixel density */ UINT16 Y_density; /* Vertical pixel density */
boolean write_Adobe_marker; /* should an Adobe marker be written? */ boolean write_Adobe_marker; /* should an Adobe marker be written? */
J_COLOR_TRANSFORM color_transform;
/* Color transform identifier, writes LSE marker if nonzero */
/* State variable: index of next scanline to be written to /* State variable: index of next scanline to be written to
* jpeg_write_scanlines(). Application may use this to control its * jpeg_write_scanlines(). Application may use this to control its
* processing loop, e.g., "while (next_scanline < image_height)". * processing loop, e.g., "while (next_scanline < image_height)".
@ -589,6 +599,9 @@ struct jpeg_decompress_struct {
boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
UINT8 Adobe_transform; /* Color transform code from Adobe marker */ UINT8 Adobe_transform; /* Color transform code from Adobe marker */
J_COLOR_TRANSFORM color_transform;
/* Color transform identifier derived from LSE marker, otherwise zero */
boolean CCIR601_sampling; /* TRUE=first samples are cosited */ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
/* Aside from the specific data retained from APPn markers known to the /* Aside from the specific data retained from APPn markers known to the
@ -681,7 +694,7 @@ struct jpeg_decompress_struct {
struct jpeg_error_mgr { struct jpeg_error_mgr {
/* Error exit handler: does not return to caller */ /* Error exit handler: does not return to caller */
JMETHOD(void, error_exit, (j_common_ptr cinfo)); JMETHOD(noreturn_t, error_exit, (j_common_ptr cinfo));
/* Conditionally emit a trace or warning message */ /* Conditionally emit a trace or warning message */
JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
/* Routine that actually outputs a trace or error message */ /* Routine that actually outputs a trace or error message */

View file

@ -1,7 +1,7 @@
/* /*
* jversion.h * jversion.h
* *
* Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -9,6 +9,6 @@
*/ */
#define JVERSION "8c 16-Jan-2011" #define JVERSION "9 13-Jan-2013"
#define JCOPYRIGHT "Copyright (C) 2011, Thomas G. Lane, Guido Vollbeding" #define JCOPYRIGHT "Copyright (C) 2013, Thomas G. Lane, Guido Vollbeding"

View file

@ -1,7 +1,7 @@
/* /*
* transupp.h * transupp.h
* *
* Copyright (C) 1997-2009, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -57,6 +57,7 @@
* corner up and/or left to make it so, simultaneously increasing the region * corner up and/or left to make it so, simultaneously increasing the region
* dimensions to keep the lower right crop corner unchanged. (Thus, the * dimensions to keep the lower right crop corner unchanged. (Thus, the
* output image covers at least the requested region, but may cover more.) * output image covers at least the requested region, but may cover more.)
* The adjustment of the region dimensions may be optionally disabled.
* *
* We also provide a lossless-resize option, which is kind of a lossless-crop * 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 * operation in the DCT coefficient block domain - it discards higher-order
@ -106,13 +107,15 @@ typedef enum {
/* /*
* Codes for crop parameters, which can individually be unspecified, * Codes for crop parameters, which can individually be unspecified,
* positive, or negative. (Negative width or height makes no sense, though.) * positive or negative for xoffset or yoffset,
* positive or forced for width or height.
*/ */
typedef enum { typedef enum {
JCROP_UNSET, JCROP_UNSET,
JCROP_POS, JCROP_POS,
JCROP_NEG JCROP_NEG,
JCROP_FORCE
} JCROP_CODE; } JCROP_CODE;
/* /*
@ -133,9 +136,9 @@ typedef struct {
* These can be filled in by jtransform_parse_crop_spec(). * These can be filled in by jtransform_parse_crop_spec().
*/ */
JDIMENSION crop_width; /* Width of selected region */ JDIMENSION crop_width; /* Width of selected region */
JCROP_CODE crop_width_set; JCROP_CODE crop_width_set; /* (forced disables adjustment) */
JDIMENSION crop_height; /* Height of selected region */ JDIMENSION crop_height; /* Height of selected region */
JCROP_CODE crop_height_set; JCROP_CODE crop_height_set; /* (forced disables adjustment) */
JDIMENSION crop_xoffset; /* X offset of selected region */ JDIMENSION crop_xoffset; /* X offset of selected region */
JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */ JCROP_CODE crop_xoffset_set; /* (negative measures from right edge) */
JDIMENSION crop_yoffset; /* Y offset of selected region */ JDIMENSION crop_yoffset; /* Y offset of selected region */