The Independent JPEG Group's JPEG software v5a

This commit is contained in:
Thomas G. Lane 1994-12-07 00:00:00 +00:00 committed by DRC
parent 36a4ccccd3
commit 9ba2f5ed36
37 changed files with 1734 additions and 1032 deletions

50
README
View File

@ -1,7 +1,7 @@
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 5a of 7-Dec-94
================================= =================================
This distribution contains the fifth public release of the Independent JPEG This distribution contains the fifth public release of the Independent JPEG
@ -9,9 +9,9 @@ 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
@ -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
@ -194,12 +193,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 +263,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.v5a.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.
@ -274,18 +273,21 @@ you can probably find a copy at any site that archives comp.sources.misc
submissions. However, only ftp.uu.net is guaranteed to have the latest 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
(GO GRAPHSUP); this version will be file jpsrc5.zip in library 15. Again, forum (GO GRAPHSUP), probably in library 15 (there are rumors of a pending
CompuServe is not guaranteed to have the very latest version. reorganization there). Again, CompuServe is not guaranteed 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,34 @@
CHANGE LOG for Independent JPEG Group's JPEG software CHANGE LOG for Independent JPEG Group's JPEG software
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
-------------------- --------------------

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) {

1921
configure vendored

File diff suppressed because it is too large Load Diff

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

@ -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.
@ -500,6 +503,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:

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,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

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

@ -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

@ -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

@ -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 */

118
jquant1.c
View 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 */
@ -226,6 +251,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 +299,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 +379,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

@ -9,6 +9,6 @@
*/ */
#define JVERSION "5 24-Sep-94" #define JVERSION "5a 7-Dec-94"
#define JCOPYRIGHT "Copyright (C) 1994, Thomas G. Lane" #define JCOPYRIGHT "Copyright (C) 1994, Thomas G. Lane"

View File

@ -657,13 +657,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(...);
@ -1561,6 +1564,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
------------------------------------------- -------------------------------------------
@ -2027,12 +2046,15 @@ 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.
At present, a 12-bit library can handle *only* 12-bit images, not both The sample applications cjpeg and djpeg can support 12-bit mode only for PPM
precisions. (If you need to include both 8- and 12-bit libraries in a and GIF file formats; you must disable the other file formats to compile a
single application, you could probably do it by defining 12-bit cjpeg or djpeg. At present, a 12-bit library can handle *only*
NEED_SHORT_EXTERNAL_NAMES for just one of the copies. You'd have to access 12-bit images, not both precisions. (If you need to include both 8- and
the 8-bit and 12-bit copies from separate application source files. This is 12-bit libraries in a single application, you could probably do it by
untested ... if you try it, we'd like to hear whether it works!) defining NEED_SHORT_EXTERNAL_NAMES for just one of the copies. You'd have
to access the 8-bit and 12-bit copies from separate application source
files. This is untested ... if you try it, we'd like to hear whether it
works!)
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 +2142,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

@ -54,10 +54,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,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@ -I$(srcdir)
# 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
@ -158,7 +158,8 @@ install-lib: libjpeg.a jconfig.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*

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 */

13
rdgif.c
View File

@ -352,9 +352,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 +513,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;

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);

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

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,