Compare commits

...

2 Commits

Author SHA1 Message Date
Thomas G. Lane
a8b67c4fbb The Independent JPEG Group's JPEG software v5b 2015-07-29 15:30:19 -05:00
Thomas G. Lane
9ba2f5ed36 The Independent JPEG Group's JPEG software v5a 2015-07-29 15:29:17 -05:00
55 changed files with 2325 additions and 1406 deletions

61
README
View File

@@ -1,17 +1,17 @@
The Independent JPEG Group's JPEG software The Independent JPEG Group's JPEG software
========================================== ==========================================
README for release 5 of 24-Sep-94 README for release 5b of 15-Mar-95
================================= ==================================
This distribution contains the fifth public release of the Independent JPEG This distribution contains the fifth 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.
Serious users of this software (particularly those incorporating it into Serious users of this software (particularly those incorporating it into
larger programs) should contact jpeg-info@uunet.uu.net to be added to our larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
electronic mailing list. Mailing list members are notified of updates and our electronic mailing list. Mailing list members are notified of updates
have a chance to participate in technical discussions, etc. and have a chance to participate in technical discussions, etc.
This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim
Boucher, Lee Crocker, George Phillips, Davide Rossi, Ge' Weijers, and other Boucher, Lee Crocker, George Phillips, Davide Rossi, Ge' Weijers, and other
@@ -82,7 +82,7 @@ although some uncommon parameter settings aren't implemented yet. For legal
reasons, we are not distributing code for the arithmetic-coding process; see reasons, we are not distributing code for the arithmetic-coding process; see
LEGAL ISSUES. At present we have made no provision for supporting the LEGAL ISSUES. At present we have made no provision for supporting the
progressive, hierarchical, or lossless processes defined in the standard. progressive, hierarchical, or lossless processes defined in the standard.
(Support for progressive mode may be offered in a future release.) (Support for progressive mode will be offered in a future release.)
In order to support file conversion and viewing software, we have included In order to support file conversion and viewing software, we have included
considerable functionality beyond the bare JPEG coding/decoding capability; considerable functionality beyond the bare JPEG coding/decoding capability;
@@ -124,7 +124,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, 1992, 1993, 1994, Thomas G. Lane. This software is copyright (C) 1991, 1992, 1993, 1994, 1995, Thomas G. Lane.
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
@@ -164,9 +164,8 @@ 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 of any program generated from the IJG code, this does not limit you more than
the foregoing paragraphs do. the foregoing paragraphs do.
The configuration script "configure" was produced by GNU Autoconf. Again, The configuration script "configure" was produced with GNU Autoconf. It
the FSF copyright terms apply only to configure, not to the IJG code; and is copyright by the Free Software Foundation but is freely distributable.
again, that does not limit your use of the object code.
It appears that the arithmetic coding option of the JPEG spec is covered by It appears that the arithmetic coding option of the JPEG spec is covered by
patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
@@ -177,6 +176,14 @@ Huffman mode, it is unlikely that very many implementations will support it.)
So far as we are aware, there are no patent restrictions on the remaining So far as we are aware, there are no patent restrictions on the remaining
code. code.
WARNING: Unisys has begun to enforce their patent on LZW compression against
GIF encoders and decoders. You will need a license from Unisys to use the
included rdgif.c or wrgif.c files in a commercial or shareware application.
At this time, Unisys is not enforcing their patent against freeware, so
distribution of this package remains legal. However, we intend to remove
GIF support from the IJG package as soon as a suitable replacement format
becomes reasonably popular.
We are required to state that We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of "The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe Incorporated. GIF(sm) is a Service Mark property of
@@ -194,12 +201,12 @@ The best short technical introduction to the JPEG compression algorithm is
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
(Adjacent articles in that issue discuss MPEG motion picture compression, (Adjacent articles in that issue discuss MPEG motion picture compression,
applications of JPEG, and related topics.) If you don't have the CACM issue applications of JPEG, and related topics.) If you don't have the CACM issue
handy, a PostScript file containing a revised version of Wallace's article is handy, a PostScript file containing a revised version of Wallace's article
available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually a is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually
preprint for an article to appear in IEEE Trans. Consumer Electronics) omits a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
the sample images that appeared in CACM, but it includes corrections and some omits the sample images that appeared in CACM, but it includes corrections
added material. Note: the Wallace article is copyright ACM and IEEE, and it and some added material. Note: the Wallace article is copyright ACM and
may not be used for commercial purposes. IEEE, and it may not be used for commercial purposes.
A somewhat less technical, more leisurely introduction to JPEG can be found in A somewhat less technical, more leisurely introduction to JPEG can be found in
"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood "The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood
@@ -264,7 +271,7 @@ ARCHIVE LOCATIONS
The "official" archive site for this software is ftp.uu.net (Internet The "official" archive site for this software is ftp.uu.net (Internet
address 192.48.96.9). The most recent released version can always be found address 192.48.96.9). The most recent released version can always be found
there in directory graphics/jpeg. This particular version will be archived there in directory graphics/jpeg. This particular version will be archived
as graphics/jpeg/jpegsrc.v5.tar.gz. If you are on the Internet, you as graphics/jpeg/jpegsrc.v5b.tar.gz. If you are on the Internet, you
can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't
have FTP access, UUNET's archives are also available via UUCP; contact have FTP access, UUNET's archives are also available via UUCP; contact
help@uunet.uu.net for information on retrieving files that way. help@uunet.uu.net for information on retrieving files that way.
@@ -275,17 +282,19 @@ submissions. However, only ftp.uu.net is guaranteed to have the latest
official version. official version.
You can also obtain this software from CompuServe, in the GRAPHSUPPORT forum You can also obtain this software from CompuServe, in the GRAPHSUPPORT forum
(GO GRAPHSUP); this version will be file jpsrc5.zip in library 15. Again, (GO GRAPHSUP), library 12 "JPEG Tools". Again, CompuServe is not guaranteed
CompuServe is not guaranteed to have the very latest version. to have the very latest version.
The JPEG FAQ (Frequently Asked Questions) article is a useful source of The JPEG FAQ (Frequently Asked Questions) article is a useful source of
general information about JPEG. It is updated constantly and therefore general information about JPEG. It is updated constantly and therefore is
is not included in this distribution. The FAQ is posted every two weeks not included in this distribution. The FAQ is posted every two weeks to
to Usenet newsgroups comp.graphics, news.answers, and other groups. You Usenet newsgroups comp.graphics, news.answers, and other groups. You can
can always obtain the latest version from the news.answers archive at always obtain the latest version from the news.answers archive at
rtfm.mit.edu (18.181.0.24). By FTP, fetch /pub/usenet/news.answers/jpeg-faq. rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and
If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu with body .../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu
"send usenet/news.answers/jpeg-faq". with body
send usenet/news.answers/jpeg-faq/part1
send usenet/news.answers/jpeg-faq/part2
RELATED SOFTWARE RELATED SOFTWARE

View File

@@ -12,29 +12,29 @@
* some other language. * some other language.
*/ */
/*
/* To define the enum list of message codes, include this file without * To define the enum list of message codes, include this file without
* defining JMAKE_MSG_TABLE. To create the message string table, include it * defining macro JMESSAGE. To create a message string table, include it
* again with JMAKE_MSG_TABLE defined (this should be done in just one module). * again with a suitable JMESSAGE definition (see jerror.c for an example).
*/ */
#ifndef JMESSAGE
#ifndef CDERROR_H
#define CDERROR_H
/* First time through, define the enum list */
#define JMAKE_ENUM_LIST
#else
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
#define JMESSAGE(code,string)
#endif /* CDERROR_H */
#endif /* JMESSAGE */
#ifdef JMAKE_MSG_TABLE #ifdef JMAKE_ENUM_LIST
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define addon_message_table cdMsgTable
#endif
const char * const addon_message_table[] = {
#define JMESSAGE(code,string) string ,
#else /* not JMAKE_MSG_TABLE */
typedef enum { typedef enum {
#define JMESSAGE(code,string) code , #define JMESSAGE(code,string) code ,
#endif /* JMAKE_MSG_TABLE */ #endif /* JMAKE_ENUM_LIST */
JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */ JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */
@@ -120,16 +120,13 @@ JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
#endif #endif
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format") JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
#ifdef JMAKE_MSG_TABLE #ifdef JMAKE_ENUM_LIST
NULL
};
#else /* not JMAKE_MSG_TABLE */
JMSG_LASTADDONCODE JMSG_LASTADDONCODE
} ADDON_MESSAGE_CODE; } ADDON_MESSAGE_CODE;
#endif /* JMAKE_MSG_TABLE */ #undef JMAKE_ENUM_LIST
#endif /* JMAKE_ENUM_LIST */
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
#undef JMESSAGE #undef JMESSAGE

View File

@@ -1,6 +1,51 @@
CHANGE LOG for Independent JPEG Group's JPEG software CHANGE LOG for Independent JPEG Group's JPEG software
Version 5b 15-Mar-95
---------------------
Correct bugs with grayscale images having v_samp_factor > 1.
jpeg_write_raw_data() now supports output suspension.
Correct bugs in "configure" script for case of compiling in
a directory other than the one containing the source files.
Repair bug in jquant1.c: sometimes didn't use as many colors as it could.
Borland C makefile and jconfig file work under either MS-DOS or OS/2.
Miscellaneous improvements to documentation.
Version 5a 7-Dec-94
--------------------
Changed color conversion roundoff behavior so that grayscale values are
represented exactly. (This causes test image files to change.)
Make ordered dither use 16x16 instead of 4x4 pattern for a small quality
improvement.
New configure script based on latest GNU Autoconf.
Fix configure script to handle CFLAGS correctly.
Rename *.auto files to *.cfg, so that configure script still works if
file names have been truncated for DOS.
Fix bug in rdbmp.c: didn't allow for extra data between header and image.
Modify rdppm.c/wrppm.c to handle 2-byte raw PPM/PGM formats for 12-bit data.
Fix several bugs in rdrle.c.
NEED_SHORT_EXTERNAL_NAMES option was broken.
Revise jerror.h/jerror.c for more flexibility in message table.
Repair oversight in jmemname.c NO_MKTEMP case: file could be there
but unreadable.
Version 5 24-Sep-94 Version 5 24-Sep-94
-------------------- --------------------

12
cjpeg.1
View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "30 August 1994" .TH CJPEG 1 "12 December 1994"
.SH NAME .SH NAME
cjpeg \- compress an image file to a JPEG file cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS .SH SYNOPSIS
@@ -115,11 +115,11 @@ Use fast integer DCT (less accurate).
.TP .TP
.B \-dct float .B \-dct float
Use floating-point DCT method. Use floating-point DCT method.
The floating-point method is the most accurate, but will be the slowest unless The float method is very slightly more accurate than the int method, but is
your machine has very fast floating-point hardware. Also note that results of much slower unless your machine has very fast floating-point hardware. Also
the floating-point method may vary slightly across machines, while the integer note that results of the floating-point method may vary slightly across
methods should give the same results everywhere. The fast integer method is machines, while the integer methods should give the same results everywhere.
much less accurate than the other two. The fast integer method is much less accurate than the other two.
.TP .TP
.BI \-restart " N" .BI \-restart " N"
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is

20
cjpeg.c
View File

@@ -24,8 +24,6 @@
*/ */
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#define JMAKE_MSG_TABLE
#include "cderror.h" /* create message string table */
#include "jversion.h" /* for version message */ #include "jversion.h" /* for version message */
#include <ctype.h> /* to declare isupper(), tolower() */ #include <ctype.h> /* to declare isupper(), tolower() */
@@ -74,6 +72,16 @@
#endif #endif
/* Create the add-on message string table. */
#define JMESSAGE(code,string) string ,
static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
NULL
};
/* /*
* This routine determines what format the input file is, * This routine determines what format the input file is,
* and selects the appropriate input-reading module. * and selects the appropriate input-reading module.
@@ -726,7 +734,7 @@ main (int argc, char **argv)
cinfo.err = jpeg_std_error(&jerr); cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo); jpeg_create_compress(&cinfo);
/* Add some application-specific error messages (from cderror.h) */ /* Add some application-specific error messages (from cderror.h) */
jerr.addon_message_table = addon_message_table; jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE; jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE; jerr.last_addon_message = JMSG_LASTADDONCODE;
@@ -863,6 +871,12 @@ main (int argc, char **argv)
jpeg_finish_compress(&cinfo); jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
/* Close files, if we opened them */
if (input_file != stdin)
fclose(input_file);
if (output_file != stdout)
fclose(output_file);
#ifdef PROGRESS_REPORT #ifdef PROGRESS_REPORT
/* Clear away progress display */ /* Clear away progress display */
if (jerr.trace_level == 0) { if (jerr.trace_level == 0) {

1948
configure vendored

File diff suppressed because it is too large Load Diff

18
djpeg.1
View File

@@ -1,4 +1,4 @@
.TH DJPEG 1 "28 August 1994" .TH DJPEG 1 "12 December 1994"
.SH NAME .SH NAME
djpeg \- decompress a JPEG file to an image file djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS .SH SYNOPSIS
@@ -117,11 +117,11 @@ Use fast integer DCT (less accurate).
.TP .TP
.B \-dct float .B \-dct float
Use floating-point DCT method. Use floating-point DCT method.
The floating-point method is the most accurate, but will be the slowest unless The float method is very slightly more accurate than the int method, but is
your machine has very fast floating-point hardware. Also note that results of much slower unless your machine has very fast floating-point hardware. Also
the floating-point method may vary slightly across machines, while the integer note that results of the floating-point method may vary slightly across
methods should give the same results everywhere. The fast integer method is machines, while the integer methods should give the same results everywhere.
much less accurate than the other two. The fast integer method is much less accurate than the other two.
.TP .TP
.B \-dither fs .B \-dither fs
Use Floyd-Steinberg dithering in color quantization. Use Floyd-Steinberg dithering in color quantization.
@@ -214,8 +214,10 @@ may give acceptable results in two-pass mode, but is seldom tolerable in
one-pass mode. one-pass mode.
.PP .PP
If you are fortunate enough to have very fast floating point hardware, If you are fortunate enough to have very fast floating point hardware,
.B \-dct float \fB\-dct float\fR may be even faster than \fB\-dct fast\fR. But on most
may be even faster than \fB\-dct fast\fR. machines \fB\-dct float\fR is slower than \fB\-dct int\fR; in this case it is
not worth using, because its theoretical accuracy advantage is too small to be
significant in practice.
.SH ENVIRONMENT .SH ENVIRONMENT
.TP .TP
.B JPEGMEM .B JPEGMEM

20
djpeg.c
View File

@@ -24,8 +24,6 @@
*/ */
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#define JMAKE_MSG_TABLE
#include "cderror.h" /* create message string table */
#include "jversion.h" /* for version message */ #include "jversion.h" /* for version message */
#include <ctype.h> /* to declare isupper(),tolower(),isprint() */ #include <ctype.h> /* to declare isupper(),tolower(),isprint() */
@@ -74,6 +72,16 @@
#endif #endif
/* Create the add-on message string table. */
#define JMESSAGE(code,string) string ,
static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
NULL
};
/* /*
* This list defines the known output image formats * This list defines the known output image formats
* (not all of which need be supported by a given version). * (not all of which need be supported by a given version).
@@ -545,7 +553,7 @@ main (int argc, char **argv)
cinfo.err = jpeg_std_error(&jerr); cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo); jpeg_create_decompress(&cinfo);
/* Add some application-specific error messages (from cderror.h) */ /* Add some application-specific error messages (from cderror.h) */
jerr.addon_message_table = addon_message_table; jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE; jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE; jerr.last_addon_message = JMSG_LASTADDONCODE;
/* Insert custom COM marker processor. */ /* Insert custom COM marker processor. */
@@ -722,6 +730,12 @@ main (int argc, char **argv)
jpeg_finish_decompress(&cinfo); jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
/* Close files, if we opened them */
if (input_file != stdin)
fclose(input_file);
if (output_file != stdout)
fclose(output_file);
#ifdef PROGRESS_REPORT #ifdef PROGRESS_REPORT
/* Clear away progress display */ /* Clear away progress display */
if (jerr.trace_level == 0) { if (jerr.trace_level == 0) {

View File

@@ -83,6 +83,8 @@ write_JPEG_file (char * filename, int quality)
* (see the second half of this file for an example). But here we just * (see the second half of this file for an example). But here we just
* take the easy way out and use the standard error handler, which will * take the easy way out and use the standard error handler, which will
* print a message on stderr and call exit() if compression fails. * print a message on stderr and call exit() if compression fails.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/ */
struct jpeg_error_mgr jerr; struct jpeg_error_mgr jerr;
/* More stuff */ /* More stuff */
@@ -281,7 +283,10 @@ read_JPEG_file (char * filename)
* working space (which is allocated as needed by the JPEG library). * working space (which is allocated as needed by the JPEG library).
*/ */
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
/* We use our private extension JPEG error handler. */ /* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr; struct my_error_mgr jerr;
/* More stuff */ /* More stuff */
FILE * infile; /* source file */ FILE * infile; /* source file */

View File

@@ -1,6 +1,6 @@
INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
Copyright (C) 1991-1994, Thomas G. Lane. Copyright (C) 1991-1995, Thomas G. Lane.
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.
@@ -102,13 +102,16 @@ For example, on HP-UX you probably want to say
./configure CC='cc -Aa' ./configure CC='cc -Aa'
to get HP's compiler to run in ANSI mode. to get HP's compiler to run in ANSI mode.
* The default CFLAGS setting is "-O". You can override this by saying,
for example, ./configure CFLAGS='-O2'.
* Configure will set up the makefile so that "make install" will install files * Configure will set up the makefile so that "make install" will install files
into /usr/local/bin, /usr/local/man, etc. You can specify an installation into /usr/local/bin, /usr/local/man, etc. You can specify an installation
prefix other than "/usr/local" by giving configure the option "--prefix=PATH". prefix other than "/usr/local" by giving configure the option "--prefix=PATH".
* If you don't have a lot of swap space, you may need to enable the IJG * If you don't have a lot of swap space, you may need to enable the IJG
software's internal virtual memory mechanism. To do this, give the option software's internal virtual memory mechanism. To do this, give the option
"--with-maxmem=N" where N is the default maxmemory limit in megabytes. "--enable-maxmem=N" where N is the default maxmemory limit in megabytes.
This is discussed in more detail under "Selecting a memory manager", below. This is discussed in more detail under "Selecting a memory manager", below.
You probably don't need to worry about this on reasonably-sized Unix machines, You probably don't need to worry about this on reasonably-sized Unix machines,
unless you plan to process very large images. unless you plan to process very large images.
@@ -129,7 +132,7 @@ Makefile jconfig file System and/or compiler
makefile.manx jconfig.manx Amiga, Manx Aztec C makefile.manx jconfig.manx Amiga, Manx Aztec C
makefile.sas jconfig.sas Amiga, SAS C makefile.sas jconfig.sas Amiga, SAS C
mak*jpeg.st jconfig.st Atari ST/STE/TT, Pure C or Turbo C mak*jpeg.st jconfig.st Atari ST/STE/TT, Pure C or Turbo C
makefile.bcc jconfig.bcc MS-DOS, Borland C (Turbo C) makefile.bcc jconfig.bcc MS-DOS or OS/2, Borland C
makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU C) makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU C)
makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C version 6.x and up makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C version 6.x and up
makefile.mms jconfig.vms Digital VMS, with MMS software makefile.mms jconfig.vms Digital VMS, with MMS software
@@ -390,6 +393,55 @@ support as follows:
the directory containing the URT "librle.a" file (typically the the directory containing the URT "librle.a" file (typically the
"lib" subdirectory of the URT distribution). "lib" subdirectory of the URT distribution).
Support for 12-bit-deep pixel data:
The JPEG standard allows either 8-bit or 12-bit data precision. (For color,
this means 8 or 12 bits per channel, of course.) If you need to work with
deeper than 8-bit data, you can compile the IJG code for 12-bit operation.
To do so:
1. In jmorecfg.h, define BITS_IN_JSAMPLE as 12 rather than 8.
2. In jconfig.h, undefine BMP_SUPPORTED, RLE_SUPPORTED, and TARGA_SUPPORTED,
because the code for those formats doesn't handle 12-bit data and won't
even compile. (The PPM code does work, as explained below. The GIF
code works too; it scales 8-bit GIF data to and from 12-bit depth
automatically.)
3. Compile. Don't expect "make test" to pass, since the supplied test
files are for 8-bit data.
Currently, 12-bit support does not work on 16-bit-int machines.
Note that a 12-bit version will not read 8-bit JPEG files, nor vice versa;
so you'll want to keep around a regular 8-bit compilation as well.
(Run-time selection of data depth, to allow a single copy that does both,
is possible but would probably slow things down considerably; it's very low
on our to-do list.)
The PPM reader (rdppm.c) can read 12-bit data from either text-format or
binary-format PPM and PGM files. Binary-format PPM/PGM files which have a
maxval greater than 255 are assumed to use 2 bytes per sample, LSB first
(little-endian order). As of early 1995, 2-byte binary format is not
officially supported by the PBMPLUS library, but it is expected that the
next release of PBMPLUS will support it. Note that the PPM reader will
read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming
data is automatically rescaled to either maxval=255 or maxval=4095 as
appropriate for the cjpeg bit depth.
The PPM writer (wrppm.c) will normally write 2-byte binary PPM or PGM
format, maxval 4095, when compiled with BITS_IN_JSAMPLE=12. Since this
format is not yet widely supported, you can disable it by compiling wrppm.c
with PPM_NORAWWORD defined; then the data is scaled down to 8 bits to make a
standard 1-byte/sample PPM or PGM file. (Yes, this means still another copy
of djpeg to keep around. But hopefully you won't need it for very long.
Poskanzer's supposed to get that new PBMPLUS release out Real Soon Now.)
Of course, if you are working with 12-bit data, you probably have it stored
in some other, nonstandard format. In that case you'll probably want to
write your own I/O modules to read and write your format.
Note that a 12-bit version of cjpeg always runs in "-optimize" mode, in
order to generate valid Huffman tables. This is necessary because our
default Huffman tables only cover 8-bit data.
Removing code: Removing code:
If you need to make a smaller version of the JPEG software, some optional If you need to make a smaller version of the JPEG software, some optional
@@ -500,6 +552,10 @@ Amiga:
SAS C 6.50 reportedly is too buggy to compile the IJG code properly. SAS C 6.50 reportedly is too buggy to compile the IJG code properly.
A patch to update to 6.51 is available from SAS or AmiNet FTP sites. A patch to update to 6.51 is available from SAS or AmiNet FTP sites.
The supplied config files are set up to use jmemname.c as the memory
manager, with temporary files being created on the device named by
"JPEGTMP:".
Atari ST/STE/TT: Atari ST/STE/TT:
@@ -731,6 +787,12 @@ Set "AR2= ar -ts" rather than "AR2= ranlib" in the Makefile. If you are
using configure, you should say using configure, you should say
./configure RANLIB='ar -ts' ./configure RANLIB='ar -ts'
On the MIPS R4000 architecture (Indy, etc.), the compiler option "-mips2"
reportedly speeds up the float DCT method substantially, enough to make it
faster than the default int method (but still slower than the fast int
method). If you use -mips2, you may want to alter the default DCT method to
be float. To do this, put "#define JDCT_DEFAULT JDCT_FLOAT" in jconfig.h.
VMS: VMS:

31
jcapi.c
View File

@@ -1,7 +1,7 @@
/* /*
* jcapi.c * jcapi.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1995, Thomas G. Lane.
* 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.
* *
@@ -199,14 +199,14 @@ jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
/* /*
* Alternate entry point to write raw data. * Alternate entry point to write raw data.
* Processes exactly one iMCU row per call. * Processes exactly one iMCU row per call, unless suspended.
*/ */
GLOBAL JDIMENSION GLOBAL JDIMENSION
jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION num_lines) JDIMENSION num_lines)
{ {
JDIMENSION mcu_ctr, lines_per_MCU_row; JDIMENSION lines_per_iMCU_row;
if (cinfo->global_state != CSTATE_RAW_OK) if (cinfo->global_state != CSTATE_RAW_OK)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
@@ -231,22 +231,19 @@ jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
(*cinfo->master->pass_startup) (cinfo); (*cinfo->master->pass_startup) (cinfo);
/* Verify that at least one iMCU row has been passed. */ /* Verify that at least one iMCU row has been passed. */
lines_per_MCU_row = cinfo->max_v_samp_factor * DCTSIZE; lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
if (num_lines < lines_per_MCU_row) if (num_lines < lines_per_iMCU_row)
ERREXIT(cinfo, JERR_BUFFER_SIZE); ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Directly compress the row. */ /* Directly compress the row. */
mcu_ctr = 0; if (! (*cinfo->coef->compress_data) (cinfo, data)) {
(*cinfo->coef->compress_data) (cinfo, data, &mcu_ctr); /* If compressor did not consume the whole row, suspend processing. */
/* If compressor did not consume the whole row, then we must need to return 0;
* suspend processing; this is not currently supported. }
*/
if (mcu_ctr != cinfo->MCUs_per_row)
ERREXIT(cinfo, JERR_CANT_SUSPEND);
/* OK, we processed one iMCU row. */ /* OK, we processed one iMCU row. */
cinfo->next_scanline += lines_per_MCU_row; cinfo->next_scanline += lines_per_iMCU_row;
return lines_per_MCU_row; return lines_per_iMCU_row;
} }
@@ -260,7 +257,7 @@ jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
GLOBAL void GLOBAL void
jpeg_finish_compress (j_compress_ptr cinfo) jpeg_finish_compress (j_compress_ptr cinfo)
{ {
JDIMENSION iMCU_row, mcu_ctr; JDIMENSION iMCU_row;
if (cinfo->global_state != CSTATE_SCANNING && if (cinfo->global_state != CSTATE_SCANNING &&
cinfo->global_state != CSTATE_RAW_OK) cinfo->global_state != CSTATE_RAW_OK)
@@ -281,9 +278,7 @@ jpeg_finish_compress (j_compress_ptr cinfo)
/* We bypass the main controller and invoke coef controller directly; /* We bypass the main controller and invoke coef controller directly;
* all work is being done from the coefficient buffer. * all work is being done from the coefficient buffer.
*/ */
mcu_ctr = 0; if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
(*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL, &mcu_ctr);
if (mcu_ctr != cinfo->MCUs_per_row)
ERREXIT(cinfo, JERR_CANT_SUSPEND); ERREXIT(cinfo, JERR_CANT_SUSPEND);
} }
(*cinfo->master->finish_pass) (cinfo); (*cinfo->master->finish_pass) (cinfo);

View File

@@ -1,7 +1,7 @@
/* /*
* jccoefct.c * jccoefct.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1995, Thomas G. Lane.
* 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,7 +34,10 @@
typedef struct { typedef struct {
struct jpeg_c_coef_controller pub; /* public fields */ struct jpeg_c_coef_controller pub; /* public fields */
JDIMENSION MCU_row_num; /* keep track of MCU row # within image */ JDIMENSION iMCU_row_num; /* iMCU row # within image */
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
int MCU_vert_offset; /* counts MCU rows within iMCU row */
int MCU_rows_per_iMCU_row; /* number of such rows needed */
/* For single-pass compression, it's sufficient to buffer just one MCU /* For single-pass compression, it's sufficient to buffer just one MCU
* (although this may prove a bit slow in practice). We allocate a * (although this may prove a bit slow in practice). We allocate a
@@ -55,16 +58,40 @@ typedef my_coef_controller * my_coef_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF void compress_data METHODDEF boolean compress_data
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_mcu_ctr)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#ifdef FULL_COEF_BUFFER_SUPPORTED #ifdef FULL_COEF_BUFFER_SUPPORTED
METHODDEF void compress_first_pass METHODDEF boolean compress_first_pass
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_mcu_ctr)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
METHODDEF void compress_output METHODDEF boolean compress_output
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf, JDIMENSION *in_mcu_ctr)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#endif #endif
LOCAL void
start_iMCU_row (j_compress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
/* In an interleaved scan, an MCU row is the same as an iMCU row.
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
* But at the bottom of the image, process only what's left.
*/
if (cinfo->comps_in_scan > 1) {
coef->MCU_rows_per_iMCU_row = 1;
} else {
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
else
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
}
coef->mcu_ctr = 0;
coef->MCU_vert_offset = 0;
}
/* /*
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
@@ -74,7 +101,8 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
coef->MCU_row_num = 0; coef->iMCU_row_num = 0;
start_iMCU_row(cinfo);
switch (pass_mode) { switch (pass_mode) {
case JBUF_PASS_THRU: case JBUF_PASS_THRU:
@@ -103,78 +131,89 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
/* /*
* Process some data in the single-pass case. * Process some data in the single-pass case.
* Up to one MCU row is processed (less if suspension is forced). * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor block rows for each component in the image.
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
* *
* NB: input_buf contains a plane for each component in image. * NB: input_buf contains a plane for each component in image.
* For single pass, this is the same as the components in the scan. * For single pass, this is the same as the components in the scan.
*/ */
METHODDEF void METHODDEF boolean
compress_data (j_compress_ptr cinfo, compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
JSAMPIMAGE input_buf, JDIMENSION *in_mcu_ctr)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION MCU_col_num; /* index of current MCU within row */
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
JDIMENSION last_MCU_row = cinfo->MCU_rows_in_scan - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
int blkn, bi, ci, yindex, blockcnt; int blkn, bi, ci, yindex, yoffset, blockcnt;
JDIMENSION ypos, xpos; JDIMENSION ypos, xpos;
jpeg_component_info *compptr; jpeg_component_info *compptr;
/* Loop to write as much as one whole MCU row */ /* Loop to write as much as one whole iMCU row */
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
for (MCU_col_num = *in_mcu_ctr; MCU_col_num <= last_MCU_col; MCU_col_num++) { yoffset++) {
/* Determine where data comes from in input_buf and do the DCT thing. for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
* Each call on forward_DCT processes a horizontal row of DCT blocks MCU_col_num++) {
* as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks /* Determine where data comes from in input_buf and do the DCT thing.
* sequentially. Dummy blocks at the right or bottom edge are filled in * Each call on forward_DCT processes a horizontal row of DCT blocks
* specially. The data in them does not matter for image reconstruction, * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
* so we fill them with values that will encode to the smallest amount of * sequentially. Dummy blocks at the right or bottom edge are filled in
* data, viz: all zeroes in the AC entries, DC entries equal to previous * specially. The data in them does not matter for image reconstruction,
* block's DC value. (Thanks to Thomas Kinsman for this idea.) * so we fill them with values that will encode to the smallest amount of
*/ * data, viz: all zeroes in the AC entries, DC entries equal to previous
blkn = 0; * block's DC value. (Thanks to Thomas Kinsman for this idea.)
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { */
compptr = cinfo->cur_comp_info[ci]; blkn = 0;
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
: compptr->last_col_width; compptr = cinfo->cur_comp_info[ci];
xpos = MCU_col_num * compptr->MCU_sample_width; blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
ypos = 0; : compptr->last_col_width;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) { xpos = MCU_col_num * compptr->MCU_sample_width;
if (coef->MCU_row_num < last_MCU_row || ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
yindex < compptr->last_row_height) { for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
(*cinfo->fdct->forward_DCT) (cinfo, compptr, if (coef->iMCU_row_num < last_iMCU_row ||
input_buf[ci], coef->MCU_buffer[blkn], yoffset+yindex < compptr->last_row_height) {
ypos, xpos, (JDIMENSION) blockcnt); (*cinfo->fdct->forward_DCT) (cinfo, compptr,
if (blockcnt < compptr->MCU_width) { input_buf[ci], coef->MCU_buffer[blkn],
/* Create some dummy blocks at the right edge of the image. */ ypos, xpos, (JDIMENSION) blockcnt);
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], if (blockcnt < compptr->MCU_width) {
(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); /* Create some dummy blocks at the right edge of the image. */
for (bi = blockcnt; bi < compptr->MCU_width; bi++) { jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
}
}
} else {
/* Create a row of dummy blocks at the bottom of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn],
compptr->MCU_width * SIZEOF(JBLOCK));
for (bi = 0; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
} }
} }
} else { blkn += compptr->MCU_width;
/* Create a whole row of dummy blocks at the bottom of the image. */ ypos += DCTSIZE;
jzero_far((void FAR *) coef->MCU_buffer[blkn],
compptr->MCU_width * SIZEOF(JBLOCK));
for (bi = 0; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
}
} }
blkn += compptr->MCU_width; }
ypos += DCTSIZE; /* Try to write the MCU. In event of a suspension failure, we will
* re-DCT the MCU on restart (a bit inefficient, could be fixed...)
*/
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
/* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
coef->mcu_ctr = MCU_col_num;
return FALSE;
} }
} }
/* Try to write the MCU. In event of a suspension failure, we will /* Completed an MCU row, but perhaps not an iMCU row */
* re-DCT the MCU on restart (a bit inefficient, could be fixed...) coef->mcu_ctr = 0;
*/
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer))
break; /* suspension forced; exit loop */
} }
if (MCU_col_num > last_MCU_col) /* Completed the iMCU row, advance counters for next one */
coef->MCU_row_num++; /* advance if we finished the row */ coef->iMCU_row_num++;
*in_mcu_ctr = MCU_col_num; start_iMCU_row(cinfo);
return TRUE;
} }
@@ -201,12 +240,11 @@ compress_data (j_compress_ptr cinfo,
* at the scan-dependent variables (MCU dimensions, etc). * at the scan-dependent variables (MCU dimensions, etc).
*/ */
METHODDEF void METHODDEF boolean
compress_first_pass (j_compress_ptr cinfo, compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
JSAMPIMAGE input_buf, JDIMENSION *in_mcu_ctr)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION last_MCU_row = cinfo->total_iMCU_rows - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
JDIMENSION blocks_across, MCUs_across, MCUindex; JDIMENSION blocks_across, MCUs_across, MCUindex;
int bi, ci, h_samp_factor, block_row, block_rows, ndummy; int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
JCOEF lastDC; JCOEF lastDC;
@@ -219,11 +257,12 @@ compress_first_pass (j_compress_ptr cinfo,
/* Align the virtual buffer for this component. */ /* Align the virtual buffer for this component. */
buffer = (*cinfo->mem->access_virt_barray) buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[ci], ((j_common_ptr) cinfo, coef->whole_image[ci],
coef->MCU_row_num * compptr->v_samp_factor, TRUE); coef->iMCU_row_num * compptr->v_samp_factor, TRUE);
/* Count non-dummy DCT block rows in this iMCU row. */ /* Count non-dummy DCT block rows in this iMCU row. */
if (coef->MCU_row_num < last_MCU_row) if (coef->iMCU_row_num < last_iMCU_row)
block_rows = compptr->v_samp_factor; block_rows = compptr->v_samp_factor;
else { else {
/* NB: can't use last_row_height here, since may not be set! */
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (block_rows == 0) block_rows = compptr->v_samp_factor; if (block_rows == 0) block_rows = compptr->v_samp_factor;
} }
@@ -257,7 +296,7 @@ compress_first_pass (j_compress_ptr cinfo,
* of the dummy blocks to match the last real block's DC value. * of the dummy blocks to match the last real block's DC value.
* This squeezes a few more bytes out of the resulting file... * This squeezes a few more bytes out of the resulting file...
*/ */
if (coef->MCU_row_num == last_MCU_row) { if (coef->iMCU_row_num == last_iMCU_row) {
blocks_across += ndummy; /* include lower right corner */ blocks_across += ndummy; /* include lower right corner */
MCUs_across = blocks_across / h_samp_factor; MCUs_across = blocks_across / h_samp_factor;
for (block_row = block_rows; block_row < compptr->v_samp_factor; for (block_row = block_rows; block_row < compptr->v_samp_factor;
@@ -277,10 +316,12 @@ compress_first_pass (j_compress_ptr cinfo,
} }
} }
} }
/* NB: compress_output will increment MCU_row_num */ /* NB: compress_output will increment iMCU_row_num if successful.
* A suspension return will result in redoing all the work above next time.
*/
/* Emit data to the entropy encoder, sharing code with subsequent passes */ /* Emit data to the entropy encoder, sharing code with subsequent passes */
compress_output(cinfo, input_buf, in_mcu_ctr); return compress_output(cinfo, input_buf);
} }
@@ -289,22 +330,18 @@ compress_first_pass (j_compress_ptr cinfo,
* We process the equivalent of one fully interleaved MCU row ("iMCU" row) * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor block rows for each component in the scan. * per call, ie, v_samp_factor block rows for each component in the scan.
* The data is obtained from the virtual arrays and fed to the entropy coder. * The data is obtained from the virtual arrays and fed to the entropy coder.
* * Returns TRUE if the iMCU row is completed, FALSE if suspended.
* Note that output suspension is not supported during multi-pass operation,
* so the complete MCU row will always be emitted to the entropy encoder
* before returning.
* *
* NB: input_buf is ignored; it is likely to be a NULL pointer. * NB: input_buf is ignored; it is likely to be a NULL pointer.
*/ */
METHODDEF void METHODDEF boolean
compress_output (j_compress_ptr cinfo, compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
JSAMPIMAGE input_buf, JDIMENSION *in_mcu_ctr)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION MCU_col_num; /* index of current MCU within row */
int blkn, ci, xindex, yindex, yoffset, num_MCU_rows; int blkn, ci, xindex, yindex, yoffset;
JDIMENSION remaining_rows, start_col; JDIMENSION start_col;
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
JBLOCKROW buffer_ptr; JBLOCKROW buffer_ptr;
jpeg_component_info *compptr; jpeg_component_info *compptr;
@@ -317,28 +354,14 @@ compress_output (j_compress_ptr cinfo,
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
buffer[ci] = (*cinfo->mem->access_virt_barray) buffer[ci] = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
coef->MCU_row_num * compptr->v_samp_factor, FALSE); coef->iMCU_row_num * compptr->v_samp_factor, FALSE);
}
/* In an interleaved scan, we process exactly one MCU row.
* In a noninterleaved scan, we need to process v_samp_factor MCU rows,
* each of which contains a single block row.
*/
if (cinfo->comps_in_scan == 1) {
compptr = cinfo->cur_comp_info[0];
num_MCU_rows = compptr->v_samp_factor;
/* but watch out for the bottom of the image */
remaining_rows = cinfo->MCU_rows_in_scan -
coef->MCU_row_num * compptr->v_samp_factor;
if (remaining_rows < (JDIMENSION) num_MCU_rows)
num_MCU_rows = (int) remaining_rows;
} else {
num_MCU_rows = 1;
} }
/* Loop to process one whole iMCU row */ /* Loop to process one whole iMCU row */
for (yoffset = 0; yoffset < num_MCU_rows; yoffset++) { for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
for (MCU_col_num = 0; MCU_col_num < cinfo->MCUs_per_row; MCU_col_num++) { yoffset++) {
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
MCU_col_num++) {
/* Construct list of pointers to DCT blocks belonging to this MCU */ /* Construct list of pointers to DCT blocks belonging to this MCU */
blkn = 0; /* index of current DCT block within MCU */ blkn = 0; /* index of current DCT block within MCU */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
@@ -353,13 +376,19 @@ compress_output (j_compress_ptr cinfo,
} }
/* Try to write the MCU. */ /* Try to write the MCU. */
if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
ERREXIT(cinfo, JERR_CANT_SUSPEND); /* not supported */ /* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
coef->mcu_ctr = MCU_col_num;
return FALSE;
} }
} }
/* Completed an MCU row, but perhaps not an iMCU row */
coef->mcu_ctr = 0;
} }
/* Completed the iMCU row, advance counters for next one */
coef->MCU_row_num++; /* advance to next iMCU row */ coef->iMCU_row_num++;
*in_mcu_ctr = cinfo->MCUs_per_row; start_iMCU_row(cinfo);
return TRUE;
} }
#endif /* FULL_COEF_BUFFER_SUPPORTED */ #endif /* FULL_COEF_BUFFER_SUPPORTED */

View File

@@ -32,9 +32,14 @@ typedef my_color_converter * my_cconvert_ptr;
* 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
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + MAXJSAMPLE/2 * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + MAXJSAMPLE/2 * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 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.)
* Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
* rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
* negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
* were not represented exactly. Now we sacrifice exact representation of
* maximum red and maximum blue in order to get exact grayscales.
* *
* To avoid floating-point arithmetic, we represent the fractional constants * To avoid floating-point arithmetic, we represent the fractional constants
* as integers scaled up by 2^16 (about 4 digits precision); we have to divide * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
@@ -46,11 +51,12 @@ typedef my_color_converter * my_cconvert_ptr;
* for 12-bit samples it is still acceptable. It's not very reasonable for * for 12-bit samples it is still acceptable. It's not very reasonable for
* 16-bit samples, but if you want lossless storage you shouldn't be changing * 16-bit samples, but if you want lossless storage you shouldn't be changing
* colorspace anyway. * colorspace anyway.
* The MAXJSAMPLE/2 offsets and the rounding fudge-factor of 0.5 are included * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
* in the tables to save adding them separately in the inner loop. * in the tables to save adding them separately in the inner loop.
*/ */
#define SCALEBITS 16 /* speediest right-shift on some machines */ #define SCALEBITS 16 /* speediest right-shift on some machines */
#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
#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))
@@ -94,9 +100,13 @@ rgb_ycc_start (j_compress_ptr cinfo)
rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i; rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i; rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + ONE_HALF*(MAXJSAMPLE+1); /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
* This ensures that the maximum output will round to MAXJSAMPLE
* not MAXJSAMPLE+1, and thus that we don't have to range-limit.
*/
rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
/* B=>Cb and R=>Cr tables are the same /* B=>Cb and R=>Cr tables are the same
rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + ONE_HALF*(MAXJSAMPLE+1); rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
*/ */
rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i; rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i; rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;

View File

@@ -1,7 +1,7 @@
/* /*
* jcmainct.c * jcmainct.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1995, Thomas G. Lane.
* 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.
* *
@@ -28,9 +28,8 @@
typedef struct { typedef struct {
struct jpeg_c_main_controller pub; /* public fields */ struct jpeg_c_main_controller pub; /* public fields */
JDIMENSION cur_mcu_row; /* number of current iMCU row */ JDIMENSION cur_iMCU_row; /* number of current iMCU row */
JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
JDIMENSION mcu_ctr; /* counts MCUs output from current row */
boolean suspended; /* remember if we suspended output */ boolean suspended; /* remember if we suspended output */
J_BUF_MODE pass_mode; /* current operating mode */ J_BUF_MODE pass_mode; /* current operating mode */
@@ -75,9 +74,8 @@ start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
if (cinfo->raw_data_in) if (cinfo->raw_data_in)
return; return;
main->cur_mcu_row = 0; /* initialize counters */ main->cur_iMCU_row = 0; /* initialize counters */
main->rowgroup_ctr = 0; main->rowgroup_ctr = 0;
main->mcu_ctr = 0;
main->suspended = FALSE; main->suspended = FALSE;
main->pass_mode = pass_mode; /* save mode for use by process_data */ main->pass_mode = pass_mode; /* save mode for use by process_data */
@@ -118,7 +116,7 @@ process_data_simple_main (j_compress_ptr cinfo,
{ {
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr main = (my_main_ptr) cinfo->main;
while (main->cur_mcu_row < cinfo->total_iMCU_rows) { while (main->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 < DCTSIZE) if (main->rowgroup_ctr < DCTSIZE)
(*cinfo->prep->pre_process_data) (cinfo, (*cinfo->prep->pre_process_data) (cinfo,
@@ -134,15 +132,13 @@ process_data_simple_main (j_compress_ptr cinfo,
return; return;
/* Send the completed row to the compressor */ /* Send the completed row to the compressor */
(*cinfo->coef->compress_data) (cinfo, main->buffer, &main->mcu_ctr); if (! (*cinfo->coef->compress_data) (cinfo, main->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->mcu_ctr < cinfo->MCUs_per_row) {
if (! main->suspended) { if (! main->suspended) {
(*in_row_ctr)--; (*in_row_ctr)--;
main->suspended = TRUE; main->suspended = TRUE;
@@ -156,9 +152,8 @@ process_data_simple_main (j_compress_ptr cinfo,
(*in_row_ctr)++; (*in_row_ctr)++;
main->suspended = FALSE; main->suspended = FALSE;
} }
main->mcu_ctr = 0;
main->rowgroup_ctr = 0; main->rowgroup_ctr = 0;
main->cur_mcu_row++; main->cur_iMCU_row++;
} }
} }
@@ -180,14 +175,14 @@ process_data_buffer_main (j_compress_ptr cinfo,
jpeg_component_info *compptr; jpeg_component_info *compptr;
boolean writing = (main->pass_mode != JBUF_CRANK_DEST); boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
while (main->cur_mcu_row < cinfo->total_iMCU_rows) { while (main->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 (main->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) main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, main->whole_image[ci], ((j_common_ptr) cinfo, main->whole_image[ci],
main->cur_mcu_row * (compptr->v_samp_factor * DCTSIZE), writing); main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), 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) {
@@ -210,14 +205,13 @@ process_data_buffer_main (j_compress_ptr cinfo,
/* 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 (main->pass_mode != JBUF_SAVE_SOURCE) {
(*cinfo->coef->compress_data) (cinfo, main->buffer, &main->mcu_ctr); if (! (*cinfo->coef->compress_data) (cinfo, main->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->mcu_ctr < cinfo->MCUs_per_row) {
if (! main->suspended) { if (! main->suspended) {
(*in_row_ctr)--; (*in_row_ctr)--;
main->suspended = TRUE; main->suspended = TRUE;
@@ -234,9 +228,8 @@ process_data_buffer_main (j_compress_ptr cinfo,
} }
/* 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->mcu_ctr = 0;
main->rowgroup_ctr = 0; main->rowgroup_ctr = 0;
main->cur_mcu_row++; main->cur_iMCU_row++;
} }
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jcmaster.c * jcmaster.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1995, Thomas G. Lane.
* 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.
* *
@@ -134,7 +134,12 @@ per_scan_setup (j_compress_ptr cinfo)
compptr->MCU_blocks = 1; compptr->MCU_blocks = 1;
compptr->MCU_sample_width = DCTSIZE; compptr->MCU_sample_width = DCTSIZE;
compptr->last_col_width = 1; compptr->last_col_width = 1;
compptr->last_row_height = 1; /* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row.
*/
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (tmp == 0) tmp = compptr->v_samp_factor;
compptr->last_row_height = tmp;
/* Prepare array describing MCU composition */ /* Prepare array describing MCU composition */
cinfo->blocks_in_MCU = 1; cinfo->blocks_in_MCU = 1;

View File

@@ -1,4 +1,4 @@
/* jconfig.bcc --- jconfig.h for Borland C (Turbo C) on MS-DOS. */ /* jconfig.bcc --- jconfig.h for Borland C (Turbo C) on MS-DOS or OS/2. */
/* see jconfig.doc for explanations */ /* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES #define HAVE_PROTOTYPES
@@ -11,19 +11,21 @@
#define HAVE_STDLIB_H #define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS #undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H #undef NEED_SYS_TYPES_H
#ifdef __MSDOS__
#define NEED_FAR_POINTERS /* for small or medium memory model */ #define NEED_FAR_POINTERS /* for small or medium memory model */
#endif
#undef NEED_SHORT_EXTERNAL_NAMES #undef NEED_SHORT_EXTERNAL_NAMES
#define INCOMPLETE_TYPES_BROKEN /* suppress undefined-structure warnings */ #undef INCOMPLETE_TYPES_BROKEN /* this assumes you have -w-stu in CFLAGS */
#ifdef JPEG_INTERNALS #ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED #undef RIGHT_SHIFT_IS_UNSIGNED
#ifdef __MSDOS__
#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */ #define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */
#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */ #define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
#define USE_FMEM /* Borland has _fmemcpy() and _fmemset() */ #define USE_FMEM /* Borland has _fmemcpy() and _fmemset() */
#endif
#endif /* JPEG_INTERNALS */ #endif /* JPEG_INTERNALS */
@@ -37,7 +39,9 @@
#define TWO_FILE_COMMANDLINE #define TWO_FILE_COMMANDLINE
#define USE_SETMODE /* Borland has setmode() */ #define USE_SETMODE /* Borland has setmode() */
#ifdef __MSDOS__
#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */ #define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */
#endif
#undef DONT_USE_B_MODE #undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */ #undef PROGRESS_REPORT /* optional */

View File

@@ -1,4 +1,4 @@
/* jconfig.auto --- source file edited by configure script */ /* jconfig.cfg --- source file edited by configure script */
/* see jconfig.doc for explanations */ /* see jconfig.doc for explanations */
#undef HAVE_PROTOTYPES #undef HAVE_PROTOTYPES

18
jdapi.c
View File

@@ -1,7 +1,7 @@
/* /*
* jdapi.c * jdapi.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1995, Thomas G. Lane.
* 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.
* *
@@ -345,14 +345,14 @@ jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
/* /*
* Alternate entry point to read raw data. * Alternate entry point to read raw data.
* Processes exactly one MCU row per call. * Processes exactly one iMCU row per call, unless suspended.
*/ */
GLOBAL JDIMENSION GLOBAL JDIMENSION
jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION max_lines) JDIMENSION max_lines)
{ {
JDIMENSION lines_per_MCU_row; JDIMENSION lines_per_iMCU_row;
if (cinfo->global_state != DSTATE_RAW_OK) if (cinfo->global_state != DSTATE_RAW_OK)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
@@ -368,18 +368,18 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
} }
/* Verify that at least one MCU row can be returned. */ /* Verify that at least one iMCU row can be returned. */
lines_per_MCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
if (max_lines < lines_per_MCU_row) if (max_lines < lines_per_iMCU_row)
ERREXIT(cinfo, JERR_BUFFER_SIZE); ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Decompress directly into user's buffer. */ /* Decompress directly into user's buffer. */
if (! (*cinfo->coef->decompress_data) (cinfo, data)) if (! (*cinfo->coef->decompress_data) (cinfo, data))
return 0; /* suspension forced, can do nothing more */ return 0; /* suspension forced, can do nothing more */
/* OK, we processed one MCU row. */ /* OK, we processed one iMCU row. */
cinfo->output_scanline += lines_per_MCU_row; cinfo->output_scanline += lines_per_iMCU_row;
return lines_per_MCU_row; return lines_per_iMCU_row;
} }

View File

@@ -137,6 +137,9 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes)
while (num_bytes > (long) src->pub.bytes_in_buffer) { while (num_bytes > (long) src->pub.bytes_in_buffer) {
num_bytes -= (long) src->pub.bytes_in_buffer; num_bytes -= (long) src->pub.bytes_in_buffer;
(void) fill_input_buffer(cinfo); (void) fill_input_buffer(cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
} }
src->pub.next_input_byte += (size_t) num_bytes; src->pub.next_input_byte += (size_t) num_bytes;
src->pub.bytes_in_buffer -= (size_t) num_bytes; src->pub.bytes_in_buffer -= (size_t) num_bytes;

View File

@@ -1,7 +1,7 @@
/* /*
* jdcoefct.c * jdcoefct.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1995, Thomas G. Lane.
* 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.
* *
@@ -20,8 +20,10 @@
typedef struct { typedef struct {
struct jpeg_d_coef_controller pub; /* public fields */ struct jpeg_d_coef_controller pub; /* public fields */
JDIMENSION MCU_col_num; /* saves next MCU column to process */ JDIMENSION iMCU_row_num; /* iMCU row # within image */
JDIMENSION MCU_row_num; /* keep track of MCU row # within image */ JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
int MCU_vert_offset; /* counts MCU rows within iMCU row */
int MCU_rows_per_iMCU_row; /* number of such rows needed */
/* In single-pass modes without block smoothing, it's sufficient to buffer /* In single-pass modes without block smoothing, it's sufficient to buffer
* just one MCU (although this may prove a bit slow in practice). * just one MCU (although this may prove a bit slow in practice).
@@ -53,6 +55,30 @@ METHODDEF boolean decompress_output
#endif #endif
LOCAL void
start_iMCU_row (j_decompress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
/* In an interleaved scan, an MCU row is the same as an iMCU row.
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
* But at the bottom of the image, process only what's left.
*/
if (cinfo->comps_in_scan > 1) {
coef->MCU_rows_per_iMCU_row = 1;
} else {
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
else
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
}
coef->mcu_ctr = 0;
coef->MCU_vert_offset = 0;
}
/* /*
* Initialize for a processing pass. * Initialize for a processing pass.
*/ */
@@ -62,8 +88,8 @@ start_pass_coef (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
coef->MCU_col_num = 0; coef->iMCU_row_num = 0;
coef->MCU_row_num = 0; start_iMCU_row(cinfo);
switch (pass_mode) { switch (pass_mode) {
case JBUF_PASS_THRU: case JBUF_PASS_THRU:
@@ -105,65 +131,67 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION MCU_col_num; /* index of current MCU within row */
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
JDIMENSION last_MCU_row = cinfo->MCU_rows_in_scan - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
int blkn, ci, xindex, yindex, useful_width; int blkn, ci, xindex, yindex, yoffset, useful_width;
JSAMPARRAY output_ptr; JSAMPARRAY output_ptr;
JDIMENSION start_col, output_col; JDIMENSION start_col, output_col;
jpeg_component_info *compptr; jpeg_component_info *compptr;
inverse_DCT_method_ptr inverse_DCT; inverse_DCT_method_ptr inverse_DCT;
/* Loop to process as much as one whole MCU row */ /* Loop to process as much as one whole iMCU row */
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
for (MCU_col_num = coef->MCU_col_num; MCU_col_num <= last_MCU_col; yoffset++) {
MCU_col_num++) { for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
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], jzero_far((void FAR *) coef->MCU_buffer[0],
(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); (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; return with row unfinished */ /* Suspension forced; update state counters and exit */
coef->MCU_col_num = MCU_col_num; /* update my state */ coef->MCU_vert_offset = yoffset;
return FALSE; coef->mcu_ctr = MCU_col_num;
} return FALSE;
/* Determine where data should go in output_buf and do the IDCT thing.
* We skip dummy blocks at the right and bottom edges (but blkn gets
* incremented past them!). Note the inner loop relies on having
* allocated the MCU_buffer[] blocks sequentially.
*/
blkn = 0; /* index of current DCT block within MCU */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* Don't bother to IDCT an uninteresting component. */
if (! compptr->component_needed) {
blkn += compptr->MCU_blocks;
continue;
} }
inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; /* Determine where data should go in output_buf and do the IDCT thing.
useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width * We skip dummy blocks at the right and bottom edges (but blkn gets
: compptr->last_col_width; * incremented past them!). Note the inner loop relies on having
output_ptr = output_buf[ci]; * allocated the MCU_buffer[] blocks sequentially.
start_col = MCU_col_num * compptr->MCU_sample_width; */
for (yindex = 0; yindex < compptr->MCU_height; yindex++) { blkn = 0; /* index of current DCT block within MCU */
if (coef->MCU_row_num < last_MCU_row || for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
yindex < compptr->last_row_height) { compptr = cinfo->cur_comp_info[ci];
output_col = start_col; /* Don't bother to IDCT an uninteresting component. */
for (xindex = 0; xindex < useful_width; xindex++) { if (! compptr->component_needed) {
(*inverse_DCT) (cinfo, compptr, blkn += compptr->MCU_blocks;
(JCOEFPTR) coef->MCU_buffer[blkn+xindex], continue;
output_ptr, output_col); }
output_col += compptr->DCT_scaled_size; inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
} useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
: compptr->last_col_width;
output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size;
start_col = MCU_col_num * compptr->MCU_sample_width;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (coef->iMCU_row_num < last_iMCU_row ||
yoffset+yindex < compptr->last_row_height) {
output_col = start_col;
for (xindex = 0; xindex < useful_width; xindex++) {
(*inverse_DCT) (cinfo, compptr,
(JCOEFPTR) coef->MCU_buffer[blkn+xindex],
output_ptr, output_col);
output_col += compptr->DCT_scaled_size;
}
}
blkn += compptr->MCU_width;
output_ptr += compptr->DCT_scaled_size;
} }
blkn += compptr->MCU_width;
output_ptr += compptr->DCT_scaled_size;
} }
} }
/* Completed an MCU row, but perhaps not an iMCU row */
coef->mcu_ctr = 0;
} }
/* Completed the iMCU row, advance counters for next one */
/* We finished the row successfully */ coef->iMCU_row_num++;
coef->MCU_col_num = 0; /* prepare for next row */ start_iMCU_row(cinfo);
coef->MCU_row_num++;
return TRUE; return TRUE;
} }
@@ -175,9 +203,7 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
* We read the equivalent of one fully interleaved MCU row ("iMCU" row) * We read the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor block rows for each component in the scan. * per call, ie, v_samp_factor block rows for each component in the scan.
* No data is returned; we just stash it in the virtual arrays. * No data is returned; we just stash it in the virtual arrays.
*
* Returns TRUE if it completed a row, FALSE if not (suspension). * Returns TRUE if it completed a row, FALSE if not (suspension).
* Currently, the suspension case is not supported.
*/ */
METHODDEF boolean METHODDEF boolean
@@ -185,8 +211,8 @@ decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION MCU_col_num; /* index of current MCU within row */
int blkn, ci, xindex, yindex, yoffset, num_MCU_rows; int blkn, ci, xindex, yindex, yoffset;
JDIMENSION total_width, remaining_rows, start_col; JDIMENSION total_width, start_col;
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
JBLOCKROW buffer_ptr; JBLOCKROW buffer_ptr;
jpeg_component_info *compptr; jpeg_component_info *compptr;
@@ -196,7 +222,7 @@ decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
buffer[ci] = (*cinfo->mem->access_virt_barray) buffer[ci] = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
coef->MCU_row_num * compptr->v_samp_factor, TRUE); coef->iMCU_row_num * compptr->v_samp_factor, TRUE);
/* Entropy decoder expects buffer to be zeroed. */ /* Entropy decoder expects buffer to be zeroed. */
total_width = (JDIMENSION) jround_up((long) compptr->width_in_blocks, total_width = (JDIMENSION) jround_up((long) compptr->width_in_blocks,
(long) compptr->h_samp_factor); (long) compptr->h_samp_factor);
@@ -206,25 +232,11 @@ decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
} }
} }
/* In an interleaved scan, we process exactly one MCU row.
* In a noninterleaved scan, we need to process v_samp_factor MCU rows,
* each of which contains a single block row.
*/
if (cinfo->comps_in_scan == 1) {
compptr = cinfo->cur_comp_info[0];
num_MCU_rows = compptr->v_samp_factor;
/* but watch out for the bottom of the image */
remaining_rows = cinfo->MCU_rows_in_scan -
coef->MCU_row_num * compptr->v_samp_factor;
if (remaining_rows < (JDIMENSION) num_MCU_rows)
num_MCU_rows = (int) remaining_rows;
} else {
num_MCU_rows = 1;
}
/* Loop to process one whole iMCU row */ /* Loop to process one whole iMCU row */
for (yoffset = 0; yoffset < num_MCU_rows; yoffset++) { for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
for (MCU_col_num = 0; MCU_col_num < cinfo->MCUs_per_row; MCU_col_num++) { yoffset++) {
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
MCU_col_num++) {
/* Construct list of pointers to DCT blocks belonging to this MCU */ /* Construct list of pointers to DCT blocks belonging to this MCU */
blkn = 0; /* index of current DCT block within MCU */ blkn = 0; /* index of current DCT block within MCU */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
@@ -239,12 +251,18 @@ decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
} }
/* Try to fetch the MCU. */ /* Try to fetch the MCU. */
if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
ERREXIT(cinfo, JERR_CANT_SUSPEND); /* not supported */ /* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
coef->mcu_ctr = MCU_col_num;
return FALSE;
} }
} }
/* Completed an MCU row, but perhaps not an iMCU row */
coef->mcu_ctr = 0;
} }
/* Completed the iMCU row, advance counters for next one */
coef->MCU_row_num++; coef->iMCU_row_num++;
start_iMCU_row(cinfo);
return TRUE; return TRUE;
} }
@@ -261,7 +279,7 @@ METHODDEF boolean
decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION last_MCU_row = cinfo->total_iMCU_rows - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
JDIMENSION block_num; JDIMENSION block_num;
int ci, block_row, block_rows; int ci, block_row, block_rows;
JBLOCKARRAY buffer; JBLOCKARRAY buffer;
@@ -279,11 +297,12 @@ decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
/* Align the virtual buffer for this component. */ /* Align the virtual buffer for this component. */
buffer = (*cinfo->mem->access_virt_barray) buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[ci], ((j_common_ptr) cinfo, coef->whole_image[ci],
coef->MCU_row_num * compptr->v_samp_factor, FALSE); coef->iMCU_row_num * compptr->v_samp_factor, FALSE);
/* Count non-dummy DCT block rows in this iMCU row. */ /* Count non-dummy DCT block rows in this iMCU row. */
if (coef->MCU_row_num < last_MCU_row) if (coef->iMCU_row_num < last_iMCU_row)
block_rows = compptr->v_samp_factor; block_rows = compptr->v_samp_factor;
else { else {
/* NB: can't use last_row_height here, since may not be set! */
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (block_rows == 0) block_rows = compptr->v_samp_factor; if (block_rows == 0) block_rows = compptr->v_samp_factor;
} }
@@ -303,7 +322,7 @@ decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
} }
} }
coef->MCU_row_num++; coef->iMCU_row_num++;
return TRUE; return TRUE;
} }

View File

@@ -37,7 +37,7 @@ typedef my_color_deconverter * my_cconvert_ptr;
* 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
* where Cb and Cr represent the incoming values less MAXJSAMPLE/2. * 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.)
* *
* To avoid floating-point arithmetic, we represent the fractional constants * To avoid floating-point arithmetic, we represent the fractional constants
@@ -70,7 +70,7 @@ METHODDEF void
ycc_rgb_start (j_decompress_ptr cinfo) ycc_rgb_start (j_decompress_ptr cinfo)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
INT32 i, x2; INT32 i, x;
SHIFT_TEMPS SHIFT_TEMPS
cconvert->Cr_r_tab = (int *) cconvert->Cr_r_tab = (int *)
@@ -86,21 +86,20 @@ ycc_rgb_start (j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32)); (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0; i <= MAXJSAMPLE; i++) { for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - MAXJSAMPLE/2 */ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
x2 = 2*i - MAXJSAMPLE; /* twice x */
/* Cr=>R value is nearest int to 1.40200 * x */ /* Cr=>R value is nearest int to 1.40200 * x */
cconvert->Cr_r_tab[i] = (int) cconvert->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.40200/2) * x2 + ONE_HALF, SCALEBITS); RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
/* Cb=>B value is nearest int to 1.77200 * x */ /* Cb=>B value is nearest int to 1.77200 * x */
cconvert->Cb_b_tab[i] = (int) cconvert->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.77200/2) * x2 + ONE_HALF, SCALEBITS); RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
/* Cr=>G value is scaled-up -0.71414 * x */ /* Cr=>G value is scaled-up -0.71414 * x */
cconvert->Cr_g_tab[i] = (- FIX(0.71414/2)) * x2; cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
/* Cb=>G value is scaled-up -0.34414 * x */ /* Cb=>G value is scaled-up -0.34414 * x */
/* We also add in ONE_HALF so that need not do it in inner loop */ /* We also add in ONE_HALF so that need not do it in inner loop */
cconvert->Cb_g_tab[i] = (- FIX(0.34414/2)) * x2 + ONE_HALF; cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
} }
} }
@@ -145,10 +144,7 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
y = GETJSAMPLE(inptr0[col]); y = GETJSAMPLE(inptr0[col]);
cb = GETJSAMPLE(inptr1[col]); cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]); cr = GETJSAMPLE(inptr2[col]);
/* Note: if the inputs were computed directly from RGB values, /* Range-limiting is essential due to noise introduced by DCT losses. */
* range-limiting would be unnecessary here; but due to possible
* noise in the DCT/IDCT phase, we do need to apply range limits.
*/
outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
outptr[RGB_GREEN] = range_limit[y + outptr[RGB_GREEN] = range_limit[y +
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
@@ -247,10 +243,7 @@ ycck_cmyk_convert (j_decompress_ptr cinfo,
y = GETJSAMPLE(inptr0[col]); y = GETJSAMPLE(inptr0[col]);
cb = GETJSAMPLE(inptr1[col]); cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]); cr = GETJSAMPLE(inptr2[col]);
/* Note: if the inputs were computed directly from RGB values, /* Range-limiting is essential due to noise introduced by DCT losses. */
* range-limiting would be unnecessary here; but due to possible
* noise in the DCT/IDCT phase, we do need to apply range limits.
*/
outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],

View File

@@ -142,6 +142,7 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
/* Initialize private state variables */ /* Initialize private state variables */
entropy->saved.bits_left = 0; entropy->saved.bits_left = 0;
entropy->saved.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
entropy->printed_eod = FALSE; entropy->printed_eod = FALSE;
/* Initialize restart counter */ /* Initialize restart counter */

View File

@@ -1,7 +1,7 @@
/* /*
* jdmaster.c * jdmaster.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1995, Thomas G. Lane.
* 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.
* *
@@ -256,7 +256,12 @@ per_scan_setup (j_decompress_ptr cinfo)
compptr->MCU_blocks = 1; compptr->MCU_blocks = 1;
compptr->MCU_sample_width = compptr->DCT_scaled_size; compptr->MCU_sample_width = compptr->DCT_scaled_size;
compptr->last_col_width = 1; compptr->last_col_width = 1;
compptr->last_row_height = 1; /* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row.
*/
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (tmp == 0) tmp = compptr->v_samp_factor;
compptr->last_row_height = tmp;
/* Prepare array describing MCU composition */ /* Prepare array describing MCU composition */
cinfo->blocks_in_MCU = 1; cinfo->blocks_in_MCU = 1;

View File

@@ -82,7 +82,7 @@ METHODDEF void
start_pass_merged_upsample (j_decompress_ptr cinfo) start_pass_merged_upsample (j_decompress_ptr cinfo)
{ {
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
INT32 i, x2; INT32 i, x;
SHIFT_TEMPS SHIFT_TEMPS
/* Mark the spare buffer empty */ /* Mark the spare buffer empty */
@@ -106,21 +106,20 @@ start_pass_merged_upsample (j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32)); (MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0; i <= MAXJSAMPLE; i++) { for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - MAXJSAMPLE/2 */ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
x2 = 2*i - MAXJSAMPLE; /* twice x */
/* Cr=>R value is nearest int to 1.40200 * x */ /* Cr=>R value is nearest int to 1.40200 * x */
upsample->Cr_r_tab[i] = (int) upsample->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.40200/2) * x2 + ONE_HALF, SCALEBITS); RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
/* Cb=>B value is nearest int to 1.77200 * x */ /* Cb=>B value is nearest int to 1.77200 * x */
upsample->Cb_b_tab[i] = (int) upsample->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.77200/2) * x2 + ONE_HALF, SCALEBITS); RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
/* Cr=>G value is scaled-up -0.71414 * x */ /* Cr=>G value is scaled-up -0.71414 * x */
upsample->Cr_g_tab[i] = (- FIX(0.71414/2)) * x2; upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
/* Cb=>G value is scaled-up -0.34414 * x */ /* Cb=>G value is scaled-up -0.34414 * x */
/* We also add in ONE_HALF so that need not do it in inner loop */ /* We also add in ONE_HALF so that need not do it in inner loop */
upsample->Cb_g_tab[i] = (- FIX(0.34414/2)) * x2 + ONE_HALF; upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
} }
} }

View File

@@ -17,16 +17,33 @@
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jversion.h" #include "jversion.h"
#include "jerror.h"
#include "jerror.h" /* get error codes */
#define JMAKE_MSG_TABLE
#include "jerror.h" /* create message string table */
#ifndef EXIT_FAILURE /* define exit() codes if not provided */ #ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1 #define EXIT_FAILURE 1
#endif #endif
/*
* Create the message string table.
* We do this from the master message list in jerror.h by re-reading
* jerror.h with a suitable definition for macro JMESSAGE.
* The message table is made an external symbol just in case any applications
* want to refer to it directly.
*/
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jpeg_std_message_table jMsgTable
#endif
#define JMESSAGE(code,string) string ,
const char * const jpeg_std_message_table[] = {
#include "jerror.h"
NULL
};
/* /*
* Error exit handler: must not return to caller. * Error exit handler: must not return to caller.
* *
@@ -200,7 +217,7 @@ jpeg_std_error (struct jpeg_error_mgr * err)
err->msg_code = 0; /* may be useful as a flag for "no error" */ err->msg_code = 0; /* may be useful as a flag for "no error" */
/* Initialize message table pointers */ /* Initialize message table pointers */
err->jpeg_message_table = jpeg_message_table; err->jpeg_message_table = jpeg_std_message_table;
err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
err->addon_message_table = NULL; err->addon_message_table = NULL;

View File

@@ -13,29 +13,28 @@
* and/or the macros. * and/or the macros.
*/ */
/*
/* To define the enum list of message codes, include this file without * To define the enum list of message codes, include this file without
* defining JMAKE_MSG_TABLE. To create the message string table, include it * defining macro JMESSAGE. To create a message string table, include it
* again with JMAKE_MSG_TABLE defined (this should be done in just one module). * again with a suitable JMESSAGE definition (see jerror.c for an example).
*/ */
#ifndef JMESSAGE
#ifndef JERROR_H
/* First time through, define the enum list */
#define JMAKE_ENUM_LIST
#else
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
#define JMESSAGE(code,string)
#endif /* JERROR_H */
#endif /* JMESSAGE */
#ifdef JMAKE_MSG_TABLE #ifdef JMAKE_ENUM_LIST
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jpeg_message_table jMsgTable
#endif
const char * const jpeg_message_table[] = {
#define JMESSAGE(code,string) string ,
#else /* not JMAKE_MSG_TABLE */
typedef enum { typedef enum {
#define JMESSAGE(code,string) code , #define JMESSAGE(code,string) code ,
#endif /* JMAKE_MSG_TABLE */ #endif /* JMAKE_ENUM_LIST */
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
@@ -160,22 +159,20 @@ JMESSAGE(JWRN_MUST_RESYNC,
JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
#ifdef JMAKE_MSG_TABLE #ifdef JMAKE_ENUM_LIST
NULL
};
#else /* not JMAKE_MSG_TABLE */
JMSG_LASTMSGCODE JMSG_LASTMSGCODE
} J_MESSAGE_CODE; } J_MESSAGE_CODE;
#endif /* JMAKE_MSG_TABLE */ #undef JMAKE_ENUM_LIST
#endif /* JMAKE_ENUM_LIST */
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
#undef JMESSAGE #undef JMESSAGE
#ifndef JMAKE_MSG_TABLE #ifndef JERROR_H
#define JERROR_H
/* Macros to simplify using the error and trace message stuff */ /* Macros to simplify using the error and trace message stuff */
/* The first parameter is either type of cinfo pointer */ /* The first parameter is either type of cinfo pointer */
@@ -261,4 +258,4 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#endif /* JMAKE_MSG_TABLE */ #endif /* JERROR_H */

View File

@@ -55,6 +55,7 @@ extern void free JPP((void *ptr));
* 3. mktemp() is used to ensure that multiple processes running * 3. mktemp() is used to ensure that multiple processes running
* simultaneously won't select the same file names. If your system * simultaneously won't select the same file names. If your system
* doesn't have mktemp(), define NO_MKTEMP to do it the hard way. * doesn't have mktemp(), define NO_MKTEMP to do it the hard way.
* (If you don't have <errno.h>, also define NO_ERRNO_H.)
* *
* 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c * 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c
* will cause the temp files to be removed if you stop the program early. * will cause the temp files to be removed if you stop the program early.
@@ -72,6 +73,19 @@ static int next_file_num; /* to distinguish among several temp files */
#define TEMP_FILE_NAME "%sJPG%03d.TMP" #define TEMP_FILE_NAME "%sJPG%03d.TMP"
#endif #endif
#ifndef NO_ERRNO_H
#include <errno.h> /* to define ENOENT */
#endif
/* ANSI C specifies that errno is a macro, but on older systems it's more
* likely to be a plain int variable. And not all versions of errno.h
* bother to declare it, so we have to in order to be most portable. Thus:
*/
#ifndef errno
extern int errno;
#endif
LOCAL void LOCAL void
select_file_name (char * fname) select_file_name (char * fname)
{ {
@@ -81,8 +95,17 @@ select_file_name (char * fname)
for (;;) { for (;;) {
next_file_num++; /* advance counter */ next_file_num++; /* advance counter */
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num); sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
if ((tfile = fopen(fname, READ_BINARY)) == NULL) if ((tfile = fopen(fname, READ_BINARY)) == NULL) {
/* fopen could have failed for a reason other than the file not
* being there; for example, file there but unreadable.
* If <errno.h> isn't available, then we cannot test the cause.
*/
#ifdef ENOENT
if (errno != ENOENT)
continue;
#endif
break; break;
}
fclose(tfile); /* oops, it's there; close tfile & try again */ fclose(tfile); /* oops, it's there; close tfile & try again */
} }
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jpegint.h * jpegint.h
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1995, Thomas G. Lane.
* 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.
* *
@@ -70,9 +70,8 @@ struct jpeg_c_prep_controller {
/* Coefficient buffer control */ /* Coefficient buffer control */
struct jpeg_c_coef_controller { struct jpeg_c_coef_controller {
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
JMETHOD(void, compress_data, (j_compress_ptr cinfo, JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
JSAMPIMAGE input_buf, JSAMPIMAGE input_buf));
JDIMENSION *in_mcu_ctr));
}; };
/* Colorspace conversion */ /* Colorspace conversion */

View File

@@ -10,6 +10,9 @@
* and perhaps jerror.h if they want to know the exact error codes. * and perhaps jerror.h if they want to know the exact error codes.
*/ */
#ifndef JPEGLIB_H
#define JPEGLIB_H
/* /*
* First we include the configuration files that record how this * First we include the configuration files that record how this
* installation of the JPEG library is set up. jconfig.h can be * installation of the JPEG library is set up. jconfig.h can be
@@ -27,7 +30,7 @@
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
*/ */
#define JPEG_LIB_VERSION 50 /* Version 5.0 */ #define JPEG_LIB_VERSION 51 /* Version 5a */
/* Various constants determining the sizes of things. /* Various constants determining the sizes of things.
@@ -928,3 +931,5 @@ struct jpeg_color_quantizer { long dummy; };
#include "jpegint.h" /* fetch private declarations */ #include "jpegint.h" /* fetch private declarations */
#include "jerror.h" /* fetch error codes too */ #include "jerror.h" /* fetch error codes too */
#endif #endif
#endif /* JPEGLIB_H */

147
jquant1.c
View File

@@ -1,7 +1,7 @@
/* /*
* jquant1.c * jquant1.c
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1995, Thomas G. Lane.
* 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.
* *
@@ -52,7 +52,7 @@
/* Declarations for ordered dithering. /* Declarations for ordered dithering.
* *
* We use a standard 4x4 ordered dither array. The basic concept of ordered * We use a standard 16x16 ordered dither array. The basic concept of ordered
* dithering is described in many references, for instance Dale Schumacher's * dithering is described in many references, for instance Dale Schumacher's
* chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
* In place of Schumacher's comparisons against a "threshold" value, we add a * In place of Schumacher's comparisons against a "threshold" value, we add a
@@ -68,11 +68,36 @@
* table in both directions. * table in both directions.
*/ */
#define ODITHER_SIZE 4 /* dimension of dither matrix */ #define ODITHER_SIZE 16 /* dimension of dither matrix */
#define ODITHER_CELLS (4*4) /* number of cells in dither matrix */ /* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
#define ODITHER_MASK 3 /* mask for wrapping around dither counters */ #define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */
#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */
typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
/* Bayer's order-4 dither array. Generated by the code given in
* Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
* The values in this array must range from 0 to ODITHER_CELLS-1.
*/
{ 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
{ 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
{ 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
{ 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
{ 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
{ 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
{ 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
{ 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
{ 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
{ 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
{ 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
{ 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
{ 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
{ 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
{ 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
{ 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
};
/* Declarations for Floyd-Steinberg dithering. /* Declarations for Floyd-Steinberg dithering.
@@ -125,7 +150,7 @@ typedef struct {
/* Variables for ordered dithering */ /* Variables for ordered dithering */
int row_index; /* cur row's vertical index in dither matrix */ int row_index; /* cur row's vertical index in dither matrix */
ODITHER_MATRIX *odither; /* one dither array per component */ ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */
/* Variables for Floyd-Steinberg dithering */ /* Variables for Floyd-Steinberg dithering */
FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */
@@ -159,6 +184,7 @@ select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
int nc = cinfo->out_color_components; /* number of color components */ int nc = cinfo->out_color_components; /* number of color components */
int max_colors = cinfo->desired_number_of_colors; int max_colors = cinfo->desired_number_of_colors;
int total_colors, iroot, i, j; int total_colors, iroot, i, j;
boolean changed;
long temp; long temp;
static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
@@ -185,18 +211,24 @@ select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
} }
/* We may be able to increment the count for one or more components without /* We may be able to increment the count for one or more components without
* exceeding max_colors, though we know not all can be incremented. * exceeding max_colors, though we know not all can be incremented.
* Sometimes, the first component can be incremented more than once!
* (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
* In RGB colorspace, try to increment G first, then R, then B. * In RGB colorspace, try to increment G first, then R, then B.
*/ */
for (i = 0; i < nc; i++) { do {
j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); changed = FALSE;
/* calculate new total_colors if Ncolors[j] is incremented */ for (i = 0; i < nc; i++) {
temp = total_colors / Ncolors[j]; j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ /* calculate new total_colors if Ncolors[j] is incremented */
if (temp > (long) max_colors) temp = total_colors / Ncolors[j];
break; /* won't fit, done */ temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */
Ncolors[j]++; /* OK, apply the increment */ if (temp > (long) max_colors)
total_colors = (int) temp; break; /* won't fit, done with this pass */
} Ncolors[j]++; /* OK, apply the increment */
total_colors = (int) temp;
changed = TRUE;
}
} while (changed);
return total_colors; return total_colors;
} }
@@ -226,6 +258,41 @@ largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
} }
/*
* Create an ordered-dither array for a component having ncolors
* distinct output values.
*/
LOCAL ODITHER_MATRIX_PTR
make_odither_array (j_decompress_ptr cinfo, int ncolors)
{
ODITHER_MATRIX_PTR odither;
int j,k;
INT32 num,den;
odither = (ODITHER_MATRIX_PTR)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(ODITHER_MATRIX));
/* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
* Hence the dither value for the matrix cell with fill order f
* (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
* On 16-bit-int machine, be careful to avoid overflow.
*/
den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
for (j = 0; j < ODITHER_SIZE; j++) {
for (k = 0; k < ODITHER_SIZE; k++) {
num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
* MAXJSAMPLE;
/* Ensure round towards zero despite C's lack of consistency
* about rounding negative values in integer division...
*/
odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
}
}
return odither;
}
/* /*
* Create the colormap and color index table. * Create the colormap and color index table.
* Also creates the ordered-dither tables, if required. * Also creates the ordered-dither tables, if required.
@@ -239,7 +306,7 @@ create_colormap (j_decompress_ptr cinfo)
JSAMPROW indexptr; JSAMPROW indexptr;
int total_colors; /* Number of distinct output colors */ int total_colors; /* Number of distinct output colors */
int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
ODITHER_MATRIX *odither; ODITHER_MATRIX_PTR odither;
int i,j,k, nci, blksize, blkdist, ptr, val, pad; int i,j,k, nci, blksize, blkdist, ptr, val, pad;
/* Select number of colors for each component */ /* Select number of colors for each component */
@@ -319,41 +386,21 @@ create_colormap (j_decompress_ptr cinfo)
cinfo->actual_number_of_colors = total_colors; cinfo->actual_number_of_colors = total_colors;
if (cinfo->dither_mode == JDITHER_ORDERED) { if (cinfo->dither_mode == JDITHER_ORDERED) {
/* Allocate and fill in the ordered-dither tables. */ /* Allocate and fill in the ordered-dither tables. Components having
odither = (ODITHER_MATRIX *) * the same number of representative colors may share a dither table.
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, */
cinfo->out_color_components * SIZEOF(ODITHER_MATRIX));
cquantize->odither = odither;
for (i = 0; i < cinfo->out_color_components; i++) { for (i = 0; i < cinfo->out_color_components; i++) {
nci = Ncolors[i]; /* # of distinct values for this color */ nci = Ncolors[i]; /* # of distinct values for this color */
/* The inter-value distance for this color is MAXJSAMPLE/(nci-1). odither = NULL; /* search for matching prior component */
* Hence the dither value for the matrix cell with fill order j for (j = 0; j < i; j++) {
* (j=1..N) should be (N+1-2*j)/(2*(N+1)) * MAXJSAMPLE/(nci-1). if (nci == Ncolors[j]) {
*/ odither = cquantize->odither[j];
val = 2 * (ODITHER_CELLS + 1) * (nci - 1); /* denominator */ break;
/* Macro is coded to ensure round towards zero despite C's }
* lack of consistency in integer division... }
*/ if (odither == NULL) /* need a new table? */
#define ODITHER_DIV(num,den) ((num)<0 ? -((-(num))/(den)) : (num)/(den)) odither = make_odither_array(cinfo, nci);
#define ODITHER_VAL(j) ODITHER_DIV((ODITHER_CELLS+1-2*j)*MAXJSAMPLE, val) cquantize->odither[i] = odither;
/* Traditional fill order for 4x4 dither; see Schumacher's figure 4. */
odither[0][0][0] = ODITHER_VAL(1);
odither[0][0][1] = ODITHER_VAL(9);
odither[0][0][2] = ODITHER_VAL(3);
odither[0][0][3] = ODITHER_VAL(11);
odither[0][1][0] = ODITHER_VAL(13);
odither[0][1][1] = ODITHER_VAL(5);
odither[0][1][2] = ODITHER_VAL(15);
odither[0][1][3] = ODITHER_VAL(7);
odither[0][2][0] = ODITHER_VAL(4);
odither[0][2][1] = ODITHER_VAL(12);
odither[0][2][2] = ODITHER_VAL(2);
odither[0][2][3] = ODITHER_VAL(10);
odither[0][3][0] = ODITHER_VAL(16);
odither[0][3][1] = ODITHER_VAL(8);
odither[0][3][2] = ODITHER_VAL(14);
odither[0][3][3] = ODITHER_VAL(6);
odither++; /* advance to next matrix */
} }
} }
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jversion.h * jversion.h
* *
* Copyright (C) 1991-1994, Thomas G. Lane. * Copyright (C) 1991-1995, Thomas G. Lane.
* 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 "5 24-Sep-94" #define JVERSION "5b 15-Mar-95"
#define JCOPYRIGHT "Copyright (C) 1994, Thomas G. Lane" #define JCOPYRIGHT "Copyright (C) 1995, Thomas G. Lane"

View File

@@ -1,6 +1,6 @@
USING THE IJG JPEG LIBRARY USING THE IJG JPEG LIBRARY
Copyright (C) 1994, Thomas G. Lane. Copyright (C) 1994-1995, Thomas G. Lane.
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.
@@ -189,7 +189,10 @@ The standard input image format is a rectangular array of pixels, with each
pixel having the same number of "component" values (color channels). You pixel having the same number of "component" values (color channels). You
must specify how many components there are and the colorspace interpretation must specify how many components there are and the colorspace interpretation
of the components. Most applications will use RGB data (three components of the components. Most applications will use RGB data (three components
per pixel) or grayscale data (one component per pixel). per pixel) or grayscale data (one component per pixel). PLEASE NOTE THAT
RGB DATA IS THREE SAMPLES PER PIXEL, GRAYSCALE ONLY ONE. A remarkable
number of people manage to miss this, only to find that their programs don't
work with grayscale JPEG files.
Note that there is no provision for colormapped input. You can feed in a Note that there is no provision for colormapped input. You can feed in a
colormapped image by expanding it to full-color format. However JPEG often colormapped image by expanding it to full-color format. However JPEG often
@@ -644,7 +647,8 @@ one or more times. At each call, you pass in the maximum number of scanlines
to be read (ie, the height of your working buffer); jpeg_read_scanlines() to be read (ie, the height of your working buffer); jpeg_read_scanlines()
will return up to that many lines. The return value is the number of lines will return up to that many lines. The return value is the number of lines
actually read. The format of the returned data is discussed under "Data actually read. The format of the returned data is discussed under "Data
formats", above. formats", above. Don't forget that grayscale and color JPEGs will return
different data formats!
Image data is returned in top-to-bottom scanline order. If you must write Image data is returned in top-to-bottom scanline order. If you must write
out the image in bottom-to-top order, you can use the JPEG library's virtual out the image in bottom-to-top order, you can use the JPEG library's virtual
@@ -657,13 +661,16 @@ this variable as the loop counter, so that the loop test looks like
"while (cinfo.output_scanline < cinfo.output_height)". (Note that the test "while (cinfo.output_scanline < cinfo.output_height)". (Note that the test
should NOT be against image_height, unless you never use scaling. The should NOT be against image_height, unless you never use scaling. The
image_height field is the height of the original unscaled image.) image_height field is the height of the original unscaled image.)
The return value always equals the change in the value of output_scanline.
If you don't use a suspending data source, it is safe to assume that If you don't use a suspending data source, it is safe to assume that
jpeg_read_scanlines() reads at least one scanline per call, until the jpeg_read_scanlines() reads at least one scanline per call, until the
bottom of the image has been reached. If you use a buffer larger than one bottom of the image has been reached. If you use a buffer larger than one
scanline, it is NOT safe to assume that jpeg_read_scanlines() fills it. scanline, it is NOT safe to assume that jpeg_read_scanlines() fills it.
In any case, the return value is the same as the change in the value of (The current implementation won't return more than cinfo.rec_outbuf_height
output_scanline. scanlines per call, no matter how large a buffer you pass.) So you must
always provide a loop that calls jpeg_read_scanlines() repeatedly until
the whole image has been read.
7. jpeg_finish_decompress(...); 7. jpeg_finish_decompress(...);
@@ -852,10 +859,10 @@ J_DCT_METHOD dct_method
JDCT_FLOAT: floating-point method JDCT_FLOAT: floating-point method
JDCT_DEFAULT: default method (normally JDCT_ISLOW) JDCT_DEFAULT: default method (normally JDCT_ISLOW)
JDCT_FASTEST: fastest method (normally JDCT_IFAST) JDCT_FASTEST: fastest method (normally JDCT_IFAST)
The floating-point method is the most accurate, but may give slightly The FLOAT method is very slightly more accurate than the ISLOW method,
different results on different machines due to varying roundoff but may give different results on different machines due to varying
behavior. The integer methods should give the same results on all roundoff behavior. The integer methods should give the same results
machines. On machines with sufficiently fast FP hardware, the on all machines. On machines with sufficiently fast FP hardware, the
floating-point method may also be the fastest. The IFAST method is floating-point method may also be the fastest. The IFAST method is
considerably less accurate than the other two; its use is not considerably less accurate than the other two; its use is not
recommended if high quality is a concern. JDCT_DEFAULT and recommended if high quality is a concern. JDCT_DEFAULT and
@@ -1047,6 +1054,9 @@ only accepted for 3-component output color spaces.]
JSAMPARRAY colormap JSAMPARRAY colormap
The color map, represented as a 2-D pixel array of out_color_components The color map, represented as a 2-D pixel array of out_color_components
rows and actual_number_of_colors columns. Ignored if not quantizing. rows and actual_number_of_colors columns. Ignored if not quantizing.
CAUTION: if the JPEG library creates its own colormap, the storage
pointed to by this field is released by jpeg_finish_decompress().
Copy the colormap somewhere else first, if you want to save it.
int actual_number_of_colors int actual_number_of_colors
The number of colors in the color map. The number of colors in the color map.
@@ -1561,6 +1571,22 @@ application for the case that the input buffer is completely full and yet the
decoder has suspended without consuming any data --- otherwise, if this decoder has suspended without consuming any data --- otherwise, if this
situation did occur, it would lead to an endless loop. situation did occur, it would lead to an endless loop.
Multiple-buffer management:
In some applications it is desirable to store the compressed data in a linked
list of buffer areas, so as to avoid data copying. This can be handled by
having empty_output_buffer() or fill_input_buffer() set the pointer and count
to reference the next available buffer; FALSE is returned only if no more
buffers are available. Although seemingly straightforward, there is a
pitfall in this approach: the backtrack that occurs when FALSE is returned
could back up into an earlier buffer. Do not discard "completed" buffers in
the empty_output_buffer() or fill_input_buffer() routine, unless you can tell
from the saved pointer/bytecount that the JPEG library will no longer attempt
to backtrack that far. It's probably simplest to postpone releasing any
buffers until the library returns to its caller; then you can use the final
bytecount to tell how much data has been fully processed, and release buffers
on that basis.
Abbreviated datastreams and multiple images Abbreviated datastreams and multiple images
------------------------------------------- -------------------------------------------
@@ -1870,8 +1896,9 @@ of Y data is dummy, so it doesn't matter what you pass for it in the data
arrays, but the scanlines count must total up to 112 so that all of the Cb arrays, but the scanlines count must total up to 112 so that all of the Cb
and Cr data gets passed. and Cr data gets passed.
Currently, output suspension is not supported with raw data output: an error Output suspension is supported with raw-data compression: if the data
will result if the data destination module tries to suspend. destination module suspends, jpeg_write_raw_data() will return 0.
In this case the same data rows must be passed again on the next call.
Decompression with raw data output implies bypassing all postprocessing: Decompression with raw data output implies bypassing all postprocessing:
@@ -2027,12 +2054,20 @@ The JPEG standard provides for both the baseline 8-bit DCT process and
a 12-bit DCT process. 12-bit lossy JPEG is supported if you define a 12-bit DCT process. 12-bit lossy JPEG is supported if you define
BITS_IN_JSAMPLE as 12 rather than 8. Note that this causes JSAMPLE to be BITS_IN_JSAMPLE as 12 rather than 8. Note that this causes JSAMPLE to be
larger than a char, so it affects the surrounding application's image data. larger than a char, so it affects the surrounding application's image data.
The sample applications cjpeg and djpeg can support 12-bit mode only for PPM
and GIF file formats; you must disable the other file formats to compile a
12-bit cjpeg or djpeg. (install.doc has more information about that.)
At present, a 12-bit library can handle *only* 12-bit images, not both At present, a 12-bit library can handle *only* 12-bit images, not both
precisions. (If you need to include both 8- and 12-bit libraries in a precisions. (If you need to include both 8- and 12-bit libraries in a single
single application, you could probably do it by defining application, you could probably do it by defining NEED_SHORT_EXTERNAL_NAMES
NEED_SHORT_EXTERNAL_NAMES for just one of the copies. You'd have to access for just one of the copies. You'd have to access the 8-bit and 12-bit copies
the 8-bit and 12-bit copies from separate application source files. This is from separate application source files. This is untested ... if you try it,
untested ... if you try it, we'd like to hear whether it works!) we'd like to hear whether it works!)
Note that a 12-bit library always compresses in Huffman optimization mode,
in order to generate valid Huffman tables. This is necessary because our
default Huffman tables only cover 8-bit data. If you need to output 12-bit
files in one pass, you'll have to supply suitable default Huffman tables.
The maximum number of components (color channels) in the image is determined The maximum number of components (color channels) in the image is determined
by MAX_COMPONENTS. The JPEG standard allows up to 255 components, but we by MAX_COMPONENTS. The JPEG standard allows up to 255 components, but we
@@ -2120,7 +2155,9 @@ The JPEG library typically needs 2Kb-3Kb of stack space. It will also
malloc about 20K-30K of near heap space while executing (and lots of far malloc about 20K-30K of near heap space while executing (and lots of far
heap, but that doesn't count in this calculation). This figure will vary heap, but that doesn't count in this calculation). This figure will vary
depending on selected operating mode, and to a lesser extent on image size. depending on selected operating mode, and to a lesser extent on image size.
Thus you have perhaps 25K available for static data and other modules' near There is also about 5Kb-6Kb of constant data which will be allocated in the
near data segment (about 4Kb of this is the error message table).
Thus you have perhaps 20K available for other modules' static data and near
heap space before you need to go to a larger memory model. The C library's heap space before you need to go to a larger memory model. The C library's
static data will account for several K of this, but that still leaves a good static data will account for several K of this, but that still leaves a good
deal for your needs. (If you are tight on space, you could reduce the sizes deal for your needs. (If you are tight on space, you could reduce the sizes

View File

@@ -57,10 +57,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg

View File

@@ -1,35 +1,63 @@
# Makefile for Independent JPEG Group's software # Makefile for Independent JPEG Group's software
# This makefile is suitable for Borland C (Turbo C) on MS-DOS. # This makefile is suitable for Borland C on MS-DOS or OS/2.
# It is set up for Borland C++, revision 3.0 or later. # It works with Borland C++ for DOS, revision 3.0 or later,
# For older versions (pre-3.0), replace "-O2" with "-O -G -Z" in CFLAGS. # and has been tested with Borland C++ for OS/2, revision 2.0.
# If you have an even older version of Turbo C, you may be able to make it # Thanks to Tom Wright and Ge' Weijers (original DOS) and
# work by saying "CC= tcc" below. (Very early versions of Turbo C++, # Ken Porter (OS/2) for this file.
# like 1.01, are so buggy that you may as well forget it.)
# Thanks to Tom Wright and Ge' Weijers for this file.
# Read installation instructions before saying "make" !! # Read installation instructions before saying "make" !!
# Are we under DOS or OS/2?
!if !$d(DOS) && !$d(OS2)
!if $d(__MSDOS__)
DOS=1
!else
OS2=1
!endif
!endif
# The name of your C compiler: # The name of your C compiler:
CC= bcc CC= bcc
# You may need to adjust these cc options: # You may need to adjust these cc options:
CFLAGS= -mm -w-par -O2 !if $d(DOS)
# -mm selects medium memory model (near data, far code pointers) CFLAGS= -O2 -mm -w-par -w-stu -w-ccc -w-rch
!else
CFLAGS= -O1 -w-par -w-stu -w-ccc -w-rch
!endif
# -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z).
# -O2 is buggy in Borland OS/2 C++ revision 2.0, so use -O1 for now.
# -mm selects medium memory model (near data, far code pointers; DOS only!)
# -w-par suppresses warnings about unused function parameters # -w-par suppresses warnings about unused function parameters
# -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z) # -w-stu suppresses warnings about incomplete structures
# -w-ccc suppresses warnings about compile-time-constant conditions
# -w-rch suppresses warnings about unreachable code
# Generally, we recommend defining any configuration symbols in jconfig.h, # Generally, we recommend defining any configuration symbols in jconfig.h,
# NOT via -D switches here. # NOT via -D switches here.
# Link-time cc options: # Link-time cc options:
!if $d(DOS)
LDFLAGS= -mm LDFLAGS= -mm
# memory model option here must match CFLAGS! # memory model option here must match CFLAGS!
!else
LDFLAGS=
# -lai full-screen app
# -lc case-significant link
!endif
# Put here the object file name for the correct system-dependent memory # Put here the object file name for the correct system-dependent memory
# manager file. For DOS, we recommend jmemdos.c and jmemdosa.asm. # manager file.
# If you change this, you'll need to modify the linker response file # For DOS, we recommend jmemdos.c and jmemdosa.asm.
# name list, below, by hand! # For OS/2, we recommend jmemnobs.c (flat memory!)
# SYSDEPMEMLIB must list the same files with "+" signs for the librarian.
!if $d(DOS)
SYSDEPMEM= jmemdos.obj jmemdosa.obj SYSDEPMEM= jmemdos.obj jmemdosa.obj
SYSDEPMEMLIB= +jmemdos.obj +jmemdosa.obj
!else
SYSDEPMEM= jmemnobs.obj
SYSDEPMEMLIB= +jmemnobs.obj
!endif
# End of configurable options. # End of configurable options.
@@ -54,10 +82,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
@@ -81,31 +109,22 @@ COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj
DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \ DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
rdcolmap.obj rdcolmap.obj
# need linker response file because file list > 128 chars
RFILE= libjpeg.ans
all: libjpeg.lib cjpeg.exe djpeg.exe rdjpgcom.exe wrjpgcom.exe all: libjpeg.lib cjpeg.exe djpeg.exe rdjpgcom.exe wrjpgcom.exe
libjpeg.lib: $(LIBOBJECTS) $(RFILE) libjpeg.lib: $(LIBOBJECTS)
del libjpeg.lib - del libjpeg.lib
tlib @$(RFILE) tlib libjpeg.lib /E /C @&&|
+jcapi.obj +jcparam.obj +jdatadst.obj +jcmaster.obj +jcmarker.obj &
# linker response file for building libjpeg.lib +jcmainct.obj +jcprepct.obj +jccoefct.obj +jccolor.obj +jcsample.obj &
$(RFILE) : Makefile +jchuff.obj +jcdctmgr.obj +jfdctfst.obj +jfdctflt.obj +jfdctint.obj &
del $(RFILE) +jdapi.obj +jdatasrc.obj +jdmaster.obj +jdmarker.obj +jdmainct.obj &
echo libjpeg.lib & >$(RFILE) +jdcoefct.obj +jdpostct.obj +jddctmgr.obj +jidctfst.obj +jidctflt.obj &
echo +jcapi.obj +jcparam.obj +jdatadst.obj +jcmaster.obj & >>$(RFILE) +jidctint.obj +jidctred.obj +jdhuff.obj +jdsample.obj +jdcolor.obj &
echo +jcmarker.obj +jcmainct.obj +jcprepct.obj & >>$(RFILE) +jquant1.obj +jquant2.obj +jdmerge.obj +jcomapi.obj +jutils.obj &
echo +jccoefct.obj +jccolor.obj +jcsample.obj +jchuff.obj & >>$(RFILE) +jerror.obj +jmemmgr.obj &
echo +jcdctmgr.obj +jfdctfst.obj +jfdctflt.obj & >>$(RFILE) $(SYSDEPMEMLIB)
echo +jfdctint.obj +jdapi.obj +jdatasrc.obj +jdmaster.obj & >>$(RFILE) |
echo +jdmarker.obj +jdmainct.obj +jdcoefct.obj & >>$(RFILE)
echo +jdpostct.obj +jddctmgr.obj +jidctfst.obj & >>$(RFILE)
echo +jidctflt.obj +jidctint.obj +jidctred.obj +jdhuff.obj & >>$(RFILE)
echo +jdsample.obj +jdcolor.obj +jquant1.obj +jquant2.obj & >>$(RFILE)
echo +jdmerge.obj +jcomapi.obj +jutils.obj +jerror.obj & >>$(RFILE)
echo +jmemmgr.obj +jmemdos.obj +jmemdosa.obj >>$(RFILE)
cjpeg.exe: $(COBJECTS) libjpeg.lib cjpeg.exe: $(COBJECTS) libjpeg.lib
$(CC) $(LDFLAGS) -ecjpeg.exe $(COBJECTS) libjpeg.lib $(CC) $(LDFLAGS) -ecjpeg.exe $(COBJECTS) libjpeg.lib
@@ -114,14 +133,24 @@ djpeg.exe: $(DOBJECTS) libjpeg.lib
$(CC) $(LDFLAGS) -edjpeg.exe $(DOBJECTS) libjpeg.lib $(CC) $(LDFLAGS) -edjpeg.exe $(DOBJECTS) libjpeg.lib
rdjpgcom.exe: rdjpgcom.c rdjpgcom.exe: rdjpgcom.c
!if $d(DOS)
$(CC) -ms -O rdjpgcom.c $(CC) -ms -O rdjpgcom.c
!else
$(CC) $(CFLAGS) rdjpgcom.c
!endif
# wrjpgcom needs large model so it can malloc a 64K chunk # On DOS, wrjpgcom needs large model so it can malloc a 64K chunk
wrjpgcom.exe: wrjpgcom.c wrjpgcom.exe: wrjpgcom.c
!if $d(DOS)
$(CC) -ml -O wrjpgcom.c $(CC) -ml -O wrjpgcom.c
!else
$(CC) $(CFLAGS) wrjpgcom.c
!endif
# This "{}" syntax allows Borland Make to "batch" source files.
# In this way, each run of the compiler can build many modules.
.c.obj: .c.obj:
$(CC) $(CFLAGS) -c $< $(CC) $(CFLAGS) -c{ $<}
jconfig.h: jconfig.doc jconfig.h: jconfig.doc
echo You must prepare a system-dependent jconfig.h file. echo You must prepare a system-dependent jconfig.h file.
@@ -129,22 +158,30 @@ jconfig.h: jconfig.doc
exit 1 exit 1
clean: clean:
del *.obj - del *.obj
del libjpeg.lib - del libjpeg.lib
del cjpeg.exe - del cjpeg.exe
del djpeg.exe - del djpeg.exe
del rdjpgcom.exe - del rdjpgcom.exe
del wrjpgcom.exe - del wrjpgcom.exe
del testout.* - del testout.*
test: cjpeg.exe djpeg.exe test: cjpeg.exe djpeg.exe
del testout.* - del testout.*
djpeg -dct int -ppm -outfile testout.ppm testorig.jpg djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
djpeg -dct int -gif -outfile testout.gif testorig.jpg djpeg -dct int -gif -outfile testout.gif testorig.jpg
cjpeg -dct int -outfile testout.jpg testimg.ppm cjpeg -dct int -outfile testout.jpg testimg.ppm
!if $d(DOS)
fc /b testimg.ppm testout.ppm fc /b testimg.ppm testout.ppm
fc /b testimg.gif testout.gif fc /b testimg.gif testout.gif
fc /b testimg.jpg testout.jpg fc /b testimg.jpg testout.jpg
!else
echo n > n.tmp
comp testimg.ppm testout.ppm < n.tmp
comp testimg.gif testout.gif < n.tmp
comp testimg.jpg testout.jpg < n.tmp
del n.tmp
!endif
jcapi.obj : jcapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jcapi.obj : jcapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h

View File

@@ -1,6 +1,6 @@
# Makefile for Independent JPEG Group's software # Makefile for Independent JPEG Group's software
# makefile.auto is edited by configure to produce a custom Makefile. # makefile.cfg is edited by configure to produce a custom Makefile.
# Read installation instructions before saying "make" !! # Read installation instructions before saying "make" !!
@@ -9,31 +9,31 @@ srcdir = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
# Where to install the programs and man pages. # Where to install the programs and man pages.
prefix = /usr/local prefix = @prefix@
exec_prefix = $(prefix) exec_prefix = @exec_prefix@
bindir = $(exec_prefix)/bin bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib libdir = $(exec_prefix)/lib
includedir = $(prefix)/include includedir = $(prefix)/include
mandir = $(prefix)/man/man1
binprefix = binprefix =
manprefix = manprefix =
manext = 1 manext = 1
mandir = $(prefix)/man/man$(manext)
# The name of your C compiler: # The name of your C compiler:
CC= @CC@ CC= @CC@
# You may need to adjust these cc options: # You may need to adjust these cc options:
CFLAGS= -O -I$(srcdir) CFLAGS= @CFLAGS@ @CPPFLAGS@ @INCLUDEFLAGS@
# Generally, we recommend defining any configuration symbols in jconfig.h, # Generally, we recommend defining any configuration symbols in jconfig.h,
# NOT via -D switches here. # NOT via -D switches here.
# However, any special defines for ansi2knr.c may be included here: # However, any special defines for ansi2knr.c may be included here:
ANSI2KNRFLAGS= @ANSI2KNRFLAGS@ ANSI2KNRFLAGS= @ANSI2KNRFLAGS@
# Link-time cc options: # Link-time cc options:
LDFLAGS= LDFLAGS= @LDFLAGS@
# To link any special libraries, add the necessary -l commands here. # To link any special libraries, add the necessary -l commands here.
LDLIBS= LDLIBS= @LIBS@
# Put here the object file name for the correct system-dependent memory # Put here the object file name for the correct system-dependent memory
# manager file. For Unix this is usually jmemnobs.o, but you may want # manager file. For Unix this is usually jmemnobs.o, but you may want
@@ -80,10 +80,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
@@ -150,15 +150,18 @@ install: cjpeg djpeg rdjpgcom wrjpgcom
$(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext) $(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext)
$(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext) $(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext)
install-lib: libjpeg.a jconfig.h install-lib: libjpeg.a install-headers
$(INSTALL_DATA) libjpeg.a $(libdir)/$(binprefix)libjpeg.a $(INSTALL_DATA) libjpeg.a $(libdir)/$(binprefix)libjpeg.a
install-headers: jconfig.h
$(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h $(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h
$(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h $(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h
$(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h
$(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h $(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h
clean: clean:
$(RM) *.o cjpeg djpeg libjpeg.a rdjpgcom wrjpgcom ansi2knr core testout.* $(RM) *.o cjpeg djpeg libjpeg.a rdjpgcom wrjpgcom ansi2knr
$(RM) core testout.* config.log config.status
distribute: distribute:
$(RM) jpegsrc.tar* $(RM) jpegsrc.tar*
@@ -167,17 +170,17 @@ distribute:
test: cjpeg djpeg test: cjpeg djpeg
$(RM) testout.ppm testout.gif testout.jpg $(RM) testout.ppm testout.gif testout.jpg
./djpeg -dct int -ppm -outfile testout.ppm testorig.jpg ./djpeg -dct int -ppm -outfile testout.ppm $(srcdir)/testorig.jpg
./djpeg -dct int -gif -outfile testout.gif testorig.jpg ./djpeg -dct int -gif -outfile testout.gif $(srcdir)/testorig.jpg
./cjpeg -dct int -outfile testout.jpg testimg.ppm ./cjpeg -dct int -outfile testout.jpg $(srcdir)/testimg.ppm
cmp testimg.ppm testout.ppm cmp $(srcdir)/testimg.ppm testout.ppm
cmp testimg.gif testout.gif cmp $(srcdir)/testimg.gif testout.gif
cmp testimg.jpg testout.jpg cmp $(srcdir)/testimg.jpg testout.jpg
check: test check: test
# GNU Make likes to know which target names are not really files to be made: # GNU Make likes to know which target names are not really files to be made:
.PHONY: all install install-lib clean distribute test check .PHONY: all install install-lib install-headers clean distribute test check
jcapi.o : jcapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jcapi.o : jcapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h

View File

@@ -61,10 +61,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg

View File

@@ -58,10 +58,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg

View File

@@ -44,10 +44,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg

View File

@@ -44,10 +44,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg

View File

@@ -66,10 +66,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg

View File

@@ -61,10 +61,10 @@ INCLUDES= jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h jpegint.h \
DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \ DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 rdjpgcom.1 wrjpgcom.1 \
example.c libjpeg.doc structure.doc coderules.doc filelist.doc \ example.c libjpeg.doc structure.doc coderules.doc filelist.doc \
change.log change.log
MKFILES= configure makefile.auto makefile.ansi makefile.unix makefile.manx \ MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.manx \
makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \ makefile.sas makcjpeg.st makdjpeg.st makljpeg.st makefile.bcc \
makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt makefile.mc6 makefile.dj makefile.mms makefile.vms makvms.opt
CONFIGFILES= jconfig.auto jconfig.manx jconfig.sas jconfig.st jconfig.bcc \ CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
jconfig.mc6 jconfig.dj jconfig.vms jconfig.mc6 jconfig.dj jconfig.vms
OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg

15
rdbmp.c
View File

@@ -246,6 +246,7 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
(((INT32) UCH(array[offset+1])) << 8) + \ (((INT32) UCH(array[offset+1])) << 8) + \
(((INT32) UCH(array[offset+2])) << 16) + \ (((INT32) UCH(array[offset+2])) << 16) + \
(((INT32) UCH(array[offset+3])) << 24)) (((INT32) UCH(array[offset+3])) << 24))
INT32 bfOffBits;
INT32 headerSize; INT32 headerSize;
INT32 biWidth = 0; /* initialize to avoid compiler warning */ INT32 biWidth = 0; /* initialize to avoid compiler warning */
INT32 biHeight = 0; INT32 biHeight = 0;
@@ -254,6 +255,7 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
INT32 biXPelsPerMeter,biYPelsPerMeter; INT32 biXPelsPerMeter,biYPelsPerMeter;
INT32 biClrUsed = 0; INT32 biClrUsed = 0;
int mapentrysize = 0; /* 0 indicates no colormap */ int mapentrysize = 0; /* 0 indicates no colormap */
INT32 bPad;
JDIMENSION row_width; JDIMENSION row_width;
/* Read and verify the bitmap file header */ /* Read and verify the bitmap file header */
@@ -261,6 +263,7 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
ERREXIT(cinfo, JERR_INPUT_EOF); ERREXIT(cinfo, JERR_INPUT_EOF);
if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */ if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */
ERREXIT(cinfo, JERR_BMP_NOT); ERREXIT(cinfo, JERR_BMP_NOT);
bfOffBits = (INT32) GET_4B(bmpfileheader,10);
/* We ignore the remaining fileheader fields */ /* We ignore the remaining fileheader fields */
/* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows), /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows),
@@ -340,6 +343,9 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break; break;
} }
/* Compute distance to bitmap data --- will adjust for colormap below */
bPad = bfOffBits - (headerSize + 14);
/* Read the colormap, if any */ /* Read the colormap, if any */
if (mapentrysize > 0) { if (mapentrysize > 0) {
if (biClrUsed <= 0) if (biClrUsed <= 0)
@@ -352,6 +358,15 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
(JDIMENSION) biClrUsed, (JDIMENSION) 3); (JDIMENSION) biClrUsed, (JDIMENSION) 3);
/* and read it from the file */ /* and read it from the file */
read_colormap(source, (int) biClrUsed, mapentrysize); read_colormap(source, (int) biClrUsed, mapentrysize);
/* account for size of colormap */
bPad -= biClrUsed * mapentrysize;
}
/* Skip any remaining pad bytes */
if (bPad < 0) /* incorrect bfOffBits value? */
ERREXIT(cinfo, JERR_BMP_BADHEADER);
while (--bPad >= 0) {
(void) read_byte(source);
} }
/* Compute row width in file, including padding to 4-byte boundary */ /* Compute row width in file, including padding to 4-byte boundary */

18
rdgif.c
View File

@@ -5,6 +5,11 @@
* 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.
* *
**************************************************************************
* WARNING: You will need an LZW patent license from Unisys in order to *
* use this file legally in any commercial or shareware application. *
**************************************************************************
*
* This file contains routines to read input images in GIF format. * This file contains routines to read input images in GIF format.
* *
* These routines may need modification for non-Unix environments or * These routines may need modification for non-Unix environments or
@@ -352,9 +357,14 @@ ReadColorMap (gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap)
int i; int i;
for (i = 0; i < cmaplen; i++) { for (i = 0; i < cmaplen; i++) {
cmap[CM_RED][i] = (JSAMPLE) ReadByte(sinfo); #if BITS_IN_JSAMPLE == 8
cmap[CM_GREEN][i] = (JSAMPLE) ReadByte(sinfo); #define UPSCALE(x) (x)
cmap[CM_BLUE][i] = (JSAMPLE) ReadByte(sinfo); #else
#define UPSCALE(x) ((x) << (BITS_IN_JSAMPLE-8))
#endif
cmap[CM_RED][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
cmap[CM_GREEN][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
cmap[CM_BLUE][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
} }
} }
@@ -508,7 +518,7 @@ start_input_gif (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* Return info about the image. */ /* Return info about the image. */
cinfo->in_color_space = JCS_RGB; cinfo->in_color_space = JCS_RGB;
cinfo->input_components = NUMCOLORS; cinfo->input_components = NUMCOLORS;
cinfo->data_precision = 8; cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
cinfo->image_width = width; cinfo->image_width = width;
cinfo->image_height = height; cinfo->image_height = height;

View File

@@ -1,7 +1,7 @@
/* /*
* rdjpgcom.c * rdjpgcom.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1995, Thomas G. Lane.
* 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.
* *
@@ -102,7 +102,7 @@ read_2_bytes (void)
#define M_SOF1 0xC1 /* N indicates which compression process */ #define M_SOF1 0xC1 /* N indicates which compression process */
#define M_SOF2 0xC2 /* Only SOF0 and SOF1 are now in common use */ #define M_SOF2 0xC2 /* Only SOF0 and SOF1 are now in common use */
#define M_SOF3 0xC3 #define M_SOF3 0xC3
#define M_SOF5 0xC5 #define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */
#define M_SOF6 0xC6 #define M_SOF6 0xC6
#define M_SOF7 0xC7 #define M_SOF7 0xC7
#define M_SOF9 0xC9 #define M_SOF9 0xC9
@@ -262,7 +262,7 @@ process_SOFn (int marker)
unsigned int image_height, image_width; unsigned int image_height, image_width;
int data_precision, num_components; int data_precision, num_components;
const char * process; const char * process;
int ci, c1, c2, c3; int ci;
length = read_2_bytes(); /* usual parameter length count */ length = read_2_bytes(); /* usual parameter length count */
@@ -296,9 +296,9 @@ process_SOFn (int marker)
ERREXIT("Bogus SOF marker length"); ERREXIT("Bogus SOF marker length");
for (ci = 0; ci < num_components; ci++) { for (ci = 0; ci < num_components; ci++) {
c1 = read_1_byte(); /* Component ID code */ (void) read_1_byte(); /* Component ID code */
c2 = read_1_byte(); /* H, V sampling factors */ (void) read_1_byte(); /* H, V sampling factors */
c3 = read_1_byte(); /* Quant table number */ (void) read_1_byte(); /* Quantization table number */
} }
} }

132
rdppm.c
View File

@@ -6,6 +6,7 @@
* 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 routines to read input images in PPM/PGM format. * This file contains routines to read input images in PPM/PGM format.
* The extended 2-byte-per-sample raw PPM/PGM formats are supported.
* The PBMPLUS library is NOT required to compile this software * The PBMPLUS library is NOT required to compile this software
* (but it is highly useful as a set of PPM image manipulation programs). * (but it is highly useful as a set of PPM image manipulation programs).
* *
@@ -72,7 +73,7 @@ typedef struct {
U_CHAR *iobuffer; /* non-FAR pointer to I/O buffer */ U_CHAR *iobuffer; /* non-FAR pointer to I/O buffer */
JSAMPROW pixrow; /* FAR pointer to same */ JSAMPROW pixrow; /* FAR pointer to same */
JDIMENSION buffer_width; /* width of one row */ size_t buffer_width; /* width of I/O buffer */
JSAMPLE *rescale; /* => maxval-remapping array, or NULL */ JSAMPLE *rescale; /* => maxval-remapping array, or NULL */
} ppm_source_struct; } ppm_source_struct;
@@ -131,8 +132,8 @@ read_pbm_integer (j_compress_ptr cinfo, FILE * infile)
* We provide several different versions depending on input file format. * We provide several different versions depending on input file format.
* In all cases, input is scaled to the size of JSAMPLE. * In all cases, input is scaled to the size of JSAMPLE.
* *
* Note that a really fast path is provided for reading raw files with * A really fast path is provided for reading byte/sample raw files with
* maxval = MAXJSAMPLE, which is the normal case (at least for 8-bit JSAMPLEs). * maxval = MAXJSAMPLE, which is the normal case for 8-bit data.
*/ */
@@ -176,7 +177,7 @@ get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
METHODDEF JDIMENSION METHODDEF JDIMENSION
get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading raw-format PGM files with any maxval */ /* This version is for reading raw-byte-format PGM files with any maxval */
{ {
ppm_source_ptr source = (ppm_source_ptr) sinfo; ppm_source_ptr source = (ppm_source_ptr) sinfo;
register JSAMPROW ptr; register JSAMPROW ptr;
@@ -197,7 +198,7 @@ get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
METHODDEF JDIMENSION METHODDEF JDIMENSION
get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading raw-format PPM files with any maxval */ /* This version is for reading raw-byte-format PPM files with any maxval */
{ {
ppm_source_ptr source = (ppm_source_ptr) sinfo; ppm_source_ptr source = (ppm_source_ptr) sinfo;
register JSAMPROW ptr; register JSAMPROW ptr;
@@ -220,9 +221,10 @@ get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
METHODDEF JDIMENSION METHODDEF JDIMENSION
get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading raw-format files with maxval = MAXJSAMPLE. */ /* This version is for reading raw-byte-format files with maxval = MAXJSAMPLE.
/* In this case we just read right into the JSAMPLE buffer! */ * In this case we just read right into the JSAMPLE buffer!
/* Note that same code works for PPM and PGM files. */ * Note that same code works for PPM and PGM files.
*/
{ {
ppm_source_ptr source = (ppm_source_ptr) sinfo; ppm_source_ptr source = (ppm_source_ptr) sinfo;
@@ -232,6 +234,60 @@ get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
} }
METHODDEF JDIMENSION
get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading raw-word-format PGM files with any maxval */
{
ppm_source_ptr source = (ppm_source_ptr) sinfo;
register JSAMPROW ptr;
register U_CHAR * bufferptr;
register JSAMPLE *rescale = source->rescale;
JDIMENSION col;
if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
ERREXIT(cinfo, JERR_INPUT_EOF);
ptr = source->pub.buffer[0];
bufferptr = source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
register int temp;
temp = UCH(*bufferptr++);
temp |= UCH(*bufferptr++) << 8;
*ptr++ = rescale[temp];
}
return 1;
}
METHODDEF JDIMENSION
get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading raw-word-format PPM files with any maxval */
{
ppm_source_ptr source = (ppm_source_ptr) sinfo;
register JSAMPROW ptr;
register U_CHAR * bufferptr;
register JSAMPLE *rescale = source->rescale;
JDIMENSION col;
if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
ERREXIT(cinfo, JERR_INPUT_EOF);
ptr = source->pub.buffer[0];
bufferptr = source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
register int temp;
temp = UCH(*bufferptr++);
temp |= UCH(*bufferptr++) << 8;
*ptr++ = rescale[temp];
temp = UCH(*bufferptr++);
temp |= UCH(*bufferptr++) << 8;
*ptr++ = rescale[temp];
temp = UCH(*bufferptr++);
temp |= UCH(*bufferptr++) << 8;
*ptr++ = rescale[temp];
}
return 1;
}
/* /*
* Read the file header; return image size and component count. * Read the file header; return image size and component count.
*/ */
@@ -242,14 +298,14 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
ppm_source_ptr source = (ppm_source_ptr) sinfo; ppm_source_ptr source = (ppm_source_ptr) sinfo;
int c; int c;
unsigned int w, h, maxval; unsigned int w, h, maxval;
boolean can_use_raw; boolean need_iobuffer, use_raw_buffer, need_rescale;
if (getc(source->pub.input_file) != 'P') if (getc(source->pub.input_file) != 'P')
ERREXIT(cinfo, JERR_PPM_NOT); ERREXIT(cinfo, JERR_PPM_NOT);
c = getc(source->pub.input_file); /* save format discriminator for a sec */ c = getc(source->pub.input_file); /* save format discriminator for a sec */
/* while we fetch the remaining header info */ /* fetch the remaining header info */
w = read_pbm_integer(cinfo, source->pub.input_file); w = read_pbm_integer(cinfo, source->pub.input_file);
h = read_pbm_integer(cinfo, source->pub.input_file); h = read_pbm_integer(cinfo, source->pub.input_file);
maxval = read_pbm_integer(cinfo, source->pub.input_file); maxval = read_pbm_integer(cinfo, source->pub.input_file);
@@ -261,8 +317,10 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
cinfo->image_width = (JDIMENSION) w; cinfo->image_width = (JDIMENSION) w;
cinfo->image_height = (JDIMENSION) h; cinfo->image_height = (JDIMENSION) h;
/* Raw PPM/PGM matches JSAMPLE representation iff: */ /* initialize flags to most common settings */
can_use_raw = (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)); need_iobuffer = TRUE; /* do we need an I/O buffer? */
use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */
need_rescale = TRUE; /* do we need a rescale array? */
switch (c) { switch (c) {
case '2': /* it's a text-format PGM file */ case '2': /* it's a text-format PGM file */
@@ -270,7 +328,7 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
cinfo->in_color_space = JCS_GRAYSCALE; cinfo->in_color_space = JCS_GRAYSCALE;
TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h);
source->pub.get_pixel_rows = get_text_gray_row; source->pub.get_pixel_rows = get_text_gray_row;
can_use_raw = FALSE; /* force a rescale array to be made */ need_iobuffer = FALSE;
break; break;
case '3': /* it's a text-format PPM file */ case '3': /* it's a text-format PPM file */
@@ -278,35 +336,37 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
cinfo->in_color_space = JCS_RGB; cinfo->in_color_space = JCS_RGB;
TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h);
source->pub.get_pixel_rows = get_text_rgb_row; source->pub.get_pixel_rows = get_text_rgb_row;
can_use_raw = FALSE; /* force a rescale array to be made */ need_iobuffer = FALSE;
break; break;
case '5': /* it's a raw-format PGM file */ case '5': /* it's a raw-format PGM file */
cinfo->input_components = 1; cinfo->input_components = 1;
cinfo->in_color_space = JCS_GRAYSCALE; cinfo->in_color_space = JCS_GRAYSCALE;
TRACEMS2(cinfo, 1, JTRC_PGM, w, h); TRACEMS2(cinfo, 1, JTRC_PGM, w, h);
if (can_use_raw) if (maxval > 255) {
source->pub.get_pixel_rows = get_word_gray_row;
} else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
source->pub.get_pixel_rows = get_raw_row; source->pub.get_pixel_rows = get_raw_row;
else use_raw_buffer = TRUE;
need_rescale = FALSE;
} else {
source->pub.get_pixel_rows = get_scaled_gray_row; source->pub.get_pixel_rows = get_scaled_gray_row;
/* allocate space for I/O buffer: 1 byte/pixel */ }
source->iobuffer = (U_CHAR *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (SIZEOF(U_CHAR) * (size_t) w));
break; break;
case '6': /* it's a raw-format PPM file */ case '6': /* it's a raw-format PPM file */
cinfo->input_components = 3; cinfo->input_components = 3;
cinfo->in_color_space = JCS_RGB; cinfo->in_color_space = JCS_RGB;
TRACEMS2(cinfo, 1, JTRC_PPM, w, h); TRACEMS2(cinfo, 1, JTRC_PPM, w, h);
if (can_use_raw) if (maxval > 255) {
source->pub.get_pixel_rows = get_word_rgb_row;
} else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
source->pub.get_pixel_rows = get_raw_row; source->pub.get_pixel_rows = get_raw_row;
else use_raw_buffer = TRUE;
need_rescale = FALSE;
} else {
source->pub.get_pixel_rows = get_scaled_rgb_row; source->pub.get_pixel_rows = get_scaled_rgb_row;
/* allocate space for I/O buffer: 3 bytes/pixel */ }
source->iobuffer = (U_CHAR *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (3 * SIZEOF(U_CHAR) * (size_t) w));
break; break;
default: default:
@@ -314,9 +374,17 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break; break;
} }
/* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */
if (need_iobuffer) {
source->buffer_width = (size_t) w * cinfo->input_components *
((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR)));
source->iobuffer = (U_CHAR *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
source->buffer_width);
}
/* Create compressor input buffer. */ /* Create compressor input buffer. */
source->buffer_width = (JDIMENSION) w * cinfo->input_components; if (use_raw_buffer) {
if (can_use_raw) {
/* For unscaled raw-input case, we can just map it onto the I/O buffer. */ /* For unscaled raw-input case, we can just map it onto the I/O buffer. */
/* Synthesize a JSAMPARRAY pointer structure */ /* Synthesize a JSAMPARRAY pointer structure */
/* Cast here implies near->far pointer conversion on PCs */ /* Cast here implies near->far pointer conversion on PCs */
@@ -327,14 +395,12 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* Need to translate anyway, so make a separate sample buffer. */ /* Need to translate anyway, so make a separate sample buffer. */
source->pub.buffer = (*cinfo->mem->alloc_sarray) source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, ((j_common_ptr) cinfo, JPOOL_IMAGE,
source->buffer_width, (JDIMENSION) 1); (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1);
source->pub.buffer_height = 1; source->pub.buffer_height = 1;
} }
/* Compute the rescaling array if required (we use it for all but raw) */ /* Compute the rescaling array if required. */
if (can_use_raw) { if (need_rescale) {
source->rescale = NULL; /* no rescaling required */
} else {
INT32 val, half_maxval; INT32 val, half_maxval;
/* On 16-bit-int machines we have to be careful of maxval = 65535 */ /* On 16-bit-int machines we have to be careful of maxval = 65535 */

23
rdrle.c
View File

@@ -66,6 +66,7 @@ typedef struct _rle_source_struct {
rle_kind visual; /* actual type of input file */ rle_kind visual; /* actual type of input file */
jvirt_sarray_ptr image; /* virtual array to hold the image */ jvirt_sarray_ptr image; /* virtual array to hold the image */
JDIMENSION row; /* current row # in the virtual array */
rle_hdr header; /* Input file information */ rle_hdr header; /* Input file information */
rle_pixel** rle_row; /* holds a row returned by rle_getrow() */ rle_pixel** rle_row; /* holds a row returned by rle_getrow() */
@@ -187,8 +188,9 @@ get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{ {
rle_source_ptr source = (rle_source_ptr) sinfo; rle_source_ptr source = (rle_source_ptr) sinfo;
source->row--;
source->pub.buffer = (*cinfo->mem->access_virt_sarray) source->pub.buffer = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, cinfo->next_scanline, FALSE); ((j_common_ptr) cinfo, source->image, source->row, FALSE);
return 1; return 1;
} }
@@ -210,14 +212,15 @@ get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
colormap = source->header.cmap; colormap = source->header.cmap;
dest_row = source->pub.buffer[0]; dest_row = source->pub.buffer[0];
source->row--;
src_row = * (*cinfo->mem->access_virt_sarray) src_row = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, cinfo->next_scanline, FALSE); ((j_common_ptr) cinfo, source->image, source->row, FALSE);
for (col = cinfo->image_width; col > 0; col--) { for (col = cinfo->image_width; col > 0; col--) {
val = GETJSAMPLE(*src_row++); val = GETJSAMPLE(*src_row++);
*dest_row++ = colormap[val ] >> 8; *dest_row++ = (JSAMPLE) (colormap[val ] >> 8);
*dest_row++ = colormap[val + 256] >> 8; *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8);
*dest_row++ = colormap[val + 512] >> 8; *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8);
} }
return 1; return 1;
@@ -249,7 +252,6 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
colormap = source->header.cmap; colormap = source->header.cmap;
rle_row = source->rle_row; rle_row = source->rle_row;
row = cinfo->image_height;
/* Read the RLE data into our virtual array. /* Read the RLE data into our virtual array.
* We assume here that (a) rle_pixel is represented the same as JSAMPLE, * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
@@ -269,7 +271,7 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
case GRAYSCALE: case GRAYSCALE:
case PSEUDOCOLOR: case PSEUDOCOLOR:
while (row--) { for (row = 0; row < cinfo->image_height; row++) {
rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, TRUE); ((j_common_ptr) cinfo, source->image, row, TRUE);
rle_getrow(&source->header, rle_row); rle_getrow(&source->header, rle_row);
@@ -284,7 +286,7 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
case MAPPEDGRAY: case MAPPEDGRAY:
case TRUECOLOR: case TRUECOLOR:
while (row--) { for (row = 0; row < cinfo->image_height; row++) {
scanline = * (*cinfo->mem->access_virt_sarray) scanline = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, TRUE); ((j_common_ptr) cinfo, source->image, row, TRUE);
rle_row = source->rle_row; rle_row = source->rle_row;
@@ -293,7 +295,7 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
for (col = 0; col < cinfo->image_width; col++) { for (col = 0; col < cinfo->image_width; col++) {
for (channel = 0; channel < source->header.ncolors; channel++) { for (channel = 0; channel < source->header.ncolors; channel++) {
*scanline++ = (JSAMPLE) *scanline++ = (JSAMPLE)
colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8; (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
} }
} }
@@ -307,7 +309,7 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
break; break;
case DIRECTCOLOR: case DIRECTCOLOR:
while (row--) { for (row = 0; row < cinfo->image_height; row++) {
scanline = * (*cinfo->mem->access_virt_sarray) scanline = * (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, source->image, row, TRUE); ((j_common_ptr) cinfo, source->image, row, TRUE);
rle_getrow(&source->header, rle_row); rle_getrow(&source->header, rle_row);
@@ -343,6 +345,7 @@ load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
} else { } else {
source->pub.get_pixel_rows = get_rle_row; source->pub.get_pixel_rows = get_rle_row;
} }
source->row = cinfo->image_height;
/* And fetch the topmost (bottommost) row */ /* And fetch the topmost (bottommost) row */
return (*source->pub.get_pixel_rows) (cinfo, sinfo); return (*source->pub.get_pixel_rows) (cinfo, sinfo);

View File

@@ -1,6 +1,6 @@
IJG JPEG LIBRARY: SYSTEM ARCHITECTURE IJG JPEG LIBRARY: SYSTEM ARCHITECTURE
Copyright (C) 1991-1994, Thomas G. Lane. Copyright (C) 1991-1995, Thomas G. Lane.
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.
@@ -362,7 +362,9 @@ The objects shown above are:
This controller handles MCU assembly, including insertion of dummy DCT This controller handles MCU assembly, including insertion of dummy DCT
blocks when needed at the right or bottom edge. When performing blocks when needed at the right or bottom edge. When performing
Huffman-code optimization or emitting a multiscan JPEG file, this Huffman-code optimization or emitting a multiscan JPEG file, this
controller is responsible for buffering the full image. controller is responsible for buffering the full image. The equivalent of
one fully interleaved MCU row of subsampled data is processed per call,
even when the JPEG file is noninterleaved.
* Forward DCT and quantization: Perform DCT, quantize, and emit coefficients * Forward DCT and quantization: Perform DCT, quantize, and emit coefficients
in zigzag block order. Works on one or more DCT blocks at a time. in zigzag block order. Works on one or more DCT blocks at a time.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -131,13 +131,13 @@ Switches for advanced users:
-dct int Use integer DCT method (default). -dct int Use integer DCT method (default).
-dct fast Use fast integer DCT (less accurate). -dct fast Use fast integer DCT (less accurate).
-dct float Use floating-point DCT method. -dct float Use floating-point DCT method.
The floating-point method is the most accurate, but The float method is very slightly more accurate than
will be the slowest unless your machine has very fast the int method, but is much slower unless your machine
floating-point hardware. Also note that results of has very fast floating-point hardware. Also note that
the floating-point method may vary slightly across results of the floating-point method may vary slightly
machines, while the integer methods should give the across machines, while the integer methods should give
same results everywhere. The fast integer method is the same results everywhere. The fast integer method
much less accurate than the other two. is much less accurate than the other two.
-restart N Emit a JPEG restart marker every N MCU rows, or every -restart N Emit a JPEG restart marker every N MCU rows, or every
N MCU blocks if "B" is attached to the number. N MCU blocks if "B" is attached to the number.
@@ -266,13 +266,13 @@ Switches for advanced users:
-dct int Use integer DCT method (default). -dct int Use integer DCT method (default).
-dct fast Use fast integer DCT (less accurate). -dct fast Use fast integer DCT (less accurate).
-dct float Use floating-point DCT method. -dct float Use floating-point DCT method.
The floating-point method is the most accurate, but The float method is very slightly more accurate than
will be the slowest unless your machine has very fast the int method, but is much slower unless your machine
floating-point hardware. Also note that results of has very fast floating-point hardware. Also note that
the floating-point method may vary slightly across results of the floating-point method may vary slightly
machines, while the integer methods should give the across machines, while the integer methods should give
same results everywhere. The fast integer method is the same results everywhere. The fast integer method
much less accurate than the other two. is much less accurate than the other two.
-dither fs Use Floyd-Steinberg dithering in color quantization. -dither fs Use Floyd-Steinberg dithering in color quantization.
-dither ordered Use ordered dithering in color quantization. -dither ordered Use ordered dithering in color quantization.
@@ -346,7 +346,10 @@ much lower quality than the default behavior. "-dither none" may give
acceptable results in two-pass mode, but is seldom tolerable in one-pass mode. acceptable results in two-pass mode, but is seldom tolerable in one-pass mode.
If you are fortunate enough to have very fast floating point hardware, If you are fortunate enough to have very fast floating point hardware,
"-dct float" may be even faster than "-dct fast". "-dct float" may be even faster than "-dct fast". But on most machines
"-dct float" is slower than "-dct int"; in this case it is not worth using,
because its theoretical accuracy advantage is too small to be significant
in practice.
Two-pass color quantization requires a good deal of memory; on MS-DOS machines Two-pass color quantization requires a good deal of memory; on MS-DOS machines
it may run out of memory even with -maxmemory 0. In that case you can still it may run out of memory even with -maxmemory 0. In that case you can still

View File

@@ -5,6 +5,11 @@
* 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.
* *
**************************************************************************
* WARNING: You will need an LZW patent license from Unisys in order to *
* use this file legally in any commercial or shareware application. *
**************************************************************************
*
* This file contains routines to write output images in GIF format. * This file contains routines to write output images in GIF format.
* *
* These routines may need modification for non-Unix environments or * These routines may need modification for non-Unix environments or

View File

@@ -1,7 +1,7 @@
/* /*
* wrjpgcom.c * wrjpgcom.c
* *
* Copyright (C) 1994, Thomas G. Lane. * Copyright (C) 1994-1995, Thomas G. Lane.
* 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,7 +152,7 @@ copy_rest_of_file (void)
#define M_SOF1 0xC1 /* N indicates which compression process */ #define M_SOF1 0xC1 /* N indicates which compression process */
#define M_SOF2 0xC2 /* Only SOF0 and SOF1 are now in common use */ #define M_SOF2 0xC2 /* Only SOF0 and SOF1 are now in common use */
#define M_SOF3 0xC3 #define M_SOF3 0xC3
#define M_SOF5 0xC5 #define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */
#define M_SOF6 0xC6 #define M_SOF6 0xC6
#define M_SOF7 0xC7 #define M_SOF7 0xC7
#define M_SOF9 0xC9 #define M_SOF9 0xC9

68
wrppm.c
View File

@@ -6,6 +6,7 @@
* 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 routines to write output images in PPM/PGM format. * This file contains routines to write output images in PPM/PGM format.
* The extended 2-byte-per-sample raw PPM/PGM formats are supported.
* The PBMPLUS library is NOT required to compile this software * The PBMPLUS library is NOT required to compile this software
* (but it is highly useful as a set of PPM image manipulation programs). * (but it is highly useful as a set of PPM image manipulation programs).
* *
@@ -20,18 +21,34 @@
/* /*
* Currently, this code only knows how to write raw PPM or PGM format, * For 12-bit JPEG data, we either downscale the values to 8 bits
* which can be no more than 8 bits/sample. As an expedient for testing * (to write standard byte-per-sample PPM/PGM files), or output
* 12-bit JPEG mode, we support writing 12-bit data to an 8-bit file by * nonstandard word-per-sample PPM/PGM files. Downscaling is done
* downscaling the values. Of course this implies loss of precision. * if PPM_NORAWWORD is defined (this can be done in the Makefile
* or in jconfig.h).
* (When the core library supports data precision reduction, a cleaner * (When the core library supports data precision reduction, a cleaner
* implementation will be to ask for that instead.) * implementation will be to ask for that instead.)
*/ */
#if BITS_IN_JSAMPLE == 8 #if BITS_IN_JSAMPLE == 8
#define DOWNSCALE(x) (x) #define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) (v)
#define BYTESPERSAMPLE 1
#define PPM_MAXVAL 255
#else #else
#define DOWNSCALE(x) ((x) >> (BITS_IN_JSAMPLE-8)) #ifdef PPM_NORAWWORD
#define PUTPPMSAMPLE(ptr,v) *ptr++ = (char) ((v) >> (BITS_IN_JSAMPLE-8))
#define BYTESPERSAMPLE 1
#define PPM_MAXVAL 255
#else
/* The word-per-sample format always puts the LSB first. */
#define PUTPPMSAMPLE(ptr,v) \
{ register int val_ = v; \
*ptr++ = (char) (val_ & 0xFF); \
*ptr++ = (char) ((val_ >> 8) & 0xFF); \
}
#define BYTESPERSAMPLE 2
#define PPM_MAXVAL ((1<<BITS_IN_JSAMPLE)-1)
#endif
#endif #endif
@@ -54,8 +71,8 @@ typedef struct {
/* Usually these two pointers point to the same place: */ /* Usually these two pointers point to the same place: */
char *iobuffer; /* fwrite's I/O buffer */ char *iobuffer; /* fwrite's I/O buffer */
JSAMPROW pixrow; /* decompressor output buffer */ JSAMPROW pixrow; /* decompressor output buffer */
size_t buffer_width; /* width of I/O buffer */
JDIMENSION buffer_width; /* width of one row */ JDIMENSION samples_per_row; /* JSAMPLEs per output row */
} ppm_dest_struct; } ppm_dest_struct;
typedef ppm_dest_struct * ppm_dest_ptr; typedef ppm_dest_struct * ppm_dest_ptr;
@@ -80,8 +97,8 @@ put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
/* /*
* This code is used when we have to copy the data because JSAMPLE is not * This code is used when we have to copy the data and apply a pixel
* the same size as char. Typically this only happens in 12-bit mode. * format translation. Typically this only happens in 12-bit mode.
*/ */
METHODDEF void METHODDEF void
@@ -95,8 +112,8 @@ copy_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
ptr = dest->pub.buffer[0]; ptr = dest->pub.buffer[0];
bufferptr = dest->iobuffer; bufferptr = dest->iobuffer;
for (col = dest->buffer_width; col > 0; col--) { for (col = dest->samples_per_row; col > 0; col--) {
*bufferptr++ = (char) DOWNSCALE(GETJSAMPLE(*ptr++)); PUTPPMSAMPLE(bufferptr, GETJSAMPLE(*ptr++));
} }
(void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
} }
@@ -124,9 +141,9 @@ put_demapped_rgb (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
bufferptr = dest->iobuffer; bufferptr = dest->iobuffer;
for (col = cinfo->output_width; col > 0; col--) { for (col = cinfo->output_width; col > 0; col--) {
pixval = GETJSAMPLE(*ptr++); pixval = GETJSAMPLE(*ptr++);
*bufferptr++ = (char) DOWNSCALE(GETJSAMPLE(color_map0[pixval])); PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map0[pixval]));
*bufferptr++ = (char) DOWNSCALE(GETJSAMPLE(color_map1[pixval])); PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map1[pixval]));
*bufferptr++ = (char) DOWNSCALE(GETJSAMPLE(color_map2[pixval])); PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map2[pixval]));
} }
(void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
} }
@@ -145,7 +162,7 @@ put_demapped_gray (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
ptr = dest->pub.buffer[0]; ptr = dest->pub.buffer[0];
bufferptr = dest->iobuffer; bufferptr = dest->iobuffer;
for (col = cinfo->output_width; col > 0; col--) { for (col = cinfo->output_width; col > 0; col--) {
*bufferptr++ = (char) DOWNSCALE(GETJSAMPLE(color_map[GETJSAMPLE(*ptr++)])); PUTPPMSAMPLE(bufferptr, GETJSAMPLE(color_map[GETJSAMPLE(*ptr++)]));
} }
(void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width); (void) JFWRITE(dest->pub.output_file, dest->iobuffer, dest->buffer_width);
} }
@@ -165,12 +182,14 @@ start_output_ppm (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
case JCS_GRAYSCALE: case JCS_GRAYSCALE:
/* emit header for raw PGM format */ /* emit header for raw PGM format */
fprintf(dest->pub.output_file, "P5\n%ld %ld\n%d\n", fprintf(dest->pub.output_file, "P5\n%ld %ld\n%d\n",
(long) cinfo->output_width, (long) cinfo->output_height, 255); (long) cinfo->output_width, (long) cinfo->output_height,
PPM_MAXVAL);
break; break;
case JCS_RGB: case JCS_RGB:
/* emit header for raw PPM format */ /* emit header for raw PPM format */
fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n", fprintf(dest->pub.output_file, "P6\n%ld %ld\n%d\n",
(long) cinfo->output_width, (long) cinfo->output_height, 255); (long) cinfo->output_width, (long) cinfo->output_height,
PPM_MAXVAL);
break; break;
default: default:
ERREXIT(cinfo, JERR_PPM_COLORSPACE); ERREXIT(cinfo, JERR_PPM_COLORSPACE);
@@ -212,15 +231,16 @@ jinit_write_ppm (j_decompress_ptr cinfo)
jpeg_calc_output_dimensions(cinfo); jpeg_calc_output_dimensions(cinfo);
/* Create physical I/O buffer. Note we make this near on a PC. */ /* Create physical I/O buffer. Note we make this near on a PC. */
dest->buffer_width = cinfo->output_width * cinfo->out_color_components; dest->samples_per_row = cinfo->output_width * cinfo->out_color_components;
dest->iobuffer = (char *) dest->buffer_width = dest->samples_per_row * (BYTESPERSAMPLE * SIZEOF(char));
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->iobuffer = (char *) (*cinfo->mem->alloc_small)
(size_t) (dest->buffer_width * SIZEOF(char))); ((j_common_ptr) cinfo, JPOOL_IMAGE, dest->buffer_width);
if (cinfo->quantize_colors || SIZEOF(JSAMPLE) != SIZEOF(char)) { if (cinfo->quantize_colors || BITS_IN_JSAMPLE != 8 ||
SIZEOF(JSAMPLE) != SIZEOF(char)) {
/* When quantizing, we need an output buffer for colormap indexes /* When quantizing, we need an output buffer for colormap indexes
* that's separate from the physical I/O buffer. We also need a * that's separate from the physical I/O buffer. We also need a
* separate buffer if JSAMPLE and char are not the same size. * separate buffer if pixel format translation must take place.
*/ */
dest->pub.buffer = (*cinfo->mem->alloc_sarray) dest->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, ((j_common_ptr) cinfo, JPOOL_IMAGE,