Compare commits

...

2 Commits

Author SHA1 Message Date
Thomas G. Lane
4a6b730364 The Independent JPEG Group's JPEG software v3 2015-07-29 15:21:19 -05:00
Thomas G. Lane
bd543f030e The Independent JPEG Group's JPEG software v2 2015-07-29 15:20:00 -05:00
83 changed files with 11155 additions and 2840 deletions

77
CHANGELOG Normal file
View File

@@ -0,0 +1,77 @@
CHANGELOG for Independent JPEG Group's JPEG software
Version 3 17-Mar-92
--------------------
Memory manager is finally capable of swapping to temp files. There are
separate versions of jmemsys.c for no temp files (same behavior as older
versions), simple temp files with or without tmpfile(), and a DOS-specific
version (including special code for EMS and XMS). This is probably much more
system-dependent than any of the older code; some bugs may surface here.
Hooks added for user interface to install progress monitoring routine
(percent-done bar, etc). See comments with dummy progress_monitor
routines in jcdeflts.c, jddeflts.c.
Two-pass color quantization (finally!). This is now the default method when
quantizing; say '-1' to djpeg for quick-and-ugly 1-pass method. There is
a test file for checking 2-pass quantization and GIF output.
Fixed bug in jcopy_block_row that broke cjpeg -o option and djpeg -b option
on MSDOS machines.
Miscellaneous small speedups; notably, DCT computation rearranged so that
GCC "inline" feature is no longer needed for good code quality.
File config.c renamed ckconfig.c to avoid name conflict with /etc/config
on Unix systems.
Added example.c to document usage of JPEG subroutines better.
Memory manager now knows how to release all storage during error exit ---
avoids memory leak when using JPEG as subroutines. This implies a couple
small changes to the subroutine interface: the old free_defaults subroutines
are no longer needed, but if you have a replacement error_exit method then it
must call the new free_all method. Also, jselvirtmem renamed to jselmemmgr.
Code for reading Targa files with 32-bit pixels was incorrect.
Colorspace conversion slightly faster and more accurate; because of
this, old "test" files will no longer match bit-for-bit.
Version 2 13-Dec-91
--------------------
Documentation improved a little --- there are man pages now.
Installation instructions moved from README to a separate file SETUP.
New program config.c is provided to help you get the configuration options
right. This should make installation a lot more foolproof.
Sense of djpeg -D switch reversed: dithering is now ON by default.
RLE image file support added (thanks to Mike Lijewski).
Targa image file support added (thanks to Lee Crocker).
PPM input now accepts all PPM and PGM files.
Bug fix: on machines where 'int' is 16 bits, high-Q-setting JPEG files
were not decoded correctly.
Numerous changes to improve portability. There should be few or no compiler
warnings now.
Makefiles cleaned up; defaults now appropriate for production use rather than
debugging.
Subroutine interface cleaned up. If you wrote code based on version 1's
jcmain/jdmain, you'll need to change it, but it should get a little shorter
and simpler.
Version 1 7-Oct-91
--------------------
Initial public release.

401
README
View File

@@ -1,27 +1,27 @@
The Independent JPEG Group's JPEG software The Independent JPEG Group's JPEG software
========================================== ==========================================
README for release of 7-Oct-91 README for release 3 of 17-Mar-92
=============================== ==================================
This distribution contains the first public release of the Independent JPEG This distribution contains the third official 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.
This software is still undergoing revision. Updated versions may be obtained For installation instructions, see file SETUP; for usage instructions, see
by anonymous FTP to uunet.uu.net; look under directory /graphics/jpeg. This file USAGE (or the cjpeg.1 and djpeg.1 manual pages).
particular version will be archived as jpegsrc.v1.tar.Z. If you don't have
access to Internet FTP, UUNET's archives are also available via UUCP; contact
postmaster@uunet.uu.net for information on retrieving files that way.
Please report any problems with this software to jpeg-info@uunet.uu.net. This software is still undergoing revision. Updated versions may be obtained
by FTP or UUCP to UUNET and other archive sites; see ARCHIVE LOCATIONS below
for details.
If you intend to become a serious user of this software, please contact If you intend to become a serious user of this software, please contact
jpeg-info@uunet to be added to our electronic mailing list. Then you'll be jpeg-info@uunet.uu.net to be added to our electronic mailing list. Then
notified of updates and have a chance to participate in discussions, etc. you'll be notified of updates and have a chance to participate in discussions,
etc.
This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, and other This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz,
members of the independent JPEG group. Lee Crocker, Ge' Weijers, and other members of the Independent JPEG Group.
DISCLAIMER DISCLAIMER
@@ -32,29 +32,32 @@ useful for anything, nor to be compatible with subsequent releases, nor to be
an accurate implementation of the JPEG standard. (See LEGAL ISSUES for even an accurate implementation of the JPEG standard. (See LEGAL ISSUES for even
more disclaimers.) more disclaimers.)
Please report any problems with this software to jpeg-info@uunet.uu.net.
WHAT'S HERE WHAT'S HERE
=========== ===========
This distribution contains software to implement JPEG image compression and This distribution contains C software to implement JPEG image compression and
decompression. JPEG is a standardized compression method for full-color and decompression. JPEG (pronounced "jay-peg") is a standardized compression
gray-scale images. JPEG is intended for "real-world" scenes; cartoons and method for full-color and gray-scale images. JPEG is intended for
other non-realistic images are not its strong suit. JPEG is lossy, meaning "real-world" scenes; cartoons and other non-realistic images are not its
that the output image is not necessarily identical to the input image. Hence strong suit. JPEG is lossy, meaning that the output image is not necessarily
you should not use JPEG if you have to have identical output bits. However, identical to the input image. Hence you should not use JPEG if you have to
on typical images of real-world scenes, very good compression levels can be have identical output bits. However, on typical images of real-world scenes,
obtained with hardly any visible change, and amazingly high compression levels very good compression levels can be obtained with no visible change, and
can be obtained if you can tolerate a low-quality image. For more details, amazingly high compression levels can be obtained if you can tolerate a
see the references, or just experiment with various compression settings. low-quality image. For more details, see the references, or just experiment
with various compression settings.
The software implements JPEG baseline and extended-sequential compression The software implements JPEG baseline and extended-sequential compression
processes. Provision is made for supporting all variants of these processes, processes. Provision is made for supporting all variants of these processes,
although some uncommon parameter settings aren't implemented yet. For legal 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 or lossless processes defined in the standard. progressive, hierarchical, or lossless processes defined in the standard.
The present software is still largely in the prototype stage. It does not The present software is not far beyond the prototype stage. It does not
support all possible variants of the JPEG standard, and some functions have support all possible variants of the JPEG standard, and some functions have
rather slow and/or crude implementations. However, it is useful already. rather slow and/or crude implementations. However, it is useful already.
@@ -67,9 +70,9 @@ the future.
This software can be used on several levels: This software can be used on several levels:
* As canned software for JPEG compression and decompression. Just edit the * As canned software for JPEG compression and decompression. Just edit the
Makefile and configuration files as needed (see SETUP), compile and go. Makefile and configuration files as needed (see file SETUP), compile and go.
Members of the independent JPEG group will improve the out-of-the-box Members of the Independent JPEG Group will improve the out-of-the-box
functionality as time goes on. functionality and speed as time goes on.
* As the basis for other JPEG programs. For example, you could incorporate * As the basis for other JPEG programs. For example, you could incorporate
the decompressor into a general image viewing package by replacing the the decompressor into a general image viewing package by replacing the
@@ -77,7 +80,7 @@ This software can be used on several levels:
specific hardware, you might want to replace some of the inner loops with specific hardware, you might want to replace some of the inner loops with
assembly code. For a non-command-line-driven system, you might want a assembly code. For a non-command-line-driven system, you might want a
different user interface. (Members of the group will be producing Macintosh different user interface. (Members of the group will be producing Macintosh
and Amiga versions with appropriate user interfaces, for example.) and Amiga versions with more appropriate user interfaces, for example.)
* As a toolkit for experimentation with JPEG and JPEG-like algorithms. Most * As a toolkit for experimentation with JPEG and JPEG-like algorithms. Most
of the individual decisions you might want to mess with are packaged up into of the individual decisions you might want to mess with are packaged up into
@@ -86,185 +89,140 @@ This software can be used on several levels:
decompressor module. You'd probably also want to extend the user interface decompressor module. You'd probably also want to extend the user interface
to give you more detailed control over the JPEG compression parameters. to give you more detailed control over the JPEG compression parameters.
In particular, we welcome the use of this software as the basis for commercial In particular, we welcome the use of this software as a component of commercial
products; no royalty is required. products; no royalty is required.
SETUP ARCHIVE LOCATIONS
===== =================
The installation process is not very automatic; you will need at least some The "official" archive site for this software is ftp.uu.net (Internet
familiarity with C programming and program build procedures for your system. address 137.39.1.9 or 192.48.96.9). The most recent released version can
(Volunteers to work on improving this situation are welcome. Also, we will always be found there in directory graphics/jpeg. This particular version
probably start distributing pre-built binaries for popular systems at some will be archived as jpegsrc.v3.tar.Z. If you are on the Internet, you can
point.) retrieve files from UUNET by anonymous FTP. If you don't have FTP access,
UUNET's archives are also available via UUCP; contact postmaster@uunet.uu.net
for information on retrieving files that way.
First, select a makefile and copy it to "Makefile". "makefile.unix" Various other Internet sites maintain copies of the UUNET file, which may or
is appropriate for most Unix and Unix-like systems. Special makefiles are may not be up-to-date. In Europe, try nic.funet.fi (128.214.6.100; look in
included for various PC compilers. If you don't see a makefile for your directory pub/graphics/programs/jpeg).
system, we recommend starting from makefile.unix.
Look over the Makefile and adjust options as needed. In particular, you'll You can also obtain this software from CompuServe, in the GRAPHSUPPORT forum
need to change the CC= and CFLAGS= definitions if you don't have gcc (GO PICS), library 10; this version will be file jpsrc3.zip.
(makefile.unix only). If you have a function-prototype-less compiler, be sure
to uncomment the .c.o rule and say "make ansi2knr". This will cause the
source files to be preprocessed to change our ANSI-style function definitions
to old-style definitions. (Thanks to Peter Deutsch of Aladdin Enterprises for
ansi2knr.)
Also look over jconfig.h and adjust #defines as necessary. If you have an If you are not reasonably handy at configuring and installing portable C
ANSI-compliant C compiler (gcc for instance), no changes should be necessary programs, you may have some difficulty installing this package. You may
except perhaps for RIGHT_SHIFT_IS_UNSIGNED and TWO_FILE_COMMANDLINE. For prefer to obtain a pre-built executable version. A collection of pre-built
older compilers other mods may be needed, depending on what ANSI features are executables for various machines is currently available for anonymous FTP at
supported. If you prefer, you can usually leave jconfig.h unmodified and add procyon.cis.ksu.edu (129.130.10.80 --- this number is due to change soon);
-D switches to the Makefile's CFLAGS= definition. look under /pub/JPEG. The administrators of this system ask that FTP traffic
be limited to non-prime hours. For more information on this archive, please
Then say "make". contact Steve Davis (strat@cis.ksu.edu). This collection is not maintained by
the Independent JPEG Group, and programs in it may not be the latest version.
If you have trouble with missing system include files or inclusion of the
wrong ones, you can fix it in jinclude.h. In particular, if you are using
gcc on a machine with non-ANSI system include files, you are likely to find
that jinclude.h tries to include the wrong files (because gcc defines
__STDC__). There's no good automatic solution to this, so you'll just have
to hand-edit jinclude.h.
As a quick test of functionality we've included three sample files:
testorig.jpg same as blkint.jpg from JPEG validation floppy.
testimg.ppm output of djpeg testorig.jpg
testimg.jpg output of cjpeg testimg.ppm
The two .jpg files aren't identical due to different parameter choices (and
wouldn't be anyway, since JPEG is lossy). However, if you can generate
duplicates of testimg.ppm and testimg.jpg then you probably have a working
port. "make test" will perform the necessary comparisons (by generating
testout.ppm and testout.jpg and comparing these to testimg.*). NOTE: this
is far from an exhaustive test of the JPEG software; some modules, such as
color quantization and GIF I/O, are not exercised at all. It's just a quick
test to give you some confidence that you haven't missed something major.
If you need to make a smaller version of the JPEG software, some optional
functions can be removed at compile time. See the xxx_SUPPORTED #defines
in jconfig.h. (Not a lot is actually removed right now, but as more optional
stuff gets added, this mechanism will start to make a difference.)
If you want to incorporate the JPEG code as subroutines in a larger program,
we recommend that you make libjpeg.a. Then use the .h files and libjpeg.a as
your interface to the JPEG functions. Your surrounding program will have to
provide functionality similar to what's in jcmain.c or jdmain.c, and you may
want to replace jerror.c and possibly other modules depending on your needs.
See the "architecture" file for more info. If it seems to you that the system
structure doesn't accommodate what you want to do, please contact the authors.
Special notes for Macintosh Think C users: If you have version 5.0 you should
be able to just turn on __STDC__ through the compiler switch that enables
that. With version 4.0 you must manually edit jconfig.h to define PROTO,
HAVE_UNSIGNED_CHAR, HAVE_UNSIGNED_SHORT, and const. (It seems to be safe to
just define __STDC__ to take care of the first three.) When setting up
project files, use the COBJECTS and DOBJECTS lists in makefile.unix as a guide
to which files need to be included, and add the ANSI and Unix C libraries in a
separate segment. You may need to divide the JPEG files into more than one
segment; you can do this pretty much as you please.
USAGE SUPPORTING SOFTWARE
===== ===================
The user interface is pretty minimal at this point. We haven't bothered to You will probably want Jef Poskanzer's PBMPLUS image software, which provides
generate manual-page files since the switches badly need redesign. At the many useful operations on PPM-format image files. In particular, it can
moment, things work like this: convert PPM images to and from a wide range of other formats. You can FTP
this free software from export.lcs.mit.edu (contrib/pbmplus*.tar.Z) or
ftp.ee.lbl.gov (pbmplus*.tar.Z). Unfortunately PBMPLUS is not nearly as
portable as the JPEG software is; you are likely to have difficulty making it
work on any non-Unix machine.
There are two programs, cjpeg to compress an image file into JPEG format, If you are using X Windows you might want to use the xv or xloadimage viewers
and djpeg to decompress. to save yourself the trouble of converting PPM to some other format. Both of
these can be found in the contrib directory at export.lcs.mit.edu. Actually,
xv version 2.00 and up incorporates our software and thus can read and write
JPEG files directly. (NOTE: since xv internally reduces all images to 8
bits/pixel, a JPEG file written by xv will not be very high quality; you may
also prefer xloadimage for viewing if you have a 24-bit display. Caveat user.)
On Unix systems, you say: For DOS machines, Lee Crocker's free Piclab program is a useful companion to
cjpeg [switches] [imagefile] >jpegfile the JPEG software. The latest version, currently 1.91, is available by FTP
djpeg [switches] [jpegfile] >imagefile from SIMTEL20 and its various mirror sites, file <msdos.graphics>piclb191.zip.
The programs read the specified input file, or standard input if none is CompuServe also has it, in the same library as the JPEG software.
named. They always write to standard output (with trace/error messages to
standard error). These conventions are handy for piping images between
programs.
On PC, Macintosh, and Amiga systems, you say:
cjpeg [switches] imagefile jpegfile
djpeg [switches] jpegfile imagefile
i.e., both input and output files are named on the command line. This style
is a little more foolproof, and it loses no functionality if you don't have
pipes. You can get this style on Unix too, if you prefer, by defining
TWO_FILE_COMMANDLINE in jconfig.h or in the Makefile. You MUST use this style
on any system that doesn't cope well with binary data fed through
stdin/stdout.
Currently supported image file formats include raw-format PPM, raw-format PGM SOFTWARE THAT'S NO HELP AT ALL
(for monochrome images), and GIF. cjpeg recognizes the input image format ==============================
automatically, but you have to tell djpeg which format to generate.
The only JPEG file format currently supported is a raw JPEG data stream. Handmade Software's shareware PC program GIF2JPG produces files that are
Unless modified, the programs use the JFIF conventions for variables left totally incompatible with our programs. They use a proprietary format that is
unspecified by the JPEG standard. (In particular, cjpeg generates a JFIF APP0 an amalgam of GIF and JPEG representations. However, you can force GIF2JPG
marker.) Support for the JPEG-in-TIFF format will probably be added at some to produce compatible files with its -j switch, and their decompression
future date. program JPG2GIF can read our files (at least ones produced with our default
option settings).
The command line switches for cjpeg are: Unfortunately, many commercial JPEG implementations are also incompatible as
of this writing, especially programs released before summer 1991. The root of
the problem is that the ISO JPEG committee failed to specify a concrete file
format. Some vendors "filled in the blanks" on their own, creating
proprietary formats that no one else could read. (For example, none of the
early commercial JPEG implementations for the Macintosh were able to exchange
compressed files.)
-I Generate noninterleaved JPEG file (not yet supported). The file format we have adopted is called JFIF (see REFERENCES). This format
has been agreed to by a number of major commercial JPEG vendors, and we expect
that it will become the de facto standard. JFIF is a minimal representation;
work is also going forward to incorporate JPEG compression into the TIFF
standard, for use in "high end" applications that need to record a lot of
additional data about an image. We intend to support JPEG-in-TIFF in the
future. We hope that these two formats will be sufficient and that other,
incompatible JPEG file formats will not proliferate.
-Q quality Scale quantization tables to adjust quality. Indeed, part of the reason for developing and releasing this free software is
Quality is 0 (worst) to 100 (best); default is 75. to help force rapid convergence to de facto standards for JPEG file formats.
(See below for more info.) SUPPORT STANDARD, NON-PROPRIETARY FORMATS: demand JFIF or JPEG-in-TIFF!
-a Use arithmetic coding rather than Huffman coding.
(Not currently supported, see LEGAL ISSUES.)
-o Perform optimization of entropy encoding parameters. USING JPEG AS A SUBROUTINE IN A LARGER PROGRAM
Without this, default Huffman or arithmetic ==============================================
parameters are used. -o makes the JPEG file a tad
smaller, but compression uses much more memory.
Image quality is unaffected by -o.
-d Enable debug printout. More -d's give more printout. You can readily incorporate the JPEG compression and decompression routines in
a larger program. The file example.c provides a skeleton of the interface
routines you'll need for this purpose. Essentially, you replace jcmain.c (for
compression) and/or jdmain.c (for decompression) with your own code. Note
that the fewer JPEG options you allow the user to twiddle, the less code you
need; all the default options are set up automatically. (Alternately, if you
know a lot about JPEG or have a special application, you may want to twiddle
the default options even more extensively than jcmain/jdmain do.)
Typically you'd use -Q settings of 50 or 75 or so. -Q 100 will generate a Most likely, you will want the uncompressed image to come from memory (for
quantization table of all 1's, meaning no quantization loss; then any compression) or go to memory or the screen (for decompression). For this
differences between input and output images are due to subsampling or to purpose you must provide image reading or writing routines that match the
roundoff error in the DCT or colorspace-conversion steps. -Q values below 50 interface used by the image file I/O modules (jrdXXX or jwrXXX); again,
may be useful for making real small, low-quality images. Try -Q 2 (or so) for example.c shows a skeleton of what is required.
some amusing Cubist effects. (Note that -Q values below about 25 generate
2-byte quantization tables, which are not decodable by pure baseline JPEG
decoders. cjpeg emits a warning message when you give such a -Q value.)
The command line switches for djpeg are: By default, any error detected inside the JPEG routines will cause a message
to be printed on stderr, followed by exit(). You can override this behavior
by supplying your own message-printing and/or error-exit routines; again,
example.c shows how.
-G Select GIF output format (implies -q, with default Mechanics: we recommend you create libjpeg.a as shown in the Makefile, then
of 256 colors). link that with your surrounding program. (If your linker is at all
reasonable, only the code you actually need will get loaded.) Include the
files jconfig.h and jpegdata.h in C files that need to call the JPEG routines.
-b Perform cross-block smoothing. This is quite CAUTION: some people have tried to compile JPEG and their surrounding code
memory-intensive and only seems to improve the image with different compilers, e.g., cc for JPEG and c++ or gcc for the rest. This
at very low quality settings (-Q 10 to 20 or so). is a Real Bad Move and you will deserve what happens to you if you try it.
(Hint: the parameter structures can get laid out differently with no warning.)
-g Force gray-scale output even if input is color. Read our "architecture" file for more info. If it seems to you that the
software structure doesn't accommodate what you want to do, please contact
the authors.
-q N Quantize to N colors. Beginning with version 3, we will endeavor to hold the interface described by
example.c constant, so that you can plug in updated versions of the JPEG code
-D Use Floyd-Steinberg dithering in color quantization. just by recompiling. However, we can't guarantee this, especially if you
choose to twiddle any JPEG options not listed in example.c. Check the
-2 Use two-pass color quantization (not yet supported). CHANGELOG when installing any new version, and compare example.c against the
prior version. Recompile your calling software (don't just relink), as we may
-d Enable debug printout. More -d's give more printout. add or subtract fields in the parameter structures.
Color quantization currently uses a rather shoddy algorithm (although it's not
so horrible when dithered). Because of this, the GIF output mode is not
recommended in the current release, except for gray-scale output. You can get
better results by applying ppmquant to the unquantized (PPM) output of djpeg,
then converting to GIF with ppmtogif. We expect to provide a considerably
better quantization algorithm in a future release.
Note that djpeg *can* read noninterleaved JPEG files even though cjpeg can't
yet generate them. For most applications this is a nonissue, since hardly
anybody seems to be using noninterleaved format.
On a non-virtual-memory machine, you may run out of memory if you use -I or -o
in cjpeg, or -q ... -2 in djpeg, or try to read an interlaced GIF file. This
will be addressed eventually by replacing jvirtmem.c with something that uses
temporary files for large images (see TO DO).
REFERENCES REFERENCES
@@ -276,13 +234,31 @@ algorithm is Wallace's article in the April '91 CACM:
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.) We highly recommend reading that applications of JPEG, and related topics.) We highly recommend reading that
article before looking at any of the JPEG software. article before trying to understand the innards of any JPEG software.
If you don't have the CACM issue handy, a PostScript file containing a revised
version of the article is available at ftp.uu.net, graphics/jpeg/wallace.ps.Z.
The file (actually a preprint for an article to appear in IEEE Trans. Consumer
Electronics) omits the sample images that appeared in CACM, but it includes
corrections and some added material. Note: the Wallace article is copyright
ACM and IEEE, and it may not be used for commercial purposes.
For more detail about the JPEG standard you pretty much have to go to the For more detail about the JPEG standard you pretty much have to go to the
draft standard, which is not nearly as intelligible as Wallace's article. draft standard (which is not nearly as intelligible as Wallace's article).
The current version is ISO/IEC Committee Draft CD 10918-1 dated 1991-03-15. The standard is not now available electronically; you must order a paper copy
The standard is not presently available electronically; you must order a paper through ISO. In the US, copies may be ordered from ANSI Sales at (212)
copy through ISO. 642-4900. The standard is divided into two parts: Part 1 is the actual
specification, and Part 2 covers compliance testing methods. The current
"committee draft" version of Part 1 is titled "Digital Compression and Coding
of Continuous-tone Still Images, Part 1: Requirements and guidelines" and has
document number ISO/IEC CD 10918-1. (The alternate number SC2 N2215 should
also be mentioned when ordering.) This draft is expected to be superseded by
the Draft International Standard version around the end of November 1991.
Ordering info will be the same as above, but replace "CD" with "DIS" in the
document number (alternate number not yet known). The committee draft of
Part 2 is expected to be available around the end of December 1991. It will
be titled "Digital Compression and Coding of Continuous-tone Still Images,
Part 2: Compliance testing" and will have document number ISO/IEC CD 10918-2
(alternate number not yet known).
The JPEG standard does not specify all details of an interchangeable file The JPEG standard does not specify all details of an interchangeable file
format. For the omitted details we follow the "JFIF" conventions, revision format. For the omitted details we follow the "JFIF" conventions, revision
@@ -292,28 +268,18 @@ format. For the omitted details we follow the "JFIF" conventions, revision
399A West Trimble Road 399A West Trimble Road
San Jose, CA 95131 San Jose, CA 95131
(408) 944-6300 (408) 944-6300
Requests can also be e-mailed to info@c3.pla.ca.us (this address good after The same source can supply copies of the draft JPEG-in-TIFF documents
10/10/91). The same source can supply copies of the draft JPEG-in-TIFF specs. (Appendixes O and P to the TIFF spec). PostScript versions of these
documents can also be obtained by e-mail from the C-Cube mail server,
netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" to obtain the
JFIF document; "send app_o_ps from jpeg" and "send app_p_ps from jpeg" will
produce the TIFF documents. Send the message "help" if you have trouble.
If you want to understand this implementation, start by reading the If you want to understand this implementation, start by reading the
"architecture" documentation file. Please read "codingrules" if you want to "architecture" documentation file. Please read "codingrules" if you want to
contribute any code. contribute any code.
SUPPORTING SOFTWARE
===================
You will probably want Jef Poskanzer's PBMPLUS image software; this provides
many useful operations on PPM-format image files. In particular, it can
convert PPM images to and from a wide range of other formats. You can FTP
this free software from export.lcs.mit.edu (contrib/pbmplus*.tar.Z) or
ftp.ee.lbl.gov (pbmplus*.tar.Z).
If you are using X Windows you might want to use the xv or xloadimage viewers
to save yourself the trouble of converting PPM to some other format.
Both of these can be found in the contrib directory at export.lcs.mit.edu.
LEGAL ISSUES LEGAL ISSUES
============ ============
@@ -322,7 +288,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, Thomas G. Lane. This software is copyright (C) 1991, 1992, 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
@@ -360,26 +326,29 @@ the foregoing paragraphs do.
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 held by IBM, and possibly also patents of AT&T and Mitsubishi. Hence patents owned by IBM and AT&T, as well as a pending Japanese patent of
arithmetic coding cannot legally be used without obtaining one or more Mitsubishi. Hence arithmetic coding cannot legally be used without obtaining
licenses. For this reason, support for arithmetic coding has been removed one or more licenses. For this reason, support for arithmetic coding has been
from the free JPEG software. (Since arithmetic coding provides only a removed from the free JPEG software. (Since arithmetic coding provides only a
marginal gain over the unpatented Huffman mode, it is unlikely that very many marginal gain over the unpatented Huffman mode, it is unlikely that very many
people will choose to use it. If you do obtain such a license, contact people will choose to use it. If you do obtain the necessary licenses,
jpeg-info@uunet.uu.net for a copy of our arithmetic coding modules.) So far contact jpeg-info@uunet.uu.net for a copy of our arithmetic coding modules.)
as we are aware, there are no patent restrictions on the remaining code. So far as we are aware, there are no patent restrictions on the remaining
code.
We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of
CompuServe Incorporated."
TO DO TO DO
===== =====
Many of the modules need fleshing out to provide more complete Many of the modules need fleshing out to provide more complete
implementations, or to provide faster paths for common cases. The greatest implementations, or to provide faster paths for common cases.
needs are for (a) decent color quantization, and (b) a memory manager Improving the speed will be the next big work item for the JPEG group.
implementation that can work in limited memory by swapping "big" images to
temporary files. I (Tom Lane) am going to work on color quantization next.
Volunteers to write a PC memory manager, or to work on any other modules, are
welcome.
We'd appreciate it if people would compile and check out the code on as wide a We'd appreciate it if people would compile and check out the code on as wide a
variety of systems as possible, and report any portability problems variety of systems as possible, and report any portability problems

368
SETUP Normal file
View File

@@ -0,0 +1,368 @@
SETUP instructions for the Independent JPEG Group's JPEG software
=================================================================
This file explains how to configure and compile the JPEG software. We have
tried to make this software extremely portable and flexible, so that it can be
adapted to almost any environment. The downside of this decision is that the
installation process is not very automatic; you will need at least a little
familiarity with C programming and program build procedures for your system.
This file contains general instructions, then sections of specific hints for
certain systems. You may save yourself considerable time if you scan the
whole file before starting to do anything.
Before installing the software you must unpack the distributed source code.
Since you are reading this file, you have probably already succeeded in this
task. However, there is one potential trap if you are on a non-Unix system:
you may need to convert these files to the local standard text file format
(for example, if you are on MS-DOS you probably have to convert LF end-of-line
to CR/LF). If so, apply the conversion to all the files EXCEPT those whose
names begin with "test". The test files contain binary data; if you change
them in any way then the self-test will give bad results.
STEP 1: PREPARE A MAKEFILE
==========================
First, select a makefile and copy it to "Makefile" (or whatever your version
of make uses as the default makefile name; for example, "makefile.mak" for
old versions of Borland C). We include several standard makefiles in the
distribution:
makefile.ansi: for Unix systems with ANSI-compatible C compilers.
makefile.unix: for Unix systems with non-ANSI C compilers.
makefile.mc5: for Microsoft C 5.x under MS-DOS.
makefile.mc6: for Microsoft C 6.x under MS-DOS.
makefile.bcc: for Borland C (Turbo C) under MS-DOS.
makefile.pwc: for Mix Software's Power C under MS-DOS.
makefile.manx: for Manx Aztec C on Amigas.
makefile.sas: for SAS C on Amigas.
makefile.mms: for VAX/VMS systems with MMS.
makefile.vms: for VAX/VMS systems without MMS.
If you don't see a makefile for your system, we recommend starting from either
makefile.ansi or makefile.unix, depending on whether your compiler accepts
ANSI C or not. Actually you should start with makefile.ansi whenever your
compiler supports ANSI-style function definitions; you don't need full ANSI
compatibility. The difference between the two makefiles is that makefile.unix
preprocesses the source code to convert function definitions to old-style C.
(Our thanks to Peter Deutsch of Aladdin Enterprises for the ansi2knr program.)
If you don't know whether your compiler supports ANSI-style function
definitions, then take a look at ckconfig.c. It is a test program that will
help you figure out this fact, as well as some other facts you'll need in
later steps. You must compile and execute ckconfig.c by hand; the makefiles
don't provide any support for this. ckconfig.c may not compile the first try
(in fact, the whole idea is for it to fail if anything is going to). If you
get compile errors, fix them by editing ckconfig.c according to the directions
given in ckconfig.c. Once you get it to run, select a makefile according to
the advice it prints out, and make any other changes it recommends.
Look over the selected Makefile and adjust options as needed. In particular
you may want to change the CC and CFLAGS definitions. For instance, if you
are using GCC, set CC=gcc. If you had to use any compiler switches to get
ckconfig.c to work, make sure the same switches are in CFLAGS.
If you are on a system that doesn't use makefiles, you'll need to set up
project files (or whatever you do use) to compile all the source files and
link them into executable files cjpeg and djpeg. See the file lists in any of
the makefiles to find out which files go into each program. As a last resort,
you can make a batch script that just compiles everything and links it all
together; makefile.vms is an example of this (it's for VMS systems that have
no make-like utility).
STEP 2: EDIT JCONFIG.H
======================
Look over jconfig.h and adjust #defines to reflect the properties of your
system and C compiler. (If you prefer, you can usually leave jconfig.h
unmodified and add -Dsymbol switches to the Makefile's CFLAGS definition.)
If you have an ANSI-compliant C compiler, no changes should be necessary
except perhaps for RIGHT_SHIFT_IS_UNSIGNED and TWO_FILE_COMMANDLINE. For
older compilers other changes may be needed, depending on what ANSI features
are supported.
If you don't know enough about C programming to understand the questions in
jconfig.h, then use ckconfig.c to figure out what to change. (See description
of ckconfig.c in step 1.)
A note about TWO_FILE_COMMANDLINE: defining this selects the command line
syntax in which the input and output files are both named on the command line.
If it's not defined, the output image goes to standard output, and the input
can optionally come from standard input. You MUST use two-file style on any
system that doesn't cope well with binary data fed through stdin/stdout; this
is true for most MS-DOS compilers, for example. If you're not on a Unix
system, it's probably safest to assume you need two-file style.
STEP 3: SELECT SYSTEM-DEPENDENT FILES
=====================================
The only system-dependent file in the current version is jmemsys.c. This file
controls use of temporary files for big images that won't fit in main memory.
You'll notice there is no file by that name in the distribution; you must
select one of the provided versions and copy, rename, or link it to jmemsys.c.
Here are the provided versions:
jmemansi.c This is a reasonably portable version that should
work on most ANSI and near-ANSI C compilers. It uses
the ANSI-standard library routine tmpfile(), which not
all pre-ANSI systems have. On some systems tmpfile()
may put the temporary file in a non-optimal location;
if you don't like what it does, use jmemname.c.
jmemname.c This version constructs the temp file name by itself.
For anything except a Unix machine, you'll need to
configure the select_file_name() routine appropriately;
see the comments near the head of jmemname.c.
If you use this version, define NEED_SIGNAL_CATCHER
in jconfig.h or in the Makefile to make sure the temp
files are removed if the program is aborted.
jmemnobs.c (That stands for No Backing Store :-). This will
compile on almost any system, but it assumes you
have enough main memory or virtual memory to hold
the biggest images you need to work with.
jmemdos.c This should be used in most MS-DOS installations; see
the system-specific notes about MS-DOS for more info.
IMPORTANT: if you use this, also copy jmemdos.h to
jmemsys.h, replacing the standard version. ALSO,
include the assembly file jmemdosa.asm in the programs.
(This last is already done if you used one of the
supplied MS-DOS-specific makefiles.)
If you have plenty of (real or virtual) main memory, just use jmemnobs.c.
"Plenty" means at least ten bytes for every pixel in the largest images
you plan to process, so a lot of systems don't meet this criterion.
If yours doesn't, try jmemansi.c first. If that doesn't compile, you'll have
to use jmemname.c; be sure to adjust select_file_name() for local conditions.
You may also need to change unlink() to remove() in close_backing_store().
Except with jmemnobs.c, you need to adjust the #define DEFAULT_MAX_MEM to a
reasonable value for your system (either by editing jmemsys.c, or by adding
a -D switch to the Makefile). This value limits the amount of data space the
program will attempt to allocate. Code and static data space isn't counted,
so the actual memory needs for cjpeg or djpeg are typically 100 to 150Kb more
than the max-memory setting. Larger max-memory settings reduce the amount of
I/O needed to process a large image, but too large a value can result in
"insufficient memory" failures. On most Unix machines (and other systems with
virtual memory), just set DEFAULT_MAX_MEM to several million and forget it.
At the other end of the spectrum, for MS-DOS machines you probably can't go
much above 300K to 400K.
STEP 4: MAKE
============
Now you should be able to "make" the software.
If you have trouble with missing system include files or inclusion of the
wrong ones, look at jinclude.h (or use ckconfig.c, if you are not a C expert).
If your compiler complains about big_sarray_control and big_barray_control
being undefined structures, you should be able to shut it up by adding
-DINCOMPLETE_TYPES_BROKEN to CFLAGS (or add #define INCOMPLETE_TYPES_BROKEN
to jconfig.h).
There are a fair number of routines that do not use all of their parameters;
some compilers will issue warnings about this, which you can ignore. Any
other warning deserves investigation.
STEP 5: TEST
============
As a quick test of functionality we've included a small sample image in
several forms:
testorig.jpg A reduced section of the well-known Lenna picture.
testimg.ppm The output of djpeg testorig.jpg
testimg.gif The output of djpeg -G testorig.jpg
testimg.jpg The output of cjpeg testimg.ppm
(The two .jpg files aren't identical since JPEG is lossy.) If you can
generate duplicates of the testimg.* files then you probably have working
programs.
With most of the makefiles, "make test" will perform the necessary
comparisons. If you're using a makefile that doesn't provide this option, run
djpeg and cjpeg to generate testout.ppm, testout.gif, and testout.jpg, then
compare these to testimg.* with whatever binary file comparison tool you have.
The files should be bit-for-bit identical.
If your choice of jmemsys.c was anything other than jmemnobs.c, you should
also test that temporary-file usage works. Try "djpeg -G -m 0 testorig.jpg"
and make sure its output matches testimg.gif. If you have any really large
images handy, try compressing them with -o and/or decompressing with -G
to make sure your DEFAULT_MAX_MEM setting is not too large.
NOTE: this is far from an exhaustive test of the JPEG software; some modules,
such as fast color quantization, are not exercised at all. It's just a quick
test to give you some confidence that you haven't missed something major.
If the test passes, you can copy the executable files cjpeg and djpeg to
wherever you normally install programs. Read the file USAGE to learn more
about using the programs.
OPTIONAL STUFF
==============
We distribute the software with support for RLE image files (Utah Raster
Toolkit format) disabled, because the RLE support won't compile without the
Utah library. If you have URT version 3.0, you can enable RLE support as
follows:
1. #define RLE_SUPPORTED in jconfig.h or in the Makefile.
2. Add a -I option to CFLAGS in the Makefile for the directory
containing the URT .h files (typically the "include"
subdirectory of the URT distribution).
3. Add -L... -lrle to LDLIBS in the Makefile, where ... specifies
the directory containing the URT "librle.a" file (typically the
"lib" subdirectory of the URT distribution).
If you want to incorporate the JPEG code as subroutines in a larger program,
we recommend that you make libjpeg.a. (See file README for more info.)
CAUTION: When you use the JPEG code as subroutines, we recommend that you make
any required configuration changes by modifying jconfig.h, not by adding -D
switches to the Makefile. Otherwise you must be sure to provide the same -D
switches when compiling any program that includes the JPEG .h files.
If you need to make a smaller version of the JPEG software, some optional
functions can be removed at compile time. See the xxx_SUPPORTED #defines in
jconfig.h. If at all possible, we recommend that you leave in decoder support
for all valid JPEG files, to ensure that you can read anyone's output.
Restricting your encoder, or removing optional functions like block smoothing,
won't hurt compatibility. Taking out support for image file formats that you
don't use is the most painless way to make the programs smaller.
NOTES FOR SPECIFIC SYSTEMS
==========================
We welcome reports on changes needed for systems not mentioned here.
Submit 'em to jpeg-info@uunet.uu.net. Also, ckconfig.c is fairly new and not
yet thoroughly tested; if it's wrong about how to configure the JPEG software
for your system, please let us know.
Amiga:
Makefiles are provided for Manx Aztec C and SAS C. I have also heard from
people who have compiled with the free DICE compiler, using makefile.ansi as a
starting point (set "CC= dcc" and "CFLAGS= -c -DAMIGA -DTWO_FILE_COMMANDLINE
-DNEED_SIGNAL_CATCHER" in the makefile). For all compilers, we recommend you
use jmemname.c as the system-dependent memory manager. Assuming you have
-DAMIGA in the makefile, jmemname.c will put temporary files in JPEGTMP:.
Change jmemname.c if you don't like this.
Cray:
Should you be so fortunate as to be running JPEG on a Cray YMP, there is a
compiler bug in Cray's Standard C versions prior to 3.1. You'll need to
insert a line reading "#pragma novector" just before the loop
for (i = 1; i <= (int) htbl->bits[l]; i++)
huffsize[p++] = (char) l;
in fix_huff_tbl (in V2, line 42 of jchuff.c and line 38 of jdhuff.c). The
usual symptom of not adding this line is a core-dump. See Cray's SPR 48222.
HP/Apollo DOMAIN:
At least in version 10.3.5, the C compiler is ANSI but the system include
files are not. Use makefile.ansi and add -DNONANSI_INCLUDES to CFLAGS.
HP-UX:
If you have HP-UX 7.05 or later with the "software development" C compiler,
then you can use makefile.ansi. Add "-Aa" to the CFLAGS line in the makefile
to make the compiler work in ANSI mode. If you have a pre-7.05 system, or if
you are using the non-ANSI C compiler delivered with a minimum HP-UX 8.0
system, then you must use makefile.unix (and do NOT add -Aa). Also, adding
"-lmalloc" to LDLIBS is recommended if you have libmalloc.a (it seems not to
be present in minimum 8.0).
On HP 9000 series 800 machines, the HP C compiler is buggy in revisions prior
to A.08.07. If you get complaints about "not a typedef name", you'll have to
convert the code to K&R style (i.e., use makefile.unix).
Macintosh Think C:
You'll have to prepare project files for cjpeg and djpeg; we don't include
those in the distribution since they are not text files. The COBJECTS and
DOBJECTS lists in makefile.unix show which files should be included in each
project. Also add the ANSI and Unix C libraries in a separate segment. You
may need to divide the JPEG files into more than one segment; you can do this
pretty much as you please.
If you have Think C version 5.0 you need not modify jconfig.h; instead you
should turn on both the ANSI Settings and Language Extensions option buttons
(so that both __STDC__ and THINK_C are predefined). With version 4.0 you must
edit jconfig.h. (You can #define HAVE_STDC to do the right thing for all
options except const; you must also #define const.)
jcmain and jdmain are set up to provide the usual command-line interface
by means of Think's ccommand() library routine. Anybody want to write a
more Mac-like interface for us?
MS-DOS, generic comments:
The JPEG code is designed to be compiled with 80x86 "small" or "medium" memory
models (i.e., data pointers are 16 bits unless explicitly declared "far"; code
pointers can be either size). You should be able to use small model to
compile cjpeg or djpeg by itself, but you will probably have to go to medium
model if you include the JPEG code in a larger application. This shouldn't
hurt performance much. You *will* take a noticeable performance hit if you
compile in a large-data memory model, and you should avoid "huge" model if at
all possible. Be sure that NEED_FAR_POINTERS is defined by jconfig.h or by
the Makefile if you use a small-data model; be sure it is NOT defined if you
use a large-data memory model. (As distributed, jconfig.h defines
NEED_FAR_POINTERS if MSDOS is defined.)
The DOS-specific memory manager, jmemdos.c, should be used if possible.
(Be sure to install jmemdos.h and jmemdosa.asm along with it.) If you
can't use jmemdos.c for some reason --- for example, because you don't have
a Microsoft-compatible assembler to assemble jmemdosa.asm --- you'll have
to fall back to jmemansi.c or jmemname.c. IMPORTANT: if you use either of
those files, you will have to compile in a large-data memory model in order
to get the right stdio library. Too bad.
None of the above advice applies if you are using a 386 flat-memory-space
environment, such as DJGPP or Watcom C. For these compilers, do NOT define
NEED_FAR_POINTERS, and do NOT use jmemdos.c. Use jmemnobs.c if the
environment supplies adequate virtual memory, otherwise use jmemansi.c or
jmemname.c.
MS-DOS, DJGPP:
The file egetopt.c conflicts with some library routines in DJGPP 1.05.
Remove #include "egetopt.c" from jcmain.c and jdmain.c, and in each of
those files change the egetopt(...) call to getopt(...). This will be
fixed more cleanly in some future version. Use makefile.ansi, and put
"-DTWO_FILE_COMMANDLINE" (but *not* -DMSDOS) in CFLAGS.
MS-DOS, Microsoft C:
Some versions of MS C fail with an "out of macro expansion space" error
because they can't cope with the macro TRACEMS8 (defined in jpegdata.h).
If this happens to you, the easiest solution is to change TRACEMS8 to
expand to nothing. You'll lose the ability to dump out JPEG coefficient
tables with djpeg -d -d, but at least you can compile.
makefile.mc6 (MS C 6.x makefile) has not been tested since jmemdosa.asm
was added; we'd appreciate hearing whether it works or not.
Sun:
Don't forget to add -DBSD to CFLAGS. If you are using GCC on SunOS 4.0.1 or
earlier, you will need to add -DNONANSI_INCLUDES to CFLAGS (your compiler may
be ANSI, but your system include files aren't). I've gotten conflicting
reports on whether this is still necessary on SunOS 4.1 or later.

212
USAGE Normal file
View File

@@ -0,0 +1,212 @@
USAGE instructions for the Independent JPEG Group's JPEG software
=================================================================
INTRODUCTION
This distribution contains software to implement JPEG image compression and
decompression. JPEG (pronounced "jay-peg") is a standardized compression
method for full-color and gray-scale images. JPEG is designed to handle
"real-world" scenes, for example scanned photographs. Cartoons, line
drawings, and other non-realistic images are not JPEG's strong suit; on this
sort of material you may get poor image quality and/or little compression.
JPEG is lossy, meaning that the output image is not necessarily identical to
the input image. Hence you should not use JPEG if you have to have identical
output bits. However, on typical real-world images, very good compression
levels can be obtained with no visible change, and amazingly high compression
is possible if you can tolerate a low-quality image. You can trade off image
quality against file size by adjusting the compressor's "quality" setting.
This file describes usage of the standard programs "cjpeg" and "djpeg" that
can be built directly from the distributed C code. See the README file for
hints on incorporating the JPEG software into other programs.
If you are on a Unix machine you may prefer to read the Unix-style manual
pages in files cjpeg.1 and djpeg.1.
NOTE: at some point we will probably redesign the user interface, so the
command line switches described here will change.
GENERAL USAGE
We provide two programs, cjpeg to compress an image file into JPEG format,
and djpeg to decompress a JPEG file back into a conventional image format.
On Unix-like systems, you say:
cjpeg [switches] [imagefile] >jpegfile
or
djpeg [switches] [jpegfile] >imagefile
The programs read the specified input file, or standard input if none is
named. They always write to standard output (with trace/error messages to
standard error). These conventions are handy for piping images between
programs.
On most non-Unix systems, you say:
cjpeg [switches] imagefile jpegfile
or
djpeg [switches] jpegfile imagefile
i.e., both the input and output files are named on the command line. This
style is a little more foolproof, and it loses no functionality if you don't
have pipes. (You can get this style on Unix too, if you prefer, by defining
TWO_FILE_COMMANDLINE when you compile the programs; see SETUP.)
The currently supported image file formats are: PPM (PBMPLUS color format),
PGM (PBMPLUS gray-scale format), GIF, Targa, and RLE (Utah Raster Toolkit
format). (RLE is supported only if the URT library is available.)
cjpeg recognizes the input image format automatically, with the exception
of some Targa-format files. You have to tell djpeg which format to generate.
The only JPEG file format currently supported is the JFIF format. Support for
the TIFF/JPEG format will probably be added at some future date.
CJPEG DETAILS
The command line switches for cjpeg are:
-Q quality Scale quantization tables to adjust image quality.
Quality is 0 (worst) to 100 (best); default is 75.
(See below for more info.)
-o Perform optimization of entropy encoding parameters.
Without this, default encoding parameters are used.
-o usually makes the JPEG file a little smaller, but
cjpeg runs somewhat slower and needs much more memory.
Image quality and speed of decompression are unaffected
by -o.
-T Input file is Targa format. Targa files that contain
an "identification" field will not be automatically
recognized by cjpeg; for such files you must specify
-T to force cjpeg to treat the input as Targa format.
-I Generate noninterleaved JPEG file (not yet supported).
-a Use arithmetic coding rather than Huffman coding.
(Not currently supported for legal reasons.)
-d Enable debug printout. More -d's give more printout.
Also, version information is printed at startup.
-m memory Set limit for amount of memory to use in processing
large images. Value is in thousands of bytes, or
millions of bytes if "M" is attached to the number.
For example, -m 4m selects 4000000 bytes. If more
space is needed, temporary files will be used.
The -Q switch lets you trade off compressed file size against quality of the
reconstructed image: the higher the -Q setting, the larger the JPEG file, and
the closer the output image will be to the original input. Normally you want
to use the lowest -Q setting (smallest file) that decompresses into something
visually indistinguishable from the original image. For this purpose the -Q
setting should be between 50 and 95; the default of 75 is often about right.
If you see defects at -Q 75, then go up 5 or 10 counts at a time until you are
happy with the output image. (The optimal setting will vary from one image to
another.)
-Q 100 will generate a quantization table of all 1's, eliminating loss in the
quantization step (but there is still information loss in subsampling, as well
as roundoff error). This setting is mainly of interest for experimental
purposes. -Q values above about 95 are NOT recommended for normal use; the
compressed file size goes up dramatically for hardly any gain in output image
quality.
In the other direction, -Q values below 50 will produce very small files of
low image quality. Settings around 5 to 10 might be useful in preparing an
index of a large image library, for example. Try -Q 2 (or so) for some
amusing Cubist effects. (Note: -Q values below about 25 generate 2-byte
quantization tables, which are considered optional in the JPEG standard.
cjpeg emits a warning message when you give such a -Q value, because some
commercial JPEG programs may be unable to decode the resulting file.)
DJPEG DETAILS
The command line switches for djpeg are:
-G Select GIF output format (implies -q, with default
of 256 colors).
-P Select PPM or PGM output format (this is the default).
PGM is emitted if the JPEG file is gray-scale or if -g
is specified.
-R Select RLE output format. Requires URT library.
-T Select Targa output format. Gray-scale format is
emitted if the JPEG file is gray-scale or if -g is
specified; otherwise, colormapped format is emitted
if -q is specified; otherwise, 24-bit full-color
format is emitted.
-g Force gray-scale output even if input is color.
-q N Quantize to N colors. This reduces the number of
colors in the output image so that it can be displayed
on a colormapped display or stored in a colormapped
file format. For example, if you have an 8-bit
display, you'd need to quantize to 256 or fewer colors.
-D Do not use dithering in color quantization.
By default, Floyd-Steinberg dithering is applied when
quantizing colors, but on some images dithering may
result in objectionable "graininess". If that
happens, you can turn off dithering with -D.
-D is ignored unless you also say -q or -G.
-1 Use one-pass instead of two-pass color quantization.
The one-pass method is faster and needs less memory,
but it produces a lower-quality image.
-1 is ignored unless you also say -q or -G. Also,
the one-pass method is always used for gray-scale
output (the two-pass method is no improvement then).
-b Perform cross-block smoothing. This is quite
memory-intensive and only seems to improve the image
at very low quality settings (-Q 10 to 20 or so).
At normal -Q settings it may make the image worse.
-d Enable debug printout. More -d's give more printout.
Also, version information is printed at startup.
-m memory Set limit for amount of memory to use in processing
large images. Value is in thousands of bytes, or
millions of bytes if "M" is attached to the number.
For example, -m 4m selects 4000000 bytes. If more
space is needed, temporary files will be used.
HINTS
Avoid running an image through a series of JPEG compression/decompression
cycles. Image quality loss will accumulate; after ten or so cycles the image
may be noticeably worse than it was after one cycle. It's best to use a
lossless format while manipulating an image, then convert to JPEG format when
you are ready to file the image away.
The -o option to cjpeg is worth using when you are making a "final" version
for posting or archiving. It's also a win when you are using low -Q settings
to make very small JPEG files; the percentage improvement is often a lot more
than it is on larger files.
The default memory usage limit (-m) is set when the software is compiled.
If you get an "insufficient memory" error, try specifying a smaller -m value,
even -m 0 to use the absolute minimum space. You may want to recompile with
a smaller default value if this happens often.
djpeg with two-pass color quantization requires a good deal of space; on
MS-DOS machines it may run out of memory even with -m 0. In that case you
can still decompress, with some loss of image quality, by specifying -1
for one-pass quantization.
If more space is needed than will fit in the available main memory (as
determined by -m), temporary files will be used. (MS-DOS versions will try to
get extended or expanded memory first.) The temporary files are often rather
large: in typical cases they occupy three bytes per pixel, for example
3*800*600 = 1.44Mb for an 800x600 image. If you don't have enough free disk
space, leave out -o (for cjpeg) or specify -1 (for djpeg). On MS-DOS, the
temporary files are created in the directory named by the TMP or TEMP
environment variable, or in the current directory if neither of those exist.
Amiga implementations put the temp files in the directory named by JPEGTMP:,
so be sure to assign JPEGTMP: to a disk partition with adequate free space.

View File

@@ -1,6 +1,7 @@
/* /*
* Received from Peter Deutsch (ghost@aladdin.com) * Received from Peter Deutsch (ghost@aladdin.com)
* Fri, 26 Apr 91 10:10:10 PDT * Fri, 26 Apr 91 10:10:10 PDT
* Small portability improvements by Tom Lane
*/ */
/* Copyright (C) 1989, 1991 Aladdin Enterprises. All rights reserved. /* Copyright (C) 1989, 1991 Aladdin Enterprises. All rights reserved.
@@ -174,34 +175,32 @@ BY ANY OTHER PARTY.
/* ansi2knr.c */ /* ansi2knr.c */
/* Convert ANSI function declarations to K&R syntax */ /* Convert ANSI function declarations to K&R syntax */
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#ifdef BSD #ifdef BSD
# include <strings.h> #include <strings.h>
# define strchr index #define strchr index
#else #else
# ifdef VMS #ifdef VMS
extern char *strcat(), *strchr(), *strcpy(), *strupr(); extern char *strcat(), *strchr(), *strcpy(), *strupr();
extern int strcmp(), strlen(), strncmp(); extern int strcmp(), strlen(), strncmp();
# else #else
# include <string.h> #include <string.h>
# endif #endif
#endif #endif
#ifdef MSDOS #ifdef MSDOS
# include <malloc.h> #include <malloc.h>
#else #else
# ifdef VMS #ifdef VMS
extern char *malloc(); extern char *malloc();
extern void free(); extern void free();
# else #else
# ifdef BSD extern char *malloc();
extern char *malloc(); extern int free();
# else #endif
# include <malloc.h>
# endif
# endif
#endif #endif
/* Usage: /* Usage:
@@ -226,12 +225,13 @@ BY ANY OTHER PARTY.
#define isidchar(ch) (isalnum(ch) || (ch) == '_') #define isidchar(ch) (isalnum(ch) || (ch) == '_')
#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_') #define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
int
main(argc, argv) main(argc, argv)
int argc; int argc;
char *argv[]; char *argv[];
{ FILE *in, *out; { FILE *in, *out;
#define bufsize 500 /* arbitrary size */ #define bufsize 500 /* arbitrary size */
char buf[bufsize]; char buf[bufsize+1];
char *line; char *line;
switch ( argc ) switch ( argc )
{ {
@@ -296,12 +296,13 @@ skipspace(p, dir)
/* /*
* Write blanks over part of a string. * Write blanks over part of a string.
*/ */
void int
writeblanks(start, end) writeblanks(start, end)
char *start; char *start;
char *end; char *end;
{ char *p; { char *p;
for ( p = start; p < end; p++ ) *p = ' '; for ( p = start; p < end; p++ ) *p = ' ';
return 0;
} }
/* /*
@@ -313,6 +314,7 @@ writeblanks(start, end)
* -1 - may be the beginning of a function definition, * -1 - may be the beginning of a function definition,
* append another line and look again. * append another line and look again.
*/ */
int
test1(buf) test1(buf)
char *buf; char *buf;
{ register char *p = buf; { register char *p = buf;
@@ -359,6 +361,7 @@ test1(buf)
return contin; return contin;
} }
int
convert1(buf, out) convert1(buf, out)
char *buf; char *buf;
FILE *out; FILE *out;

View File

@@ -1,5 +1,5 @@
JPEG SYSTEM ARCHITECTURE 3-OCT-91 JPEG SYSTEM ARCHITECTURE 29-FEB-92
This file provides an overview of the "architecture" of the portable JPEG This file provides an overview of the "architecture" of the portable JPEG
@@ -13,7 +13,7 @@ to the mark. Also, it is frequently the case that several different modules
present a common interface to callers; the term "object" or "method" refers to present a common interface to callers; the term "object" or "method" refers to
this common interface (see "Poor man's object-oriented programming", below). this common interface (see "Poor man's object-oriented programming", below).
JPEG-specific terminology follows the JPEG R9 draft: JPEG-specific terminology follows the JPEG standard:
A "component" means a color channel, e.g., Red or Luminance. A "component" means a color channel, e.g., Red or Luminance.
A "sample" is a pixel component value (i.e., one number in the image data). A "sample" is a pixel component value (i.e., one number in the image data).
A "coefficient" is a frequency coefficient (a DCT transform output number). A "coefficient" is a frequency coefficient (a DCT transform output number).
@@ -52,8 +52,7 @@ real-time, which nobody is going to do with a pure software implementation.
There is some value in supporting the hierarchical mode, which allows for There is some value in supporting the hierarchical mode, which allows for
successive frames of higher resolution. This could be of use for including successive frames of higher resolution. This could be of use for including
"thumbnail" representations. Also, Storm's JPEG++ files probably use the "thumbnail" representations. However, this appears to add a lot more
hierarchical mode (I haven't looked). However, this appears to add a lot more
complexity than it is worth. complexity than it is worth.
A variety of uncompressed image file formats and user interfaces must be A variety of uncompressed image file formats and user interfaces must be
@@ -79,10 +78,10 @@ baggage.)
The *logical* steps needed in (non-lossless) JPEG compression are: The *logical* steps needed in (non-lossless) JPEG compression are:
1. Conversion from incoming image format to a standardized internal form 1. Conversion from incoming image format to a standardized internal form
(either RGB or greyscale). (either RGB or grayscale).
2. Color space conversion (e.g., RGB to YCbCr). This is a null step for 2. Color space conversion (e.g., RGB to YCbCr). This is a null step for
greyscale (unless we support mapping color inputs to greyscale, which grayscale (unless we support mapping color inputs to grayscale, which
would most easily be done here). Gamma adjustment may also be needed here. would most easily be done here). Gamma adjustment may also be needed here.
3. Subsampling (reduction of number of samples in some color components). 3. Subsampling (reduction of number of samples in some color components).
@@ -171,7 +170,7 @@ The *logical* steps needed in (non-lossless) JPEG decompression are:
4. MCU disassembly (conversion of a possibly interleaved sequence of 8x8 4. MCU disassembly (conversion of a possibly interleaved sequence of 8x8
blocks back to separate components in pixel map order). blocks back to separate components in pixel map order).
5. (Optional) Cross-block smoothing per JPEG section 13.10 or a similar 5. (Optional) Cross-block smoothing per JPEG section K.8 or a similar
algorithm. (Steps 5-8 operate independently on each component.) algorithm. (Steps 5-8 operate independently on each component.)
6. Inverse DCT transformation of each 8x8 block. 6. Inverse DCT transformation of each 8x8 block.
@@ -189,19 +188,23 @@ The *logical* steps needed in (non-lossless) JPEG decompression are:
sizes. sizes.
10. Color space reconversion (e.g., YCbCr to RGB). This is a null step for 10. Color space reconversion (e.g., YCbCr to RGB). This is a null step for
greyscale. (Note that if we support mapping color JPEG to greyscale, grayscale. (Note that mapping a color JPEG to grayscale output is most
it could be done as part of this step.) Gamma adjustment may also be easily done in this step.) Gamma adjustment may also be needed here.
needed here.
11. Color quantization (only if a colormapped output format is requested). 11. Color quantization (only if a colormapped output format is requested).
NOTE: it might be better to do this on the internal color space instead of NOTE: it is probably preferable to perform quantization in the internal
RGB? If so, it would need to be performed one step earlier. (JPEG) colorspace rather than the output colorspace. Doing it that way,
color conversion need only be applied to the colormap entries, not to
every pixel; and quantization gets to operate in a non-gamma-corrected
space. But the internal space may not be suitable for some algorithms.
The system design is such that only the color quantizer module knows
whether color conversion happens before or after quantization.
12. Writing of the desired image format. 12. Writing of the desired image format.
As before, some of these will be combined into single steps. When dealing As before, some of these will be combined into single steps. When dealing
with a noninterleaved JPEG file, steps 2-9 will be performed once for each with a noninterleaved JPEG file, steps 2-9 will be performed once for each
scan; the resulting data will need to be buffered up so that step 10 can scan; the resulting data will need to be buffered up so that steps 10-12 can
process all the color components together. process all the color components together.
The same auxiliary modules are needed as before, except for compression The same auxiliary modules are needed as before, except for compression
@@ -429,12 +432,8 @@ different instances (choose to execute different modules).
To minimize the number of object pointers that have to be passed around, it To minimize the number of object pointers that have to be passed around, it
will be easiest to have just a few big structs containing all the method will be easiest to have just a few big structs containing all the method
pointers. We'll actually use two such structs, one for "globally" defined pointers. We'll actually use two such structs, one for "system-dependent"
methods (applicable to the whole file or to all components of the current methods (memory allocation and error handling) and one for everything else.
scan) and one for methods applicable to a single component. There'll be one
copy of the second kind of struct for each component of the current scan.
This is necessary so that preselection of an optimal method can be done based
on component-specific information (like sampling ratios...)
Because of this choice, it's best not to think of an "object" as a specific Because of this choice, it's best not to think of an "object" as a specific
data structure. Rather, an "object" is just a group of related methods. data structure. Rather, an "object" is just a group of related methods.
@@ -528,7 +527,10 @@ aren't described here; see the header files. Notice that any object that
might need to allocate working storage receives an "init" and a "term" call; might need to allocate working storage receives an "init" and a "term" call;
"term" should be careful to free all allocated storage so that the JPEG system "term" should be careful to free all allocated storage so that the JPEG system
can be used multiple times during a program run. (For the same reason, can be used multiple times during a program run. (For the same reason,
depending on static initialization of variables is a no-no.) depending on static initialization of variables is a no-no. The only
exception to the free-all-allocated-storage rule is that storage allocated for
the entire processing of an image need not be explicitly freed, since the
memory manager's free_all cleanup will free it.)
1. Input file conversion to standardized form. This provides these methods: 1. Input file conversion to standardized form. This provides these methods:
input_init: read the file header, report image size & component count. input_init: read the file header, report image size & component count.
@@ -677,8 +679,8 @@ depending on static initialization of variables is a no-no.)
afresh for each non-Unix-like platform the compressor is ported to. afresh for each non-Unix-like platform the compressor is ported to.
The UI is expected to supply input and output files and values for all The UI is expected to supply input and output files and values for all
non-automatically-chosen compression parameters. (Hence defaults are non-automatically-chosen compression parameters. (Hence defaults are
determined by the UI; we should probably provide helpful routines to fill determined by the UI; we should provide helpful routines to fill in
in recommended defaults.) The UI must also supply error handling the recommended defaults.) The UI must also supply error handling
routines and some mechanism for trace messages. routines and some mechanism for trace messages.
(This module hides the user interface provided --- command line, (This module hides the user interface provided --- command line,
interactive, etc. Except for error/message handling, the UI calls the interactive, etc. Except for error/message handling, the UI calls the
@@ -749,7 +751,8 @@ depending on static initialization of variables is a no-no.)
alloc_small: allocate an object of given size; use for any random alloc_small: allocate an object of given size; use for any random
data that's not an image array. data that's not an image array.
free_small: release same. free_small: release same.
alloc_medium: like alloc_small, but returns a FAR pointer. alloc_medium: like alloc_small, but returns a FAR pointer. Use for
any object bigger than a couple kilobytes.
free_medium: release same. free_medium: release same.
alloc_small_sarray: construct an all-in-memory image sample array. alloc_small_sarray: construct an all-in-memory image sample array.
free_small_sarray: release same. free_small_sarray: release same.
@@ -766,9 +769,13 @@ depending on static initialization of variables is a no-no.)
figure out how much space to leave unallocated. figure out how much space to leave unallocated.
access_big_sarray: obtain access to a specified portion of a virtual access_big_sarray: obtain access to a specified portion of a virtual
image sample array. image sample array.
access_big_barray: ditto for block (coefficient) arrays.
free_big_sarray: release a virtual sample array. free_big_sarray: release a virtual sample array.
access_big_barray,
free_big_barray: ditto for block (coefficient) arrays. free_big_barray: ditto for block (coefficient) arrays.
free_all: release any remaining storage. This is called
before normal or error termination; the main reason
why it must exist is to ensure that any temporary
files will be deleted upon error termination.
alloc_big_arrays will be called by the pipeline controller, which does alloc_big_arrays will be called by the pipeline controller, which does
most of the memory allocation anyway. The only reason for having separate most of the memory allocation anyway. The only reason for having separate
@@ -783,8 +790,8 @@ depending on static initialization of variables is a no-no.)
The distinction between sample and coefficient array routines is annoying, The distinction between sample and coefficient array routines is annoying,
but it has to be maintained for machines in which "char *" is represented but it has to be maintained for machines in which "char *" is represented
differently from "int *"... on byte-addressable machines some of these differently from "int *". On byte-addressable machines some of these
methods could point to the same code. methods could perhaps point to the same code.
The array routines will operate on only 2-D arrays (one component at a The array routines will operate on only 2-D arrays (one component at a
time), since different components may require different-size arrays. time), since different components may require different-size arrays.
@@ -796,8 +803,8 @@ Note that any given implementation will presumably contain only one
instantiation of input file header reading, overall control, user interface, instantiation of input file header reading, overall control, user interface,
and memory management. Thus these could be called as simple subroutines, and memory management. Thus these could be called as simple subroutines,
without bothering with an object indirection. This is essential for overall without bothering with an object indirection. This is essential for overall
control (which has to initialize the object structure); I'm undecided whether control (which has to initialize the object structure); for consistency we
to impose objectness on the other three. will impose objectness on the other three.
*** Decompression object structure *** *** Decompression object structure ***
@@ -835,7 +842,7 @@ comments at the top of the compression object section also apply here.
interface module to single-handedly implement special applications like interface module to single-handedly implement special applications like
reading from a non-stdio source. For JPEG-in-TIFF format, the need for reading from a non-stdio source. For JPEG-in-TIFF format, the need for
random access will make it impossible for this to work; hence the TIFF random access will make it impossible for this to work; hence the TIFF
header module will probably override the UI read_jpeg_data routine. header module will override the UI-supplied read_jpeg_data routine.
Non-stdio input from a TIFF file will require extensive surgery to the TIFF Non-stdio input from a TIFF file will require extensive surgery to the TIFF
header module, if indeed it is practical at all. header module, if indeed it is practical at all.
@@ -864,7 +871,7 @@ comments at the top of the compression object section also apply here.
always a multiple of an MCU's dimensions. always a multiple of an MCU's dimensions.
(An object on the grounds that multiple instantiations might be useful.) (An object on the grounds that multiple instantiations might be useful.)
5. Cross-block smoothing per JPEG section 13.10 or a similar algorithm. 5. Cross-block smoothing per JPEG section K.8 or a similar algorithm.
smooth_coefficients: Given three block rows' worth of a single smooth_coefficients: Given three block rows' worth of a single
component, emit a smoothed equivalent of the component, emit a smoothed equivalent of the
middle row. The "above" and "below" pointers middle row. The "above" and "below" pointers
@@ -874,8 +881,13 @@ comments at the top of the compression object section also apply here.
extra memory is needed to buffer the additional block rows. extra memory is needed to buffer the additional block rows.
(This object hides the details of the smoothing algorithm.) (This object hides the details of the smoothing algorithm.)
6. Inverse DCT transformation of each 8x8 block. (This can be a plain 6. Inverse DCT transformation of each 8x8 block.
subroutine processing one block per call.) reverse_DCT: given an MCU row's worth of blocks, perform inverse
DCT on each block and output the results into an array
of samples.
We put this method into the jdmcu module for symmetry with the division of
labor in compression. Note that the actual IDCT code is a separate source
file.
7. De-subsampling and smoothing: this will be applied to one component at a 7. De-subsampling and smoothing: this will be applied to one component at a
time. Note that cross-pixel smoothing, which was a separate step in the time. Note that cross-pixel smoothing, which was a separate step in the
@@ -905,9 +917,13 @@ comments at the top of the compression object section also apply here.
output are image arrays of same size but possibly output are image arrays of same size but possibly
different numbers of components. different numbers of components.
colorout_term: cleanup (probably a no-op except for memory dealloc). colorout_term: cleanup (probably a no-op except for memory dealloc).
In practice will always be given an MCU row's worth of pixel rows, except In practice will usually be given an MCU row's worth of pixel rows, except
at the bottom where a smaller number of rows may be left over. Note that at the bottom where a smaller number of rows may be left over. Note that
this object works on all the components at once. this object works on all the components at once.
When quantizing colors, color_convert may be applied to the colormap
instead of actual pixel data. color_convert is called by the color
quantizer in this case; the pipeline controller calls color_convert
directly only when not quantizing.
(Hides all knowledge of color space semantics and conversion. Remaining (Hides all knowledge of color space semantics and conversion. Remaining
modules only need to know the number of JPEG and output components.) modules only need to know the number of JPEG and output components.)
@@ -927,33 +943,44 @@ comments at the top of the compression object section also apply here.
"big" sample image, output is via put_color_map and "big" sample image, output is via put_color_map and
put_pixel_rows. (Used only in 2-pass quantization.) put_pixel_rows. (Used only in 2-pass quantization.)
color_quant_term: cleanup (probably a no-op except for memory dealloc). color_quant_term: cleanup (probably a no-op except for memory dealloc).
The input to the color quantizer is always in the unconverted colorspace;
its output colormap must be in the converted colorspace. The quantizer
has the choice of which space to work in internally. It must call
color_convert either on its input data or on the colormap it sends to the
output module.
For one-pass quantization the image is simply processed by color_quantize, For one-pass quantization the image is simply processed by color_quantize,
a few rows at a time. For two-pass quantization, the pipeline controller a few rows at a time. For two-pass quantization, the pipeline controller
accumulates the output of color_convert into a "big" sample image. The accumulates the output of steps 1-8 into a "big" sample image. The
color_quant_prescan method is invoked during this process so that the color_quant_prescan method is invoked during this process so that the
quantizer can accumulate statistics. At the end of the image, quantizer can accumulate statistics. (If the input file has multiple
color_quant_doit is called; it must rescan the "big" image and pass scans, the prescan may be done during the final scan or as a separate
converted data to the output module. Additional scans of the image could pass.) At the end of the image, color_quant_doit is called; it must
be made before the output pass is done (in fact, prescan could be a no-op). create and output a colormap, then rescan the "big" image and pass mapped
data to the output module. Additional scans of the image could be made
before the output pass is done (in fact, prescan could be a no-op).
As with entropy parameter optimization, the pipeline controller actually As with entropy parameter optimization, the pipeline controller actually
passes an iterator function rather than direct access to the big image. passes an iterator function rather than direct access to the big image.
NOTE: it might be better to do this on the internal color space instead of
RGB? If so, it would need to be performed one step earlier.
(Hides color quantization algorithm.) (Hides color quantization algorithm.)
11. Writing of the desired image format. 11. Writing of the desired image format.
output_init: produce the file header given data from read_file_header. output_init: produce the file header given data from read_file_header.
put_color_map: output colormap, if any (called by color quantizer). put_color_map: output colormap, if any (called by color quantizer).
If used, must be called before any pixel data is output.
put_pixel_rows: output image data in desired format. put_pixel_rows: output image data in desired format.
output_term: finish up at the end. output_term: finish up at the end.
The actual timing of I/O may differ from that suggested by the routine
names; for instance, writing of the file header may be delayed until
put_color_map time if the actual number of colors is needed in the header.
Also, the colormap is available to put_pixel_rows and output_term as well
as put_color_map.
Note that whether colormapping is needed will be determined by the user Note that whether colormapping is needed will be determined by the user
interface object prior to method selection. In implementations that interface object prior to method selection. In implementations that
support multiple output formats, the actual output format will also be support multiple output formats, the actual output format will also be
determined by the user interface. determined by the user interface.
(Hides format of output image and mechanism used to write it. Note that (Hides format of output image and mechanism used to write it. Note that
several other objects know the color model used by the output format. The several other objects know the color model used by the output format.
actual mechanism for writing the file is private to this object and the The actual mechanism for writing the file is private to this object and
user interface.) the user interface.)
12. Pipeline control. This object will provide the "main loop" that invokes 12. Pipeline control. This object will provide the "main loop" that invokes
all the pipeline objects. Note that we will need several different main all the pipeline objects. Note that we will need several different main
@@ -985,9 +1012,6 @@ comments at the top of the compression object section also apply here.
application program", i.e., that which invokes the JPEG decompressor. application program", i.e., that which invokes the JPEG decompressor.
The UI is expected to supply input and output files and values for all The UI is expected to supply input and output files and values for all
operational parameters. The UI must also supply error handling routines. operational parameters. The UI must also supply error handling routines.
At the moment I can't think of any nonfatal errors the JPEG code is likely
to report, so a single report-this-error-and-exit method should be
sufficient.
(This module hides the user interface provided --- command line, (This module hides the user interface provided --- command line,
interactive, etc. Except for error handling, the UI calls the portable interactive, etc. Except for error handling, the UI calls the portable
JPEG code, not the other way around.) JPEG code, not the other way around.)
@@ -1050,9 +1074,52 @@ needs a lot smaller temp file than is implied by the maximum-height method.
For this approach we'd simply treat DNL as a no-op in the decompressor (at For this approach we'd simply treat DNL as a no-op in the decompressor (at
most, check that it matches the SOF image height). most, check that it matches the SOF image height).
We will not worry about making the compressor capable of outputting DNL. Note We will not worry about making the compressor capable of outputting DNL.
that something similar to the first scheme above could be applied if anyone Something similar to the first scheme above could be applied if anyone ever
ever wants to make that work. wants to make that work.
*** Memory manager internal structure ***
The memory manager contains the most potential for system dependencies.
To isolate system dependencies as much as possible, we have broken the
memory manager into two parts. There is a reasonably system-independent
"front end" (jmemmgr.c) and a "back end" that contains only the code
likely to change across systems. All of the memory management methods
outlined above are implemented by the front end. The back end provides
the following routines for use by the front end (none of these routines
are known to the rest of the JPEG code):
jmem_init, jmem_term system-dependent initialization/shutdown
jget_small, jfree_small interface to malloc and free library routines
jget_large, jfree_large interface to FAR malloc/free in MS-DOS machines;
otherwise same as jget_small/jfree_small
jmem_available estimate available memory
jopen_backing_store create a backing-store object
read_backing_store, manipulate a backing store object
write_backing_store,
close_backing_store
On some systems there will be more than one type of backing-store object
(specifically, in MS-DOS a backing store file might be an area of extended
memory as well as a disk file). jopen_backing_store is responsible for
choosing how to implement a given object. The read/write/close routines
are method pointers in the structure that describes a given object; this
lets them be different for different object types.
It may be necessary to ensure that backing store objects are explicitly
released upon abnormal program termination. (For example, MS-DOS won't free
extended memory by itself.) To support this, we will expect the main program
or surrounding application to arrange to call the free_all method upon
abnormal termination; this may require a SIGINT signal handler, for instance.
(We don't want to have the system-dependent module install its own signal
handler, because that would pre-empt the surrounding application's ability
to control signal handling.)
*** Notes for MS-DOS implementors *** *** Notes for MS-DOS implementors ***
@@ -1067,10 +1134,10 @@ significant speed penalty.
When integrating the JPEG code into a larger application, it's a good idea to When integrating the JPEG code into a larger application, it's a good idea to
stay with a small-data-space model if possible. An 8K stack is much more than stay with a small-data-space model if possible. An 8K stack is much more than
sufficient for the JPEG code, and its static data requirements are less than sufficient for the JPEG code, and its static data requirements are less than
1K. When executed, it will typically malloc about 10K worth of near heap 1K. When executed, it will typically malloc about 10K-20K worth of near heap
space (and lots of far heap, but that doesn't count in this calculation). space (and lots of far heap, but that doesn't count in this calculation).
This figure will vary depending on image size and other factors, but figuring This figure will vary depending on image size and other factors, but figuring
20K should be more than sufficient. Thus you have about 35K available for 30K should be more than sufficient. Thus you have about 25K available for
other modules' static data and near heap requirements before you need to go to other modules' static data and near heap requirements before you need to go to
a larger memory model. The C library's static data will account for several K a larger memory model. The C library's static data will account for several K
of this, but that still leaves a good deal for your needs. (If you are tight of this, but that still leaves a good deal for your needs. (If you are tight
@@ -1084,6 +1151,13 @@ JPEG code is stand-alone. (The LZW tables in jrdgif/jwrgif are examples.)
To make an optimal implementation, you might want to move these structures To make an optimal implementation, you might want to move these structures
back to near heap if you know there is sufficient space. back to near heap if you know there is sufficient space.
FAR data space may also be a tight resource when you are dealing with large
images. The most memory-intensive case is decompression with two-pass color
quantization. This requires a 128Kb color histogram plus strip buffers
amounting to about 150 bytes per column for typical sampling ratios (eg, about
96000 bytes for a 640-pixel-wide image). You may not be able to process wide
images if you have large data structures of your own.
*** Potential optimizations *** *** Potential optimizations ***

144
cjpeg.1 Normal file
View File

@@ -0,0 +1,144 @@
.TH CJPEG 1 "28 February 1992"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
.B cjpeg
[
.BI \-Q " quality"
]
[
.B \-oTIad
]
[
.BI \-m " memory"
]
[
.I filename
]
.LP
.SH DESCRIPTION
.LP
.B cjpeg
compresses the named image file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output.
The currently supported image file formats are: PPM (PBMPLUS color
format), PGM (PBMPLUS gray-scale format), GIF, Targa, and RLE (Utah Raster
Toolkit format). (RLE is supported only if the URT library is available.)
.SH OPTIONS
.TP
.BI \-Q " quality"
Scale quantization tables to adjust image quality. Quality is 0 (worst) to
100 (best); default is 75. (See below for more info.)
.TP
.B \-o
Perform optimization of entropy encoding parameters. Without this, default
encoding parameters are used.
.B \-o
usually makes the JPEG file a little smaller, but
.B cjpeg
runs somewhat slower and needs much more memory. Image quality and speed of
decompression are unaffected by
.BR \-o .
.TP
.B \-T
Input file is Targa format. Targa files that contain an "identification"
field will not be automatically recognized by
.BR cjpeg ;
for such files you must specify
.B \-T
to force
.B cjpeg
to treat the input as Targa format.
.TP
.B \-I
Generate noninterleaved JPEG file (not yet supported).
.TP
.B \-a
Use arithmetic coding rather than Huffman coding (not currently
supported for legal reasons).
.TP
.B \-d
Enable debug printout. More
.BR \-d 's
give more output. Also, version information is printed at startup.
.TP
.BI \-m " memory"
Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example,
.B \-m 4m
selects 4000000 bytes. If more space is needed, temporary files will be used.
.PP
The
.B \-Q
switch lets you trade off compressed file size against quality of the
reconstructed image: the higher the
.B \-Q
setting, the larger the JPEG file, and the closer the output image will be to
the original input. Normally you want to use the lowest
.B \-Q
setting (smallest file) that decompresses into something visually
indistinguishable from the original image. For this purpose the
.B \-Q
setting should be between 50 and 95; the default of 75 is often about right.
If you see defects at
.B \-Q
75, then go up 5 or 10 counts at a time until you are happy with the output
image. (The optimal setting will vary from one image to another.)
.PP
.B \-Q
100 will generate a quantization table of all 1's, eliminating loss in the
quantization step (but there is still information loss in subsampling, as well
as roundoff error). This setting is mainly of interest for experimental
purposes.
.B \-Q
values above about 95 are
.B not
recommended for normal use; the compressed file size goes up dramatically for
hardly any gain in output image quality.
.PP
In the other direction,
.B \-Q
values below 50 will produce very small files of low image quality. Settings
around 5 to 10 might be useful in preparing an index of a large image library,
for example. Try
.B \-Q
2 (or so) for some amusing Cubist effects. (Note:
.B \-Q
values below about 25 generate 2-byte quantization tables, which are
considered optional in the JPEG standard.
.B cjpeg
emits a warning message when you give such a
.B \-Q
value, because some commercial JPEG programs may be unable to decode the
resulting file.)
.SH EXAMPLES
.LP
This example compresses the PPM file foo.ppm with a quality factor of
60 and saves the output as foo.jpg:
.IP
.B cjpeg \-Q
.I 60 foo.ppm
.B >
.I foo.jpg
.SH SEE ALSO
.BR djpeg (1)
.br
.BR ppm (5),
.BR pgm (5)
.br
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
Arithmetic coding and interleaved output not yet supported.
.PP
Not all variants of Targa file format are supported.
.PP
The
.B -T
switch is not a bug, it's a feature. (It would be a bug if the Targa format
designers had not been clueless.)
.PP
Not as fast as we'd like.

403
ckconfig.c Normal file
View File

@@ -0,0 +1,403 @@
/*
* ckconfig.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*/
/*
* This program is intended to help you determine how to configure the JPEG
* software for installation on a particular system. The idea is to try to
* compile and execute this program. If your compiler fails to compile the
* program, make changes as indicated in the comments below. Once you can
* compile the program, run it, and it will tell you how to set the various
* switches in jconfig.h and in your Makefile.
*
* This could all be done automatically if we could assume we were on a Unix
* system, but we don't want to assume that, so you'll have to edit and
* recompile this program until it works.
*
* As a general rule, each time you try to compile this program,
* pay attention only to the *first* error message you get from the compiler.
* Many C compilers will issue lots of spurious error messages once they
* have gotten confused. Go to the line indicated in the first error message,
* and read the comments preceding that line to see what to change.
*
* Almost all of the edits you may need to make to this program consist of
* changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL",
* or vice versa. This is called defining or undefining that symbol.
*/
/* First we must see if your system has the include files we need.
* We start out with the assumption that your system follows the ANSI
* conventions for include files. If you get any error in the next dozen
* lines, undefine INCLUDES_ARE_ANSI.
*/
#define INCLUDES_ARE_ANSI /* replace 'define' by 'undef' if error here */
#ifdef INCLUDES_ARE_ANSI /* this will be skipped if you undef... */
#include <stdio.h> /* If you ain't got this, you ain't got C. */
#ifdef __SASC /* Amiga SAS C provides size_t in stddef.h. */
#include <stddef.h> /* (They are wrong...) */
#endif
#include <string.h> /* size_t might be here too. */
typedef size_t my_size_t; /* The payoff: do we have size_t now? */
#include <stdlib.h> /* Check other ANSI includes we use. */
#endif
/* If your system doesn't follow the ANSI conventions, we have to figure out
* what it does follow. If you didn't get an error before this line, you can
* ignore everything down to "#define HAVE_ANSI_DEFINITIONS".
*/
#ifndef INCLUDES_ARE_ANSI /* skip these tests if INCLUDES_ARE_ANSI */
#include <stdio.h> /* If you ain't got this, you ain't got C. */
/* jinclude.h will try to include <sys/types.h> if you don't set
* INCLUDES_ARE_ANSI. We need to test whether that include file is provided.
* If you get an error here, undefine HAVE_TYPES_H.
*/
#define HAVE_TYPES_H
#ifdef HAVE_TYPES_H
#include <sys/types.h>
#endif
/* We have to see if your string functions are defined by
* strings.h (BSD convention) or string.h (everybody else).
* We try the non-BSD convention first; define BSD if the compiler
* says it can't find string.h.
*/
#undef BSD
#ifdef BSD
#include <strings.h>
#else
#include <string.h>
#endif
/* Usually size_t is defined in stdio.h, sys/types.h, and/or string.h.
* If not, you'll get an error on the "typedef size_t my_size_t;" line below.
* In that case, you'll have to search through your system library to
* figure out which include file defines "size_t". Look for a line that
* says "typedef something-or-other size_t;" (stddef.h and stdlib.h are
* good places to look first). Then, change the line below that says
* "#include <someincludefile.h>" to instead include the file
* you found size_t in, and define NEED_SPECIAL_INCLUDE.
*/
#undef NEED_SPECIAL_INCLUDE /* assume we DON'T need it, for starters */
#ifdef NEED_SPECIAL_INCLUDE
#include <someincludefile.h>
#endif
typedef size_t my_size_t; /* The payoff: do we have size_t now? */
#endif /* INCLUDES_ARE_ANSI */
/* The next question is whether your compiler supports ANSI-style function
* definitions. You need to know this in order to choose between using
* makefile.ansi and using makefile.unix.
* The #define line below is set to assume you have ANSI function definitions.
* If you get an error in this group of lines, undefine HAVE_ANSI_DEFINITIONS.
*/
#define HAVE_ANSI_DEFINITIONS
#ifdef HAVE_ANSI_DEFINITIONS
int testfunction (int arg1, int * arg2); /* check prototypes */
struct methods_struct { /* check method-pointer declarations */
int (*error_exit) (char *msgtext);
int (*trace_message) (char *msgtext);
int (*another_method) (void);
};
int testfunction (int arg1, int * arg2) /* check definitions */
{
return arg2[arg1];
}
int testfunction1 (void) /* check void arg list */
{
return 0;
}
#endif
/* Now we want to find out if your compiler knows what "unsigned char" means.
* If you get an error on the "unsigned char un_char;" line,
* then undefine HAVE_UNSIGNED_CHAR.
*/
#define HAVE_UNSIGNED_CHAR
#ifdef HAVE_UNSIGNED_CHAR
unsigned char un_char;
#endif
/* Now we want to find out if your compiler knows what "unsigned short" means.
* If you get an error on the "unsigned short un_short;" line,
* then undefine HAVE_UNSIGNED_SHORT.
*/
#define HAVE_UNSIGNED_SHORT
#ifdef HAVE_UNSIGNED_SHORT
unsigned short un_short;
#endif
/* Now we want to find out if your compiler understands type "void".
* If you get an error anywhere in here, undefine HAVE_VOID.
*/
#define HAVE_VOID
#ifdef HAVE_VOID
typedef void * void_ptr; /* check void * */
typedef void (*void_func) (); /* check ptr to function returning void */
void testfunction2 (arg1, arg2) /* check void function result */
void_ptr arg1;
void_func arg2;
{
char * locptr = (char *) arg1; /* check casting to and from void * */
arg1 = (void *) locptr;
(*arg2) (1, 2); /* check call of fcn returning void */
}
#endif
/* Now we want to find out if your compiler knows what "const" means.
* If you get an error here, undefine HAVE_CONST.
*/
#define HAVE_CONST
#ifdef HAVE_CONST
static const int carray[3] = {1, 2, 3};
int testfunction3 (arg1)
const int arg1;
{
return carray[arg1];
}
#endif
/************************************************************************
* OK, that's it. You should not have to change anything beyond this
* point in order to compile and execute this program. (You might get
* some warnings, but you can ignore them.)
* When you run the program, it will make a couple more tests that it
* can do automatically, and then it will print out a summary of the changes
* that you need to make to the makefile and jconfig.h.
************************************************************************
*/
static int any_changes = 0;
int new_change ()
{
if (! any_changes) {
printf("\nMost of the changes recommended by this program can be made either\n");
printf("by editing jconfig.h, or by adding -Dsymbol switches to the CFLAGS\n");
printf("line in your Makefile. (Some PC compilers expect /Dsymbol instead.)\n");
printf("The CFLAGS method is simpler, but if your system doesn't use makefiles,\n");
printf("or if your compiler doesn't support -D, then you must change jconfig.h.\n");
any_changes = 1;
}
printf("\n"); /* blank line before each problem report */
return 0;
}
int test_char_sign (arg)
int arg;
{
if (arg == 189) { /* expected result for unsigned char */
new_change();
printf("You should add -DCHAR_IS_UNSIGNED to CFLAGS,\n");
printf("or else remove the /* */ comment marks from the line\n");
printf("/* #define CHAR_IS_UNSIGNED */ in jconfig.h.\n");
printf("(Be sure to delete the space before the # character too.)\n");
}
else if (arg != -67) { /* expected result for signed char */
new_change();
printf("Hmm, it seems 'char' is less than eight bits wide on your machine.\n");
printf("I fear the JPEG software will not work at all.\n");
}
return 0;
}
int test_shifting (arg)
long arg;
/* See whether right-shift on a long is signed or not. */
{
long res = arg >> 4;
if (res == 0x80817F4L) { /* expected result for unsigned */
new_change();
printf("You must add -DRIGHT_SHIFT_IS_UNSIGNED to CFLAGS,\n");
printf("or else remove the /* */ comment marks from the line\n");
printf("/* #define RIGHT_SHIFT_IS_UNSIGNED */ in jconfig.h.\n");
}
else if (res != -0x7F7E80CL) { /* expected result for signed */
new_change();
printf("Right shift isn't acting as I expect it to.\n");
printf("I fear the JPEG software will not work at all.\n");
}
return 0;
}
int main (argc, argv)
int argc;
char ** argv;
{
char signed_char_check = (char) (-67);
printf("Results of configuration check for Independent JPEG Group's software:\n");
printf("\nIf there's not a specific makefile provided for your compiler,\n");
#ifdef HAVE_ANSI_DEFINITIONS
printf("you should use makefile.ansi as the starting point for your Makefile.\n");
#else
printf("you should use makefile.unix as the starting point for your Makefile.\n");
#endif
/* Check whether we have all the ANSI features, */
/* and whether this agrees with __STDC__ being predefined. */
#ifdef __STDC__
#define HAVE_STDC /* ANSI compilers won't allow redefining __STDC__ */
#endif
#ifdef HAVE_ANSI_DEFINITIONS
#ifdef HAVE_UNSIGNED_CHAR
#ifdef HAVE_UNSIGNED_SHORT
#ifdef HAVE_CONST
#define HAVE_ALL_ANSI_FEATURES
#endif
#endif
#endif
#endif
#ifdef HAVE_ALL_ANSI_FEATURES
#ifndef HAVE_STDC
new_change();
printf("Your compiler doesn't claim to be ANSI-compliant, but it is close enough\n");
printf("for me. Either add -DHAVE_STDC to CFLAGS, or add #define HAVE_STDC at the\n");
printf("beginning of jconfig.h.\n");
#define HAVE_STDC
#endif
#else /* !HAVE_ALL_ANSI_FEATURES */
#ifdef HAVE_STDC
new_change();
printf("Your compiler claims to be ANSI-compliant, but it is lying!\n");
printf("Delete the line #define HAVE_STDC near the beginning of jconfig.h.\n");
#undef HAVE_STDC
#endif
#endif /* HAVE_ALL_ANSI_FEATURES */
#ifndef HAVE_STDC
#ifdef HAVE_ANSI_DEFINITIONS
new_change();
printf("You should add -DPROTO to CFLAGS, or else take out the several\n");
printf("#ifdef/#else/#endif lines surrounding #define PROTO in jconfig.h.\n");
printf("(Leave only one #define PROTO line.)\n");
#endif
#ifdef HAVE_UNSIGNED_CHAR
#ifdef HAVE_UNSIGNED_SHORT
new_change();
printf("You should add -DHAVE_UNSIGNED_CHAR and -DHAVE_UNSIGNED_SHORT\n");
printf("to CFLAGS, or else take out the #ifdef HAVE_STDC/#endif lines\n");
printf("surrounding #define HAVE_UNSIGNED_CHAR and #define HAVE_UNSIGNED_SHORT\n");
printf("in jconfig.h.\n");
#else /* only unsigned char */
new_change();
printf("You should add -DHAVE_UNSIGNED_CHAR to CFLAGS,\n");
printf("or else move #define HAVE_UNSIGNED_CHAR outside the\n");
printf("#ifdef HAVE_STDC/#endif lines surrounding it in jconfig.h.\n");
#endif
#else /* !HAVE_UNSIGNED_CHAR */
#ifdef HAVE_UNSIGNED_SHORT
new_change();
printf("You should add -DHAVE_UNSIGNED_SHORT to CFLAGS,\n");
printf("or else move #define HAVE_UNSIGNED_SHORT outside the\n");
printf("#ifdef HAVE_STDC/#endif lines surrounding it in jconfig.h.\n");
#endif
#endif /* HAVE_UNSIGNED_CHAR */
#ifdef HAVE_CONST
new_change();
printf("You should delete the #define const line from jconfig.h.\n");
#endif
#endif /* HAVE_STDC */
test_char_sign((int) signed_char_check);
test_shifting(-0x7F7E80B1L);
#ifndef HAVE_VOID
new_change();
printf("You should add -Dvoid=char to CFLAGS,\n");
printf("or else remove the /* */ comment marks from the line\n");
printf("/* #define void char */ in jconfig.h.\n");
printf("(Be sure to delete the space before the # character too.)\n");
#endif
#ifdef INCLUDES_ARE_ANSI
#ifndef __STDC__
new_change();
printf("You should add -DINCLUDES_ARE_ANSI to CFLAGS, or else add\n");
printf("#define INCLUDES_ARE_ANSI at the beginning of jinclude.h (NOT jconfig.h).\n");
#endif
#else /* !INCLUDES_ARE_ANSI */
#ifdef __STDC__
new_change();
printf("You should add -DNONANSI_INCLUDES to CFLAGS, or else add\n");
printf("#define NONANSI_INCLUDES at the beginning of jinclude.h (NOT jconfig.h).\n");
#endif
#ifdef NEED_SPECIAL_INCLUDE
new_change();
printf("In jinclude.h, change the line reading #include <sys/types.h>\n");
printf("to instead include the file you found size_t in.\n");
#else /* !NEED_SPECIAL_INCLUDE */
#ifndef HAVE_TYPES_H
new_change();
printf("In jinclude.h, delete the line reading #include <sys/types.h>.\n");
#endif
#endif /* NEED_SPECIAL_INCLUDE */
#ifdef BSD
new_change();
printf("You should add -DBSD to CFLAGS, or else add\n");
printf("#define BSD at the beginning of jinclude.h (NOT jconfig.h).\n");
#endif
#endif /* INCLUDES_ARE_ANSI */
if (any_changes) {
printf("\nI think that's everything...\n");
} else {
printf("\nI think jconfig.h is OK as distributed.\n");
}
return any_changes;
}

122
djpeg.1 Normal file
View File

@@ -0,0 +1,122 @@
.TH DJPEG 1 "28 February 1992"
.SH NAME
djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS
.B djpeg
[
.B \-GPRTgD1bd
]
[
.BI \-q " colors"
]
[
.BI \-m " memory"
]
[
.I filename
]
.LP
.SH DESCRIPTION
.LP
.B djpeg
decompresses the named JPEG file, or the standard input if no file is named,
and produces an image file on the standard output. PPM, GIF, Targa, or RLE
output format can be selected. (RLE is supported only if the URT library is
available.)
.SH OPTIONS
.TP
.B \-G
Select GIF output format (implies
.BR \-q ,
with default of 256 colors).
.TP
.B \-P
Select PPM or PGM output format (this is the default). PGM is emitted if the
JPEG file is gray-scale or if
.B \-g
is specified.
.TP
.B \-R
Select RLE output format. Requires URT library.
.TP
.B \-T
Select Targa output format. Gray-scale format is emitted if the JPEG file is
gray-scale or if
.B \-g
is specified; otherwise, colormapped format is emitted if
.B \-q
is specified; otherwise, 24-bit full-color format is emitted.
.TP
.B \-g
Force gray-scale output even if input is color.
.TP
.BI \-q " N"
Quantize to N colors. This reduces the number of colors in the output image
so that it can be displayed on a colormapped display or stored in a
colormapped file format. For example, if you have an 8-bit display, you'd
need to quantize to 256 or fewer colors.
.TP
.B \-D
Do not use dithering in color quantization. By default, Floyd-Steinberg
dithering is applied when quantizing colors, but on some images dithering may
result in objectionable "graininess". If that happens, you can turn off
dithering with
.BR \-D .
.B \-D
is ignored unless you also say
.B \-q
or
.BR \-G .
.TP
.B \-1
Use one-pass instead of two-pass color quantization. The one-pass method is
faster and needs less memory, but it produces a lower-quality image.
.B \-1
is ignored unless you also say
.B \-q
or
.BR \-G .
Also, the one-pass method is always used for gray-scale output (the two-pass
method is no improvement then).
.TP
.B \-b
Perform cross-block smoothing. This is quite memory-intensive and only seems
to improve the image at low quality settings (\fB\-Q\fR 10 to 20 or so).
At normal
.B \-Q
settings it may make the image worse.
.TP
.B \-d
Enable debug printout. More
.BR \-d 's
give more output. Also, version information is printed at startup.
.TP
.BI \-m " memory"
Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example,
.B \-m 4m
selects 4000000 bytes. If more space is needed, temporary files will be used.
.SH EXAMPLES
.LP
This example decompresses the JPEG file foo.jpg, quantizes to 256 colors,
and saves the output in GIF format in foo.gif:
.IP
.B djpeg \-G
.I foo.jpg
.B >
.I foo.gif
.SH SEE ALSO
.BR cjpeg (1)
.br
.BR ppm (5),
.BR pgm (5)
.br
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
Arithmetic coding is not supported for legal reasons.
.PP
Not as fast as we'd like.

View File

@@ -40,21 +40,27 @@
* UUCP: ...!ames!fxgrp!ljz * UUCP: ...!ames!fxgrp!ljz
* *
* May, 1988 * May, 1988
*
* Modified for use in free JPEG code:
*
* Ed Hanway
* UUCP: uunet!sisd!jeh
*
* October, 1991
*/ */
/* /* The original egetopt.c was written not to need stdio.h.
* If you want, include stdio.h or something where EOF and NULL are defined. * For the JPEG code this is an unnecessary and unportable assumption.
* However, egetopt() is written so as not to need stdio.h, which should * Also, we make all the variables and routines "static" to avoid
* make it significantly smaller on some systems. * possible conflicts with a system-library version of getopt.
*
* In the JPEG code, this file is compiled by #including it in jcmain.c
* or jdmain.c. Since ANSI2KNR does not process include files, we can't
* rely on it to convert function definitions to K&R style. Hence we
* provide both styles of function header with an explicit #ifdef PROTO (ick).
*/ */
#ifndef EOF #define GVAR static /* make empty to export these variables */
# define EOF (-1)
#endif /* ! EOF */
#ifndef NULL
# define NULL (char *)0
#endif /* ! NULL */
/* /*
* None of these constants are referenced in the executable portion of * None of these constants are referenced in the executable portion of
@@ -63,23 +69,21 @@
#define BADCH (int)'?' #define BADCH (int)'?'
#define NEEDSEP (int)':' #define NEEDSEP (int)':'
#define MAYBESEP (int)'\0' #define MAYBESEP (int)'\0'
#define ERRFD 2
#define EMSG "" #define EMSG ""
#define START "-" #define START "-"
/* /*
* Here are all the pertinent global variables. * Here are all the pertinent global variables.
*/ */
int opterr = 1; /* if true, output error message */ GVAR int opterr = 1; /* if true, output error message */
int optind = 1; /* index into parent argv vector */ GVAR int optind = 1; /* index into parent argv vector */
int optopt; /* character checked for validity */ GVAR int optopt; /* character checked for validity */
int optbad = BADCH; /* character returned on error */ GVAR int optbad = BADCH; /* character returned on error */
int optchar = 0; /* character that begins returned option */ GVAR int optchar = 0; /* character that begins returned option */
int optneed = NEEDSEP; /* flag for mandatory argument */ GVAR int optneed = NEEDSEP; /* flag for mandatory argument */
int optmaybe = MAYBESEP;/* flag for optional argument */ GVAR int optmaybe = MAYBESEP; /* flag for optional argument */
int opterrfd = ERRFD; /* file descriptor for error text */ GVAR const char *optarg; /* argument associated with option */
char *optarg; /* argument associated with option */ GVAR const char *optstart = START; /* list of characters that start options */
char *optstart = START; /* list of characters that start options */
/* /*
@@ -88,17 +92,11 @@ char *optstart = START; /* list of characters that start options */
/* /*
* Conditionally print out an error message and return (depends on the * Conditionally print out an error message and return (depends on the
* setting of 'opterr' and 'opterrfd'). Note that this version of * setting of 'opterr').
* TELL() doesn't require the existence of stdio.h.
*/ */
#define TELL(S) { \ #define TELL(S) { \
if (opterr && opterrfd >= 0) { \ if (opterr) \
char option = optopt; \ fprintf(stderr, "%s%s%c\n", *nargv, (S), optopt); \
write(opterrfd, *nargv, strlen(*nargv)); \
write(opterrfd, (S), strlen(S)); \
write(opterrfd, &option, 1); \
write(opterrfd, "\n", 1); \
} \
return (optbad); \ return (optbad); \
} }
@@ -106,10 +104,16 @@ char *optstart = START; /* list of characters that start options */
* This works similarly to index() and strchr(). I include it so that you * This works similarly to index() and strchr(). I include it so that you
* don't need to be concerned as to which one your system has. * don't need to be concerned as to which one your system has.
*/ */
static char *
_sindex(string, ch) #ifdef PROTO
char *string; LOCAL const char *
int ch; _sindex (const char *string, int ch)
#else
LOCAL const char *
_sindex (string, ch)
const char *string;
int ch;
#endif
{ {
if (string != NULL) { if (string != NULL) {
for (; *string != '\0'; ++string) { for (; *string != '\0'; ++string) {
@@ -125,15 +129,21 @@ int ch;
/* /*
* Here it is: * Here it is:
*/ */
int
egetopt(nargc, nargv, ostr) #ifdef PROTO
int nargc; LOCAL int
char **nargv; egetopt (int nargc, char **nargv, const char *ostr)
char *ostr; #else
LOCAL int
egetopt (nargc, nargv, ostr)
int nargc;
char **nargv;
const char *ostr;
#endif
{ {
static char *place = EMSG; /* option letter processing */ static const char *place = EMSG; /* option letter processing */
register char *oli; /* option letter list index */ register const char *oli; /* option letter list index */
register char *osi = NULL; /* option start list index */ register const char *osi = NULL; /* option start list index */
if (nargv == (char **)NULL) { if (nargv == (char **)NULL) {
return (EOF); return (EOF);

624
example.c Normal file
View File

@@ -0,0 +1,624 @@
/*
* example.c
*
* This file is not actually part of the JPEG software. Rather, it provides
* a skeleton that may be useful for constructing applications that use the
* JPEG software as subroutines. This code will NOT do anything useful as is.
*
* This file illustrates how to use the JPEG code as a subroutine library
* to read or write JPEG image files. We assume here that you are not
* merely interested in converting the image to yet another image file format
* (if you are, you should be adding another I/O module to cjpeg/djpeg, not
* constructing a new application). Instead, we show how to pass the
* decompressed image data into or out of routines that you provide. For
* example, a viewer program might use the JPEG decompressor together with
* routines that write the decompressed image directly to a display.
*
* We present these routines in the same coding style used in the JPEG code
* (ANSI function definitions, etc); but you are of course free to code your
* routines in a different style if you prefer.
*/
/*
* Include file for declaring JPEG data structures.
* This file also includes some system headers like <stdio.h>;
* if you prefer, you can include "jconfig.h" and "jpegdata.h" instead.
*/
#include "jinclude.h"
/*
* <setjmp.h> is used for the optional error recovery mechanism shown in
* the second part of the example.
*/
#include <setjmp.h>
/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
/* This half of the example shows how to feed data into the JPEG compressor.
* We present a minimal version that does not worry about refinements such
* as error recovery (the JPEG code will just exit() if it gets an error).
*/
/*
* To supply the image data for compression, you must define three routines
* input_init, get_input_row, and input_term. These routines will be called
* from the JPEG compressor via function pointer values that you store in the
* cinfo data structure; hence they need not be globally visible and the exact
* names don't matter. (In fact, the "METHODDEF" macro expands to "static" if
* you use the unmodified JPEG include files.)
*
* The input file reading modules (jrdppm.c, jrdgif.c, jrdtarga.c, etc) may be
* useful examples of what these routines should actually do, although each of
* them is encrusted with a lot of specialized code for its own file format.
*/
METHODDEF void
input_init (compress_info_ptr cinfo)
/* Initialize for input; return image size and component data. */
{
/* This routine must return five pieces of information about the incoming
* image, and must do any setup needed for the get_input_row routine.
* The image information is returned in fields of the cinfo struct.
* (If you don't care about modularity, you could initialize these fields
* in the main JPEG calling routine, and make this routine be a no-op.)
* We show some example values here.
*/
cinfo->image_width = 640; /* width in pixels */
cinfo->image_height = 480; /* height in pixels */
/* JPEG views an image as being a rectangular array of pixels, with each
* pixel having the same number of "component" values (color channels).
* You must specify how many components there are and the colorspace
* interpretation of the components. Most applications will use RGB data or
* grayscale data. If you want to use something else, you'll need to study
* and perhaps modify jcdeflts.c, jccolor.c, and jdcolor.c.
*/
cinfo->input_components = 3; /* or 1 for grayscale */
cinfo->in_color_space = CS_RGB; /* or CS_GRAYSCALE for grayscale */
cinfo->data_precision = 8; /* bits per pixel component value */
/* In the current JPEG software, data_precision must be set equal to
* BITS_IN_JSAMPLE, which is 8 unless you twiddle jconfig.h. Future
* versions might allow you to say either 8 or 12 if compiled with
* 12-bit JSAMPLEs, or up to 16 in lossless mode. In any case,
* it is up to you to scale incoming pixel values to the range
* 0 .. (1<<data_precision)-1.
* If your image data format is fixed at a byte per component,
* then saying "8" is probably the best long-term solution.
*/
}
/*
* This function is called repeatedly and must supply the next row of pixels
* on each call. The rows MUST be returned in top-to-bottom order if you want
* your JPEG files to be compatible with everyone else's. (If you cannot
* readily read your data in that order, you'll need an intermediate array to
* hold the image. See jrdtarga.c or jrdrle.c for examples of handling
* bottom-to-top source data using the JPEG code's portable mechanisms.)
* The data is to be returned into a 2-D array of JSAMPLEs, indexed as
* JSAMPLE pixel_row[component][column]
* where component runs from 0 to cinfo->input_components-1, and column runs
* from 0 to cinfo->image_width-1 (column 0 is left edge of image). Note that
* this is actually an array of pointers to arrays rather than a true 2D array,
* since C does not support variable-size multidimensional arrays.
* JSAMPLE is typically typedef'd as "unsigned char".
*/
METHODDEF void
get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* Read next row of pixels into pixel_row[][] */
{
/* This example shows how you might read RGB data (3 components)
* from an input file in which the data is stored 3 bytes per pixel
* in left-to-right, top-to-bottom order.
*/
register FILE * infile = cinfo->input_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = 0; col < cinfo->image_width; col++) {
*ptr0++ = (JSAMPLE) getc(infile); /* red */
*ptr1++ = (JSAMPLE) getc(infile); /* green */
*ptr2++ = (JSAMPLE) getc(infile); /* blue */
}
}
METHODDEF void
input_term (compress_info_ptr cinfo)
/* Finish up at the end of the input */
{
/* This termination routine will very often have no work to do, */
/* but you must provide it anyway. */
/* Note that the JPEG code will only call it during successful exit; */
/* if you want it called during error exit, you gotta do that yourself. */
}
/*
* That's it for the routines that deal with reading the input image data.
* Now we have overall control and parameter selection routines.
*/
/*
* This routine must determine what output JPEG file format is to be written,
* and make any other compression parameter changes that are desirable.
* This routine gets control after the input file header has been read
* (i.e., right after input_init has been called). You could combine its
* functions into input_init, or even into the main control routine, but
* if you have several different input_init routines, it's a definite win
* to keep this separate. You MUST supply this routine even if it's a no-op.
*/
METHODDEF void
c_ui_method_selection (compress_info_ptr cinfo)
{
/* If the input is gray scale, generate a monochrome JPEG file. */
if (cinfo->in_color_space == CS_GRAYSCALE)
j_monochrome_default(cinfo);
/* For now, always select JFIF output format. */
jselwjfif(cinfo);
}
/*
* OK, here is the main function that actually causes everything to happen.
* We assume here that the target filename is supplied by the caller of this
* routine, and that all JPEG compression parameters can be default values.
*/
GLOBAL void
write_JPEG_file (char * filename)
{
/* These three structs contain JPEG parameters and working data.
* They must survive for the duration of parameter setup and one
* call to jpeg_compress; typically, making them local data in the
* calling routine is the best strategy.
*/
struct compress_info_struct cinfo;
struct compress_methods_struct c_methods;
struct external_methods_struct e_methods;
/* Initialize the system-dependent method pointers. */
cinfo.methods = &c_methods; /* links to method structs */
cinfo.emethods = &e_methods;
/* Here we use the default JPEG error handler, which will just print
* an error message on stderr and call exit(). See the second half of
* this file for an example of more graceful error recovery.
*/
jselerror(&e_methods); /* select std error/trace message routines */
/* Here we use the standard memory manager provided with the JPEG code.
* In some cases you might want to replace the memory manager, or at
* least the system-dependent part of it, with your own code.
*/
jselmemmgr(&e_methods); /* select std memory allocation routines */
/* If the compressor requires full-image buffers (for entropy-coding
* optimization or a noninterleaved JPEG file), it will create temporary
* files for anything that doesn't fit within the maximum-memory setting.
* (Note that temp files are NOT needed if you use the default parameters.)
* You can change the default maximum-memory setting by changing
* e_methods.max_memory_to_use after jselmemmgr returns.
* On some systems you may also need to set up a signal handler to
* ensure that temporary files are deleted if the program is interrupted.
* (This is most important if you are on MS-DOS and use the jmemdos.c
* memory manager back end; it will try to grab extended memory for
* temp files, and that space will NOT be freed automatically.)
* See jcmain.c or jdmain.c for an example signal handler.
*/
/* Here, set up pointers to your own routines for input data handling
* and post-init parameter selection.
*/
c_methods.input_init = input_init;
c_methods.get_input_row = get_input_row;
c_methods.input_term = input_term;
c_methods.c_ui_method_selection = c_ui_method_selection;
/* Set up default JPEG parameters in the cinfo data structure. */
j_c_defaults(&cinfo, 75, FALSE);
/* Note: 75 is the recommended default quality level; you may instead pass
* a user-specified quality level. Be aware that values below 25 will cause
* non-baseline JPEG files to be created (and a warning message to that
* effect to be emitted on stderr). This won't bother our decoder, but some
* commercial JPEG implementations may choke on non-baseline JPEG files.
* If you want to force baseline compatibility, pass TRUE instead of FALSE.
* (If non-baseline files are fine, but you could do without that warning
* message, set e_methods.trace_level to -1.)
*/
/* At this point you can modify the default parameters set by j_c_defaults
* as needed. For a minimal implementation, you shouldn't need to change
* anything. See jcmain.c for some examples of what you might change.
*/
/* Select the input and output files.
* Note that cinfo.input_file is only used if your input reading routines
* use it; otherwise, you can just make it NULL.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to write binary files.
*/
cinfo.input_file = NULL; /* if no actual input file involved */
if ((cinfo.output_file = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
/* Here we go! */
jpeg_compress(&cinfo);
/* That's it, son. Nothin' else to do, except close files. */
/* Here we assume only the output file need be closed. */
fclose(cinfo.output_file);
/* Note: if you want to compress more than one image, we recommend you
* repeat this whole routine. You MUST repeat the j_c_defaults()/alter
* parameters/jpeg_compress() sequence, as some data structures allocated
* in j_c_defaults are freed upon exit from jpeg_compress.
*/
}
/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
/* This half of the example shows how to read data from the JPEG decompressor.
* It's a little more refined than the above in that we show how to do your
* own error recovery. If you don't care about that, you don't need these
* next two routines.
*/
/*
* These routines replace the default trace/error routines included with the
* JPEG code. The example trace_message routine shown here is actually the
* same as the standard one, but you could modify it if you don't want messages
* sent to stderr. The example error_exit routine is set up to return
* control to read_JPEG_file() rather than calling exit(). You can use the
* same routines for both compression and decompression error recovery.
*/
/* These static variables are needed by the error routines. */
static jmp_buf setjmp_buffer; /* for return to caller */
static external_methods_ptr emethods; /* needed for access to message_parm */
/* This routine is used for any and all trace, debug, or error printouts
* from the JPEG code. The parameter is a printf format string; up to 8
* integer data values for the format string have been stored in the
* message_parm[] field of the external_methods struct.
*/
METHODDEF void
trace_message (const char *msgtext)
{
fprintf(stderr, msgtext,
emethods->message_parm[0], emethods->message_parm[1],
emethods->message_parm[2], emethods->message_parm[3],
emethods->message_parm[4], emethods->message_parm[5],
emethods->message_parm[6], emethods->message_parm[7]);
fprintf(stderr, "\n"); /* there is no \n in the format string! */
}
/*
* The error_exit() routine should not return to its caller. The default
* routine calls exit(), but here we assume that we want to return to
* read_JPEG_data, which has set up a setjmp context for the purpose.
* You should make sure that the free_all method is called, either within
* error_exit or after the return to the outer-level routine.
*/
METHODDEF void
error_exit (const char *msgtext)
{
trace_message(msgtext); /* report the error message */
(*emethods->free_all) (); /* clean up memory allocation & temp files */
longjmp(setjmp_buffer, 1); /* return control to outer routine */
}
/*
* To accept the image data from decompression, you must define four routines
* output_init, put_color_map, put_pixel_rows, and output_term.
*
* You must understand the distinction between full color output mode
* (N independent color components) and colormapped output mode (a single
* output component representing an index into a color map). You should use
* colormapped mode to write to a colormapped display screen or output file.
* Colormapped mode is also useful for reducing grayscale output to a small
* number of gray levels: when using the 1-pass quantizer on grayscale data,
* the colormap entries will be evenly spaced from 0 to MAX_JSAMPLE, so you
* can regard the indexes are directly representing gray levels at reduced
* precision. In any other case, you should not depend on the colormap
* entries having any particular order.
* To get colormapped output, set cinfo->quantize_colors to TRUE and set
* cinfo->desired_number_of_colors to the maximum number of entries in the
* colormap. This can be done either in your main routine or in
* d_ui_method_selection. For grayscale quantization, also set
* cinfo->two_pass_quantize to FALSE to ensure the 1-pass quantizer is used
* (presently this is the default, but it may not be so in the future).
*
* The output file writing modules (jwrppm.c, jwrgif.c, jwrtarga.c, etc) may be
* useful examples of what these routines should actually do, although each of
* them is encrusted with a lot of specialized code for its own file format.
*/
METHODDEF void
output_init (decompress_info_ptr cinfo)
/* This routine should do any setup required */
{
/* This routine can initialize for output based on the data passed in cinfo.
* Useful fields include:
* image_width, image_height Pretty obvious, I hope.
* data_precision bits per pixel value; typically 8.
* out_color_space output colorspace previously requested
* color_out_comps number of color components in same
* final_out_comps number of components actually output
* final_out_comps is 1 if quantize_colors is true, else it is equal to
* color_out_comps.
*
* If you have requested color quantization, the colormap is NOT yet set.
* You may wish to defer output initialization until put_color_map is called.
*/
}
/*
* This routine is called if and only if you have set cinfo->quantize_colors
* to TRUE. It is given the selected colormap and can complete any required
* initialization. This call will occur after output_init and before any
* calls to put_pixel_rows. Note that the colormap pointer is also placed
* in a cinfo field, whence it can be used by put_pixel_rows or output_term.
* num_colors will be less than or equal to desired_number_of_colors.
*
* The colormap data is supplied as a 2-D array of JSAMPLEs, indexed as
* JSAMPLE colormap[component][indexvalue]
* where component runs from 0 to cinfo->color_out_comps-1, and indexvalue
* runs from 0 to num_colors-1. Note that this is actually an array of
* pointers to arrays rather than a true 2D array, since C does not support
* variable-size multidimensional arrays.
* JSAMPLE is typically typedef'd as "unsigned char". If you want your code
* to be as portable as the JPEG code proper, you should always access JSAMPLE
* values with the GETJSAMPLE() macro, which will do the right thing if the
* machine has only signed chars.
*/
METHODDEF void
put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
/* Write the color map */
{
/* You need not provide this routine if you always set cinfo->quantize_colors
* FALSE; but a safer practice is to provide it and have it just print an
* error message, like this:
*/
fprintf(stderr, "put_color_map called: there's a bug here somewhere!\n");
}
/*
* This function is called repeatedly, with a few more rows of pixels supplied
* on each call. With the current JPEG code, some multiple of 8 rows will be
* passed on each call except the last, but it is extremely bad form to depend
* on this. You CAN assume num_rows > 0.
* The data is supplied in top-to-bottom row order (the standard order within
* a JPEG file). If you cannot readily use the data in that order, you'll
* need an intermediate array to hold the image. See jwrrle.c for an example
* of outputting data in bottom-to-top order.
*
* The data is supplied as a 3-D array of JSAMPLEs, indexed as
* JSAMPLE pixel_data[component][row][column]
* where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
* num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
* left edge of image). Note that this is actually an array of pointers to
* pointers to arrays rather than a true 3D array, since C does not support
* variable-size multidimensional arrays.
* JSAMPLE is typically typedef'd as "unsigned char". If you want your code
* to be as portable as the JPEG code proper, you should always access JSAMPLE
* values with the GETJSAMPLE() macro, which will do the right thing if the
* machine has only signed chars.
*
* If quantize_colors is true, then there is only one component, and its values
* are indexes into the previously supplied colormap. Otherwise the values
* are actual data in your selected output colorspace.
*/
METHODDEF void
put_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
/* Write some rows of output data */
{
/* This example shows how you might write full-color RGB data (3 components)
* to an output file in which the data is stored 3 bytes per pixel.
*/
register FILE * outfile = cinfo->output_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
register int row;
for (row = 0; row < num_rows; row++) {
ptr0 = pixel_data[0][row];
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
for (col = 0; col < cinfo->image_width; col++) {
putc(GETJSAMPLE(*ptr0), outfile); /* red */
ptr0++;
putc(GETJSAMPLE(*ptr1), outfile); /* green */
ptr1++;
putc(GETJSAMPLE(*ptr2), outfile); /* blue */
ptr2++;
}
}
}
METHODDEF void
output_term (decompress_info_ptr cinfo)
/* Finish up at the end of the output */
{
/* This termination routine may not need to do anything. */
/* Note that the JPEG code will only call it during successful exit; */
/* if you want it called during error exit, you gotta do that yourself. */
}
/*
* That's it for the routines that deal with writing the output image.
* Now we have overall control and parameter selection routines.
*/
/*
* This routine gets control after the JPEG file header has been read;
* at this point the image size and colorspace are known.
* The routine must determine what output routines are to be used, and make
* any decompression parameter changes that are desirable. For example,
* if it is found that the JPEG file is grayscale, you might want to do
* things differently than if it is color. You can also delay setting
* quantize_colors and associated options until this point.
*
* j_d_defaults initializes out_color_space to CS_RGB. If you want grayscale
* output you should set out_color_space to CS_GRAYSCALE. Note that you can
* force grayscale output from a color JPEG file (though not vice versa).
*/
METHODDEF void
d_ui_method_selection (decompress_info_ptr cinfo)
{
/* if grayscale input, force grayscale output; */
/* else leave the output colorspace as set by main routine. */
if (cinfo->jpeg_color_space == CS_GRAYSCALE)
cinfo->out_color_space = CS_GRAYSCALE;
/* select output routines */
cinfo->methods->output_init = output_init;
cinfo->methods->put_color_map = put_color_map;
cinfo->methods->put_pixel_rows = put_pixel_rows;
cinfo->methods->output_term = output_term;
}
/*
* OK, here is the main function that actually causes everything to happen.
* We assume here that the JPEG filename is supplied by the caller of this
* routine, and that all decompression parameters can be default values.
* The routine returns 1 if successful, 0 if not.
*/
GLOBAL int
read_JPEG_file (char * filename)
{
/* These three structs contain JPEG parameters and working data.
* They must survive for the duration of parameter setup and one
* call to jpeg_decompress; typically, making them local data in the
* calling routine is the best strategy.
*/
struct decompress_info_struct cinfo;
struct decompress_methods_struct dc_methods;
struct external_methods_struct e_methods;
/* Select the input and output files.
* In this example we want to open the input file before doing anything else,
* so that the setjmp() error recovery below can assume the file is open.
* Note that cinfo.output_file is only used if your output handling routines
* use it; otherwise, you can just make it NULL.
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
* requires it in order to read binary files.
*/
if ((cinfo.input_file = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
cinfo.output_file = NULL; /* if no actual output file involved */
/* Initialize the system-dependent method pointers. */
cinfo.methods = &dc_methods; /* links to method structs */
cinfo.emethods = &e_methods;
/* Here we supply our own error handler; compare to use of standard error
* handler in the previous write_JPEG_file example.
*/
emethods = &e_methods; /* save struct addr for possible access */
e_methods.error_exit = error_exit; /* supply error-exit routine */
e_methods.trace_message = trace_message; /* supply trace-message routine */
/* prepare setjmp context for possible exit from error_exit */
if (setjmp(setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error.
* Memory allocation has already been cleaned up (see free_all call in
* error_exit), but we need to close the input file before returning.
* You might also need to close an output file, etc.
*/
fclose(cinfo.input_file);
return 0;
}
/* Here we use the standard memory manager provided with the JPEG code.
* In some cases you might want to replace the memory manager, or at
* least the system-dependent part of it, with your own code.
*/
jselmemmgr(&e_methods); /* select std memory allocation routines */
/* If the decompressor requires full-image buffers (for two-pass color
* quantization or a noninterleaved JPEG file), it will create temporary
* files for anything that doesn't fit within the maximum-memory setting.
* You can change the default maximum-memory setting by changing
* e_methods.max_memory_to_use after jselmemmgr returns.
* On some systems you may also need to set up a signal handler to
* ensure that temporary files are deleted if the program is interrupted.
* (This is most important if you are on MS-DOS and use the jmemdos.c
* memory manager back end; it will try to grab extended memory for
* temp files, and that space will NOT be freed automatically.)
* See jcmain.c or jdmain.c for an example signal handler.
*/
/* Here, set up the pointer to your own routine for post-header-reading
* parameter selection. You could also initialize the pointers to the
* output data handling routines here, if they are not dependent on the
* image type.
*/
dc_methods.d_ui_method_selection = d_ui_method_selection;
/* Set up default decompression parameters. */
j_d_defaults(&cinfo, TRUE);
/* TRUE indicates that an input buffer should be allocated.
* In unusual cases you may want to allocate the input buffer yourself;
* see jddeflts.c for commentary.
*/
/* At this point you can modify the default parameters set by j_d_defaults
* as needed; for example, you can request color quantization or force
* grayscale output. See jdmain.c for examples of what you might change.
*/
/* Set up to read a JFIF or baseline-JPEG file. */
/* This is the only JPEG file format currently supported. */
jselrjfif(&cinfo);
/* Here we go! */
jpeg_decompress(&cinfo);
/* That's it, son. Nothin' else to do, except close files. */
/* Here we assume only the input file need be closed. */
fclose(cinfo.input_file);
return 1; /* indicate success */
/* Note: if you want to decompress more than one image, we recommend you
* repeat this whole routine. You MUST repeat the j_d_defaults()/alter
* parameters/jpeg_decompress() sequence, as some data structures allocated
* in j_d_defaults are freed upon exit from jpeg_decompress.
*/
}

View File

@@ -1,7 +1,7 @@
/* /*
* jbsmooth.c * jbsmooth.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -43,7 +43,7 @@ smooth_coefficients (decompress_info_ptr cinfo,
if (above != NULL && below != NULL) { if (above != NULL && below != NULL) {
for (col = 1; col < blocks_in_row-1; col++) { for (col = 1; col < blocks_in_row-1; col++) {
/* See section 13.10 of JPEG-8-R8, or K.8 of JPEG-9-R6. /* See section K.8 of the JPEG standard.
* *
* As I understand it, this produces approximations * As I understand it, this produces approximations
* for the low frequency AC components, based on the * for the low frequency AC components, based on the
@@ -51,9 +51,7 @@ smooth_coefficients (decompress_info_ptr cinfo,
* (Thus it can't be used for blocks on the image edges.) * (Thus it can't be used for blocks on the image edges.)
*/ */
/* The layout of these variables corresponds to /* The layout of these variables corresponds to text and figure in K.8 */
* the text in 13.10
*/
JCOEF DC1, DC2, DC3; JCOEF DC1, DC2, DC3;
JCOEF DC4, DC5, DC6; JCOEF DC4, DC5, DC6;
@@ -94,7 +92,7 @@ smooth_coefficients (decompress_info_ptr cinfo,
#define ABS(x) ((x) < 0 ? -(x) : (x)) #define ABS(x) ((x) < 0 ? -(x) : (x))
#define COND_ASSIGN(_ac,_n,_z) if ((ABS(output[col][_n] - (_ac))<<1) <= Qptr[_z]) output[col][_n] = (_ac) #define COND_ASSIGN(_ac,_n,_z) if ((ABS(output[col][_n] - (_ac))<<1) <= Qptr[_z]) output[col][_n] = (JCOEF) (_ac)
COND_ASSIGN(AC01, 1, 1); COND_ASSIGN(AC01, 1, 1);
COND_ASSIGN(AC02, 2, 5); COND_ASSIGN(AC02, 2, 5);

View File

@@ -1,7 +1,7 @@
/* /*
* jcarith.c * jcarith.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *

View File

@@ -1,7 +1,7 @@
/* /*
* jccolor.c * jccolor.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -32,11 +32,35 @@ colorin_init (compress_info_ptr cinfo)
/* /*
* Fetch some rows of pixels from get_input_row and convert to the * Fetch some rows of pixels from get_input_row and convert to the
* JPEG colorspace. * JPEG colorspace.
*/
/*
* This version handles RGB -> YCbCr conversion. * This version handles RGB -> YCbCr conversion.
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
* The conversion equations to be implemented are therefore
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B
* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B
* where Cb and Cr must be incremented by MAXJSAMPLE/2 to create a
* nonnegative output value.
* (These numbers are derived from TIFF Appendix O, draft of 4/10/91.)
*
* To avoid floating-point arithmetic, we represent the fractional constants
* as integers scaled up by 2^14 (about 4 digits precision); we have to divide
* the products by 2^14, with appropriate rounding, to get the correct answer.
*
* For even more speed, we could avoid any multiplications in the inner loop
* by precalculating the constants times R,G,B for all possible values.
* This is not currently implemented.
*/ */
#define SCALEBITS 14
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
METHODDEF void METHODDEF void
get_rgb_ycc_rows (compress_info_ptr cinfo, get_rgb_ycc_rows (compress_info_ptr cinfo,
int rows_to_read, JSAMPIMAGE image_data) int rows_to_read, JSAMPIMAGE image_data)
@@ -63,14 +87,22 @@ get_rgb_ycc_rows (compress_info_ptr cinfo,
g = GETJSAMPLE(*inptr1++); g = GETJSAMPLE(*inptr1++);
b = GETJSAMPLE(*inptr2++); b = GETJSAMPLE(*inptr2++);
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
* must be too; do not need an explicit range-limiting operation. * must be too; we do not need an explicit range-limiting operation.
* Hence the value being shifted is never negative, and we don't
* need the general RIGHT_SHIFT macro.
*/ */
/* Y */ /* Y */
*outptr0++ = ( 306*r + 601*g + 117*b + (INT32) 512) >> 10; *outptr0++ = (JSAMPLE)
(( FIX(0.29900)*r + FIX(0.58700)*g + FIX(0.11400)*b
+ ONE_HALF) >> SCALEBITS);
/* Cb */ /* Cb */
*outptr1++ = ((-173)*r - 339*g + 512*b + (INT32) 512*(MAXJSAMPLE+1)) >> 10; *outptr1++ = (JSAMPLE)
(((-FIX(0.16874))*r - FIX(0.33126)*g + FIX(0.50000)*b
+ ONE_HALF*(MAXJSAMPLE+1)) >> SCALEBITS);
/* Cr */ /* Cr */
*outptr2++ = ( 512*r - 429*g - 83*b + (INT32) 512*(MAXJSAMPLE+1)) >> 10; *outptr2++ = (JSAMPLE)
(( FIX(0.50000)*r - FIX(0.41869)*g - FIX(0.08131)*b
+ ONE_HALF*(MAXJSAMPLE+1)) >> SCALEBITS);
} }
} }
} }
@@ -129,9 +161,7 @@ get_noconvert_rows (compress_info_ptr cinfo,
METHODDEF void METHODDEF void
colorin_term (compress_info_ptr cinfo) colorin_term (compress_info_ptr cinfo)
{ {
/* Release the workspace. */ /* no work (we let free_all release the workspace) */
(*cinfo->emethods->free_small_sarray)
(pixel_row, (long) cinfo->input_components);
} }
@@ -150,6 +180,8 @@ jselccolor (compress_info_ptr cinfo)
break; break;
case CS_RGB: case CS_RGB:
case CS_YCbCr:
case CS_YIQ:
if (cinfo->input_components != 3) if (cinfo->input_components != 3)
ERREXIT(cinfo->emethods, "Bogus input colorspace"); ERREXIT(cinfo->emethods, "Bogus input colorspace");
break; break;
@@ -180,6 +212,8 @@ jselccolor (compress_info_ptr cinfo)
ERREXIT(cinfo->emethods, "Bogus JPEG colorspace"); ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
if (cinfo->in_color_space == CS_RGB) if (cinfo->in_color_space == CS_RGB)
cinfo->methods->get_sample_rows = get_rgb_ycc_rows; cinfo->methods->get_sample_rows = get_rgb_ycc_rows;
else if (cinfo->in_color_space == CS_YCbCr)
cinfo->methods->get_sample_rows = get_noconvert_rows;
else else
ERREXIT(cinfo->emethods, "Unsupported color conversion request"); ERREXIT(cinfo->emethods, "Unsupported color conversion request");
break; break;

View File

@@ -1,27 +1,58 @@
/* /*
* jcdeflts.c * jcdeflts.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
* This file contains optional default-setting code for the JPEG compressor. * This file contains optional default-setting code for the JPEG compressor.
* User interfaces do not have to use this file, but those that don't use it
* must know a lot more about the innards of the JPEG code.
*/ */
#include "jinclude.h" #include "jinclude.h"
/* Default do-nothing progress monitoring routine.
* This can be overridden by a user interface that wishes to
* provide progress monitoring; just set methods->progress_monitor
* after j_c_defaults is done. The routine will be called periodically
* during the compression process.
*
* During any one pass, loopcounter increases from 0 up to (not including)
* looplimit; the step size is not necessarily 1. Both the step size and
* the limit may differ between passes. The expected total number of passes
* is in cinfo->total_passes, and the number of passes already completed is
* in cinfo->completed_passes. Thus the fraction of work completed may be
* estimated as
* completed_passes + (loopcounter/looplimit)
* ------------------------------------------
* total_passes
* ignoring the fact that the passes may not be equal amounts of work.
*/
METHODDEF void
progress_monitor (compress_info_ptr cinfo, long loopcounter, long looplimit)
{
/* do nothing */
}
/*
* Table setup routines
*/
LOCAL void LOCAL void
add_huff_table (compress_info_ptr cinfo, add_huff_table (compress_info_ptr cinfo,
HUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) HUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
/* Define a Huffman table */ /* Define a Huffman table */
{ {
if (*htblptr == NULL) if (*htblptr == NULL)
*htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL)); *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
memcpy((void *) (*htblptr)->bits, (void *) bits, memcpy((void *) (*htblptr)->bits, (const void *) bits,
SIZEOF((*htblptr)->bits)); SIZEOF((*htblptr)->bits));
memcpy((void *) (*htblptr)->huffval, (void *) val, memcpy((void *) (*htblptr)->huffval, (const void *) val,
SIZEOF((*htblptr)->huffval)); SIZEOF((*htblptr)->huffval));
/* Initialize sent_table FALSE so table will be written to JPEG file. /* Initialize sent_table FALSE so table will be written to JPEG file.
@@ -36,7 +67,8 @@ add_huff_table (compress_info_ptr cinfo,
LOCAL void LOCAL void
std_huff_tables (compress_info_ptr cinfo) std_huff_tables (compress_info_ptr cinfo)
/* Set up the standard Huffman tables (cf. JPEG-8-R8 section 13.3) */ /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
/* IMPORTANT: these are only valid for 8-bit data precision! */
{ {
static const UINT8 dc_luminance_bits[17] = static const UINT8 dc_luminance_bits[17] =
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
@@ -109,7 +141,7 @@ std_huff_tables (compress_info_ptr cinfo)
} }
/* This is the sample quantization table given in JPEG-8-R8 sec 13.1, /* This is the sample quantization table given in the JPEG spec section K.1,
* but expressed in zigzag order (as are all of our quant. tables). * but expressed in zigzag order (as are all of our quant. tables).
* The spec says that the values given produce "good" quality, and * The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality. (These two settings are * when divided by 2, "very good" quality. (These two settings are
@@ -152,7 +184,7 @@ add_quant_table (compress_info_ptr cinfo, int which_tbl,
long temp; long temp;
if (*qtblptr == NULL) if (*qtblptr == NULL)
*qtblptr = (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL)); *qtblptr = (QUANT_TBL_PTR) (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
temp = ((long) basic_table[i] * scale_factor + 50L) / 100L; temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
@@ -207,14 +239,16 @@ j_set_quality (compress_info_ptr cinfo, int quality, boolean force_baseline)
* *
* User interfaces that don't choose to use this routine must do their * User interfaces that don't choose to use this routine must do their
* own setup of all these parameters. Alternately, you can call this * own setup of all these parameters. Alternately, you can call this
* to establish defaults and then alter parameters selectively. * to establish defaults and then alter parameters selectively. This
* is the recommended approach since, if we add any new parameters,
* your code will still work (they'll be set to reasonable defaults).
* *
* See above for the meaning of the 'quality' parameter. Typically, * See above for the meaning of the 'quality' and 'force_baseline' parameters.
* the application's default quality setting will be passed to this * Typically, the application's default quality setting will be passed to this
* routine. A later call on j_set_quality() can be used to change to * routine. A later call on j_set_quality() can be used to change to a
* a user-specified quality setting. * user-specified quality setting.
* *
* This sets up for a color image; to output a grayscale image, * This routine sets up for a color image; to output a grayscale image,
* do this first and call j_monochrome_default() afterwards. * do this first and call j_monochrome_default() afterwards.
* (The latter can be called within c_ui_method_selection, so the * (The latter can be called within c_ui_method_selection, so the
* choice can depend on the input file header.) * choice can depend on the input file header.)
@@ -222,18 +256,13 @@ j_set_quality (compress_info_ptr cinfo, int quality, boolean force_baseline)
* you should also change the component ID codes, and you should NOT emit * you should also change the component ID codes, and you should NOT emit
* a JFIF header (set write_JFIF_header = FALSE). * a JFIF header (set write_JFIF_header = FALSE).
* *
* CAUTION: if you want to compress multiple images per run, it's safest * CAUTION: if you want to compress multiple images per run, it's necessary
* to call j_default_compression before *each* call to jpeg_compress (and * to call j_c_defaults before *each* call to jpeg_compress, since subsidiary
* j_free_defaults afterwards). If this isn't practical, you'll have to * structures like the Huffman tables are automatically freed during cleanup.
* be careful to reset any individual parameters that may change during
* the compression run. The main thing you need to worry about as this
* is written is that the sent_table boolean in each Huffman table must
* be reset to FALSE before each compression; otherwise, Huffman tables
* won't get emitted for the second and subsequent images.
*/ */
GLOBAL void GLOBAL void
j_default_compression (compress_info_ptr cinfo, int quality) j_c_defaults (compress_info_ptr cinfo, int quality, boolean force_baseline)
/* NB: the external methods must already be set up. */ /* NB: the external methods must already be set up. */
{ {
short i; short i;
@@ -248,7 +277,7 @@ j_default_compression (compress_info_ptr cinfo, int quality)
cinfo->ac_huff_tbl_ptrs[i] = NULL; cinfo->ac_huff_tbl_ptrs[i] = NULL;
} }
cinfo->data_precision = 8; /* default; can be overridden by input_init */ cinfo->data_precision = BITS_IN_JSAMPLE; /* default; can be overridden by input_init */
cinfo->density_unit = 0; /* Pixel size is unknown by default */ cinfo->density_unit = 0; /* Pixel size is unknown by default */
cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
cinfo->Y_density = 1; cinfo->Y_density = 1;
@@ -260,8 +289,8 @@ j_default_compression (compress_info_ptr cinfo, int quality)
cinfo->write_JFIF_header = TRUE; cinfo->write_JFIF_header = TRUE;
cinfo->jpeg_color_space = CS_YCbCr; cinfo->jpeg_color_space = CS_YCbCr;
cinfo->num_components = 3; cinfo->num_components = 3;
cinfo->comp_info = (*cinfo->emethods->alloc_small) cinfo->comp_info = (jpeg_component_info *)
(4 * SIZEOF(jpeg_component_info)); (*cinfo->emethods->alloc_small) (4 * SIZEOF(jpeg_component_info));
/* Note: we allocate a 4-entry comp_info array so that user interface can /* Note: we allocate a 4-entry comp_info array so that user interface can
* easily change over to CMYK color space if desired. * easily change over to CMYK color space if desired.
*/ */
@@ -294,8 +323,7 @@ j_default_compression (compress_info_ptr cinfo, int quality)
compptr->ac_tbl_no = 1; compptr->ac_tbl_no = 1;
/* Set up two quantization tables using the specified quality scaling */ /* Set up two quantization tables using the specified quality scaling */
/* Baseline compatibility is forced (a nonissue for reasonable defaults) */ j_set_quality(cinfo, quality, force_baseline);
j_set_quality(cinfo, quality, TRUE);
/* Set up two Huffman tables in case user interface wants Huffman coding */ /* Set up two Huffman tables in case user interface wants Huffman coding */
std_huff_tables(cinfo); std_huff_tables(cinfo);
@@ -321,13 +349,16 @@ j_default_compression (compress_info_ptr cinfo, int quality)
/* No restart markers */ /* No restart markers */
cinfo->restart_interval = 0; cinfo->restart_interval = 0;
/* Install default do-nothing progress monitoring method. */
cinfo->methods->progress_monitor = progress_monitor;
} }
GLOBAL void GLOBAL void
j_monochrome_default (compress_info_ptr cinfo) j_monochrome_default (compress_info_ptr cinfo)
/* Change the j_default_compression() values to emit a monochrome JPEG file. */ /* Change the j_c_defaults() values to emit a monochrome JPEG file. */
{ {
jpeg_component_info * compptr; jpeg_component_info * compptr;
@@ -338,27 +369,3 @@ j_monochrome_default (compress_info_ptr cinfo)
compptr->h_samp_factor = 1; compptr->h_samp_factor = 1;
compptr->v_samp_factor = 1; compptr->v_samp_factor = 1;
} }
/* This routine releases storage allocated by j_default_compression.
* Note that freeing the method pointer structs and the compress_info_struct
* itself are the responsibility of the user interface.
*/
GLOBAL void
j_free_defaults (compress_info_ptr cinfo)
{
short i;
#define FREE(ptr) if ((ptr) != NULL) \
(*cinfo->emethods->free_small) ((void *) ptr)
FREE(cinfo->comp_info);
for (i = 0; i < NUM_QUANT_TBLS; i++)
FREE(cinfo->quant_tbl_ptrs[i]);
for (i = 0; i < NUM_HUFF_TBLS; i++) {
FREE(cinfo->dc_huff_tbl_ptrs[i]);
FREE(cinfo->ac_huff_tbl_ptrs[i]);
}
}

View File

@@ -1,7 +1,7 @@
/* /*
* jcexpand.c * jcexpand.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *

115
jchuff.c
View File

@@ -1,7 +1,7 @@
/* /*
* jchuff.c * jchuff.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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,25 +34,25 @@ fix_huff_tbl (HUFF_TBL * htbl)
UINT16 huffcode[257]; UINT16 huffcode[257];
UINT16 code; UINT16 code;
/* Figure 7.3.5.4.2.1: make table of Huffman code length for each symbol */ /* Figure C.1: make table of Huffman code length for each symbol */
/* Note that this is in code-length order. */ /* Note that this is in code-length order. */
p = 0; p = 0;
for (l = 1; l <= 16; l++) { for (l = 1; l <= 16; l++) {
for (i = 1; i <= htbl->bits[l]; i++) for (i = 1; i <= (int) htbl->bits[l]; i++)
huffsize[p++] = l; huffsize[p++] = (char) l;
} }
huffsize[p] = 0; huffsize[p] = 0;
lastp = p; lastp = p;
/* Figure 7.3.5.4.2.2: generate the codes themselves */ /* Figure C.2: generate the codes themselves */
/* Note that this is in code-length order. */ /* Note that this is in code-length order. */
code = 0; code = 0;
si = huffsize[0]; si = huffsize[0];
p = 0; p = 0;
while (huffsize[p]) { while (huffsize[p]) {
while (huffsize[p] == si) { while (((int) huffsize[p]) == si) {
huffcode[p++] = code; huffcode[p++] = code;
code++; code++;
} }
@@ -60,27 +60,21 @@ fix_huff_tbl (HUFF_TBL * htbl)
si++; si++;
} }
/* Figure 7.3.5.4.2.3: generate encoding tables */ /* Figure C.3: generate encoding tables */
/* These are code and size indexed by symbol value */ /* These are code and size indexed by symbol value */
/* Set any codeless symbols to have code length 0;
* this allows emit_bits to detect any attempt to emit such symbols.
*/
MEMZERO((void *) htbl->ehufsi, SIZEOF(htbl->ehufsi));
for (p = 0; p < lastp; p++) { for (p = 0; p < lastp; p++) {
htbl->ehufco[htbl->huffval[p]] = huffcode[p]; htbl->ehufco[htbl->huffval[p]] = huffcode[p];
htbl->ehufsi[htbl->huffval[p]] = huffsize[p]; htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
} }
/* Figure 13.4.2.3.1: generate decoding tables */ /* We don't bother to fill in the decoding tables mincode[], maxcode[], */
/* and valptr[], since they are not used for encoding. */
p = 0;
for (l = 1; l <= 16; l++) {
if (htbl->bits[l]) {
htbl->valptr[l] = p; /* huffval[] index of 1st sym of code len l */
htbl->mincode[l] = huffcode[p]; /* minimum code of length l */
p += htbl->bits[l];
htbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
} else {
htbl->maxcode[l] = -1;
}
}
} }
@@ -95,10 +89,10 @@ flush_bytes (void)
} }
#define emit_byte(val) ((bytes_in_buffer >= JPEG_BUF_SIZE ? \ #define emit_byte(val) \
(flush_bytes(), 0) : 0), \ MAKESTMT( if (bytes_in_buffer >= JPEG_BUF_SIZE) \
output_buffer[bytes_in_buffer] = (val), \ flush_bytes(); \
bytes_in_buffer++) output_buffer[bytes_in_buffer++] = (char) (val); )
@@ -117,6 +111,10 @@ emit_bits (UINT16 code, int size)
register INT32 put_buffer = code; register INT32 put_buffer = code;
register int put_bits = huff_put_bits; register int put_bits = huff_put_bits;
/* if size is 0, caller used an invalid Huffman table entry */
if (size == 0)
ERREXIT(cinfo->emethods, "Missing Huffman code table entry");
put_buffer &= (((INT32) 1) << size) - 1; /* Mask off any excess bits in code */ put_buffer &= (((INT32) 1) << size) - 1; /* Mask off any excess bits in code */
put_bits += size; /* new number of bits in buffer */ put_bits += size; /* new number of bits in buffer */
@@ -157,16 +155,22 @@ flush_bits (void)
LOCAL void LOCAL void
encode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl) encode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
{ {
register INT32 temp; register int temp, temp2;
register int nbits; register int nbits;
register int k, r, i; register int k, r, i;
/* Encode the DC coefficient difference per section 7.3.5.1 */ /* Encode the DC coefficient difference per section F.1.2.1 */
temp = temp2 = block[0];
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
/* For a negative input, want temp2 = bitwise complement of abs(input) */
/* This code assumes we are on a two's complement machine */
temp2--;
}
/* Find the number of bits needed for the magnitude of the coefficient */ /* Find the number of bits needed for the magnitude of the coefficient */
temp = block[0];
if (temp < 0) temp = -temp;
nbits = 0; nbits = 0;
while (temp) { while (temp) {
nbits++; nbits++;
@@ -175,15 +179,13 @@ encode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
/* Emit the Huffman-coded symbol for the number of bits */ /* Emit the Huffman-coded symbol for the number of bits */
emit_bits(dctbl->ehufco[nbits], dctbl->ehufsi[nbits]); emit_bits(dctbl->ehufco[nbits], dctbl->ehufsi[nbits]);
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (nbits) /* emit_bits rejects calls with size 0 */
emit_bits((UINT16) temp2, nbits);
/* If positive, emit nbits low order bits; */ /* Encode the AC coefficients per section F.1.2.2 */
/* if negative, emit nbits low order bits of value-1 */
if ((temp = block[0]) < 0)
temp--;
emit_bits((UINT16) temp, nbits);
/* Encode the AC coefficients per section 7.3.5.2 */
r = 0; /* r = run length of zeros */ r = 0; /* r = run length of zeros */
@@ -196,10 +198,15 @@ encode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
emit_bits(actbl->ehufco[0xF0], actbl->ehufsi[0xF0]); emit_bits(actbl->ehufco[0xF0], actbl->ehufsi[0xF0]);
r -= 16; r -= 16;
} }
temp2 = temp;
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
/* This code assumes we are on a two's complement machine */
temp2--;
}
/* Find the number of bits needed for the magnitude of the coefficient */ /* Find the number of bits needed for the magnitude of the coefficient */
if (temp < 0) temp = -temp;
nbits = 1; /* there must be at least one 1 bit */ nbits = 1; /* there must be at least one 1 bit */
while (temp >>= 1) while (temp >>= 1)
nbits++; nbits++;
@@ -208,12 +215,9 @@ encode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
i = (r << 4) + nbits; i = (r << 4) + nbits;
emit_bits(actbl->ehufco[i], actbl->ehufsi[i]); emit_bits(actbl->ehufco[i], actbl->ehufsi[i]);
/* If positive, emit nbits low order bits; */ /* Emit that number of bits of the value, if positive, */
/* if negative, emit nbits low order bits of value-1 */ /* or the complement of its magnitude, if negative. */
if ((temp = block[k]) < 0) emit_bits((UINT16) temp2, nbits);
temp--;
emit_bits((UINT16) temp, nbits);
r = 0; r = 0;
} }
@@ -373,7 +377,7 @@ gen_huff_coding (compress_info_ptr cinfo, HUFF_TBL *htbl, long freq[])
int p, i, j; int p, i, j;
long v; long v;
/* This algorithm is explained in section 13.2 of JPEG-8-R8 */ /* This algorithm is explained in section K.2 of the JPEG standard */
MEMZERO((void *) bits, SIZEOF(bits)); MEMZERO((void *) bits, SIZEOF(bits));
MEMZERO((void *) codesize, SIZEOF(codesize)); MEMZERO((void *) codesize, SIZEOF(codesize));
@@ -488,7 +492,7 @@ gen_huff_coding (compress_info_ptr cinfo, HUFF_TBL *htbl, long freq[])
for (i = 1; i <= MAX_CLEN; i++) { for (i = 1; i <= MAX_CLEN; i++) {
for (j = 0; j <= 255; j++) { for (j = 0; j <= 255; j++) {
if (codesize[j] == i) { if (codesize[j] == i) {
htbl->huffval[p] = j; htbl->huffval[p] = (UINT8) j;
p++; p++;
} }
} }
@@ -507,7 +511,7 @@ htest_one_block (JBLOCK block, JCOEF block0,
register int nbits; register int nbits;
register int k, r; register int k, r;
/* Encode the DC coefficient difference per section 7.3.5.1 */ /* Encode the DC coefficient difference per section F.1.2.1 */
/* Find the number of bits needed for the magnitude of the coefficient */ /* Find the number of bits needed for the magnitude of the coefficient */
temp = block0; temp = block0;
@@ -519,7 +523,7 @@ htest_one_block (JBLOCK block, JCOEF block0,
/* Count the Huffman symbol for the number of bits */ /* Count the Huffman symbol for the number of bits */
dc_counts[nbits]++; dc_counts[nbits]++;
/* Encode the AC coefficients per section 7.3.5.2 */ /* Encode the AC coefficients per section F.1.2.2 */
r = 0; /* r = run length of zeros */ r = 0; /* r = run length of zeros */
@@ -645,7 +649,7 @@ huff_optimize (compress_info_ptr cinfo, MCU_output_caller_ptr source_method)
if (dc_count_ptrs[tbl] != NULL) { if (dc_count_ptrs[tbl] != NULL) {
htblptr = & cinfo->dc_huff_tbl_ptrs[tbl]; htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
if (*htblptr == NULL) if (*htblptr == NULL)
*htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL)); *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
/* Set sent_table FALSE so updated table will be written to JPEG file. */ /* Set sent_table FALSE so updated table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE; (*htblptr)->sent_table = FALSE;
/* Compute the optimal Huffman encoding */ /* Compute the optimal Huffman encoding */
@@ -656,7 +660,7 @@ huff_optimize (compress_info_ptr cinfo, MCU_output_caller_ptr source_method)
if (ac_count_ptrs[tbl] != NULL) { if (ac_count_ptrs[tbl] != NULL) {
htblptr = & cinfo->ac_huff_tbl_ptrs[tbl]; htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
if (*htblptr == NULL) if (*htblptr == NULL)
*htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL)); *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
/* Set sent_table FALSE so updated table will be written to JPEG file. */ /* Set sent_table FALSE so updated table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE; (*htblptr)->sent_table = FALSE;
/* Compute the optimal Huffman encoding */ /* Compute the optimal Huffman encoding */
@@ -684,6 +688,15 @@ jselchuffman (compress_info_ptr cinfo)
cinfo->methods->entropy_encoder_term = huff_term; cinfo->methods->entropy_encoder_term = huff_term;
#ifdef ENTROPY_OPT_SUPPORTED #ifdef ENTROPY_OPT_SUPPORTED
cinfo->methods->entropy_optimize = huff_optimize; cinfo->methods->entropy_optimize = huff_optimize;
/* The standard Huffman tables are only valid for 8-bit data precision.
* If the precision is higher, force optimization on so that usable
* tables will be computed. This test can be removed if default tables
* are supplied that are valid for the desired precision.
*/
if (cinfo->data_precision > 8)
cinfo->optimize_coding = TRUE;
if (cinfo->optimize_coding)
cinfo->total_passes++; /* one pass needed for entropy optimization */
#endif #endif
} }
} }

188
jcmain.c
View File

@@ -1,7 +1,7 @@
/* /*
* jcmain.c * jcmain.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -21,9 +21,12 @@
*/ */
#include "jinclude.h" #include "jinclude.h"
#ifdef __STDC__ #ifdef INCLUDES_ARE_ANSI
#include <stdlib.h> /* to declare exit() */ #include <stdlib.h> /* to declare exit() */
#endif #endif
#ifdef NEED_SIGNAL_CATCHER
#include <signal.h> /* to declare signal() */
#endif
#ifdef THINK_C #ifdef THINK_C
#include <console.h> /* command-line reader for Macintosh */ #include <console.h> /* command-line reader for Macintosh */
@@ -37,20 +40,26 @@
#define WRITE_BINARY "wb" #define WRITE_BINARY "wb"
#endif #endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#ifdef VMS
#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
#else
#define EXIT_SUCCESS 0
#endif
#endif
#include "jversion.h" /* for version message */
/* /*
* If your system has getopt(3), you can use your library version by * PD version of getopt(3).
* defining HAVE_GETOPT. By default, we use the PD 'egetopt'.
*/ */
#ifdef HAVE_GETOPT
extern int getopt PP((int argc, char **argv, char *optstring));
extern char * optarg;
extern int optind;
#else
#include "egetopt.c" #include "egetopt.c"
#define getopt(argc,argv,opt) egetopt(argc,argv,opt)
#endif
/* /*
@@ -58,24 +67,44 @@ extern int optind;
* and selects the appropriate input-reading module. * and selects the appropriate input-reading module.
* *
* To determine which family of input formats the file belongs to, * To determine which family of input formats the file belongs to,
* we look only at the first byte of the file, since C does not * we may look only at the first byte of the file, since C does not
* guarantee that more than one character can be pushed back with ungetc. * guarantee that more than one character can be pushed back with ungetc.
* This is sufficient for the currently envisioned set of input formats. * Looking at additional bytes would require one of these approaches:
* * 1) assume we can fseek() the input file (fails for piped input);
* If you need to look at more than one character to select an input module, * 2) assume we can push back more than one character (works in
* you can either
* 1) assume you can fseek() the input file (may fail for piped input);
* 2) assume you can push back more than one character (works in
* some C implementations, but unportable); * some C implementations, but unportable);
* or 3) don't put back the data, and modify the various input_init * 3) provide our own buffering as is done in djpeg (breaks input readers
* methods to assume they start reading after the start of file. * that want to use stdio directly, such as the RLE library);
* or 4) don't put back the data, and modify the input_init methods to assume
* they start reading after the start of file (also breaks RLE library).
* #1 is attractive for MS-DOS but is untenable on Unix.
*
* The most portable solution for file types that can't be identified by their
* first byte is to make the user tell us what they are. This is also the
* only approach for "raw" file types that contain only arbitrary values.
* We presently apply this method for Targa files. Most of the time Targa
* files start with 0x00, so we recognize that case. Potentially, however,
* a Targa file could start with any byte value (byte 0 is the length of the
* seldom-used ID field), so we accept a -T switch to force Targa input mode.
*/ */
static boolean is_targa; /* records user -T switch */
LOCAL void LOCAL void
select_file_type (compress_info_ptr cinfo) select_file_type (compress_info_ptr cinfo)
{ {
int c; int c;
if (is_targa) {
#ifdef TARGA_SUPPORTED
jselrtarga(cinfo);
#else
ERREXIT(cinfo->emethods, "Targa support was not compiled");
#endif
return;
}
if ((c = getc(cinfo->input_file)) == EOF) if ((c = getc(cinfo->input_file)) == EOF)
ERREXIT(cinfo->emethods, "Empty input file"); ERREXIT(cinfo->emethods, "Empty input file");
@@ -89,9 +118,23 @@ select_file_type (compress_info_ptr cinfo)
case 'P': case 'P':
jselrppm(cinfo); jselrppm(cinfo);
break; break;
#endif
#ifdef RLE_SUPPORTED
case 'R':
jselrrle(cinfo);
break;
#endif
#ifdef TARGA_SUPPORTED
case 0x00:
jselrtarga(cinfo);
break;
#endif #endif
default: default:
ERREXIT(cinfo->emethods, "Unsupported input file format"); #ifdef TARGA_SUPPORTED
ERREXIT(cinfo->emethods, "Unrecognized input file format --- did you forget -T ?");
#else
ERREXIT(cinfo->emethods, "Unrecognized input file format");
#endif
break; break;
} }
@@ -121,18 +164,39 @@ c_ui_method_selection (compress_info_ptr cinfo)
} }
/*
* Signal catcher to ensure that temporary files are removed before aborting.
* NB: for Amiga Manx C this is actually a global routine named _abort();
* see -Dsignal_catcher=_abort in CFLAGS. Talk about bogus...
*/
#ifdef NEED_SIGNAL_CATCHER
static external_methods_ptr emethods; /* for access to free_all */
GLOBAL void
signal_catcher (int signum)
{
emethods->trace_level = 0; /* turn off trace output */
(*emethods->free_all) (); /* clean up memory allocation & temp files */
exit(EXIT_FAILURE);
}
#endif
LOCAL void LOCAL void
usage (char * progname) usage (char * progname)
/* complain about bad command line */ /* complain about bad command line */
{ {
fprintf(stderr, "usage: %s ", progname); fprintf(stderr, "usage: %s ", progname);
fprintf(stderr, "[-I] [-Q quality 0..100] [-a] [-o] [-d]"); fprintf(stderr, "[-Q quality 0..100] [-o] [-T] [-I] [-a] [-d] [-m mem]");
#ifdef TWO_FILE_COMMANDLINE #ifdef TWO_FILE_COMMANDLINE
fprintf(stderr, " inputfile outputfile\n"); fprintf(stderr, " inputfile outputfile\n");
#else #else
fprintf(stderr, " [inputfile]\n"); fprintf(stderr, " [inputfile]\n");
#endif #endif
exit(2); exit(EXIT_FAILURE);
} }
@@ -140,7 +204,7 @@ usage (char * progname)
* The main program. * The main program.
*/ */
GLOBAL void GLOBAL int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct compress_info_struct cinfo; struct compress_info_struct cinfo;
@@ -157,21 +221,25 @@ main (int argc, char **argv)
cinfo.methods = &c_methods; cinfo.methods = &c_methods;
cinfo.emethods = &e_methods; cinfo.emethods = &e_methods;
jselerror(&e_methods); /* error/trace message routines */ jselerror(&e_methods); /* error/trace message routines */
jselvirtmem(&e_methods); /* memory allocation routines */ jselmemmgr(&e_methods); /* memory allocation routines */
c_methods.c_ui_method_selection = c_ui_method_selection; c_methods.c_ui_method_selection = c_ui_method_selection;
/* Set up default input and output file references. */ /* Now OK to enable signal catcher. */
/* (These may be overridden below.) */ #ifdef NEED_SIGNAL_CATCHER
cinfo.input_file = stdin; emethods = &e_methods;
cinfo.output_file = stdout; signal(SIGINT, signal_catcher);
#ifdef SIGTERM /* not all systems have SIGTERM */
signal(SIGTERM, signal_catcher);
#endif
#endif
/* Set up default parameters. */ /* Set up default JPEG parameters. */
e_methods.trace_level = 0; j_c_defaults(&cinfo, 75, FALSE); /* default quality level = 75 */
j_default_compression(&cinfo, 75); /* default quality level */ is_targa = FALSE;
/* Scan parameters */ /* Scan command line options, adjust parameters */
while ((c = getopt(argc, argv, "IQ:aod")) != EOF) while ((c = egetopt(argc, argv, "IQ:Taom:d")) != EOF)
switch (c) { switch (c) {
case 'I': /* Create noninterleaved file. */ case 'I': /* Create noninterleaved file. */
#ifdef MULTISCAN_FILES_SUPPORTED #ifdef MULTISCAN_FILES_SUPPORTED
@@ -179,7 +247,7 @@ main (int argc, char **argv)
#else #else
fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n", fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n",
argv[0]); argv[0]);
exit(2); exit(EXIT_FAILURE);
#endif #endif
break; break;
case 'Q': /* Quality factor. */ case 'Q': /* Quality factor. */
@@ -188,20 +256,23 @@ main (int argc, char **argv)
usage(argv[0]); usage(argv[0]);
if (sscanf(optarg, "%d", &val) != 1) if (sscanf(optarg, "%d", &val) != 1)
usage(argv[0]); usage(argv[0]);
/* Note: for now, we leave force_baseline FALSE. /* Note: for now, we make force_baseline FALSE.
* In a production user interface, probably should make it TRUE * This means non-baseline JPEG files can be created with low Q values.
* unless overridden by a separate switch. * To ensure only baseline files are generated, pass TRUE instead.
*/ */
j_set_quality(&cinfo, val, FALSE); j_set_quality(&cinfo, val, FALSE);
} }
break; break;
case 'T': /* Input file is Targa format. */
is_targa = TRUE;
break;
case 'a': /* Use arithmetic coding. */ case 'a': /* Use arithmetic coding. */
#ifdef ARITH_CODING_SUPPORTED #ifdef ARITH_CODING_SUPPORTED
cinfo.arith_code = TRUE; cinfo.arith_code = TRUE;
#else #else
fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
argv[0]); argv[0]);
exit(2); exit(EXIT_FAILURE);
#endif #endif
break; break;
case 'o': /* Enable entropy parm optimization. */ case 'o': /* Enable entropy parm optimization. */
@@ -210,9 +281,22 @@ main (int argc, char **argv)
#else #else
fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n", fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
argv[0]); argv[0]);
exit(2); exit(EXIT_FAILURE);
#endif #endif
break; break;
case 'm': /* Maximum memory in Kb (or Mb with 'm'). */
{ long lval;
char ch = 'x';
if (optarg == NULL)
usage(argv[0]);
if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
usage(argv[0]);
if (ch == 'm' || ch == 'M')
lval *= 1000L;
e_methods.max_memory_to_use = lval * 1000L;
}
break;
case 'd': /* Debugging. */ case 'd': /* Debugging. */
e_methods.trace_level++; e_methods.trace_level++;
break; break;
@@ -222,6 +306,11 @@ main (int argc, char **argv)
break; break;
} }
/* If -d appeared, print version identification */
if (e_methods.trace_level > 0)
fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n",
JVERSION, JCOPYRIGHT);
/* Select the input and output files */ /* Select the input and output files */
#ifdef TWO_FILE_COMMANDLINE #ifdef TWO_FILE_COMMANDLINE
@@ -232,15 +321,18 @@ main (int argc, char **argv)
} }
if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) { if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]); fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
exit(2); exit(EXIT_FAILURE);
} }
if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) { if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]); fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
exit(2); exit(EXIT_FAILURE);
} }
#else /* not TWO_FILE_COMMANDLINE -- use Unix style */ #else /* not TWO_FILE_COMMANDLINE -- use Unix style */
cinfo.input_file = stdin; /* default input file */
cinfo.output_file = stdout; /* always the output file */
if (optind < argc-1) { if (optind < argc-1) {
fprintf(stderr, "%s: only one input file\n", argv[0]); fprintf(stderr, "%s: only one input file\n", argv[0]);
usage(argv[0]); usage(argv[0]);
@@ -248,7 +340,7 @@ main (int argc, char **argv)
if (optind < argc) { if (optind < argc) {
if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) { if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]); fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
exit(2); exit(EXIT_FAILURE);
} }
} }
@@ -260,13 +352,7 @@ main (int argc, char **argv)
/* Do it to it! */ /* Do it to it! */
jpeg_compress(&cinfo); jpeg_compress(&cinfo);
/* Release memory. */
j_free_defaults(&cinfo);
#ifdef MEM_STATS
if (e_methods.trace_level > 0)
j_mem_stats();
#endif
/* All done. */ /* All done. */
exit(0); exit(EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jcmaster.c * jcmaster.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -92,6 +92,10 @@ initial_setup (compress_info_ptr cinfo)
GLOBAL void GLOBAL void
jpeg_compress (compress_info_ptr cinfo) jpeg_compress (compress_info_ptr cinfo)
{ {
/* Init pass counts to 0 --- total_passes is adjusted in method selection */
cinfo->total_passes = 0;
cinfo->completed_passes = 0;
/* Read the input file header: determine image size & component count. /* Read the input file header: determine image size & component count.
* NOTE: the user interface must have initialized the input_init method * NOTE: the user interface must have initialized the input_init method
* pointer (eg, by calling jselrppm) before calling me. * pointer (eg, by calling jselrppm) before calling me.
@@ -123,5 +127,7 @@ jpeg_compress (compress_info_ptr cinfo)
(*cinfo->methods->colorin_term) (cinfo); (*cinfo->methods->colorin_term) (cinfo);
(*cinfo->methods->input_term) (cinfo); (*cinfo->methods->input_term) (cinfo);
(*cinfo->emethods->free_all) ();
/* My, that was easy, wasn't it? */ /* My, that was easy, wasn't it? */
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jcmcu.c * jcmcu.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *

View File

@@ -1,7 +1,7 @@
/* /*
* jconfig.h * jconfig.h
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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,10 +20,23 @@
* predefined by such compilers. * predefined by such compilers.
*/ */
/* Does your compiler support function prototypes? */ /*
/* (If not, you also need to use ansi2knr, see README) */ * HAVE_STDC is tested below to see whether ANSI features are available.
* We avoid testing __STDC__ directly for arcane reasons of portability.
* (On some compilers, __STDC__ is only defined if a switch is given,
* but the switch also disables machine-specific features we need to get at.
* In that case, -DHAVE_STDC in the Makefile is a convenient solution.)
*/
#ifdef __STDC__ /* ANSI C compilers always have prototypes */ #ifdef __STDC__ /* if compiler claims to be ANSI, believe it */
#define HAVE_STDC
#endif
/* Does your compiler support function prototypes? */
/* (If not, you also need to use ansi2knr, see SETUP) */
#ifdef HAVE_STDC /* ANSI C compilers always have prototypes */
#define PROTO #define PROTO
#else #else
#ifdef __cplusplus /* So do C++ compilers */ #ifdef __cplusplus /* So do C++ compilers */
@@ -34,7 +47,7 @@
/* Does your compiler support the declaration "unsigned char" ? */ /* Does your compiler support the declaration "unsigned char" ? */
/* How about "unsigned short" ? */ /* How about "unsigned short" ? */
#ifdef __STDC__ /* ANSI C compilers must support both */ #ifdef HAVE_STDC /* ANSI C compilers must support both */
#define HAVE_UNSIGNED_CHAR #define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT #define HAVE_UNSIGNED_SHORT
#endif #endif
@@ -49,7 +62,6 @@
/* Define this if your compiler implements ">>" on signed values as a logical /* Define this if your compiler implements ">>" on signed values as a logical
* (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift, * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
* which is the normal and rational definition. * which is the normal and rational definition.
* The DCT and IDCT routines will compute wrong values if you get this wrong!
*/ */
/* #define RIGHT_SHIFT_IS_UNSIGNED */ /* #define RIGHT_SHIFT_IS_UNSIGNED */
@@ -64,7 +76,7 @@
/* Define const as empty if your compiler doesn't know the "const" keyword. */ /* Define const as empty if your compiler doesn't know the "const" keyword. */
/* (Even if it does, defining const as empty won't break anything.) */ /* (Even if it does, defining const as empty won't break anything.) */
#ifndef __STDC__ /* ANSI C and C++ compilers should know it. */ #ifndef HAVE_STDC /* ANSI C and C++ compilers should know it. */
#ifndef __cplusplus #ifndef __cplusplus
#define const #define const
#endif #endif
@@ -77,16 +89,12 @@
* "far" pointers and to be allocated with a special version of malloc.) * "far" pointers and to be allocated with a special version of malloc.)
*/ */
#ifdef MSDOS /* Microsoft C and compatibles */ #ifdef MSDOS
#define NEED_FAR_POINTERS #define NEED_FAR_POINTERS
#else
#ifdef __TURBOC__ /* Turbo C doesn't define MSDOS */
#define NEED_FAR_POINTERS
#endif
#endif #endif
/* The next couple of symbols only affect the system-dependent user interface /* The next three symbols only affect the system-dependent user interface
* modules (jcmain.c, jdmain.c). You can ignore these if you are supplying * modules (jcmain.c, jdmain.c). You can ignore these if you are supplying
* your own user interface code. * your own user interface code.
*/ */
@@ -99,15 +107,20 @@
#ifdef MSDOS /* two-file style is needed for PCs */ #ifdef MSDOS /* two-file style is needed for PCs */
#define TWO_FILE_COMMANDLINE #define TWO_FILE_COMMANDLINE
#else
#ifdef __TURBOC__ /* Turbo C doesn't define MSDOS */
#define TWO_FILE_COMMANDLINE
#endif
#endif #endif
#ifdef THINK_C /* needed for Macintosh too */ #ifdef THINK_C /* needed for Macintosh too */
#define TWO_FILE_COMMANDLINE #define TWO_FILE_COMMANDLINE
#endif #endif
/* Define this if your system needs explicit cleanup of temporary files.
* This is crucial under MS-DOS, where the temporary "files" may be areas
* of extended memory; on most other systems it's not as important.
*/
#ifdef MSDOS
#define NEED_SIGNAL_CATCHER
#endif
/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb"). /* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
* This is necessary on systems that distinguish text files from binary files, * This is necessary on systems that distinguish text files from binary files,
* and is harmless on most systems that don't. If you have one of the rare * and is harmless on most systems that don't. If you have one of the rare
@@ -122,16 +135,6 @@
*/ */
/* If your compiler supports inline functions, define INLINE as
* the inline keyword; otherwise define it as empty.
*/
#ifdef __GNUC__ /* GNU C has inline... */
#define INLINE inline
#else /* ...but I don't think anyone else does. */
#define INLINE
#endif
/* On a few systems, type boolean and/or macros FALSE, TRUE may appear /* On a few systems, type boolean and/or macros FALSE, TRUE may appear
* in standard header files. Or you may have conflicts with application- * in standard header files. Or you may have conflicts with application-
* specific header files that you want to include together with these files. * specific header files that you want to include together with these files.
@@ -139,6 +142,8 @@
*/ */
typedef int boolean; typedef int boolean;
#undef FALSE /* in case these macros already exist */
#undef TRUE
#define FALSE 0 /* values of boolean */ #define FALSE 0 /* values of boolean */
#define TRUE 1 #define TRUE 1
@@ -166,13 +171,15 @@ typedef int boolean;
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ #define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing during decoding? */ #define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing during decoding? */
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ #define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
#undef QUANT_2PASS_SUPPORTED /* 2-pass color quantization? (not yet impl.) */ #define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
/* these defines indicate which JPEG file formats are allowed */ /* these defines indicate which JPEG file formats are allowed */
#define JFIF_SUPPORTED /* JFIF or "raw JPEG" files */ #define JFIF_SUPPORTED /* JFIF or "raw JPEG" files */
#undef JTIFF_SUPPORTED /* JPEG-in-TIFF (not yet implemented) */ #undef JTIFF_SUPPORTED /* JPEG-in-TIFF (not yet implemented) */
/* these defines indicate which image (non-JPEG) file formats are allowed */ /* these defines indicate which image (non-JPEG) file formats are allowed */
#define PPM_SUPPORTED /* PPM/PGM image file format */
#define GIF_SUPPORTED /* GIF image file format */ #define GIF_SUPPORTED /* GIF image file format */
/* #define RLE_SUPPORTED */ /* RLE image file format (by default, no) */
#define PPM_SUPPORTED /* PPM/PGM image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#undef TIFF_SUPPORTED /* TIFF image file format (not yet impl.) */ #undef TIFF_SUPPORTED /* TIFF image file format (not yet impl.) */
/* more capability options later, no doubt */ /* more capability options later, no doubt */
@@ -186,6 +193,11 @@ typedef int boolean;
* color value. 16-bit should only be used for the lossless JPEG mode (not * color value. 16-bit should only be used for the lossless JPEG mode (not
* currently supported). Note that 12- and 16-bit values take up twice as * currently supported). Note that 12- and 16-bit values take up twice as
* much memory as 8-bit! * much memory as 8-bit!
* Note: if you select 12- or 16-bit precision, it is dangerous to turn off
* ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
* precision, so jchuff.c normally uses entropy optimization to compute
* usable tables for higher precision. If you don't want to do optimization,
* you'll have to supply different default Huffman tables.
*/ */
#define EIGHT_BIT_SAMPLES #define EIGHT_BIT_SAMPLES
@@ -230,6 +242,7 @@ typedef char JSAMPLE;
#endif /* CHAR_IS_UNSIGNED */ #endif /* CHAR_IS_UNSIGNED */
#endif /* HAVE_UNSIGNED_CHAR */ #endif /* HAVE_UNSIGNED_CHAR */
#define BITS_IN_JSAMPLE 8
#define MAXJSAMPLE 255 #define MAXJSAMPLE 255
#define CENTERJSAMPLE 128 #define CENTERJSAMPLE 128
@@ -243,6 +256,7 @@ typedef char JSAMPLE;
typedef short JSAMPLE; typedef short JSAMPLE;
#define GETJSAMPLE(value) (value) #define GETJSAMPLE(value) (value)
#define BITS_IN_JSAMPLE 12
#define MAXJSAMPLE 4095 #define MAXJSAMPLE 4095
#define CENTERJSAMPLE 2048 #define CENTERJSAMPLE 2048
@@ -268,6 +282,7 @@ typedef unsigned int JSAMPLE;
#endif /* HAVE_UNSIGNED_SHORT */ #endif /* HAVE_UNSIGNED_SHORT */
#define BITS_IN_JSAMPLE 16
#define MAXJSAMPLE 65535 #define MAXJSAMPLE 65535
#define CENTERJSAMPLE 32768 #define CENTERJSAMPLE 32768
@@ -312,9 +327,13 @@ typedef unsigned int UINT16;
/* INT16 must hold at least the values -32768..32767. */ /* INT16 must hold at least the values -32768..32767. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
typedef short INT16; typedef short INT16;
#endif
/* INT32 must hold signed 32-bit values; if your machine happens */ /* INT32 must hold signed 32-bit values; if your machine happens */
/* to have 64-bit longs, you might want to change this. */ /* to have 64-bit longs, you might want to change this. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
typedef long INT32; typedef long INT32;
#endif

View File

@@ -1,7 +1,7 @@
/* /*
* jcpipe.c * jcpipe.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -169,18 +169,17 @@ alloc_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2],
} }
#if 0 /* this routine not currently needed */
LOCAL void LOCAL void
free_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2]) free_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2])
/* Release a sampling buffer created by alloc_sampling_buffer */ /* Release a sampling buffer created by alloc_sampling_buffer */
{ {
short ci, vs; short ci;
vs = cinfo->max_v_samp_factor; /* row group height */
for (ci = 0; ci < cinfo->num_components; ci++) { for (ci = 0; ci < cinfo->num_components; ci++) {
/* Free the real storage */ /* Free the real storage */
(*cinfo->emethods->free_small_sarray) (*cinfo->emethods->free_small_sarray) (fullsize_data[0][ci]);
(fullsize_data[0][ci], (long) (vs * (DCTSIZE+2)));
/* Free the scrambled-order pointers */ /* Free the scrambled-order pointers */
(*cinfo->emethods->free_small) ((void *) fullsize_data[1][ci]); (*cinfo->emethods->free_small) ((void *) fullsize_data[1][ci]);
} }
@@ -190,6 +189,8 @@ free_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2])
(*cinfo->emethods->free_small) ((void *) fullsize_data[1]); (*cinfo->emethods->free_small) ((void *) fullsize_data[1]);
} }
#endif
LOCAL void LOCAL void
subsample (compress_info_ptr cinfo, subsample (compress_info_ptr cinfo,
@@ -248,7 +249,7 @@ subsample (compress_info_ptr cinfo,
* row of whole_scan_MCUs as we can get without exceeding 64KB per row. * row of whole_scan_MCUs as we can get without exceeding 64KB per row.
*/ */
#define MAX_WHOLE_ROW_BLOCKS (65500 / SIZEOF(JBLOCK)) /* max blocks/row */ #define MAX_WHOLE_ROW_BLOCKS ((int) (65500 / SIZEOF(JBLOCK))) /* max blocks/row */
static big_barray_ptr whole_scan_MCUs; /* Big array for saving the MCUs */ static big_barray_ptr whole_scan_MCUs; /* Big array for saving the MCUs */
static int MCUs_in_big_row; /* # of MCUs in each row of whole_scan_MCUs */ static int MCUs_in_big_row; /* # of MCUs in each row of whole_scan_MCUs */
@@ -302,6 +303,8 @@ dump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
next_index = MCUs_in_big_row; next_index = MCUs_in_big_row;
for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) { for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) {
(*cinfo->methods->progress_monitor) (cinfo, mcurow,
cinfo->MCU_rows_in_scan);
for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) { for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
if (next_index >= MCUs_in_big_row) { if (next_index >= MCUs_in_big_row) {
rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs, rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
@@ -311,7 +314,7 @@ dump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
} }
#ifdef NEED_FAR_POINTERS #ifdef NEED_FAR_POINTERS
jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU, jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU,
(JBLOCKROW) MCU_data, /* note cast */ (JBLOCKROW) MCU_data, /* casts near to far pointer! */
(long) cinfo->blocks_in_MCU); (long) cinfo->blocks_in_MCU);
(*output_method) (cinfo, MCU_data); (*output_method) (cinfo, MCU_data);
#else #else
@@ -320,6 +323,8 @@ dump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
next_index++; next_index++;
} }
} }
cinfo->completed_passes++;
} }
@@ -360,6 +365,7 @@ single_ccontroller (compress_info_ptr cinfo)
/* in an interleaved scan, one MCU row contains Vk block rows */ /* in an interleaved scan, one MCU row contains Vk block rows */
mcu_rows_per_loop = 1; mcu_rows_per_loop = 1;
} }
cinfo->total_passes++;
/* Compute dimensions of full-size pixel buffers */ /* Compute dimensions of full-size pixel buffers */
/* Note these are the same whether interleaved or not. */ /* Note these are the same whether interleaved or not. */
@@ -403,11 +409,15 @@ single_ccontroller (compress_info_ptr cinfo)
for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height; for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
cur_pixel_row += rows_in_mem) { cur_pixel_row += rows_in_mem) {
(*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
cinfo->image_height);
whichss ^= 1; /* switch to other fullsize_data buffer */ whichss ^= 1; /* switch to other fullsize_data buffer */
/* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */ /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
/* Then we have exactly DCTSIZE row groups for subsampling. */ /* Then we have exactly DCTSIZE row groups for subsampling. */
rows_this_time = MIN(rows_in_mem, cinfo->image_height - cur_pixel_row); rows_this_time = (int) MIN((long) rows_in_mem,
cinfo->image_height - cur_pixel_row);
(*cinfo->methods->get_sample_rows) (cinfo, rows_this_time, (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
fullsize_data[whichss]); fullsize_data[whichss]);
@@ -462,15 +472,10 @@ single_ccontroller (compress_info_ptr cinfo)
(*cinfo->methods->subsample_term) (cinfo); (*cinfo->methods->subsample_term) (cinfo);
(*cinfo->methods->entropy_encoder_term) (cinfo); (*cinfo->methods->entropy_encoder_term) (cinfo);
(*cinfo->methods->write_scan_trailer) (cinfo); (*cinfo->methods->write_scan_trailer) (cinfo);
cinfo->completed_passes++;
/* Release working memory */ /* Release working memory */
free_sampling_buffer(cinfo, fullsize_data); /* (no work -- we let free_all release what's needful) */
for (ci = 0; ci < cinfo->num_components; ci++) {
(*cinfo->emethods->free_small_sarray)
(subsampled_data[ci],
(long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
}
(*cinfo->emethods->free_small) ((void *) subsampled_data);
} }
@@ -513,6 +518,7 @@ single_eopt_ccontroller (compress_info_ptr cinfo)
/* in an interleaved scan, one MCU row contains Vk block rows */ /* in an interleaved scan, one MCU row contains Vk block rows */
mcu_rows_per_loop = 1; mcu_rows_per_loop = 1;
} }
cinfo->total_passes += 2; /* entropy encoder must add # passes it uses */
/* Compute dimensions of full-size pixel buffers */ /* Compute dimensions of full-size pixel buffers */
/* Note these are the same whether interleaved or not. */ /* Note these are the same whether interleaved or not. */
@@ -565,11 +571,15 @@ single_eopt_ccontroller (compress_info_ptr cinfo)
for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height; for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
cur_pixel_row += rows_in_mem) { cur_pixel_row += rows_in_mem) {
(*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
cinfo->image_height);
whichss ^= 1; /* switch to other fullsize_data buffer */ whichss ^= 1; /* switch to other fullsize_data buffer */
/* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */ /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
/* Then we have exactly DCTSIZE row groups for subsampling. */ /* Then we have exactly DCTSIZE row groups for subsampling. */
rows_this_time = MIN(rows_in_mem, cinfo->image_height - cur_pixel_row); rows_this_time = (int) MIN((long) rows_in_mem,
cinfo->image_height - cur_pixel_row);
(*cinfo->methods->get_sample_rows) (cinfo, rows_this_time, (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
fullsize_data[whichss]); fullsize_data[whichss]);
@@ -624,6 +634,8 @@ single_eopt_ccontroller (compress_info_ptr cinfo)
(*cinfo->methods->extract_term) (cinfo); (*cinfo->methods->extract_term) (cinfo);
(*cinfo->methods->subsample_term) (cinfo); (*cinfo->methods->subsample_term) (cinfo);
cinfo->completed_passes++;
(*cinfo->methods->entropy_optimize) (cinfo, dump_scan_MCUs); (*cinfo->methods->entropy_optimize) (cinfo, dump_scan_MCUs);
/* Emit scan to output file */ /* Emit scan to output file */
@@ -637,14 +649,7 @@ single_eopt_ccontroller (compress_info_ptr cinfo)
(*cinfo->methods->write_scan_trailer) (cinfo); (*cinfo->methods->write_scan_trailer) (cinfo);
/* Release working memory */ /* Release working memory */
free_sampling_buffer(cinfo, fullsize_data); /* (no work -- we let free_all release what's needful) */
for (ci = 0; ci < cinfo->num_components; ci++) {
(*cinfo->emethods->free_small_sarray)
(subsampled_data[ci],
(long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
}
(*cinfo->emethods->free_small) ((void *) subsampled_data);
(*cinfo->emethods->free_big_barray) (whole_scan_MCUs);
} }
#endif /* ENTROPY_OPT_SUPPORTED */ #endif /* ENTROPY_OPT_SUPPORTED */

View File

@@ -1,7 +1,7 @@
/* /*
* jcsample.c * jcsample.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -63,10 +63,10 @@ subsample (compress_info_ptr cinfo, int which_component,
for (v = 0; v < v_expand; v++) { for (v = 0; v < v_expand; v++) {
inptr = input_data[inrow+v] + (outcol*h_expand); inptr = input_data[inrow+v] + (outcol*h_expand);
for (h = 0; h < h_expand; h++) { for (h = 0; h < h_expand; h++) {
outvalue += GETJSAMPLE(*inptr++); outvalue += (INT32) GETJSAMPLE(*inptr++);
} }
} }
*outptr++ = (outvalue + numpix2) / numpix; *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
} }
inrow += v_expand; inrow += v_expand;
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jdarith.c * jdarith.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *

198
jdcolor.c
View File

@@ -1,7 +1,7 @@
/* /*
* jdcolor.c * jdcolor.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -13,34 +13,107 @@
#include "jinclude.h" #include "jinclude.h"
/**************** YCbCr -> RGB conversion: most common case **************/
/*
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
* The conversion equations to be implemented are therefore
* R = Y + 1.40200 * Cr
* G = Y - 0.34414 * Cb - 0.71414 * Cr
* B = Y + 1.77200 * Cb
* where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
* (These numbers are derived from TIFF Appendix O, draft of 4/10/91.)
*
* To avoid floating-point arithmetic, we represent the fractional constants
* as integers scaled up by 2^14 (about 4 digits precision); we have to divide
* the products by 2^14, with appropriate rounding, to get the correct answer.
* Notice that Y, being an integral input, does not contribute any fraction
* so it need not participate in the rounding.
*
* For even more speed, we avoid doing any multiplications in the inner loop
* by precalculating the constants times Cb and Cr for all possible values.
* For 8-bit JSAMPLEs this is very reasonable (only 256 table entries); 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
* colorspace anyway.
* The Cr=>R and Cb=>B values can be rounded to integers in advance; the
* values for the G calculation are left scaled up, since we must add them
* together before rounding.
*/
#define SCALEBITS 14
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
static INT16 * Cr_r_tab; /* => table for Cr to R conversion */
static INT16 * Cb_b_tab; /* => table for Cb to B conversion */
static INT32 * Cr_g_tab; /* => table for Cr to G conversion */
static INT32 * Cb_g_tab; /* => table for Cb to G conversion */
/* /*
* Initialize for colorspace conversion. * Initialize for colorspace conversion.
*/ */
METHODDEF void METHODDEF void
colorout_init (decompress_info_ptr cinfo) ycc_rgb_init (decompress_info_ptr cinfo)
{ {
/* no work needed */ #ifdef SIXTEEN_BIT_SAMPLES
INT32 i, x2;
#else
int i, x2; /* smart compiler may do 16x16=>32 multiply */
#endif
SHIFT_TEMPS
Cr_r_tab = (INT16 *) (*cinfo->emethods->alloc_small)
((MAXJSAMPLE+1) * SIZEOF(INT16));
Cb_b_tab = (INT16 *) (*cinfo->emethods->alloc_small)
((MAXJSAMPLE+1) * SIZEOF(INT16));
Cr_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
((MAXJSAMPLE+1) * SIZEOF(INT32));
Cb_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
((MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0; i <= MAXJSAMPLE; i++) {
/* 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 */
x2 = 2*i - MAXJSAMPLE; /* twice x */
/* Cr=>R value is nearest int to 1.40200 * x */
Cr_r_tab[i] = (INT16)
RIGHT_SHIFT(FIX(1.40200/2) * x2 + ONE_HALF, SCALEBITS);
/* Cb=>B value is nearest int to 1.77200 * x */
Cb_b_tab[i] = (INT16)
RIGHT_SHIFT(FIX(1.77200/2) * x2 + ONE_HALF, SCALEBITS);
/* Cr=>G value is scaled-up -0.71414 * x */
Cr_g_tab[i] = (- FIX(0.71414/2)) * x2;
/* Cb=>G value is scaled-up -0.34414 * x */
/* We also add in ONE_HALF so that need not do it in inner loop */
Cb_g_tab[i] = (- FIX(0.34414/2)) * x2 + ONE_HALF;
}
} }
/* /*
* Convert some rows of samples to the output colorspace. * Convert some rows of samples to the output colorspace.
* This version handles YCbCr -> RGB conversion.
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
*/ */
METHODDEF void METHODDEF void
ycc_rgb_convert (decompress_info_ptr cinfo, int num_rows, ycc_rgb_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
JSAMPIMAGE input_data, JSAMPIMAGE output_data) JSAMPIMAGE input_data, JSAMPIMAGE output_data)
{ {
register INT32 y, u, v, x; #ifdef SIXTEEN_BIT_SAMPLES
register UINT16 y, cb, cr;
register INT32 x;
#else
register int y, cb, cr;
register int x;
#endif
register JSAMPROW inptr0, inptr1, inptr2; register JSAMPROW inptr0, inptr1, inptr2;
register JSAMPROW outptr0, outptr1, outptr2; register JSAMPROW outptr0, outptr1, outptr2;
register long col; long col;
register long width = cinfo->image_width; int row;
register int row; SHIFT_TEMPS
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
inptr0 = input_data[0][row]; inptr0 = input_data[0][row];
@@ -49,45 +122,70 @@ ycc_rgb_convert (decompress_info_ptr cinfo, int num_rows,
outptr0 = output_data[0][row]; outptr0 = output_data[0][row];
outptr1 = output_data[1][row]; outptr1 = output_data[1][row];
outptr2 = output_data[2][row]; outptr2 = output_data[2][row];
for (col = width; col > 0; col--) { for (col = num_cols; col > 0; col--) {
y = GETJSAMPLE(*inptr0++); y = GETJSAMPLE(*inptr0++);
u = (int) GETJSAMPLE(*inptr1++) - CENTERJSAMPLE; cb = GETJSAMPLE(*inptr1++);
v = (int) GETJSAMPLE(*inptr2++) - CENTERJSAMPLE; cr = GETJSAMPLE(*inptr2++);
/* Note: if the inputs were computed directly from RGB values, /* Note: if the inputs were computed directly from RGB values,
* range-limiting would be unnecessary here; but due to possible * range-limiting would be unnecessary here; but due to possible
* noise in the DCT/IDCT phase, we do need to apply range limits. * noise in the DCT/IDCT phase, we do need to apply range limits.
*/ */
y *= 1024; /* in case compiler can't spot common subexpression */ x = y + Cr_r_tab[cr]; /* red */
x = y + 1436*v + 512; /* red */
if (x < 0) x = 0; if (x < 0) x = 0;
if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024; else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
*outptr0++ = x >> 10; *outptr0++ = (JSAMPLE) x;
x = y - 352*u - 731*v + 512; /* green */ x = y + ((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS));
if (x < 0) x = 0; if (x < 0) x = 0;
if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024; else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
*outptr1++ = x >> 10; *outptr1++ = (JSAMPLE) x;
x = y + 1815*u + 512; /* blue */ x = y + Cb_b_tab[cb]; /* blue */
if (x < 0) x = 0; if (x < 0) x = 0;
if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024; else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
*outptr2++ = x >> 10; *outptr2++ = (JSAMPLE) x;
} }
} }
} }
/*
* Finish up at the end of the file.
*/
METHODDEF void
ycc_rgb_term (decompress_info_ptr cinfo)
{
/* no work (we let free_all release the workspace) */
}
/**************** Cases other than YCbCr -> RGB **************/
/*
* Initialize for colorspace conversion.
*/
METHODDEF void
null_init (decompress_info_ptr cinfo)
/* colorout_init for cases where no setup is needed */
{
/* no work needed */
}
/* /*
* Color conversion for no colorspace change: just copy the data. * Color conversion for no colorspace change: just copy the data.
*/ */
METHODDEF void METHODDEF void
null_convert (decompress_info_ptr cinfo, int num_rows, null_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
JSAMPIMAGE input_data, JSAMPIMAGE output_data) JSAMPIMAGE input_data, JSAMPIMAGE output_data)
{ {
short ci; short ci;
for (ci = 0; ci < cinfo->num_components; ci++) { for (ci = 0; ci < cinfo->num_components; ci++) {
jcopy_sample_rows(input_data[ci], 0, output_data[ci], 0, jcopy_sample_rows(input_data[ci], 0, output_data[ci], 0,
num_rows, cinfo->image_width); num_rows, num_cols);
} }
} }
@@ -99,11 +197,11 @@ null_convert (decompress_info_ptr cinfo, int num_rows,
*/ */
METHODDEF void METHODDEF void
grayscale_convert (decompress_info_ptr cinfo, int num_rows, grayscale_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
JSAMPIMAGE input_data, JSAMPIMAGE output_data) JSAMPIMAGE input_data, JSAMPIMAGE output_data)
{ {
jcopy_sample_rows(input_data[0], 0, output_data[0], 0, jcopy_sample_rows(input_data[0], 0, output_data[0], 0,
num_rows, cinfo->image_width); num_rows, num_cols);
} }
@@ -112,12 +210,14 @@ grayscale_convert (decompress_info_ptr cinfo, int num_rows,
*/ */
METHODDEF void METHODDEF void
colorout_term (decompress_info_ptr cinfo) null_term (decompress_info_ptr cinfo)
/* colorout_term for cases where no teardown is needed */
{ {
/* no work needed */ /* no work needed */
} }
/* /*
* The method selection routine for output colorspace conversion. * The method selection routine for output colorspace conversion.
*/ */
@@ -133,8 +233,8 @@ jseldcolor (decompress_info_ptr cinfo)
break; break;
case CS_RGB: case CS_RGB:
case CS_YIQ:
case CS_YCbCr: case CS_YCbCr:
case CS_YIQ:
if (cinfo->num_components != 3) if (cinfo->num_components != 3)
ERREXIT(cinfo->emethods, "Bogus JPEG colorspace"); ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
break; break;
@@ -155,32 +255,37 @@ jseldcolor (decompress_info_ptr cinfo)
cinfo->color_out_comps = 1; cinfo->color_out_comps = 1;
if (cinfo->jpeg_color_space == CS_GRAYSCALE || if (cinfo->jpeg_color_space == CS_GRAYSCALE ||
cinfo->jpeg_color_space == CS_YCbCr || cinfo->jpeg_color_space == CS_YCbCr ||
cinfo->jpeg_color_space == CS_YIQ) cinfo->jpeg_color_space == CS_YIQ) {
cinfo->methods->color_convert = grayscale_convert; cinfo->methods->color_convert = grayscale_convert;
else cinfo->methods->colorout_init = null_init;
cinfo->methods->colorout_term = null_term;
} else
ERREXIT(cinfo->emethods, "Unsupported color conversion request"); ERREXIT(cinfo->emethods, "Unsupported color conversion request");
break; break;
case CS_RGB: case CS_RGB:
cinfo->color_out_comps = 3; cinfo->color_out_comps = 3;
if (cinfo->jpeg_color_space == CS_YCbCr) if (cinfo->jpeg_color_space == CS_YCbCr) {
cinfo->methods->color_convert = ycc_rgb_convert; cinfo->methods->color_convert = ycc_rgb_convert;
else if (cinfo->jpeg_color_space == CS_RGB) cinfo->methods->colorout_init = ycc_rgb_init;
cinfo->methods->colorout_term = ycc_rgb_term;
} else if (cinfo->jpeg_color_space == CS_RGB) {
cinfo->methods->color_convert = null_convert; cinfo->methods->color_convert = null_convert;
else cinfo->methods->colorout_init = null_init;
ERREXIT(cinfo->emethods, "Unsupported color conversion request"); cinfo->methods->colorout_term = null_term;
break; } else
case CS_CMYK:
cinfo->color_out_comps = 4;
if (cinfo->jpeg_color_space == CS_CMYK)
cinfo->methods->color_convert = null_convert;
else
ERREXIT(cinfo->emethods, "Unsupported color conversion request"); ERREXIT(cinfo->emethods, "Unsupported color conversion request");
break; break;
default: default:
ERREXIT(cinfo->emethods, "Unsupported output colorspace"); /* Permit null conversion from CMYK or YCbCr to same output space */
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
cinfo->color_out_comps = cinfo->num_components;
cinfo->methods->color_convert = null_convert;
cinfo->methods->colorout_init = null_init;
cinfo->methods->colorout_term = null_term;
} else /* unsupported non-null conversion */
ERREXIT(cinfo->emethods, "Unsupported color conversion request");
break; break;
} }
@@ -188,7 +293,4 @@ jseldcolor (decompress_info_ptr cinfo)
cinfo->final_out_comps = 1; /* single colormapped output component */ cinfo->final_out_comps = 1; /* single colormapped output component */
else else
cinfo->final_out_comps = cinfo->color_out_comps; cinfo->final_out_comps = cinfo->color_out_comps;
cinfo->methods->colorout_init = colorout_init;
cinfo->methods->colorout_term = colorout_term;
} }

154
jddeflts.c Normal file
View File

@@ -0,0 +1,154 @@
/*
* jddeflts.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains optional default-setting code for the JPEG decompressor.
* User interfaces do not have to use this file, but those that don't use it
* must know more about the innards of the JPEG code.
*/
#include "jinclude.h"
/* Default do-nothing progress monitoring routine.
* This can be overridden by a user interface that wishes to
* provide progress monitoring; just set methods->progress_monitor
* after j_d_defaults is done. The routine will be called periodically
* during the decompression process.
*
* During any one pass, loopcounter increases from 0 up to (not including)
* looplimit; the step size is not necessarily 1. Both the step size and
* the limit may differ between passes. The expected total number of passes
* is in cinfo->total_passes, and the number of passes already completed is
* in cinfo->completed_passes. Thus the fraction of work completed may be
* estimated as
* completed_passes + (loopcounter/looplimit)
* ------------------------------------------
* total_passes
* ignoring the fact that the passes may not be equal amounts of work.
*
* When decompressing, the total_passes figure is an estimate that may be
* on the high side; completed_passes will jump by more than one if some
* passes are skipped.
*/
METHODDEF void
progress_monitor (decompress_info_ptr cinfo, long loopcounter, long looplimit)
{
/* do nothing */
}
/*
* Reload the input buffer after it's been emptied, and return the next byte.
* See the JGETC macro for calling conditions.
*
* This routine can be overridden by the system-dependent user interface,
* in case the data source is not a stdio stream or some other special
* condition applies. Note, however, that this capability only applies for
* JFIF or similar serial-access JPEG file formats. The input file control
* module for a random-access format such as TIFF/JPEG would most likely
* override the read_jpeg_data method with its own routine.
*/
METHODDEF int
read_jpeg_data (decompress_info_ptr cinfo)
{
cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
cinfo->next_input_byte,
JPEG_BUF_SIZE);
if (cinfo->bytes_in_buffer <= 0)
ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
return JGETC(cinfo);
}
/* Default parameter setup for decompression.
*
* User interfaces that don't choose to use this routine must do their
* own setup of all these parameters. Alternately, you can call this
* to establish defaults and then alter parameters selectively. This
* is the recommended approach since, if we add any new parameters,
* your code will still work (they'll be set to reasonable defaults).
*
* standard_buffering should be TRUE to cause an input buffer to be allocated
* (the normal case); if FALSE, the user interface must provide a buffer.
* This option is most useful in the case that the buffer must not be freed
* at the end of an image. (For example, when reading a sequence of images
* from a single file, the remaining data in the buffer represents the
* start of the next image and mustn't be discarded.) To handle this,
* allocate the input buffer yourself at startup, WITHOUT using alloc_small
* (probably a direct call to malloc() instead). Then pass FALSE on each
* call to j_d_defaults to ensure the buffer state is not modified.
*
* If the source of the JPEG data is not a stdio stream, override the
* read_jpeg_data method with your own routine after calling j_d_defaults.
* You can still use the standard buffer if it's appropriate.
*
* CAUTION: if you want to decompress multiple images per run, it's necessary
* to call j_d_defaults before *each* call to jpeg_decompress, since subsidiary
* structures like the quantization tables are automatically freed during
* cleanup.
*/
GLOBAL void
j_d_defaults (decompress_info_ptr cinfo, boolean standard_buffering)
/* NB: the external methods must already be set up. */
{
short i;
/* Initialize pointers as needed to mark stuff unallocated. */
/* Outer application may fill in default tables for abbreviated files... */
cinfo->comp_info = NULL;
for (i = 0; i < NUM_QUANT_TBLS; i++)
cinfo->quant_tbl_ptrs[i] = NULL;
for (i = 0; i < NUM_HUFF_TBLS; i++) {
cinfo->dc_huff_tbl_ptrs[i] = NULL;
cinfo->ac_huff_tbl_ptrs[i] = NULL;
}
cinfo->colormap = NULL;
/* Default to RGB output */
/* UI can override by changing out_color_space */
cinfo->out_color_space = CS_RGB;
cinfo->jpeg_color_space = CS_UNKNOWN;
/* Setting any other value in jpeg_color_space overrides heuristics in */
/* jrdjfif.c. That might be useful when reading non-JFIF JPEG files, */
/* but ordinarily the UI shouldn't change it. */
/* Default to no gamma correction of output */
cinfo->output_gamma = 1.0;
/* Default to no color quantization */
cinfo->quantize_colors = FALSE;
/* but set reasonable default parameters for quantization, */
/* so that turning on quantize_colors is sufficient to do something useful */
cinfo->two_pass_quantize = TRUE;
cinfo->use_dithering = TRUE;
cinfo->desired_number_of_colors = 256;
/* Default to no smoothing */
cinfo->do_block_smoothing = FALSE;
cinfo->do_pixel_smoothing = FALSE;
/* Allocate memory for input buffer, unless outer application provides it. */
if (standard_buffering) {
cinfo->input_buffer = (char *) (*cinfo->emethods->alloc_small)
((size_t) (JPEG_BUF_SIZE + MIN_UNGET));
cinfo->bytes_in_buffer = 0; /* initialize buffer to empty */
}
/* Install standard buffer-reloading method (outer code may override). */
cinfo->methods->read_jpeg_data = read_jpeg_data;
/* Install default do-nothing progress monitoring method. */
cinfo->methods->progress_monitor = progress_monitor;
}

View File

@@ -1,7 +1,7 @@
/* /*
* jdhuff.c * jdhuff.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -17,7 +17,7 @@
static decompress_info_ptr dcinfo; static decompress_info_ptr dcinfo;
static unsigned int get_buffer; /* current bit-extraction buffer */ static INT32 get_buffer; /* current bit-extraction buffer */
static int bits_left; /* # of unused bits in it */ static int bits_left; /* # of unused bits in it */
@@ -25,46 +25,40 @@ LOCAL void
fix_huff_tbl (HUFF_TBL * htbl) fix_huff_tbl (HUFF_TBL * htbl)
/* Compute derived values for a Huffman table */ /* Compute derived values for a Huffman table */
{ {
int p, i, l, lastp, si; int p, i, l, si;
char huffsize[257]; char huffsize[257];
UINT16 huffcode[257]; UINT16 huffcode[257];
UINT16 code; UINT16 code;
/* Figure 7.3.5.4.2.1: make table of Huffman code length for each symbol */ /* Figure C.1: make table of Huffman code length for each symbol */
/* Note that this is in code-length order. */ /* Note that this is in code-length order. */
p = 0; p = 0;
for (l = 1; l <= 16; l++) { for (l = 1; l <= 16; l++) {
for (i = 1; i <= htbl->bits[l]; i++) for (i = 1; i <= (int) htbl->bits[l]; i++)
huffsize[p++] = l; huffsize[p++] = (char) l;
} }
huffsize[p] = 0; huffsize[p] = 0;
lastp = p;
/* Figure 7.3.5.4.2.2: generate the codes themselves */ /* Figure C.2: generate the codes themselves */
/* Note that this is in code-length order. */ /* Note that this is in code-length order. */
code = 0; code = 0;
si = huffsize[0]; si = huffsize[0];
p = 0; p = 0;
while (huffsize[p]) { while (huffsize[p]) {
while (huffsize[p] == si) { while (((int) huffsize[p]) == si) {
huffcode[p++] = code; huffcode[p++] = code;
code++; code++;
} }
code <<= 1; code <<= 1;
si++; si++;
} }
/* Figure 7.3.5.4.2.3: generate encoding tables */
/* These are code and size indexed by symbol value */
for (p = 0; p < lastp; p++) { /* We don't bother to fill in the encoding tables ehufco[] and ehufsi[], */
htbl->ehufco[htbl->huffval[p]] = huffcode[p]; /* since they are not used for decoding. */
htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
} /* Figure F.15: generate decoding tables */
/* Figure 13.4.2.3.1: generate decoding tables */
p = 0; p = 0;
for (l = 1; l <= 16; l++) { for (l = 1; l <= 16; l++) {
@@ -77,10 +71,11 @@ fix_huff_tbl (HUFF_TBL * htbl)
htbl->maxcode[l] = -1; htbl->maxcode[l] = -1;
} }
} }
htbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
} }
/* Extract the next N bits from the input stream (N <= 8) */ /* Extract the next N bits from the input stream (N <= 15) */
LOCAL int LOCAL int
get_bits (int nbits) get_bits (int nbits)
@@ -90,7 +85,8 @@ get_bits (int nbits)
while (nbits > bits_left) { while (nbits > bits_left) {
int c = JGETC(dcinfo); int c = JGETC(dcinfo);
get_buffer = (get_buffer << 8) + c; get_buffer <<= 8;
get_buffer |= c;
bits_left += 8; bits_left += 8;
/* If it's 0xFF, check and discard stuffed zero byte */ /* If it's 0xFF, check and discard stuffed zero byte */
if (c == 0xff) { if (c == 0xff) {
@@ -102,18 +98,18 @@ get_bits (int nbits)
} }
bits_left -= nbits; bits_left -= nbits;
result = (get_buffer >> bits_left) & ((1 << nbits) - 1); result = ((int) (get_buffer >> bits_left)) & ((1 << nbits) - 1);
return result; return result;
} }
/* Macro to make things go at some speed! */ /* Macro to make things go at some speed! */
#define get_bit() (bits_left ? \ #define get_bit() (bits_left ? \
((get_buffer >> (--bits_left)) & 1) : \ ((int) (get_buffer >> (--bits_left))) & 1 : \
get_bits(1)) get_bits(1))
/* Figure 13.4.2.3.2: extract next coded symbol from input stream */ /* Figure F.16: extract next coded symbol from input stream */
LOCAL int LOCAL int
huff_DECODE (HUFF_TBL * htbl) huff_DECODE (HUFF_TBL * htbl)
@@ -127,14 +123,22 @@ huff_DECODE (HUFF_TBL * htbl)
code = (code << 1) + get_bit(); code = (code << 1) + get_bit();
l++; l++;
} }
/* With garbage input we may reach the sentinel value l = 17. */
if (l > 16) {
ERREXIT(dcinfo->emethods, "Corrupted data in JPEG file");
}
p = (int) (htbl->valptr[l] + (code - htbl->mincode[l]));
p = htbl->valptr[l] + (code - htbl->mincode[l]); return (int) htbl->huffval[p];
return htbl->huffval[p];
} }
/* Figure 13.4.2.1.1: extend sign bit */ /* Figure F.12: extend sign bit */
/* NB: on some compilers this will only work for s > 0 */
#define huff_EXTEND(x, s) ((x) < (1 << ((s)-1)) ? \ #define huff_EXTEND(x, s) ((x) < (1 << ((s)-1)) ? \
(x) + (-1 << (s)) + 1 : \ (x) + (-1 << (s)) + 1 : \
@@ -153,13 +157,16 @@ decode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
MEMZERO((void *) block, SIZEOF(JBLOCK)); MEMZERO((void *) block, SIZEOF(JBLOCK));
/* Section 13.4.2.1: decode the DC coefficient difference */ /* Section F.2.2.1: decode the DC coefficient difference */
s = huff_DECODE(dctbl); s = huff_DECODE(dctbl);
r = get_bits(s); if (s) {
block[0] = huff_EXTEND(r, s); r = get_bits(s);
s = huff_EXTEND(r, s);
/* Section 13.4.2.2: decode the AC coefficients */ }
block[0] = s;
/* Section F.2.2.2: decode the AC coefficients */
for (k = 1; k < DCTSIZE2; k++) { for (k = 1; k < DCTSIZE2; k++) {
r = huff_DECODE(actbl); r = huff_DECODE(actbl);
@@ -168,7 +175,7 @@ decode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
n = r >> 4; n = r >> 4;
if (s) { if (s) {
k = k + n; k += n;
r = get_bits(s); r = get_bits(s);
block[k] = huff_EXTEND(r, s); block[k] = huff_EXTEND(r, s);
} else { } else {

212
jdmain.c
View File

@@ -1,7 +1,7 @@
/* /*
* jdmain.c * jdmain.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -21,9 +21,12 @@
*/ */
#include "jinclude.h" #include "jinclude.h"
#ifdef __STDC__ #ifdef INCLUDES_ARE_ANSI
#include <stdlib.h> /* to declare exit() */ #include <stdlib.h> /* to declare exit() */
#endif #endif
#ifdef NEED_SIGNAL_CATCHER
#include <signal.h> /* to declare signal() */
#endif
#ifdef THINK_C #ifdef THINK_C
#include <console.h> /* command-line reader for Macintosh */ #include <console.h> /* command-line reader for Macintosh */
@@ -37,28 +40,47 @@
#define WRITE_BINARY "wb" #define WRITE_BINARY "wb"
#endif #endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
/* #define EXIT_FAILURE 1
* If your system has getopt(3), you can use your library version by #endif
* defining HAVE_GETOPT. By default, we use the PD 'egetopt'. #ifndef EXIT_SUCCESS
*/ #ifdef VMS
#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
#ifdef HAVE_GETOPT
extern int getopt PP((int argc, char **argv, char *optstring));
extern char * optarg;
extern int optind;
#else #else
#include "egetopt.c" #define EXIT_SUCCESS 0
#define getopt(argc,argv,opt) egetopt(argc,argv,opt) #endif
#endif #endif
typedef enum { /* defines known output image formats */ #include "jversion.h" /* for version message */
FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
/*
* PD version of getopt(3).
*/
#include "egetopt.c"
/*
* This list defines the known output image formats
* (not all of which need be supported by a given version).
* You can change the default output format by defining DEFAULT_FMT;
* indeed, you had better do so if you undefine PPM_SUPPORTED.
*/
typedef enum {
FMT_GIF, /* GIF format */ FMT_GIF, /* GIF format */
FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
FMT_RLE, /* RLE format */
FMT_TARGA, /* Targa format */
FMT_TIFF /* TIFF format */ FMT_TIFF /* TIFF format */
} IMAGE_FORMATS; } IMAGE_FORMATS;
#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */
#define DEFAULT_FMT FMT_PPM
#endif
static IMAGE_FORMATS requested_fmt; static IMAGE_FORMATS requested_fmt;
@@ -92,6 +114,16 @@ d_ui_method_selection (decompress_info_ptr cinfo)
case FMT_PPM: case FMT_PPM:
jselwppm(cinfo); jselwppm(cinfo);
break; break;
#endif
#ifdef RLE_SUPPORTED
case FMT_RLE:
jselwrle(cinfo);
break;
#endif
#ifdef TARGA_SUPPORTED
case FMT_TARGA:
jselwtarga(cinfo);
break;
#endif #endif
default: default:
ERREXIT(cinfo->emethods, "Unsupported output file format"); ERREXIT(cinfo->emethods, "Unsupported output file format");
@@ -101,28 +133,24 @@ d_ui_method_selection (decompress_info_ptr cinfo)
/* /*
* Reload the input buffer after it's been emptied, and return the next byte. * Signal catcher to ensure that temporary files are removed before aborting.
* See the JGETC macro for calling conditions. * NB: for Amiga Manx C this is actually a global routine named _abort();
* * see -Dsignal_catcher=_abort in CFLAGS. Talk about bogus...
* This routine would need to be replaced if reading JPEG data from something
* other than a stdio stream.
*/ */
METHODDEF int #ifdef NEED_SIGNAL_CATCHER
read_jpeg_data (decompress_info_ptr cinfo)
{
cinfo->bytes_in_buffer = fread(cinfo->input_buffer + MIN_UNGET,
1, JPEG_BUF_SIZE,
cinfo->input_file);
cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
if (cinfo->bytes_in_buffer <= 0)
ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
return JGETC(cinfo); static external_methods_ptr emethods; /* for access to free_all */
GLOBAL void
signal_catcher (int signum)
{
emethods->trace_level = 0; /* turn off trace output */
(*emethods->free_all) (); /* clean up memory allocation & temp files */
exit(EXIT_FAILURE);
} }
#endif
LOCAL void LOCAL void
@@ -130,13 +158,13 @@ usage (char * progname)
/* complain about bad command line */ /* complain about bad command line */
{ {
fprintf(stderr, "usage: %s ", progname); fprintf(stderr, "usage: %s ", progname);
fprintf(stderr, "[-b] [-q colors] [-2] [-d] [-g] [-G]"); fprintf(stderr, "[-G] [-P] [-R] [-T] [-b] [-g] [-q colors] [-1] [-D] [-d] [-m mem]");
#ifdef TWO_FILE_COMMANDLINE #ifdef TWO_FILE_COMMANDLINE
fprintf(stderr, " inputfile outputfile\n"); fprintf(stderr, " inputfile outputfile\n");
#else #else
fprintf(stderr, " [inputfile]\n"); fprintf(stderr, " [inputfile]\n");
#endif #endif
exit(2); exit(EXIT_FAILURE);
} }
@@ -144,7 +172,7 @@ usage (char * progname)
* The main program. * The main program.
*/ */
GLOBAL void GLOBAL int
main (int argc, char **argv) main (int argc, char **argv)
{ {
struct decompress_info_struct cinfo; struct decompress_info_struct cinfo;
@@ -161,47 +189,44 @@ main (int argc, char **argv)
cinfo.methods = &dc_methods; cinfo.methods = &dc_methods;
cinfo.emethods = &e_methods; cinfo.emethods = &e_methods;
jselerror(&e_methods); /* error/trace message routines */ jselerror(&e_methods); /* error/trace message routines */
jselvirtmem(&e_methods); /* memory allocation routines */ jselmemmgr(&e_methods); /* memory allocation routines */
dc_methods.d_ui_method_selection = d_ui_method_selection; dc_methods.d_ui_method_selection = d_ui_method_selection;
dc_methods.read_jpeg_data = read_jpeg_data;
/* Allocate memory for input buffer. */ /* Now OK to enable signal catcher. */
cinfo.input_buffer = (char *) (*cinfo.emethods->alloc_small) #ifdef NEED_SIGNAL_CATCHER
((size_t) (JPEG_BUF_SIZE + MIN_UNGET)); emethods = &e_methods;
cinfo.bytes_in_buffer = 0; /* initialize buffer to empty */ signal(SIGINT, signal_catcher);
#ifdef SIGTERM /* not all systems have SIGTERM */
/* Set up default input and output file references. */ signal(SIGTERM, signal_catcher);
/* (These may be overridden below.) */ #endif
cinfo.input_file = stdin;
cinfo.output_file = stdout;
/* Set up default parameters. */
e_methods.trace_level = 0;
cinfo.output_gamma = 1.0;
cinfo.quantize_colors = FALSE;
cinfo.two_pass_quantize = FALSE;
cinfo.use_dithering = FALSE;
cinfo.desired_number_of_colors = 256;
cinfo.do_block_smoothing = FALSE;
cinfo.do_pixel_smoothing = FALSE;
cinfo.out_color_space = CS_RGB;
cinfo.jpeg_color_space = CS_UNKNOWN;
/* setting any other value in jpeg_color_space overrides heuristics */
/* in jrdjfif.c ... */
/* You may wanta change the default output format; here's the place: */
#ifdef PPM_SUPPORTED
requested_fmt = FMT_PPM;
#else
requested_fmt = FMT_GIF;
#endif #endif
/* Scan parameters */ /* Set up default JPEG parameters. */
j_d_defaults(&cinfo, TRUE);
requested_fmt = DEFAULT_FMT; /* set default output file format */
/* Scan command line options, adjust parameters */
while ((c = getopt(argc, argv, "bq:2DdgG")) != EOF) while ((c = egetopt(argc, argv, "GPRTbgq:1Dm:d")) != EOF)
switch (c) { switch (c) {
case 'G': /* GIF output format. */
requested_fmt = FMT_GIF;
break;
case 'P': /* PPM output format. */
requested_fmt = FMT_PPM;
break;
case 'R': /* RLE output format. */
requested_fmt = FMT_RLE;
break;
case 'T': /* Targa output format. */
requested_fmt = FMT_TARGA;
break;
case 'b': /* Enable cross-block smoothing. */ case 'b': /* Enable cross-block smoothing. */
cinfo.do_block_smoothing = TRUE; cinfo.do_block_smoothing = TRUE;
break; break;
case 'g': /* Force grayscale output. */
cinfo.out_color_space = CS_GRAYSCALE;
break;
case 'q': /* Do color quantization. */ case 'q': /* Do color quantization. */
{ int val; { int val;
if (optarg == NULL) if (optarg == NULL)
@@ -212,27 +237,39 @@ main (int argc, char **argv)
} }
cinfo.quantize_colors = TRUE; cinfo.quantize_colors = TRUE;
break; break;
case '2': /* Use two-pass quantization. */ case '1': /* Use fast one-pass quantization. */
cinfo.two_pass_quantize = TRUE; cinfo.two_pass_quantize = FALSE;
break; break;
case 'D': /* Use dithering in color quantization. */ case 'D': /* Suppress dithering in color quantization. */
cinfo.use_dithering = TRUE; cinfo.use_dithering = FALSE;
break;
case 'm': /* Maximum memory in Kb (or Mb with 'm'). */
{ long lval;
char ch = 'x';
if (optarg == NULL)
usage(argv[0]);
if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
usage(argv[0]);
if (ch == 'm' || ch == 'M')
lval *= 1000L;
e_methods.max_memory_to_use = lval * 1000L;
}
break; break;
case 'd': /* Debugging. */ case 'd': /* Debugging. */
e_methods.trace_level++; e_methods.trace_level++;
break; break;
case 'g': /* Force grayscale output. */
cinfo.out_color_space = CS_GRAYSCALE;
break;
case 'G': /* GIF output format. */
requested_fmt = FMT_GIF;
break;
case '?': case '?':
default: default:
usage(argv[0]); usage(argv[0]);
break; break;
} }
/* If -d appeared, print version identification */
if (e_methods.trace_level > 0)
fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n",
JVERSION, JCOPYRIGHT);
/* Select the input and output files */ /* Select the input and output files */
#ifdef TWO_FILE_COMMANDLINE #ifdef TWO_FILE_COMMANDLINE
@@ -243,15 +280,18 @@ main (int argc, char **argv)
} }
if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) { if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]); fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
exit(2); exit(EXIT_FAILURE);
} }
if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) { if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]); fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
exit(2); exit(EXIT_FAILURE);
} }
#else /* not TWO_FILE_COMMANDLINE -- use Unix style */ #else /* not TWO_FILE_COMMANDLINE -- use Unix style */
cinfo.input_file = stdin; /* default input file */
cinfo.output_file = stdout; /* always the output file */
if (optind < argc-1) { if (optind < argc-1) {
fprintf(stderr, "%s: only one input file\n", argv[0]); fprintf(stderr, "%s: only one input file\n", argv[0]);
usage(argv[0]); usage(argv[0]);
@@ -259,7 +299,7 @@ main (int argc, char **argv)
if (optind < argc) { if (optind < argc) {
if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) { if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]); fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
exit(2); exit(EXIT_FAILURE);
} }
} }
@@ -277,13 +317,7 @@ main (int argc, char **argv)
/* Do it to it! */ /* Do it to it! */
jpeg_decompress(&cinfo); jpeg_decompress(&cinfo);
/* Release memory. */
(*cinfo.emethods->free_small) ((void *) cinfo.input_buffer);
#ifdef MEM_STATS
if (e_methods.trace_level > 0)
j_mem_stats();
#endif
/* All done. */ /* All done. */
exit(0); exit(EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jdmaster.c * jdmaster.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -49,9 +49,15 @@ d_initial_method_selection (decompress_info_ptr cinfo)
/* Gamma and color space conversion */ /* Gamma and color space conversion */
jseldcolor(cinfo); jseldcolor(cinfo);
/* Color quantization */ /* Color quantization selection rules */
#ifdef QUANT_1PASS_SUPPORTED #ifdef QUANT_1PASS_SUPPORTED
#ifndef QUANT_2PASS_SUPPORTED #ifdef QUANT_2PASS_SUPPORTED
/* We have both, check for conditions in which 1-pass should be used */
if (cinfo->num_components != 3 || cinfo->jpeg_color_space != CS_YCbCr)
cinfo->two_pass_quantize = FALSE; /* 2-pass only handles YCbCr input */
if (cinfo->out_color_space == CS_GRAYSCALE)
cinfo->two_pass_quantize = FALSE; /* Should use 1-pass for grayscale out */
#else /* not QUANT_2PASS_SUPPORTED */
cinfo->two_pass_quantize = FALSE; /* only have 1-pass */ cinfo->two_pass_quantize = FALSE; /* only have 1-pass */
#endif #endif
#else /* not QUANT_1PASS_SUPPORTED */ #else /* not QUANT_1PASS_SUPPORTED */
@@ -121,16 +127,9 @@ initial_setup (decompress_info_ptr cinfo)
GLOBAL void GLOBAL void
jpeg_decompress (decompress_info_ptr cinfo) jpeg_decompress (decompress_info_ptr cinfo)
{ {
short i; /* Init pass counts to 0 --- total_passes is adjusted in method selection */
cinfo->total_passes = 0;
/* Initialize pointers as needed to mark stuff unallocated. */ cinfo->completed_passes = 0;
cinfo->comp_info = NULL;
for (i = 0; i < NUM_QUANT_TBLS; i++)
cinfo->quant_tbl_ptrs[i] = NULL;
for (i = 0; i < NUM_HUFF_TBLS; i++) {
cinfo->dc_huff_tbl_ptrs[i] = NULL;
cinfo->ac_huff_tbl_ptrs[i] = NULL;
}
/* Read the JPEG file header markers; everything up through the first SOS /* Read the JPEG file header markers; everything up through the first SOS
* marker is read now. NOTE: the user interface must have initialized the * marker is read now. NOTE: the user interface must have initialized the
@@ -151,30 +150,24 @@ jpeg_decompress (decompress_info_ptr cinfo)
d_initial_method_selection(cinfo); d_initial_method_selection(cinfo);
/* Initialize the output file & other modules as needed */ /* Initialize the output file & other modules as needed */
/* (color_quant and entropy_decoder are inited by pipeline controller) */ /* (modules needing per-scan init are called by pipeline controller) */
(*cinfo->methods->output_init) (cinfo); (*cinfo->methods->output_init) (cinfo);
(*cinfo->methods->colorout_init) (cinfo); (*cinfo->methods->colorout_init) (cinfo);
if (cinfo->quantize_colors)
(*cinfo->methods->color_quant_init) (cinfo);
/* And let the pipeline controller do the rest. */ /* And let the pipeline controller do the rest. */
(*cinfo->methods->d_pipeline_controller) (cinfo); (*cinfo->methods->d_pipeline_controller) (cinfo);
/* Finish output file, release working storage, etc */ /* Finish output file, release working storage, etc */
if (cinfo->quantize_colors)
(*cinfo->methods->color_quant_term) (cinfo);
(*cinfo->methods->colorout_term) (cinfo); (*cinfo->methods->colorout_term) (cinfo);
(*cinfo->methods->output_term) (cinfo); (*cinfo->methods->output_term) (cinfo);
(*cinfo->methods->read_file_trailer) (cinfo); (*cinfo->methods->read_file_trailer) (cinfo);
/* Release allocated storage for tables */ (*cinfo->emethods->free_all) ();
#define FREE(ptr) if ((ptr) != NULL) \
(*cinfo->emethods->free_small) ((void *) ptr)
FREE(cinfo->comp_info);
for (i = 0; i < NUM_QUANT_TBLS; i++)
FREE(cinfo->quant_tbl_ptrs[i]);
for (i = 0; i < NUM_HUFF_TBLS; i++) {
FREE(cinfo->dc_huff_tbl_ptrs[i]);
FREE(cinfo->ac_huff_tbl_ptrs[i]);
}
/* My, that was easy, wasn't it? */ /* My, that was easy, wasn't it? */
} }

81
jdmcu.c
View File

@@ -1,12 +1,12 @@
/* /*
* jdmcu.c * jdmcu.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
* This file contains MCU disassembly routines and quantization descaling. * This file contains MCU disassembly routines and quantization descaling.
* These routines are invoked via the disassemble_MCU and * These routines are invoked via the disassemble_MCU, reverse_DCT, and
* disassemble_init/term methods. * disassemble_init/term methods.
*/ */
@@ -35,10 +35,11 @@ static const short ZAG[DCTSIZE2] = {
LOCAL void LOCAL void
qdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl) qdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl)
{ {
const short * zagptr = ZAG;
short i; short i;
for (i = 0; i < DCTSIZE2; i++) { for (i = DCTSIZE2-1; i >= 0; i--) {
(*outputptr)[ZAG[i]] = (*input++) * (*quanttbl++); (*outputptr)[*zagptr++] = (*input++) * (*quanttbl++);
} }
} }
@@ -107,6 +108,77 @@ disassemble_interleaved_MCU (decompress_info_ptr cinfo,
} }
/*
* Perform inverse DCT on each block in an MCU row's worth of data;
* output the results into a sample array starting at row start_row.
* NB: start_row can only be nonzero when dealing with a single-component
* scan; otherwise we'd have to pass different offsets for different
* components, since the heights of interleaved MCU rows can vary.
* But the pipeline controller logic is such that this is not necessary.
*/
METHODDEF void
reverse_DCT (decompress_info_ptr cinfo,
JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data, int start_row)
{
DCTBLOCK block;
JBLOCKROW browptr;
JSAMPARRAY srowptr;
long blocksperrow, bi;
short numrows, ri;
short ci;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
/* calculate size of an MCU row in this component */
blocksperrow = cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE;
numrows = cinfo->cur_comp_info[ci]->MCU_height;
/* iterate through all blocks in MCU row */
for (ri = 0; ri < numrows; ri++) {
browptr = coeff_data[ci][ri];
srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
for (bi = 0; bi < blocksperrow; bi++) {
/* copy the data into a local DCTBLOCK. This allows for change of
* representation (if DCTELEM != JCOEF). On 80x86 machines it also
* brings the data back from FAR storage to NEAR storage.
*/
{ register JCOEFPTR elemptr = browptr[bi];
register DCTELEM *localblkptr = block;
register short elem = DCTSIZE2;
while (--elem >= 0)
*localblkptr++ = (DCTELEM) *elemptr++;
}
j_rev_dct(block); /* perform inverse DCT */
/* output the data into the sample array.
* Note change from signed to unsigned representation:
* DCT calculation works with values +-CENTERJSAMPLE,
* but sample arrays always hold 0..MAXJSAMPLE.
* Have to do explicit range-limiting because of quantization errors
* and so forth in the DCT/IDCT phase.
*/
{ register JSAMPROW elemptr;
register DCTELEM *localblkptr = block;
register short elemr, elemc;
register DCTELEM temp;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = srowptr[elemr] + (bi * DCTSIZE);
for (elemc = 0; elemc < DCTSIZE; elemc++) {
temp = (*localblkptr++) + CENTERJSAMPLE;
if (temp < 0) temp = 0;
else if (temp > MAXJSAMPLE) temp = MAXJSAMPLE;
*elemptr++ = (JSAMPLE) temp;
}
}
}
}
}
}
}
/* /*
* Initialize for processing a scan. * Initialize for processing a scan.
*/ */
@@ -141,6 +213,7 @@ jseldmcu (decompress_info_ptr cinfo)
cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU; cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
else else
cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU; cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
cinfo->methods->reverse_DCT = reverse_DCT;
cinfo->methods->disassemble_init = disassemble_init; cinfo->methods->disassemble_init = disassemble_init;
cinfo->methods->disassemble_term = disassemble_term; cinfo->methods->disassemble_term = disassemble_term;
} }

683
jdpipe.c
View File

@@ -1,33 +1,38 @@
/* /*
* jdpipe.c * jdpipe.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
* This file contains decompression pipeline controllers. * This file contains decompression pipeline controllers.
* These routines are invoked via the d_pipeline_controller method. * These routines are invoked via the d_pipeline_controller method.
* *
* There are four basic pipeline controllers, one for each combination of: * There are two basic pipeline controllers. The simpler one handles a
* single-scan JPEG file (single component or fully interleaved) * single-scan JPEG file (single component or fully interleaved) with no
* vs. multiple-scan JPEG file (noninterleaved or partially interleaved). * color quantization or 1-pass quantization. In this case, the file can
* be processed in one top-to-bottom pass. The more complex controller is
* used when 2-pass color quantization is requested and/or the JPEG file
* has multiple scans (noninterleaved or partially interleaved). In this
* case, the entire image must be buffered up in a "big" array.
* *
* 2-pass color quantization * If you need to make a minimal implementation, the more complex controller
* vs. no color quantization or 1-pass quantization. * can be compiled out by disabling the appropriate configuration options.
* * We don't recommend this, since then you can't handle all legal JPEG files.
* Note that these conditions determine the needs for "big" images:
* multiple scans imply a big image for recombining the color components;
* 2-pass color quantization needs a big image for saving the data for pass 2.
*
* All but the simplest controller (single-scan, no 2-pass quantization) can be
* compiled out through configuration options, if you need to make a minimal
* implementation. You should leave in multiple-scan support if at all
* possible, so that you can handle all legal JPEG files.
*/ */
#include "jinclude.h" #include "jinclude.h"
#ifdef MULTISCAN_FILES_SUPPORTED /* wish we could assume ANSI's defined() */
#define NEED_COMPLEX_CONTROLLER
#else
#ifdef QUANT_2PASS_SUPPORTED
#define NEED_COMPLEX_CONTROLLER
#endif
#endif
/* /*
* About the data structures: * About the data structures:
* *
@@ -62,15 +67,19 @@
* These variables are logically local to the pipeline controller, * These variables are logically local to the pipeline controller,
* but we make them static so that scan_big_image can use them * but we make them static so that scan_big_image can use them
* without having to pass them through the quantization routines. * without having to pass them through the quantization routines.
* If you don't support 2-pass quantization, you could make them locals.
*/ */
static int rows_in_mem; /* # of sample rows in full-size buffers */ static int rows_in_mem; /* # of sample rows in full-size buffers */
/* Full-size image array holding desubsampled, color-converted data. */ /* Work buffer for data being passed to output module. */
static big_sarray_ptr *fullsize_cnvt_image; /* This has color_out_comps components if not quantizing, */
static JSAMPIMAGE fullsize_cnvt_ptrs; /* workspace for access_big_sarray() results */ /* but only one component when quantizing. */
/* Work buffer for color quantization output (full size, only 1 component). */ static JSAMPIMAGE output_workspace;
static JSAMPARRAY quantize_out;
#ifdef NEED_COMPLEX_CONTROLLER
/* Full-size image array holding desubsampled, but not color-processed data. */
static big_sarray_ptr *fullsize_image;
static JSAMPIMAGE fullsize_ptrs; /* workspace for access_big_sarray() result */
#endif
/* /*
@@ -154,74 +163,6 @@ noninterleaved_scan_setup (decompress_info_ptr cinfo)
} }
LOCAL void
reverse_DCT (decompress_info_ptr cinfo,
JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data,
int start_row)
/* Perform inverse DCT on each block in an MCU row's worth of data; */
/* output the results into a sample array starting at row start_row. */
/* NB: start_row can only be nonzero when dealing with a single-component */
/* scan; otherwise we'd have to provide for different offsets for different */
/* components, since the heights of interleaved MCU rows can vary. */
{
DCTBLOCK block;
JBLOCKROW browptr;
JSAMPARRAY srowptr;
long blocksperrow, bi;
short numrows, ri;
short ci;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
/* calc size of an MCU row in this component */
blocksperrow = cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE;
numrows = cinfo->cur_comp_info[ci]->MCU_height;
/* iterate through all blocks in MCU row */
for (ri = 0; ri < numrows; ri++) {
browptr = coeff_data[ci][ri];
srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
for (bi = 0; bi < blocksperrow; bi++) {
/* copy the data into a local DCTBLOCK. This allows for change of
* representation (if DCTELEM != JCOEF). On 80x86 machines it also
* brings the data back from FAR storage to NEAR storage.
*/
{ register JCOEFPTR elemptr = browptr[bi];
register DCTELEM *localblkptr = block;
register short elem = DCTSIZE2;
while (--elem >= 0)
*localblkptr++ = (DCTELEM) *elemptr++;
}
j_rev_dct(block); /* perform inverse DCT */
/* output the data into the sample array.
* Note change from signed to unsigned representation:
* DCT calculation works with values +-CENTERJSAMPLE,
* but sample arrays always hold 0..MAXJSAMPLE.
* Have to do explicit range-limiting because of quantization errors
* and so forth in the DCT/IDCT phase.
*/
{ register JSAMPROW elemptr;
register DCTELEM *localblkptr = block;
register short elemr, elemc;
register DCTELEM temp;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = srowptr[elemr] + (bi * DCTSIZE);
for (elemc = 0; elemc < DCTSIZE; elemc++) {
temp = (*localblkptr++) + CENTERJSAMPLE;
if (temp < 0) temp = 0;
else if (temp > MAXJSAMPLE) temp = MAXJSAMPLE;
*elemptr++ = (JSAMPLE) temp;
}
}
}
}
}
}
}
LOCAL JSAMPIMAGE LOCAL JSAMPIMAGE
alloc_sampimage (decompress_info_ptr cinfo, alloc_sampimage (decompress_info_ptr cinfo,
@@ -240,19 +181,22 @@ alloc_sampimage (decompress_info_ptr cinfo,
} }
#if 0 /* this routine not currently needed */
LOCAL void LOCAL void
free_sampimage (decompress_info_ptr cinfo, JSAMPIMAGE image, free_sampimage (decompress_info_ptr cinfo, JSAMPIMAGE image, int num_comps)
int num_comps, long num_rows)
/* Release a sample image created by alloc_sampimage */ /* Release a sample image created by alloc_sampimage */
{ {
int ci; int ci;
for (ci = 0; ci < num_comps; ci++) { for (ci = 0; ci < num_comps; ci++) {
(*cinfo->emethods->free_small_sarray) (image[ci], num_rows); (*cinfo->emethods->free_small_sarray) (image[ci]);
} }
(*cinfo->emethods->free_small) ((void *) image); (*cinfo->emethods->free_small) ((void *) image);
} }
#endif
LOCAL JBLOCKIMAGE LOCAL JBLOCKIMAGE
alloc_MCU_row (decompress_info_ptr cinfo) alloc_MCU_row (decompress_info_ptr cinfo)
@@ -272,6 +216,8 @@ alloc_MCU_row (decompress_info_ptr cinfo)
} }
#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
LOCAL void LOCAL void
free_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image) free_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image)
/* Release a coefficient block array created by alloc_MCU_row */ /* Release a coefficient block array created by alloc_MCU_row */
@@ -279,12 +225,13 @@ free_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image)
int ci; int ci;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
(*cinfo->emethods->free_small_barray) (*cinfo->emethods->free_small_barray) (image[ci]);
(image[ci], (long) cinfo->cur_comp_info[ci]->MCU_height);
} }
(*cinfo->emethods->free_small) ((void *) image); (*cinfo->emethods->free_small) ((void *) image);
} }
#endif
LOCAL void LOCAL void
alloc_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2]) alloc_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
@@ -321,17 +268,17 @@ alloc_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
} }
#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
LOCAL void LOCAL void
free_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2]) free_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
/* Release a sampling buffer created by alloc_sampling_buffer */ /* Release a sampling buffer created by alloc_sampling_buffer */
{ {
short ci, vs; short ci;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
vs = cinfo->cur_comp_info[ci]->v_samp_factor; /* row group height */
/* Free the real storage */ /* Free the real storage */
(*cinfo->emethods->free_small_sarray) (*cinfo->emethods->free_small_sarray) (subsampled_data[0][ci]);
(subsampled_data[0][ci], (long) (vs * (DCTSIZE+2)));
/* Free the scrambled-order pointers */ /* Free the scrambled-order pointers */
(*cinfo->emethods->free_small) ((void *) subsampled_data[1][ci]); (*cinfo->emethods->free_small) ((void *) subsampled_data[1][ci]);
} }
@@ -341,6 +288,8 @@ free_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
(*cinfo->emethods->free_small) ((void *) subsampled_data[1]); (*cinfo->emethods->free_small) ((void *) subsampled_data[1]);
} }
#endif
LOCAL void LOCAL void
duplicate_row (JSAMPARRAY image_data, duplicate_row (JSAMPARRAY image_data,
@@ -409,82 +358,62 @@ expand (decompress_info_ptr cinfo,
LOCAL void LOCAL void
emit_1pass (decompress_info_ptr cinfo, int num_rows, emit_1pass (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE fullsize_data,
JSAMPIMAGE fullsize_data, JSAMPIMAGE color_data) JSAMPARRAY dummy)
/* Do color conversion and output of num_rows full-size rows. */ /* Do color processing and output of num_rows full-size rows. */
/* This is not used for 2-pass color quantization. */ /* This is not used when doing 2-pass color quantization. */
/* The dummy argument simply lets this be called via scan_big_image. */
{ {
(*cinfo->methods->color_convert) (cinfo, num_rows,
fullsize_data, color_data);
if (cinfo->quantize_colors) { if (cinfo->quantize_colors) {
(*cinfo->methods->color_quantize) (cinfo, num_rows, (*cinfo->methods->color_quantize) (cinfo, num_rows, fullsize_data,
color_data, quantize_out); output_workspace[0]);
(*cinfo->methods->put_pixel_rows) (cinfo, num_rows,
&quantize_out);
} else { } else {
(*cinfo->methods->put_pixel_rows) (cinfo, num_rows, (*cinfo->methods->color_convert) (cinfo, num_rows, cinfo->image_width,
color_data); fullsize_data, output_workspace);
} }
(*cinfo->methods->put_pixel_rows) (cinfo, num_rows, output_workspace);
} }
/* /*
* Support routines for 2-pass color quantization. * Support routines for complex controller.
*/ */
#ifdef QUANT_2PASS_SUPPORTED #ifdef NEED_COMPLEX_CONTROLLER
LOCAL void
emit_2pass (decompress_info_ptr cinfo, long top_row, int num_rows,
JSAMPIMAGE fullsize_data)
/* Do color conversion and output data to the quantization buffer image. */
/* This is used only with 2-pass color quantization. */
{
short ci;
/* Realign the big buffers */
for (ci = 0; ci < cinfo->num_components; ci++) {
fullsize_cnvt_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
(fullsize_cnvt_image[ci], top_row, TRUE);
}
/* Do colorspace conversion */
(*cinfo->methods->color_convert) (cinfo, num_rows,
fullsize_data, fullsize_cnvt_ptrs);
/* Let quantizer get first-pass peek at the data. */
/* (Quantizer could change data if it wants to.) */
(*cinfo->methods->color_quant_prescan) (cinfo, num_rows, fullsize_cnvt_ptrs);
}
METHODDEF void METHODDEF void
scan_big_image (decompress_info_ptr cinfo, quantize_method_ptr quantize_method) scan_big_image (decompress_info_ptr cinfo, quantize_method_ptr quantize_method)
/* This is the "iterator" routine used by the quantizer. */ /* Apply quantize_method to entire image stored in fullsize_image[]. */
/* This is the "iterator" routine used by the 2-pass color quantizer. */
/* We also use it directly in some cases. */
{ {
long pixel_rows_output; long pixel_rows_output;
short ci; short ci;
for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height; for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height;
pixel_rows_output += rows_in_mem) { pixel_rows_output += rows_in_mem) {
(*cinfo->methods->progress_monitor) (cinfo, pixel_rows_output,
cinfo->image_height);
/* Realign the big buffers */ /* Realign the big buffers */
for (ci = 0; ci < cinfo->num_components; ci++) { for (ci = 0; ci < cinfo->num_components; ci++) {
fullsize_cnvt_ptrs[ci] = (*cinfo->emethods->access_big_sarray) fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
(fullsize_cnvt_image[ci], pixel_rows_output, FALSE); (fullsize_image[ci], pixel_rows_output, FALSE);
} }
/* Let the quantizer have its way with the data. /* Let the quantizer have its way with the data.
* Note that quantize_out is simply workspace for the quantizer; * Note that output_workspace is simply workspace for the quantizer;
* when it's ready to output, it must call put_pixel_rows itself. * when it's ready to output, it must call put_pixel_rows itself.
*/ */
(*quantize_method) (cinfo, (*quantize_method) (cinfo,
(int) MIN(rows_in_mem, (int) MIN((long) rows_in_mem,
cinfo->image_height - pixel_rows_output), cinfo->image_height - pixel_rows_output),
fullsize_cnvt_ptrs, quantize_out); fullsize_ptrs, output_workspace[0]);
} }
cinfo->completed_passes++;
} }
#endif /* QUANT_2PASS_SUPPORTED */ #endif /* NEED_COMPLEX_CONTROLLER */
/* /*
@@ -587,7 +516,7 @@ get_smoothed_row (decompress_info_ptr cinfo, JBLOCKIMAGE coeff_data,
*/ */
METHODDEF void METHODDEF void
single_dcontroller (decompress_info_ptr cinfo) simple_dcontroller (decompress_info_ptr cinfo)
{ {
long fullsize_width; /* # of samples per row in full-size buffers */ long fullsize_width; /* # of samples per row in full-size buffers */
long cur_mcu_row; /* counts # of MCU rows processed */ long cur_mcu_row; /* counts # of MCU rows processed */
@@ -604,14 +533,14 @@ single_dcontroller (decompress_info_ptr cinfo)
JSAMPIMAGE subsampled_data[2]; JSAMPIMAGE subsampled_data[2];
/* Work buffer for desubsampled data */ /* Work buffer for desubsampled data */
JSAMPIMAGE fullsize_data; JSAMPIMAGE fullsize_data;
/* Work buffer for color conversion output (full size) */
JSAMPIMAGE color_data;
int whichss, ri; int whichss, ri;
short i; short i;
/* Initialize for 1-pass color quantization, if needed */ /* Compute dimensions of full-size pixel buffers */
if (cinfo->quantize_colors) /* Note these are the same whether interleaved or not. */
(*cinfo->methods->color_quant_init) (cinfo); rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
fullsize_width = jround_up(cinfo->image_width,
(long) (cinfo->max_h_samp_factor * DCTSIZE));
/* Prepare for single scan containing all components */ /* Prepare for single scan containing all components */
if (cinfo->comps_in_scan == 1) { if (cinfo->comps_in_scan == 1) {
@@ -623,12 +552,7 @@ single_dcontroller (decompress_info_ptr cinfo)
/* in an interleaved scan, one MCU row provides Vk block rows */ /* in an interleaved scan, one MCU row provides Vk block rows */
mcu_rows_per_loop = 1; mcu_rows_per_loop = 1;
} }
cinfo->total_passes++;
/* Compute dimensions of full-size pixel buffers */
/* Note these are the same whether interleaved or not. */
rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
fullsize_width = jround_up(cinfo->image_width,
(long) (cinfo->max_h_samp_factor * DCTSIZE));
/* Allocate working memory: */ /* Allocate working memory: */
/* coeff_data holds a single MCU row of coefficient blocks */ /* coeff_data holds a single MCU row of coefficient blocks */
@@ -646,13 +570,9 @@ single_dcontroller (decompress_info_ptr cinfo)
/* fullsize_data is sample data after unsubsampling */ /* fullsize_data is sample data after unsubsampling */
fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components, fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
(long) rows_in_mem, fullsize_width); (long) rows_in_mem, fullsize_width);
/* color_data is the result of the colorspace conversion step */ /* output_workspace is the color-processed data */
color_data = alloc_sampimage(cinfo, (int) cinfo->color_out_comps, output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
(long) rows_in_mem, fullsize_width); (long) rows_in_mem, fullsize_width);
/* if quantizing colors, also need a one-component output area for that. */
if (cinfo->quantize_colors)
quantize_out = (*cinfo->emethods->alloc_small_sarray)
(fullsize_width, (long) rows_in_mem);
/* Tell the memory manager to instantiate big arrays. /* Tell the memory manager to instantiate big arrays.
* We don't need any big arrays in this controller, * We don't need any big arrays in this controller,
@@ -662,7 +582,8 @@ single_dcontroller (decompress_info_ptr cinfo)
((long) 0, /* no more small sarrays */ ((long) 0, /* no more small sarrays */
(long) 0, /* no more small barrays */ (long) 0, /* no more small barrays */
(long) 0); /* no more "medium" objects */ (long) 0); /* no more "medium" objects */
/* NB: quantizer must get any such objects at color_quant_init time */ /* NB: if quantizer needs any "medium" size objects, it must get them */
/* at color_quant_init time */
/* Initialize to read scan data */ /* Initialize to read scan data */
@@ -677,6 +598,9 @@ single_dcontroller (decompress_info_ptr cinfo)
for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan; for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
cur_mcu_row += mcu_rows_per_loop) { cur_mcu_row += mcu_rows_per_loop) {
(*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
cinfo->MCU_rows_in_scan);
whichss ^= 1; /* switch to other subsample buffer */ whichss ^= 1; /* switch to other subsample buffer */
/* Obtain v_samp_factor block rows of each component in the scan. */ /* Obtain v_samp_factor block rows of each component in the scan. */
@@ -696,8 +620,9 @@ single_dcontroller (decompress_info_ptr cinfo)
#endif #endif
(*cinfo->methods->disassemble_MCU) (cinfo, coeff_data); (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
reverse_DCT(cinfo, coeff_data, subsampled_data[whichss], (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
ri * DCTSIZE); subsampled_data[whichss],
ri * DCTSIZE);
} else { } else {
/* Need to pad out with copies of the last subsampled row. */ /* Need to pad out with copies of the last subsampled row. */
/* This can only happen if there is just one component. */ /* This can only happen if there is just one component. */
@@ -716,7 +641,7 @@ single_dcontroller (decompress_info_ptr cinfo)
(short) DCTSIZE, (short) (DCTSIZE+1), (short) 0, (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
(short) (DCTSIZE-1)); (short) (DCTSIZE-1));
/* and dump the previous set's expanded data */ /* and dump the previous set's expanded data */
emit_1pass (cinfo, rows_in_mem, fullsize_data, color_data); emit_1pass (cinfo, rows_in_mem, fullsize_data, NULL);
pixel_rows_output += rows_in_mem; pixel_rows_output += rows_in_mem;
/* Expand first row group of this set */ /* Expand first row group of this set */
expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width, expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
@@ -743,273 +668,47 @@ single_dcontroller (decompress_info_ptr cinfo)
(short) (DCTSIZE-1)); (short) (DCTSIZE-1));
/* and dump the remaining data (may be less than full height) */ /* and dump the remaining data (may be less than full height) */
emit_1pass (cinfo, (int) (cinfo->image_height - pixel_rows_output), emit_1pass (cinfo, (int) (cinfo->image_height - pixel_rows_output),
fullsize_data, color_data); fullsize_data, NULL);
/* Clean up after the scan */ /* Clean up after the scan */
(*cinfo->methods->disassemble_term) (cinfo); (*cinfo->methods->disassemble_term) (cinfo);
(*cinfo->methods->unsubsample_term) (cinfo); (*cinfo->methods->unsubsample_term) (cinfo);
(*cinfo->methods->entropy_decoder_term) (cinfo); (*cinfo->methods->entropy_decoder_term) (cinfo);
(*cinfo->methods->read_scan_trailer) (cinfo); (*cinfo->methods->read_scan_trailer) (cinfo);
cinfo->completed_passes++;
/* Verify that we've seen the whole input file */ /* Verify that we've seen the whole input file */
if ((*cinfo->methods->read_scan_header) (cinfo)) if ((*cinfo->methods->read_scan_header) (cinfo))
ERREXIT(cinfo->emethods, "Didn't expect more than one scan"); ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
/* Release working memory */ /* Release working memory */
free_MCU_row(cinfo, coeff_data); /* (no work -- we let free_all release what's needful) */
#ifdef BLOCK_SMOOTHING_SUPPORTED
if (cinfo->do_block_smoothing) {
free_MCU_row(cinfo, bsmooth[0]);
free_MCU_row(cinfo, bsmooth[1]);
free_MCU_row(cinfo, bsmooth[2]);
}
#endif
free_sampling_buffer(cinfo, subsampled_data);
free_sampimage(cinfo, fullsize_data, (int) cinfo->num_components,
(long) rows_in_mem);
free_sampimage(cinfo, color_data, (int) cinfo->color_out_comps,
(long) rows_in_mem);
if (cinfo->quantize_colors)
(*cinfo->emethods->free_small_sarray)
(quantize_out, (long) rows_in_mem);
/* Close up shop */
if (cinfo->quantize_colors)
(*cinfo->methods->color_quant_term) (cinfo);
} }
/*
* Decompression pipeline controller used for single-scan files
* with 2-pass color quantization.
*/
#ifdef QUANT_2PASS_SUPPORTED
METHODDEF void
single_2quant_dcontroller (decompress_info_ptr cinfo)
{
long fullsize_width; /* # of samples per row in full-size buffers */
long cur_mcu_row; /* counts # of MCU rows processed */
long pixel_rows_output; /* # of pixel rows actually emitted */
int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
/* Work buffer for dequantized coefficients (IDCT input) */
JBLOCKIMAGE coeff_data;
/* Work buffer for cross-block smoothing input */
#ifdef BLOCK_SMOOTHING_SUPPORTED
JBLOCKIMAGE bsmooth[3]; /* this is optional */
int whichb;
#endif
/* Work buffer for subsampled image data (see comments at head of file) */
JSAMPIMAGE subsampled_data[2];
/* Work buffer for desubsampled data */
JSAMPIMAGE fullsize_data;
int whichss, ri;
short ci, i;
/* Initialize for 2-pass color quantization */
(*cinfo->methods->color_quant_init) (cinfo);
/* Prepare for single scan containing all components */
if (cinfo->comps_in_scan == 1) {
noninterleaved_scan_setup(cinfo);
/* Need to read Vk MCU rows to obtain Vk block rows */
mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
} else {
interleaved_scan_setup(cinfo);
/* in an interleaved scan, one MCU row provides Vk block rows */
mcu_rows_per_loop = 1;
}
/* Compute dimensions of full-size pixel buffers */
/* Note these are the same whether interleaved or not. */
rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
fullsize_width = jround_up(cinfo->image_width,
(long) (cinfo->max_h_samp_factor * DCTSIZE));
/* Allocate working memory: */
/* coeff_data holds a single MCU row of coefficient blocks */
coeff_data = alloc_MCU_row(cinfo);
/* if doing cross-block smoothing, need extra space for its input */
#ifdef BLOCK_SMOOTHING_SUPPORTED
if (cinfo->do_block_smoothing) {
bsmooth[0] = alloc_MCU_row(cinfo);
bsmooth[1] = alloc_MCU_row(cinfo);
bsmooth[2] = alloc_MCU_row(cinfo);
}
#endif
/* subsampled_data is sample data before unsubsampling */
alloc_sampling_buffer(cinfo, subsampled_data);
/* fullsize_data is sample data after unsubsampling */
fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
(long) rows_in_mem, fullsize_width);
/* Also need a one-component output area for color quantizer. */
quantize_out = (*cinfo->emethods->alloc_small_sarray)
(fullsize_width, (long) rows_in_mem);
/* Get a big image for quantizer input: desubsampled, color-converted data */
fullsize_cnvt_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
(cinfo->num_components * SIZEOF(big_sarray_ptr));
for (ci = 0; ci < cinfo->num_components; ci++) {
fullsize_cnvt_image[ci] = (*cinfo->emethods->request_big_sarray)
(fullsize_width,
jround_up(cinfo->image_height, (long) rows_in_mem),
(long) rows_in_mem);
}
/* Also get an area for pointers to currently accessible chunks */
fullsize_cnvt_ptrs = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
(cinfo->num_components * SIZEOF(JSAMPARRAY));
/* Tell the memory manager to instantiate big arrays */
(*cinfo->emethods->alloc_big_arrays)
((long) 0, /* no more small sarrays */
(long) 0, /* no more small barrays */
(long) 0); /* no more "medium" objects */
/* NB: quantizer must get any such objects at color_quant_init time */
/* Initialize to read scan data */
(*cinfo->methods->entropy_decoder_init) (cinfo);
(*cinfo->methods->unsubsample_init) (cinfo);
(*cinfo->methods->disassemble_init) (cinfo);
/* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
pixel_rows_output = 0;
whichss = 1; /* arrange to start with subsampled_data[0] */
for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
cur_mcu_row += mcu_rows_per_loop) {
whichss ^= 1; /* switch to other subsample buffer */
/* Obtain v_samp_factor block rows of each component in the scan. */
/* This is a single MCU row if interleaved, multiple MCU rows if not. */
/* In the noninterleaved case there might be fewer than v_samp_factor */
/* block rows remaining; if so, pad with copies of the last pixel row */
/* so that unsubsampling doesn't have to treat it as a special case. */
for (ri = 0; ri < mcu_rows_per_loop; ri++) {
if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
/* OK to actually read an MCU row. */
#ifdef BLOCK_SMOOTHING_SUPPORTED
if (cinfo->do_block_smoothing)
get_smoothed_row(cinfo, coeff_data,
bsmooth, &whichb, cur_mcu_row + ri);
else
#endif
(*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
reverse_DCT(cinfo, coeff_data, subsampled_data[whichss],
ri * DCTSIZE);
} else {
/* Need to pad out with copies of the last subsampled row. */
/* This can only happen if there is just one component. */
duplicate_row(subsampled_data[whichss][0],
cinfo->cur_comp_info[0]->subsampled_width,
ri * DCTSIZE - 1, DCTSIZE);
}
}
/* Unsubsample the data */
/* First time through is a special case */
if (cur_mcu_row) {
/* Expand last row group of previous set */
expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
(short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
(short) (DCTSIZE-1));
/* and dump the previous set's expanded data */
emit_2pass (cinfo, pixel_rows_output, rows_in_mem, fullsize_data);
pixel_rows_output += rows_in_mem;
/* Expand first row group of this set */
expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
(short) (DCTSIZE+1), (short) 0, (short) 1,
(short) 0);
} else {
/* Expand first row group with dummy above-context */
expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
(short) (-1), (short) 0, (short) 1,
(short) 0);
}
/* Expand second through next-to-last row groups of this set */
for (i = 1; i <= DCTSIZE-2; i++) {
expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
(short) (i-1), (short) i, (short) (i+1),
(short) i);
}
} /* end of outer loop */
/* Expand the last row group with dummy below-context */
/* Note whichss points to last buffer side used */
expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
(short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
(short) (DCTSIZE-1));
/* and dump the remaining data (may be less than full height) */
emit_2pass (cinfo, pixel_rows_output,
(int) (cinfo->image_height - pixel_rows_output),
fullsize_data);
/* Clean up after the scan */
(*cinfo->methods->disassemble_term) (cinfo);
(*cinfo->methods->unsubsample_term) (cinfo);
(*cinfo->methods->entropy_decoder_term) (cinfo);
(*cinfo->methods->read_scan_trailer) (cinfo);
/* Verify that we've seen the whole input file */
if ((*cinfo->methods->read_scan_header) (cinfo))
ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
/* Now that we've collected the data, let the color quantizer do its thing */
(*cinfo->methods->color_quant_doit) (cinfo, scan_big_image);
/* Release working memory */
free_MCU_row(cinfo, coeff_data);
#ifdef BLOCK_SMOOTHING_SUPPORTED
if (cinfo->do_block_smoothing) {
free_MCU_row(cinfo, bsmooth[0]);
free_MCU_row(cinfo, bsmooth[1]);
free_MCU_row(cinfo, bsmooth[2]);
}
#endif
free_sampling_buffer(cinfo, subsampled_data);
free_sampimage(cinfo, fullsize_data, (int) cinfo->num_components,
(long) rows_in_mem);
(*cinfo->emethods->free_small_sarray)
(quantize_out, (long) rows_in_mem);
for (ci = 0; ci < cinfo->num_components; ci++) {
(*cinfo->emethods->free_big_sarray) (fullsize_cnvt_image[ci]);
}
(*cinfo->emethods->free_small) ((void *) fullsize_cnvt_image);
(*cinfo->emethods->free_small) ((void *) fullsize_cnvt_ptrs);
/* Close up shop */
(*cinfo->methods->color_quant_term) (cinfo);
}
#endif /* QUANT_2PASS_SUPPORTED */
/* /*
* Decompression pipeline controller used for multiple-scan files * Decompression pipeline controller used for multiple-scan files
* without 2-pass color quantization. * and/or 2-pass color quantization.
* *
* The current implementation places the "big" buffer at the stage of * The current implementation places the "big" buffer at the stage of
* desubsampled data. Buffering subsampled data instead would reduce the * desubsampled, non-color-processed data. This is the only place that
* size of temp files (by about a factor of 2 in typical cases). However, * makes sense when doing 2-pass quantization. For processing multiple-scan
* the unsubsampling logic is dependent on the assumption that unsubsampling * files without 2-pass quantization, it would be possible to develop another
* occurs during a scan, so it's much easier to do the enlargement as the * controller that buffers the subsampled data instead, thus reducing the size
* JPEG file is read. This also simplifies life for the memory manager, * of the temp files (by about a factor of 2 in typical cases). However,
* which would otherwise have to deal with overlapping access_big_sarray() * our present unsubsampling logic is dependent on the assumption that
* requests. * unsubsampling occurs during a scan, so it's much easier to do the
* * enlargement as the JPEG file is read. This also simplifies life for the
* At present it appears that most JPEG files will be single-scan, so * memory manager, which would otherwise have to deal with overlapping
* it doesn't seem worthwhile to try to make this implementation smarter. * access_big_sarray() requests.
* At present it appears that most JPEG files will be single-scan,
* so it doesn't seem worthwhile to worry about this optimization.
*/ */
#ifdef MULTISCAN_FILES_SUPPORTED #ifdef NEED_COMPLEX_CONTROLLER
METHODDEF void METHODDEF void
multi_dcontroller (decompress_info_ptr cinfo) complex_dcontroller (decompress_info_ptr cinfo)
{ {
long fullsize_width; /* # of samples per row in full-size buffers */ long fullsize_width; /* # of samples per row in full-size buffers */
long cur_mcu_row; /* counts # of MCU rows processed */ long cur_mcu_row; /* counts # of MCU rows processed */
@@ -1024,17 +723,9 @@ multi_dcontroller (decompress_info_ptr cinfo)
#endif #endif
/* Work buffer for subsampled image data (see comments at head of file) */ /* Work buffer for subsampled image data (see comments at head of file) */
JSAMPIMAGE subsampled_data[2]; JSAMPIMAGE subsampled_data[2];
/* Full-image buffer holding desubsampled, but not color-converted, data */
big_sarray_ptr *fullsize_image;
JSAMPIMAGE fullsize_ptrs; /* workspace for access_big_sarray() results */
/* Work buffer for color conversion output (full size) */
JSAMPIMAGE color_data;
int whichss, ri; int whichss, ri;
short ci, i; short ci, i;
boolean single_scan;
/* Initialize for 1-pass color quantization, if needed */
if (cinfo->quantize_colors)
(*cinfo->methods->color_quant_init) (cinfo);
/* Compute dimensions of full-size pixel buffers */ /* Compute dimensions of full-size pixel buffers */
/* Note these are the same whether interleaved or not. */ /* Note these are the same whether interleaved or not. */
@@ -1043,13 +734,9 @@ multi_dcontroller (decompress_info_ptr cinfo)
(long) (cinfo->max_h_samp_factor * DCTSIZE)); (long) (cinfo->max_h_samp_factor * DCTSIZE));
/* Allocate all working memory that doesn't depend on scan info */ /* Allocate all working memory that doesn't depend on scan info */
/* color_data is the result of the colorspace conversion step */ /* output_workspace is the color-processed data */
color_data = alloc_sampimage(cinfo, (int) cinfo->color_out_comps, output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
(long) rows_in_mem, fullsize_width); (long) rows_in_mem, fullsize_width);
/* if quantizing colors, also need a one-component output area for that. */
if (cinfo->quantize_colors)
quantize_out = (*cinfo->emethods->alloc_small_sarray)
(fullsize_width, (long) rows_in_mem);
/* Get a big image: fullsize_image is sample data after unsubsampling. */ /* Get a big image: fullsize_image is sample data after unsubsampling. */
fullsize_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small) fullsize_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
@@ -1076,9 +763,34 @@ multi_dcontroller (decompress_info_ptr cinfo)
* cinfo->num_components /* max components per scan */ * cinfo->num_components /* max components per scan */
* (cinfo->do_block_smoothing ? 4 : 1)),/* how many of these we need */ * (cinfo->do_block_smoothing ? 4 : 1)),/* how many of these we need */
/* no extra "medium"-object space */ /* no extra "medium"-object space */
/* NB: quantizer must get any such objects at color_quant_init time */
(long) 0); (long) 0);
/* NB: if quantizer needs any "medium" size objects, it must get them */
/* at color_quant_init time */
/* If file is single-scan, we can do color quantization prescan on-the-fly
* during the scan (we must be doing 2-pass quantization, else this method
* would not have been selected). If it is multiple scans, we have to make
* a separate pass after we've collected all the components. (We could save
* some I/O by doing CQ prescan during the last scan, but the extra logic
* doesn't seem worth the trouble.)
*/
single_scan = (cinfo->comps_in_scan == cinfo->num_components);
/* Account for passes needed (color quantizer adds its passes separately).
* If multiscan file, we guess that each component has its own scan,
* and increment completed_passes by the number of components in the scan.
*/
if (single_scan)
cinfo->total_passes++; /* the single scan */
else {
cinfo->total_passes += cinfo->num_components; /* guessed # of scans */
if (cinfo->two_pass_quantize)
cinfo->total_passes++; /* account for separate CQ prescan pass */
}
if (! cinfo->two_pass_quantize)
cinfo->total_passes++; /* count output pass unless quantizer does it */
/* Loop over scans in file */ /* Loop over scans in file */
@@ -1109,7 +821,7 @@ multi_dcontroller (decompress_info_ptr cinfo)
/* subsampled_data is sample data before unsubsampling */ /* subsampled_data is sample data before unsubsampling */
alloc_sampling_buffer(cinfo, subsampled_data); alloc_sampling_buffer(cinfo, subsampled_data);
/* line up the big buffers */ /* line up the big buffers for components in this scan */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray) fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
(fullsize_image[cinfo->cur_comp_info[ci]->component_index], (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
@@ -1129,6 +841,9 @@ multi_dcontroller (decompress_info_ptr cinfo)
for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan; for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
cur_mcu_row += mcu_rows_per_loop) { cur_mcu_row += mcu_rows_per_loop) {
(*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
cinfo->MCU_rows_in_scan);
whichss ^= 1; /* switch to other subsample buffer */ whichss ^= 1; /* switch to other subsample buffer */
/* Obtain v_samp_factor block rows of each component in the scan. */ /* Obtain v_samp_factor block rows of each component in the scan. */
@@ -1148,8 +863,9 @@ multi_dcontroller (decompress_info_ptr cinfo)
#endif #endif
(*cinfo->methods->disassemble_MCU) (cinfo, coeff_data); (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
reverse_DCT(cinfo, coeff_data, subsampled_data[whichss], (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
ri * DCTSIZE); subsampled_data[whichss],
ri * DCTSIZE);
} else { } else {
/* Need to pad out with copies of the last subsampled row. */ /* Need to pad out with copies of the last subsampled row. */
/* This can only happen if there is just one component. */ /* This can only happen if there is just one component. */
@@ -1167,6 +883,11 @@ multi_dcontroller (decompress_info_ptr cinfo)
expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width, expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
(short) DCTSIZE, (short) (DCTSIZE+1), (short) 0, (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
(short) (DCTSIZE-1)); (short) (DCTSIZE-1));
/* If single scan, can do color quantization prescan on-the-fly */
if (single_scan)
(*cinfo->methods->color_quant_prescan) (cinfo, rows_in_mem,
fullsize_ptrs,
output_workspace[0]);
/* Realign the big buffers */ /* Realign the big buffers */
pixel_rows_output += rows_in_mem; pixel_rows_output += rows_in_mem;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
@@ -1190,19 +911,28 @@ multi_dcontroller (decompress_info_ptr cinfo)
(short) (i-1), (short) i, (short) (i+1), (short) (i-1), (short) i, (short) (i+1),
(short) i); (short) i);
} }
} /* end of outer loop */ } /* end of loop over scan's data */
/* Expand the last row group with dummy below-context */ /* Expand the last row group with dummy below-context */
/* Note whichss points to last buffer side used */ /* Note whichss points to last buffer side used */
expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width, expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
(short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1), (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
(short) (DCTSIZE-1)); (short) (DCTSIZE-1));
/* If single scan, finish on-the-fly color quantization prescan */
if (single_scan)
(*cinfo->methods->color_quant_prescan) (cinfo,
(int) (cinfo->image_height - pixel_rows_output),
fullsize_ptrs, output_workspace[0]);
/* Clean up after the scan */ /* Clean up after the scan */
(*cinfo->methods->disassemble_term) (cinfo); (*cinfo->methods->disassemble_term) (cinfo);
(*cinfo->methods->unsubsample_term) (cinfo); (*cinfo->methods->unsubsample_term) (cinfo);
(*cinfo->methods->entropy_decoder_term) (cinfo); (*cinfo->methods->entropy_decoder_term) (cinfo);
(*cinfo->methods->read_scan_trailer) (cinfo); (*cinfo->methods->read_scan_trailer) (cinfo);
if (single_scan)
cinfo->completed_passes++;
else
cinfo->completed_passes += cinfo->comps_in_scan;
/* Release scan-local working memory */ /* Release scan-local working memory */
free_MCU_row(cinfo, coeff_data); free_MCU_row(cinfo, coeff_data);
@@ -1216,60 +946,32 @@ multi_dcontroller (decompress_info_ptr cinfo)
free_sampling_buffer(cinfo, subsampled_data); free_sampling_buffer(cinfo, subsampled_data);
/* Repeat if there is another scan */ /* Repeat if there is another scan */
} while ((*cinfo->methods->read_scan_header) (cinfo)); } while ((!single_scan) && (*cinfo->methods->read_scan_header) (cinfo));
/* Now that we've collected all the data, color convert & output it. */ if (single_scan) {
/* If we expected just one scan, make SURE there's just one */
for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height; if ((*cinfo->methods->read_scan_header) (cinfo))
pixel_rows_output += rows_in_mem) { ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
/* We did the CQ prescan on-the-fly, so we are all set. */
/* realign the big buffers */ } else {
for (ci = 0; ci < cinfo->num_components; ci++) { /* For multiple-scan file, do the CQ prescan as a separate pass. */
fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray) /* The main reason why prescan is passed the output_workspace is */
(fullsize_image[ci], pixel_rows_output, FALSE); /* so that we can use scan_big_image to call it... */
} if (cinfo->two_pass_quantize)
scan_big_image(cinfo, cinfo->methods->color_quant_prescan);
emit_1pass (cinfo,
(int) MIN(rows_in_mem, cinfo->image_height-pixel_rows_output),
fullsize_ptrs, color_data);
} }
/* Now that we've collected the data, do color processing and output */
if (cinfo->two_pass_quantize)
(*cinfo->methods->color_quant_doit) (cinfo, scan_big_image);
else
scan_big_image(cinfo, emit_1pass);
/* Release working memory */ /* Release working memory */
free_sampimage(cinfo, color_data, (int) cinfo->color_out_comps, /* (no work -- we let free_all release what's needful) */
(long) rows_in_mem);
if (cinfo->quantize_colors)
(*cinfo->emethods->free_small_sarray)
(quantize_out, (long) rows_in_mem);
for (ci = 0; ci < cinfo->num_components; ci++) {
(*cinfo->emethods->free_big_sarray) (fullsize_image[ci]);
}
(*cinfo->emethods->free_small) ((void *) fullsize_image);
(*cinfo->emethods->free_small) ((void *) fullsize_ptrs);
/* Close up shop */
if (cinfo->quantize_colors)
(*cinfo->methods->color_quant_term) (cinfo);
} }
#endif /* MULTISCAN_FILES_SUPPORTED */ #endif /* NEED_COMPLEX_CONTROLLER */
/*
* Decompression pipeline controller used for multiple-scan files
* with 2-pass color quantization.
*/
#ifdef MULTISCAN_FILES_SUPPORTED
#ifdef QUANT_2PASS_SUPPORTED
METHODDEF void
multi_2quant_dcontroller (decompress_info_ptr cinfo)
{
ERREXIT(cinfo->emethods, "Not implemented yet");
}
#endif /* QUANT_2PASS_SUPPORTED */
#endif /* MULTISCAN_FILES_SUPPORTED */
/* /*
@@ -1287,21 +989,18 @@ jseldpipeline (decompress_info_ptr cinfo)
if (cinfo->comps_in_scan == cinfo->num_components) { if (cinfo->comps_in_scan == cinfo->num_components) {
/* It's a single-scan file */ /* It's a single-scan file */
#ifdef QUANT_2PASS_SUPPORTED if (cinfo->two_pass_quantize) {
if (cinfo->two_pass_quantize) #ifdef NEED_COMPLEX_CONTROLLER
cinfo->methods->d_pipeline_controller = single_2quant_dcontroller; cinfo->methods->d_pipeline_controller = complex_dcontroller;
else #else
ERREXIT(cinfo->emethods, "2-pass quantization support was not compiled");
#endif #endif
cinfo->methods->d_pipeline_controller = single_dcontroller; } else
cinfo->methods->d_pipeline_controller = simple_dcontroller;
} else { } else {
/* It's a multiple-scan file */ /* It's a multiple-scan file */
#ifdef MULTISCAN_FILES_SUPPORTED #ifdef NEED_COMPLEX_CONTROLLER
#ifdef QUANT_2PASS_SUPPORTED cinfo->methods->d_pipeline_controller = complex_dcontroller;
if (cinfo->two_pass_quantize)
cinfo->methods->d_pipeline_controller = multi_2quant_dcontroller;
else
#endif
cinfo->methods->d_pipeline_controller = multi_dcontroller;
#else #else
ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled"); ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
#endif #endif

View File

@@ -1,7 +1,7 @@
/* /*
* jdsample.c * jdsample.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -26,30 +26,33 @@ unsubsample_init (decompress_info_ptr cinfo)
/* /*
* Un-subsample pixel values of a single component. * Un-subsample pixel values of a single component.
* This version only handles integral sampling ratios. * This version handles any integral sampling ratios.
* This is not used for typical JPEG files, so it need not be fast.
*/ */
METHODDEF void METHODDEF void
unsubsample (decompress_info_ptr cinfo, int which_component, int_unsubsample (decompress_info_ptr cinfo, int which_component,
long input_cols, int input_rows, long input_cols, int input_rows,
long output_cols, int output_rows, long output_cols, int output_rows,
JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below, JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
JSAMPARRAY output_data) JSAMPARRAY output_data)
{ {
jpeg_component_info * compptr = cinfo->cur_comp_info[which_component]; jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
short h_expand, v_expand, h, v; register JSAMPROW inptr, outptr;
register JSAMPLE invalue;
register short h_expand, h;
short v_expand, v;
int inrow, outrow; int inrow, outrow;
long incol; register long incol;
JSAMPROW inptr, outptr;
JSAMPLE invalue;
/* TEMP FOR DEBUGGING PIPELINE CONTROLLER */ #ifdef DEBUG /* for debugging pipeline controller */
if (input_rows != compptr->v_samp_factor || if (input_rows != compptr->v_samp_factor ||
output_rows != cinfo->max_v_samp_factor || output_rows != cinfo->max_v_samp_factor ||
(input_cols % compptr->h_samp_factor) != 0 || (input_cols % compptr->h_samp_factor) != 0 ||
(output_cols % cinfo->max_h_samp_factor) != 0 || (output_cols % cinfo->max_h_samp_factor) != 0 ||
output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor) output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor)
ERREXIT(cinfo->emethods, "Bogus unsubsample parameters"); ERREXIT(cinfo->emethods, "Bogus unsubsample parameters");
#endif
h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor; h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor; v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
@@ -70,6 +73,85 @@ unsubsample (decompress_info_ptr cinfo, int which_component,
} }
/*
* Un-subsample pixel values of a single component.
* This version handles the extremely common case of
* horizontal expansion by 2 and any integral vertical expansion.
*/
METHODDEF void
h2_unsubsample (decompress_info_ptr cinfo, int which_component,
long input_cols, int input_rows,
long output_cols, int output_rows,
JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
JSAMPARRAY output_data)
{
jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
register JSAMPROW inptr, outptr;
register JSAMPLE invalue;
short v_expand, v;
int inrow, outrow;
register long incol;
#ifdef DEBUG /* for debugging pipeline controller */
if (input_rows != compptr->v_samp_factor ||
output_rows != cinfo->max_v_samp_factor ||
(input_cols % compptr->h_samp_factor) != 0 ||
(output_cols % cinfo->max_h_samp_factor) != 0 ||
output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor)
ERREXIT(cinfo->emethods, "Bogus unsubsample parameters");
#endif
v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
/* The subsampled image width will always be a multiple of DCTSIZE,
* so we can unroll the inner loop.
*/
outrow = 0;
for (inrow = 0; inrow < input_rows; inrow++) {
for (v = 0; v < v_expand; v++) {
inptr = input_data[inrow];
outptr = output_data[outrow++];
#if DCTSIZE == 8
for (incol = 0; incol < input_cols; incol += DCTSIZE) {
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
}
#else /* nonstandard DCTSIZE */
for (incol = 0; incol < input_cols; incol++) {
invalue = GETJSAMPLE(*inptr++);
*outptr++ = invalue;
*outptr++ = invalue;
}
#endif
}
}
}
/* /*
* Un-subsample pixel values of a single component. * Un-subsample pixel values of a single component.
* This version handles the special case of a full-size component. * This version handles the special case of a full-size component.
@@ -82,8 +164,10 @@ fullsize_unsubsample (decompress_info_ptr cinfo, int which_component,
JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below, JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
JSAMPARRAY output_data) JSAMPARRAY output_data)
{ {
if (input_cols != output_cols || input_rows != output_rows) /* DEBUG */ #ifdef DEBUG /* for debugging pipeline controller */
if (input_cols != output_cols || input_rows != output_rows)
ERREXIT(cinfo->emethods, "Pipeline controller messed up"); ERREXIT(cinfo->emethods, "Pipeline controller messed up");
#endif
jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols); jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols);
} }
@@ -121,9 +205,12 @@ jselunsubsample (decompress_info_ptr cinfo)
if (compptr->h_samp_factor == cinfo->max_h_samp_factor && if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
compptr->v_samp_factor == cinfo->max_v_samp_factor) compptr->v_samp_factor == cinfo->max_v_samp_factor)
cinfo->methods->unsubsample[ci] = fullsize_unsubsample; cinfo->methods->unsubsample[ci] = fullsize_unsubsample;
else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
(cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
cinfo->methods->unsubsample[ci] = h2_unsubsample;
else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 && else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
(cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
cinfo->methods->unsubsample[ci] = unsubsample; cinfo->methods->unsubsample[ci] = int_unsubsample;
else else
ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet"); ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jerror.c * jerror.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -13,24 +13,28 @@
* The error_exit() routine should not return to its caller. Within a * The error_exit() routine should not return to its caller. Within a
* larger application, you might want to have it do a longjmp() to return * larger application, you might want to have it do a longjmp() to return
* control to the outer user interface routine. This should work since * control to the outer user interface routine. This should work since
* the portable JPEG code doesn't use setjmp/longjmp. However, this won't * the portable JPEG code doesn't use setjmp/longjmp. You should make sure
* release allocated memory or close temp files --- some bookkeeping would * that free_all is called either within error_exit or after the return to
* need to be added to the memory manager module to make that work. * the outer-level routine.
* *
* These routines are used by both the compression and decompression code. * These routines are used by both the compression and decompression code.
*/ */
#include "jinclude.h" #include "jinclude.h"
#ifdef __STDC__ #ifdef INCLUDES_ARE_ANSI
#include <stdlib.h> /* to declare exit() */ #include <stdlib.h> /* to declare exit() */
#endif #endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
static external_methods_ptr methods; /* saved for access to message_parm */
static external_methods_ptr methods; /* saved for access to message_parm, free_all */
METHODDEF void METHODDEF void
trace_message (char *msgtext) trace_message (const char *msgtext)
{ {
fprintf(stderr, msgtext, fprintf(stderr, msgtext,
methods->message_parm[0], methods->message_parm[1], methods->message_parm[0], methods->message_parm[1],
@@ -42,10 +46,11 @@ trace_message (char *msgtext)
METHODDEF void METHODDEF void
error_exit (char *msgtext) error_exit (const char *msgtext)
{ {
trace_message(msgtext); trace_message(msgtext);
exit(1); (*methods->free_all) (); /* clean up memory allocation */
exit(EXIT_FAILURE);
} }
@@ -58,7 +63,7 @@ error_exit (char *msgtext)
GLOBAL void GLOBAL void
jselerror (external_methods_ptr emethods) jselerror (external_methods_ptr emethods)
{ {
methods = emethods; /* save struct addr for msg parm access */ methods = emethods; /* save struct addr for later access */
emethods->error_exit = error_exit; emethods->error_exit = error_exit;
emethods->trace_message = trace_message; emethods->trace_message = trace_message;

257
jfwddct.c
View File

@@ -1,7 +1,7 @@
/* /*
* jfwddct.c * jfwddct.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -16,164 +16,193 @@
#include "jinclude.h" #include "jinclude.h"
/*
* This routine is specialized to the case DCTSIZE = 8.
*/
#if DCTSIZE != 8
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
#endif
/* The poop on this scaling stuff is as follows: /* The poop on this scaling stuff is as follows:
* *
* Most of the numbers (after multiplication by the constants) are * We have to do addition and subtraction of the integer inputs, which
* (logically) shifted left by LG2_DCT_SCALE. This is undone by UNFIXH * is no problem, and multiplication by fractional constants, which is
* before assignment to the output array. Note that we want an additional * a problem to do in integer arithmetic. We multiply all the constants
* division by 2 on the output (required by the equations). * by DCT_SCALE and convert them to integer constants (thus retaining
* LG2_DCT_SCALE bits of precision in the constants). After doing a
* multiplication we have to divide the product by DCT_SCALE, with proper
* rounding, to produce the correct output. The division can be implemented
* cheaply as a right shift of LG2_DCT_SCALE bits. The DCT equations also
* specify an additional division by 2 on the final outputs; this can be
* folded into the right-shift by shifting one more bit (see UNFIXH).
* *
* If right shifts are unsigned, then there is a potential problem. * If you are planning to recode this in assembler, you might want to set
* However, shifting right by 16 and then assigning to a short * LG2_DCT_SCALE to 15. This loses a bit of precision, but then all the
* (assuming short = 16 bits) will keep the sign right!! * multiplications are between 16-bit quantities (given 8-bit JSAMPLEs!)
* * so you could use a signed 16x16=>32 bit multiply instruction instead of
* For other shifts, * full 32x32 multiply. Unfortunately there's no way to describe such a
* * multiply portably in C, so we've gone for the extra bit of accuracy here.
* ((x + (1 << 30)) >> shft) - (1 << (30 - shft))
*
* gives a nice right shift with sign (assuming no overflow). However, all the
* scaling is such that this isn't a problem. (Is this true?)
*/ */
#ifdef EIGHT_BIT_SAMPLES
#define ONE 1L /* remove L if long > 32 bits */
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define LG2_DCT_SCALE 15
#define RIGHT_SHIFT(_x,_shft) ((((_x) + (ONE << 30)) >> (_shft)) - (ONE << (30 - (_shft))))
#else
#define LG2_DCT_SCALE 16 #define LG2_DCT_SCALE 16
#define RIGHT_SHIFT(_x,_shft) ((_x) >> (_shft)) #else
#define LG2_DCT_SCALE 15 /* lose a little precision to avoid overflow */
#endif #endif
#define ONE ((INT32) 1)
#define DCT_SCALE (ONE << LG2_DCT_SCALE) #define DCT_SCALE (ONE << LG2_DCT_SCALE)
/* In some places we shift the inputs left by a couple more bits, */
/* so that they can be added to fractional results without too much */
/* loss of precision. */
#define LG2_OVERSCALE 2 #define LG2_OVERSCALE 2
#define OVERSCALE (ONE << LG2_OVERSCALE) #define OVERSCALE (ONE << LG2_OVERSCALE)
#define OVERSHIFT(x) ((x) <<= LG2_OVERSCALE)
#define FIX(x) ((INT32) ((x) * DCT_SCALE + 0.5)) /* Scale a fractional constant by DCT_SCALE */
#define FIX(x) ((INT32) ((x) * DCT_SCALE + 0.5))
/* Scale a fractional constant by DCT_SCALE/OVERSCALE */
/* Such a constant can be multiplied with an overscaled input */
/* to produce something that's scaled by DCT_SCALE */
#define FIXO(x) ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5)) #define FIXO(x) ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5))
#define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
#define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
#define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)), LG2_DCT_SCALE-LG2_OVERSCALE)
#define OVERSH(x) ((x) << LG2_OVERSCALE)
#define SIN_1_4 FIX(0.7071067811856476) /* Descale and correctly round a value that's scaled by DCT_SCALE */
#define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
/* Same with an additional division by 2, ie, correctly rounded UNFIX(x/2) */
#define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
/* Take a value scaled by DCT_SCALE and round to integer scaled by OVERSCALE */
#define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)),\
LG2_DCT_SCALE-LG2_OVERSCALE)
/* Here are the constants we need */
/* SIN_i_j is sine of i*pi/j, scaled by DCT_SCALE */
/* COS_i_j is cosine of i*pi/j, scaled by DCT_SCALE */
#define SIN_1_4 FIX(0.707106781)
#define COS_1_4 SIN_1_4 #define COS_1_4 SIN_1_4
#define SIN_1_8 FIX(0.3826834323650898) #define SIN_1_8 FIX(0.382683432)
#define COS_1_8 FIX(0.9238795325112870) #define COS_1_8 FIX(0.923879533)
#define SIN_3_8 COS_1_8 #define SIN_3_8 COS_1_8
#define COS_3_8 SIN_1_8 #define COS_3_8 SIN_1_8
#define SIN_1_16 FIX(0.1950903220161282) #define SIN_1_16 FIX(0.195090322)
#define COS_1_16 FIX(0.9807852804032300) #define COS_1_16 FIX(0.980785280)
#define SIN_7_16 COS_1_16 #define SIN_7_16 COS_1_16
#define COS_7_16 SIN_1_16 #define COS_7_16 SIN_1_16
#define SIN_3_16 FIX(0.5555702330196022) #define SIN_3_16 FIX(0.555570233)
#define COS_3_16 FIX(0.8314696123025450) #define COS_3_16 FIX(0.831469612)
#define SIN_5_16 COS_3_16 #define SIN_5_16 COS_3_16
#define COS_5_16 SIN_3_16 #define COS_5_16 SIN_3_16
#define OSIN_1_4 FIXO(0.707106781185647) /* OSIN_i_j is sine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
/* OCOS_i_j is cosine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
#define OSIN_1_4 FIXO(0.707106781)
#define OCOS_1_4 OSIN_1_4 #define OCOS_1_4 OSIN_1_4
#define OSIN_1_8 FIXO(0.3826834323650898) #define OSIN_1_8 FIXO(0.382683432)
#define OCOS_1_8 FIXO(0.9238795325112870) #define OCOS_1_8 FIXO(0.923879533)
#define OSIN_3_8 OCOS_1_8 #define OSIN_3_8 OCOS_1_8
#define OCOS_3_8 OSIN_1_8 #define OCOS_3_8 OSIN_1_8
#define OSIN_1_16 FIXO(0.1950903220161282) #define OSIN_1_16 FIXO(0.195090322)
#define OCOS_1_16 FIXO(0.9807852804032300) #define OCOS_1_16 FIXO(0.980785280)
#define OSIN_7_16 OCOS_1_16 #define OSIN_7_16 OCOS_1_16
#define OCOS_7_16 OSIN_1_16 #define OCOS_7_16 OSIN_1_16
#define OSIN_3_16 FIXO(0.5555702330196022) #define OSIN_3_16 FIXO(0.555570233)
#define OCOS_3_16 FIXO(0.8314696123025450) #define OCOS_3_16 FIXO(0.831469612)
#define OSIN_5_16 OCOS_3_16 #define OSIN_5_16 OCOS_3_16
#define OCOS_5_16 OSIN_3_16 #define OCOS_5_16 OSIN_3_16
INLINE
LOCAL void
fast_dct_8 (DCTELEM *in, int stride)
{
/* tmp1x are new values of tmpx -- flashy register colourers
* should be able to do this lot very well
*/
INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17;
INT32 tmp25, tmp26;
INT32 in0, in1, in2, in3, in4, in5, in6, in7;
in0 = in[ 0];
in1 = in[stride ];
in2 = in[stride*2];
in3 = in[stride*3];
in4 = in[stride*4];
in5 = in[stride*5];
in6 = in[stride*6];
in7 = in[stride*7];
tmp0 = in7 + in0;
tmp1 = in6 + in1;
tmp2 = in5 + in2;
tmp3 = in4 + in3;
tmp4 = in3 - in4;
tmp5 = in2 - in5;
tmp6 = in1 - in6;
tmp7 = in0 - in7;
tmp10 = tmp3 + tmp0 ;
tmp11 = tmp2 + tmp1 ;
tmp12 = tmp1 - tmp2 ;
tmp13 = tmp0 - tmp3 ;
/* Now using tmp10, tmp11, tmp12, tmp13 */
in[ 0] = UNFIXH((tmp10 + tmp11) * SIN_1_4);
in[stride*4] = UNFIXH((tmp10 - tmp11) * COS_1_4);
in[stride*2] = UNFIXH(tmp13*COS_1_8 + tmp12*SIN_1_8);
in[stride*6] = UNFIXH(tmp13*SIN_1_8 - tmp12*COS_1_8);
tmp16 = UNFIXO((tmp6 + tmp5) * SIN_1_4);
tmp15 = UNFIXO((tmp6 - tmp5) * COS_1_4);
/* Now using tmp10, tmp11, tmp13, tmp14, tmp15, tmp16 */
tmp14 = OVERSH(tmp4) + tmp15;
tmp25 = OVERSH(tmp4) - tmp15;
tmp26 = OVERSH(tmp7) - tmp16;
tmp17 = OVERSH(tmp7) + tmp16;
/* These are now overscaled by OVERSCALE */
/* tmp10, tmp11, tmp12, tmp13, tmp14, tmp25, tmp26, tmp17 */
in[stride ] = UNFIXH(tmp17*OCOS_1_16 + tmp14*OSIN_1_16);
in[stride*7] = UNFIXH(tmp17*OCOS_7_16 - tmp14*OSIN_7_16);
in[stride*5] = UNFIXH(tmp26*OCOS_5_16 + tmp25*OSIN_5_16);
in[stride*3] = UNFIXH(tmp26*OCOS_3_16 - tmp25*OSIN_3_16);
}
/* /*
* Perform the forward DCT on one block of samples. * Perform the forward DCT on one block of samples.
* *
* Note that this code is specialized to the case DCTSIZE = 8. * A 2-D DCT can be done by 1-D DCT on each row
* followed by 1-D DCT on each column.
*/ */
GLOBAL void GLOBAL void
j_fwd_dct (DCTBLOCK data) j_fwd_dct (DCTBLOCK data)
{ {
int i; int pass, rowctr;
register DCTELEM *inptr, *outptr;
for (i = 0; i < DCTSIZE; i++) DCTBLOCK workspace;
fast_dct_8(data+i*DCTSIZE, 1);
for (i = 0; i < DCTSIZE; i++) /* Each iteration of the inner loop performs one 8-point 1-D DCT.
fast_dct_8(data+i, DCTSIZE); * It reads from a *row* of the input matrix and stores into a *column*
* of the output matrix. In the first pass, we read from the data[] array
* and store into the local workspace[]. In the second pass, we read from
* the workspace[] array and store into data[], thus performing the
* equivalent of a columnar DCT pass with no variable array indexing.
*/
inptr = data; /* initialize pointers for first pass */
outptr = workspace;
for (pass = 1; pass >= 0; pass--) {
for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
/* many tmps have nonoverlapping lifetime -- flashy register colourers
* should be able to do this lot very well
*/
INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
INT32 tmp10, tmp11, tmp12, tmp13;
INT32 tmp14, tmp15, tmp16, tmp17;
INT32 tmp25, tmp26;
SHIFT_TEMPS
tmp0 = inptr[7] + inptr[0];
tmp1 = inptr[6] + inptr[1];
tmp2 = inptr[5] + inptr[2];
tmp3 = inptr[4] + inptr[3];
tmp4 = inptr[3] - inptr[4];
tmp5 = inptr[2] - inptr[5];
tmp6 = inptr[1] - inptr[6];
tmp7 = inptr[0] - inptr[7];
tmp10 = tmp3 + tmp0;
tmp11 = tmp2 + tmp1;
tmp12 = tmp1 - tmp2;
tmp13 = tmp0 - tmp3;
outptr[ 0] = (DCTELEM) UNFIXH((tmp10 + tmp11) * SIN_1_4);
outptr[DCTSIZE*4] = (DCTELEM) UNFIXH((tmp10 - tmp11) * COS_1_4);
outptr[DCTSIZE*2] = (DCTELEM) UNFIXH(tmp13*COS_1_8 + tmp12*SIN_1_8);
outptr[DCTSIZE*6] = (DCTELEM) UNFIXH(tmp13*SIN_1_8 - tmp12*COS_1_8);
tmp16 = UNFIXO((tmp6 + tmp5) * SIN_1_4);
tmp15 = UNFIXO((tmp6 - tmp5) * COS_1_4);
OVERSHIFT(tmp4);
OVERSHIFT(tmp7);
/* tmp4, tmp7, tmp15, tmp16 are overscaled by OVERSCALE */
tmp14 = tmp4 + tmp15;
tmp25 = tmp4 - tmp15;
tmp26 = tmp7 - tmp16;
tmp17 = tmp7 + tmp16;
outptr[DCTSIZE ] = (DCTELEM) UNFIXH(tmp17*OCOS_1_16 + tmp14*OSIN_1_16);
outptr[DCTSIZE*7] = (DCTELEM) UNFIXH(tmp17*OCOS_7_16 - tmp14*OSIN_7_16);
outptr[DCTSIZE*5] = (DCTELEM) UNFIXH(tmp26*OCOS_5_16 + tmp25*OSIN_5_16);
outptr[DCTSIZE*3] = (DCTELEM) UNFIXH(tmp26*OCOS_3_16 - tmp25*OSIN_3_16);
inptr += DCTSIZE; /* advance inptr to next row */
outptr++; /* advance outptr to next column */
}
/* end of pass; in case it was pass 1, set up for pass 2 */
inptr = workspace;
outptr = data;
}
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jinclude.h * jinclude.h
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -13,12 +13,25 @@
*/ */
/*
* Normally the __STDC__ macro can be taken as indicating that the system
* include files conform to the ANSI C standard. However, if you are running
* GCC on a machine with non-ANSI system include files, that is not the case.
* In that case change the following, or add -DNONANSI_INCLUDES to your CFLAGS.
*/
#ifdef __STDC__
#ifndef NONANSI_INCLUDES
#define INCLUDES_ARE_ANSI /* this is what's tested before including */
#endif
#endif
/* /*
* <stdio.h> is included to get the FILE typedef and NULL macro. * <stdio.h> is included to get the FILE typedef and NULL macro.
* Note that the core portable-JPEG files do not actually do any I/O * Note that the core portable-JPEG files do not actually do any I/O
* using the stdio library; only the user interface, error handler, * using the stdio library; only the user interface, error handler,
* and file reading/writing modules invoke any stdio functions. * and file reading/writing modules invoke any stdio functions.
* (Well, we did cheat a bit in jvirtmem.c, but only if MEM_STATS is defined.) * (Well, we did cheat a bit in jmemmgr.c, but only if MEM_STATS is defined.)
*/ */
#include <stdio.h> #include <stdio.h>
@@ -27,11 +40,15 @@
* We need the size_t typedef, which defines the parameter type of malloc(). * We need the size_t typedef, which defines the parameter type of malloc().
* In an ANSI-conforming implementation this is provided by <stdio.h>, * In an ANSI-conforming implementation this is provided by <stdio.h>,
* but on non-ANSI systems it's more likely to be in <sys/types.h>. * but on non-ANSI systems it's more likely to be in <sys/types.h>.
* On some not-quite-ANSI systems you may find it in <stddef.h>.
*/ */
#ifndef __STDC__ /* shouldn't need this if __STDC__ */ #ifndef INCLUDES_ARE_ANSI /* shouldn't need this if ANSI C */
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef __SASC /* Amiga SAS C provides it in stddef.h. */
#include <stddef.h>
#endif
/* /*
* In ANSI C, and indeed any rational implementation, size_t is also the * In ANSI C, and indeed any rational implementation, size_t is also the
@@ -41,8 +58,20 @@
* we always use this SIZEOF() macro in place of using sizeof() directly. * we always use this SIZEOF() macro in place of using sizeof() directly.
*/ */
#undef SIZEOF /* in case you included X11/xmd.h */
#define SIZEOF(object) ((size_t) sizeof(object)) #define SIZEOF(object) ((size_t) sizeof(object))
/*
* fread() and fwrite() are always invoked through these macros.
* On some systems you may need to twiddle the argument casts.
* CAUTION: argument order is different from underlying functions!
*/
#define JFREAD(file,buf,sizeofbuf) \
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
#define JFWRITE(file,buf,sizeofbuf) \
((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
/* /*
* We need the memcpy() and strcmp() functions, plus memory zeroing. * We need the memcpy() and strcmp() functions, plus memory zeroing.
* ANSI and System V implementations declare these in <string.h>. * ANSI and System V implementations declare these in <string.h>.
@@ -51,10 +80,10 @@
* Insert casts in these macros if not! * Insert casts in these macros if not!
*/ */
#ifdef __STDC__ #ifdef INCLUDES_ARE_ANSI
#include <string.h> #include <string.h>
#define MEMZERO(voidptr,size) memset((voidptr), 0, (size)) #define MEMZERO(voidptr,size) memset((voidptr), 0, (size))
#else /* not STDC */ #else /* not ANSI */
#ifdef BSD #ifdef BSD
#include <strings.h> #include <strings.h>
#define MEMZERO(voidptr,size) bzero((voidptr), (size)) #define MEMZERO(voidptr,size) bzero((voidptr), (size))
@@ -63,7 +92,7 @@
#include <string.h> #include <string.h>
#define MEMZERO(voidptr,size) memset((voidptr), 0, (size)) #define MEMZERO(voidptr,size) memset((voidptr), 0, (size))
#endif /* BSD */ #endif /* BSD */
#endif /* STDC */ #endif /* ANSI */
/* Now include the portable JPEG definition files. */ /* Now include the portable JPEG definition files. */

157
jmemansi.c Normal file
View File

@@ -0,0 +1,157 @@
/*
* jmemansi.c (jmemsys.c)
*
* Copyright (C) 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides a simple generic implementation of the system-
* dependent portion of the JPEG memory manager. This implementation
* assumes that you have the ANSI-standard library routine tmpfile().
* Also, the problem of determining the amount of memory available
* is shoved onto the user.
*/
#include "jinclude.h"
#include "jmemsys.h"
#ifdef INCLUDES_ARE_ANSI
#include <stdlib.h> /* to declare malloc(), free() */
#else
extern void * malloc PP((size_t size));
extern void free PP((void *ptr));
#endif
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
#define SEEK_SET 0 /* if not, assume 0 is correct */
#endif
static external_methods_ptr methods; /* saved for access to error_exit */
static long total_used; /* total memory requested so far */
/*
* Memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL void *
jget_small (size_t sizeofobject)
{
total_used += sizeofobject;
return (void *) malloc(sizeofobject);
}
GLOBAL void
jfree_small (void * object)
{
free(object);
}
/*
* We assume NEED_FAR_POINTERS is not defined and so the separate entry points
* jget_large, jfree_large are not needed.
*/
/*
* This routine computes the total memory space available for allocation.
* It's impossible to do this in a portable way; our current solution is
* to make the user tell us (with a default value set at compile time).
* If you can actually get the available space, it's a good idea to subtract
* a slop factor of 5% or so.
*/
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
#endif
GLOBAL long
jmem_available (long min_bytes_needed, long max_bytes_needed)
{
return methods->max_memory_to_use - total_used;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jmem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
METHODDEF void
read_backing_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(methods, "fseek failed on temporary file");
if (JFREAD(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(methods, "fread failed on temporary file");
}
METHODDEF void
write_backing_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(methods, "fseek failed on temporary file");
if (JFWRITE(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(methods, "fwrite failed on temporary file --- out of disk space?");
}
METHODDEF void
close_backing_store (backing_store_ptr info)
{
fclose(info->temp_file);
/* Since this implementation uses tmpfile() to create the file,
* no explicit file deletion is needed.
*/
}
/*
* Initial opening of a backing-store object.
*
* This version uses tmpfile(), which constructs a suitable file name
* behind the scenes. We don't have to use temp_name[] at all;
* indeed, we can't even find out the actual name of the temp file.
*/
GLOBAL void
jopen_backing_store (backing_store_ptr info, long total_bytes_needed)
{
if ((info->temp_file = tmpfile()) == NULL)
ERREXIT(methods, "Failed to create temporary file");
info->read_backing_store = read_backing_store;
info->write_backing_store = write_backing_store;
info->close_backing_store = close_backing_store;
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required. Keep in mind that jmem_term may be called more than
* once.
*/
GLOBAL void
jmem_init (external_methods_ptr emethods)
{
methods = emethods; /* save struct addr for error exit access */
emethods->max_memory_to_use = DEFAULT_MAX_MEM;
total_used = 0;
}
GLOBAL void
jmem_term (void)
{
/* no work */
}

608
jmemdos.c Normal file
View File

@@ -0,0 +1,608 @@
/*
* jmemdos.c (jmemsys.c)
*
* Copyright (C) 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides an MS-DOS-compatible implementation of the system-
* dependent portion of the JPEG memory manager. Temporary data can be
* stored in extended or expanded memory as well as in regular DOS files.
*
* If you use this file, you must be sure that NEED_FAR_POINTERS is defined
* if you compile in a small-data memory model; it should NOT be defined if
* you use a large-data memory model. This file is not recommended if you
* are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
*
* Based on code contributed by Ge' Weijers.
*/
/*
* If you have both extended and expanded memory, you may want to change the
* order in which they are tried in jopen_backing_store. On a 286 machine
* expanded memory is usually faster, since extended memory access involves
* an expensive protected-mode-and-back switch. On 386 and better, extended
* memory is usually faster. As distributed, the code tries extended memory
* first (what? not everyone has a 386? :-).
*
* You can disable use of extended/expanded memory entirely by altering these
* definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
*/
#ifndef XMS_SUPPORTED
#define XMS_SUPPORTED 1
#endif
#ifndef EMS_SUPPORTED
#define EMS_SUPPORTED 1
#endif
#include "jinclude.h"
#include "jmemsys.h"
#ifdef INCLUDES_ARE_ANSI
#include <stdlib.h> /* to declare malloc(), free() */
#else
extern void * malloc PP((size_t size));
extern void free PP((void *ptr));
#endif
#ifdef NEED_FAR_POINTERS
#ifdef __TURBOC__
/* These definitions work for Borland C (Turbo C) */
#include <alloc.h> /* need farmalloc(), farfree() */
#define far_malloc(x) farmalloc(x)
#define far_free(x) farfree(x)
#else
/* These definitions work for Microsoft C and compatible compilers */
#include <malloc.h> /* need _fmalloc(), _ffree() */
#define far_malloc(x) _fmalloc(x)
#define far_free(x) _ffree(x)
#endif
#endif
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#else
#define READ_BINARY "rb"
#endif
/*
* Declarations for assembly-language support routines (see jmemdosa.asm).
*
* The functions are declared "far" as are all pointer arguments;
* this ensures the assembly source code will work regardless of the
* compiler memory model. We assume "short" is 16 bits, "long" is 32.
*/
typedef void far * XMSDRIVER; /* actually a pointer to code */
typedef struct { /* registers for calling XMS driver */
unsigned short ax, dx, bx;
void far * ds_si;
} XMScontext;
typedef struct { /* registers for calling EMS driver */
unsigned short ax, dx, bx;
void far * ds_si;
} EMScontext;
EXTERN short far jdos_open PP((short far * handle, char far * filename));
EXTERN short far jdos_close PP((short handle));
EXTERN short far jdos_seek PP((short handle, long offset));
EXTERN short far jdos_read PP((short handle, void far * buffer,
unsigned short count));
EXTERN short far jdos_write PP((short handle, void far * buffer,
unsigned short count));
EXTERN void far jxms_getdriver PP((XMSDRIVER far *));
EXTERN void far jxms_calldriver PP((XMSDRIVER, XMScontext far *));
EXTERN short far jems_available PP((void));
EXTERN void far jems_calldriver PP((EMScontext far *));
static external_methods_ptr methods; /* saved for access to error_exit */
static long total_used; /* total FAR memory requested so far */
/*
* Selection of a file name for a temporary file.
* This is highly system-dependent, and you may want to customize it.
*/
static int next_file_num; /* to distinguish among several temp files */
LOCAL void
select_file_name (char * fname)
{
const char * env;
char * ptr;
FILE * tfile;
/* Keep generating file names till we find one that's not in use */
for (;;) {
/* Get temp directory name from environment TMP or TEMP variable;
* if none, use "."
*/
if ((env = (const char *) getenv("TMP")) == NULL)
if ((env = (const char *) getenv("TEMP")) == NULL)
env = ".";
if (*env == '\0') /* null string means "." */
env = ".";
ptr = fname; /* copy name to fname */
while (*env != '\0')
*ptr++ = *env++;
if (ptr[-1] != '\\' && ptr[-1] != '/')
*ptr++ = '\\'; /* append backslash if not in env variable */
/* Append a suitable file name */
next_file_num++; /* advance counter */
sprintf(ptr, "JPG%03d.TMP", next_file_num);
/* Probe to see if file name is already in use */
if ((tfile = fopen(fname, READ_BINARY)) == NULL)
break;
fclose(tfile); /* oops, it's there; close tfile & try again */
}
}
/*
* Near-memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL void *
jget_small (size_t sizeofobject)
{
/* near data space is NOT counted in total_used */
#ifndef NEED_FAR_POINTERS
total_used += sizeofobject;
#endif
return (void *) malloc(sizeofobject);
}
GLOBAL void
jfree_small (void * object)
{
free(object);
}
/*
* Far-memory allocation and freeing
*/
#ifdef NEED_FAR_POINTERS
GLOBAL void FAR *
jget_large (size_t sizeofobject)
{
total_used += sizeofobject;
return (void FAR *) far_malloc(sizeofobject);
}
GLOBAL void
jfree_large (void FAR * object)
{
far_free(object);
}
#endif
/*
* This routine computes the total memory space available for allocation.
* It's impossible to do this in a portable way; our current solution is
* to make the user tell us (with a default value set at compile time).
* If you can actually get the available space, it's a good idea to subtract
* a slop factor of 5% or so.
*/
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */
#endif
GLOBAL long
jmem_available (long min_bytes_needed, long max_bytes_needed)
{
return methods->max_memory_to_use - total_used;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jmem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
/*
* For MS-DOS we support three types of backing storage:
* 1. Conventional DOS files. We access these by direct DOS calls rather
* than via the stdio package. This provides a bit better performance,
* but the real reason is that the buffers to be read or written are FAR.
* The stdio library for small-data memory models can't cope with that.
* 2. Extended memory, accessed per the XMS V2.0 specification.
* 3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
* You'll need copies of those specs to make sense of the related code.
* The specs are available by Internet FTP from SIMTEL20 and its various
* mirror sites; see microsoft/xms20.arc and info/limems41.zip.
*/
/*
* Access methods for a DOS file.
*/
METHODDEF void
read_file_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
if (jdos_seek(info->handle.file_handle, file_offset))
ERREXIT(methods, "seek failed on temporary file");
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
if (byte_count > 65535L) /* safety check */
ERREXIT(methods, "MAX_ALLOC_CHUNK should be less than 64K");
if (jdos_read(info->handle.file_handle, buffer_address,
(unsigned short) byte_count))
ERREXIT(methods, "read failed on temporary file");
}
METHODDEF void
write_file_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
if (jdos_seek(info->handle.file_handle, file_offset))
ERREXIT(methods, "seek failed on temporary file");
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
if (byte_count > 65535L) /* safety check */
ERREXIT(methods, "MAX_ALLOC_CHUNK should be less than 64K");
if (jdos_write(info->handle.file_handle, buffer_address,
(unsigned short) byte_count))
ERREXIT(methods, "write failed on temporary file --- out of disk space?");
}
METHODDEF void
close_file_store (backing_store_ptr info)
{
jdos_close(info->handle.file_handle); /* close the file */
remove(info->temp_name); /* delete the file */
/* If your system doesn't have remove(), try unlink() instead.
* remove() is the ANSI-standard name for this function, but
* unlink() was more common in pre-ANSI systems.
*/
TRACEMS1(methods, 1, "Closed DOS file %d", info->handle.file_handle);
}
LOCAL boolean
open_file_store (backing_store_ptr info, long total_bytes_needed)
{
short handle;
char tracemsg[TEMP_NAME_LENGTH+40];
select_file_name(info->temp_name);
if (jdos_open((short far *) & handle, (char far *) info->temp_name))
return FALSE;
info->handle.file_handle = handle;
info->read_backing_store = read_file_store;
info->write_backing_store = write_file_store;
info->close_backing_store = close_file_store;
/* hack to get around TRACEMS' inability to handle string parameters */
sprintf(tracemsg, "Opened DOS file %d %s", handle, info->temp_name);
TRACEMS(methods, 1, tracemsg);
return TRUE; /* succeeded */
}
/*
* Access methods for extended memory.
*/
#if XMS_SUPPORTED
static XMSDRIVER xms_driver; /* saved address of XMS driver */
typedef union { /* either long offset or real-mode pointer */
long offset;
void far * ptr;
} XMSPTR;
typedef struct { /* XMS move specification structure */
long length;
XMSH src_handle;
XMSPTR src;
XMSH dst_handle;
XMSPTR dst;
} XMSspec;
#define ODD(X) (((X) & 1L) != 0)
METHODDEF void
read_xms_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
XMScontext ctx;
XMSspec spec;
char endbuffer[2];
/* The XMS driver can't cope with an odd length, so handle the last byte
* specially if byte_count is odd. We don't expect this to be common.
*/
spec.length = byte_count & (~ 1L);
spec.src_handle = info->handle.xms_handle;
spec.src.offset = file_offset;
spec.dst_handle = 0;
spec.dst.ptr = buffer_address;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x0b00; /* EMB move */
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
ERREXIT(methods, "read from extended memory failed");
if (ODD(byte_count)) {
read_xms_store(info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
}
}
METHODDEF void
write_xms_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
XMScontext ctx;
XMSspec spec;
char endbuffer[2];
/* The XMS driver can't cope with an odd length, so handle the last byte
* specially if byte_count is odd. We don't expect this to be common.
*/
spec.length = byte_count & (~ 1L);
spec.src_handle = 0;
spec.src.ptr = buffer_address;
spec.dst_handle = info->handle.xms_handle;
spec.dst.offset = file_offset;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x0b00; /* EMB move */
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
ERREXIT(methods, "write to extended memory failed");
if (ODD(byte_count)) {
read_xms_store(info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
write_xms_store(info, (void FAR *) endbuffer,
file_offset + byte_count - 1L, 2L);
}
}
METHODDEF void
close_xms_store (backing_store_ptr info)
{
XMScontext ctx;
ctx.dx = info->handle.xms_handle;
ctx.ax = 0x0a00;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
TRACEMS1(methods, 1, "Freed XMS handle %u", info->handle.xms_handle);
/* we ignore any error return from the driver */
}
LOCAL boolean
open_xms_store (backing_store_ptr info, long total_bytes_needed)
{
XMScontext ctx;
/* Get address of XMS driver */
jxms_getdriver((XMSDRIVER far *) & xms_driver);
if (xms_driver == NULL)
return FALSE; /* no driver to be had */
/* Get version number, must be >= 2.00 */
ctx.ax = 0x0000;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax < (unsigned short) 0x0200)
return FALSE;
/* Try to get space (expressed in kilobytes) */
ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
ctx.ax = 0x0900;
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
if (ctx.ax != 1)
return FALSE;
/* Succeeded, save the handle and away we go */
info->handle.xms_handle = ctx.dx;
info->read_backing_store = read_xms_store;
info->write_backing_store = write_xms_store;
info->close_backing_store = close_xms_store;
TRACEMS1(methods, 1, "Obtained XMS handle %u", ctx.dx);
return TRUE; /* succeeded */
}
#endif /* XMS_SUPPORTED */
/*
* Access methods for expanded memory.
*/
#if EMS_SUPPORTED
typedef union { /* either offset/page or real-mode pointer */
struct { unsigned short offset, page; } ems;
void far * ptr;
} EMSPTR;
typedef struct { /* EMS move specification structure */
long length;
char src_type; /* 1 = EMS, 0 = conventional memory */
EMSH src_handle; /* use 0 if conventional memory */
EMSPTR src;
char dst_type;
EMSH dst_handle;
EMSPTR dst;
} EMSspec;
#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */
#define HIBYTE(W) (((W) >> 8) & 0xFF)
#define LOBYTE(W) ((W) & 0xFF)
METHODDEF void
read_ems_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
EMScontext ctx;
EMSspec spec;
spec.length = byte_count;
spec.src_type = 1;
spec.src_handle = info->handle.ems_handle;
spec.src.ems.page = (unsigned short) (file_offset / EMSPAGESIZE);
spec.src.ems.offset = (unsigned short) (file_offset % EMSPAGESIZE);
spec.dst_type = 0;
spec.dst_handle = 0;
spec.dst.ptr = buffer_address;
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x5700; /* move memory region */
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
ERREXIT(methods, "read from expanded memory failed");
}
METHODDEF void
write_ems_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
EMScontext ctx;
EMSspec spec;
spec.length = byte_count;
spec.src_type = 0;
spec.src_handle = 0;
spec.src.ptr = buffer_address;
spec.dst_type = 1;
spec.dst_handle = info->handle.ems_handle;
spec.dst.ems.page = (unsigned short) (file_offset / EMSPAGESIZE);
spec.dst.ems.offset = (unsigned short) (file_offset % EMSPAGESIZE);
ctx.ds_si = (void far *) & spec;
ctx.ax = 0x5700; /* move memory region */
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
ERREXIT(methods, "write to expanded memory failed");
}
METHODDEF void
close_ems_store (backing_store_ptr info)
{
EMScontext ctx;
ctx.ax = 0x4500;
ctx.dx = info->handle.ems_handle;
jems_calldriver((EMScontext far *) & ctx);
TRACEMS1(methods, 1, "Freed EMS handle %u", info->handle.ems_handle);
/* we ignore any error return from the driver */
}
LOCAL boolean
open_ems_store (backing_store_ptr info, long total_bytes_needed)
{
EMScontext ctx;
/* Is EMS driver there? */
if (! jems_available())
return FALSE;
/* Get status, make sure EMS is OK */
ctx.ax = 0x4000;
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
return FALSE;
/* Get version, must be >= 4.0 */
ctx.ax = 0x4600;
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
return FALSE;
/* Try to allocate requested space */
ctx.ax = 0x4300;
ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
jems_calldriver((EMScontext far *) & ctx);
if (HIBYTE(ctx.ax) != 0)
return FALSE;
/* Succeeded, save the handle and away we go */
info->handle.ems_handle = ctx.dx;
info->read_backing_store = read_ems_store;
info->write_backing_store = write_ems_store;
info->close_backing_store = close_ems_store;
TRACEMS1(methods, 1, "Obtained EMS handle %u", ctx.dx);
return TRUE; /* succeeded */
}
#endif /* EMS_SUPPORTED */
/*
* Initial opening of a backing-store object.
*/
GLOBAL void
jopen_backing_store (backing_store_ptr info, long total_bytes_needed)
{
/* Try extended memory, then expanded memory, then regular file. */
#if XMS_SUPPORTED
if (open_xms_store(info, total_bytes_needed))
return;
#endif
#if EMS_SUPPORTED
if (open_ems_store(info, total_bytes_needed))
return;
#endif
if (open_file_store(info, total_bytes_needed))
return;
ERREXIT(methods, "Failed to create temporary file");
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required. Keep in mind that jmem_term may be called more than
* once.
*/
GLOBAL void
jmem_init (external_methods_ptr emethods)
{
methods = emethods; /* save struct addr for error exit access */
emethods->max_memory_to_use = DEFAULT_MAX_MEM;
total_used = 0;
next_file_num = 0;
}
GLOBAL void
jmem_term (void)
{
/* no work */
}

135
jmemdos.h Normal file
View File

@@ -0,0 +1,135 @@
/*
* jmemdos.h (jmemsys.h)
*
* Copyright (C) 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This include file defines the interface between the system-independent
* and system-dependent portions of the JPEG memory manager. (The system-
* independent portion is jmemmgr.c; there are several different versions
* of the system-dependent portion, and of this file for that matter.)
*
* This version is suitable for MS-DOS (80x86) implementations.
*/
/*
* These two functions are used to allocate and release small chunks of
* memory (typically the total amount requested through jget_small is
* no more than 20Kb or so). Behavior should be the same as for the
* standard library functions malloc and free; in particular, jget_small
* returns NULL on failure. On most systems, these ARE malloc and free.
* On an 80x86 machine using small-data memory model, these manage near heap.
*/
EXTERN void * jget_small PP((size_t sizeofobject));
EXTERN void jfree_small PP((void * object));
/*
* These two functions are used to allocate and release large chunks of
* memory (up to the total free space designated by jmem_available).
* The interface is the same as above, except that on an 80x86 machine,
* far pointers are used. On other systems these ARE the same as above.
*/
#ifdef NEED_FAR_POINTERS /* typically not needed except on 80x86 */
EXTERN void FAR * jget_large PP((size_t sizeofobject));
EXTERN void jfree_large PP((void FAR * object));
#else
#define jget_large(sizeofobject) jget_small(sizeofobject)
#define jfree_large(object) jfree_small(object)
#endif
/*
* The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
* be requested in a single call on jget_large (and jget_small for that
* matter, but that case should never come into play). This macro is needed
* to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
* On machines with flat address spaces, any large constant may be used here.
*/
#define MAX_ALLOC_CHUNK 65400L
/*
* This routine computes the total space available for allocation by
* jget_large. If more space than this is needed, backing store will be used.
* NOTE: any memory already allocated must not be counted.
*
* There is a minimum space requirement, corresponding to the minimum
* feasible buffer sizes; jmemmgr.c will request that much space even if
* jmem_available returns zero. The maximum space needed, enough to hold
* all working storage in memory, is also passed in case it is useful.
*
* It is OK for jmem_available to underestimate the space available (that'll
* just lead to more backing-store access than is really necessary).
* However, an overestimate will lead to failure. Hence it's wise to subtract
* a slop factor from the true available space, especially if jget_small space
* comes from the same pool. 5% should be enough.
*
* On machines with lots of virtual memory, any large constant may be returned.
* Conversely, zero may be returned to always use the minimum amount of memory.
*/
EXTERN long jmem_available PP((long min_bytes_needed, long max_bytes_needed));
/*
* This structure holds whatever state is needed to access a single
* backing-store object. The read/write/close method pointers are called
* by jmemmgr.c to manipulate the backing-store object; all other fields
* are private to the system-dependent backing store routines.
*/
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
typedef unsigned short XMSH; /* type of extended-memory handles */
typedef unsigned short EMSH; /* type of expanded-memory handles */
typedef union {
short file_handle; /* DOS file handle if it's a temp file */
XMSH xms_handle; /* handle if it's a chunk of XMS */
EMSH ems_handle; /* handle if it's a chunk of EMS */
} handle_union;
typedef struct backing_store_struct * backing_store_ptr;
typedef struct backing_store_struct {
/* Methods for reading/writing/closing this backing-store object */
METHOD(void, read_backing_store, (backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count));
METHOD(void, write_backing_store, (backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count));
METHOD(void, close_backing_store, (backing_store_ptr info));
/* Private fields for system-dependent backing-store management */
/* For the MS-DOS environment, we need: */
handle_union handle; /* reference to backing-store storage object */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
} backing_store_info;
/*
* Initial opening of a backing-store object. This must fill in the
* read/write/close pointers in the object. The read/write routines
* may take an error exit if the specified maximum file size is exceeded.
* (If jmem_available always returns a large value, this routine can just
* take an error exit.)
*/
EXTERN void jopen_backing_store PP((backing_store_ptr info,
long total_bytes_needed));
/*
* These routines take care of any system-dependent initialization and
* cleanup required. The system methods struct address should be saved
* by jmem_init in case an error exit must be taken. jmem_term may assume
* that all requested memory has been freed and that all opened backing-
* store objects have been closed.
* NB: jmem_term may be called more than once, and must behave reasonably
* if that happens.
*/
EXTERN void jmem_init PP((external_methods_ptr emethods));
EXTERN void jmem_term PP((void));

379
jmemdosa.asm Normal file
View File

@@ -0,0 +1,379 @@
;
; jmemdosa.asm
;
; Copyright (C) 1992, Thomas G. Lane.
; This file is part of the Independent JPEG Group's software.
; For conditions of distribution and use, see the accompanying README file.
;
; This file contains low-level interface routines to support the MS-DOS
; backing store manager (jmemdos.c). Routines are provided to access disk
; files through direct DOS calls, and to access XMS and EMS drivers.
;
; This file should assemble with Microsoft's MASM or any compatible
; assembler (including Borland's Turbo Assembler). If you haven't got
; a compatible assembler, better fall back to jmemansi.c or jmemname.c.
;
; To minimize dependence on the C compiler's register usage conventions,
; we save and restore all 8086 registers, even though most compilers only
; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return
; values, which everybody returns in AX.
;
; Based on code contributed by Ge' Weijers.
;
JMEMDOSA_TXT segment byte public 'CODE'
assume cs:JMEMDOSA_TXT
public _jdos_open
public _jdos_close
public _jdos_seek
public _jdos_read
public _jdos_write
public _jxms_getdriver
public _jxms_calldriver
public _jems_available
public _jems_calldriver
;
; short far jdos_open (short far * handle, char far * filename)
;
; Create and open a temporary file
;
_jdos_open proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov cx,0 ; normal file attributes
lds dx,dword ptr [bp+10] ; get filename pointer
mov ah,3ch ; create file
int 21h
jc open_err ; if failed, return error code
lds bx,dword ptr [bp+6] ; get handle pointer
mov word ptr [bx],ax ; save the handle
xor ax,ax ; return zero for OK
open_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_open endp
;
; short far jdos_close (short handle)
;
; Close the file handle
;
_jdos_close proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
mov ah,3eh ; close file
int 21h
jc close_err ; if failed, return error code
xor ax,ax ; return zero for OK
close_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_close endp
;
; short far jdos_seek (short handle, long offset)
;
; Set file position
;
_jdos_seek proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
mov dx,word ptr [bp+8] ; LS offset
mov cx,word ptr [bp+10] ; MS offset
mov ax,4200h ; absolute seek
int 21h
jc seek_err ; if failed, return error code
xor ax,ax ; return zero for OK
seek_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_seek endp
;
; short far jdos_read (short handle, void far * buffer, unsigned short count)
;
; Read from file
;
_jdos_read proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
lds dx,dword ptr [bp+8] ; buffer address
mov cx,word ptr [bp+12] ; number of bytes
mov ah,3fh ; read file
int 21h
jc read_err ; if failed, return error code
cmp ax,word ptr [bp+12] ; make sure all bytes were read
je read_ok
mov ax,1 ; else return 1 for not OK
jmp short read_err
read_ok: xor ax,ax ; return zero for OK
read_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_read endp
;
; short far jdos_write (short handle, void far * buffer, unsigned short count)
;
; Write to file
;
_jdos_write proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov bx,word ptr [bp+6] ; file handle
lds dx,dword ptr [bp+8] ; buffer address
mov cx,word ptr [bp+12] ; number of bytes
mov ah,40h ; write file
int 21h
jc write_err ; if failed, return error code
cmp ax,word ptr [bp+12] ; make sure all bytes written
je write_ok
mov ax,1 ; else return 1 for not OK
jmp short write_err
write_ok: xor ax,ax ; return zero for OK
write_err: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jdos_write endp
;
; void far jxms_getdriver (XMSDRIVER far *)
;
; Get the address of the XMS driver, or NULL if not available
;
_jxms_getdriver proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov ax,4300h ; call multiplex interrupt with
int 2fh ; a magic cookie, hex 4300
cmp al,80h ; AL should contain hex 80
je xmsavail
xor dx,dx ; no XMS driver available
xor ax,ax ; return a nil pointer
jmp short xmsavail_done
xmsavail: mov ax,4310h ; fetch driver address with
int 2fh ; another magic cookie
mov dx,es ; copy address to dx:ax
mov ax,bx
xmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value
mov word ptr es:[bx],ax
mov word ptr es:[bx+2],dx
pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jxms_getdriver endp
;
; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
;
; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.
; These are loaded, the XMS call is performed, and the new values of the
; AX,DX,BX registers are written back to the context structure.
;
_jxms_calldriver proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
les bx,dword ptr [bp+10] ; get XMScontext pointer
mov ax,word ptr es:[bx] ; load registers
mov dx,word ptr es:[bx+2]
mov si,word ptr es:[bx+6]
mov ds,word ptr es:[bx+8]
mov bx,word ptr es:[bx+4]
call dword ptr [bp+6] ; call the driver
mov cx,bx ; save returned BX for a sec
les bx,dword ptr [bp+10] ; get XMScontext pointer
mov word ptr es:[bx],ax ; put back ax,dx,bx
mov word ptr es:[bx+2],dx
mov word ptr es:[bx+4],cx
pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jxms_calldriver endp
;
; short far jems_available (void)
;
; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
;
_jems_available proc far
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
mov ax,3567h ; get interrupt vector 67h
int 21h
push cs
pop ds
mov di,000ah ; check offs 10 in returned seg
lea si,ASCII_device_name ; against literal string
mov cx,8
cld
repe cmpsb
jne no_ems
mov ax,1 ; match, it's there
jmp short avail_done
no_ems: xor ax,ax ; it's not there
avail_done: pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
ret
ASCII_device_name db "EMMXXXX0"
_jems_available endp
;
; void far jems_calldriver (EMScontext far *)
;
; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers.
; These are loaded, the EMS trap is performed, and the new values of the
; AX,DX,BX registers are written back to the context structure.
;
_jems_calldriver proc far
push bp ; linkage
mov bp,sp
push si ; save all registers for safety
push di
push bx
push cx
push dx
push es
push ds
les bx,dword ptr [bp+6] ; get EMScontext pointer
mov ax,word ptr es:[bx] ; load registers
mov dx,word ptr es:[bx+2]
mov si,word ptr es:[bx+6]
mov ds,word ptr es:[bx+8]
mov bx,word ptr es:[bx+4]
int 67h ; call the EMS driver
mov cx,bx ; save returned BX for a sec
les bx,dword ptr [bp+6] ; get EMScontext pointer
mov word ptr es:[bx],ax ; put back ax,dx,bx
mov word ptr es:[bx+2],dx
mov word ptr es:[bx+4],cx
pop ds ; restore registers and exit
pop es
pop dx
pop cx
pop bx
pop di
pop si
pop bp
ret
_jems_calldriver endp
JMEMDOSA_TXT ends
end

1049
jmemmgr.c Normal file

File diff suppressed because it is too large Load Diff

248
jmemname.c Normal file
View File

@@ -0,0 +1,248 @@
/*
* jmemname.c (jmemsys.c)
*
* Copyright (C) 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides a generic implementation of the system-dependent
* portion of the JPEG memory manager. This implementation assumes that
* you must explicitly construct a name for each temp file.
* Also, the problem of determining the amount of memory available
* is shoved onto the user.
*/
#include "jinclude.h"
#include "jmemsys.h"
#ifdef INCLUDES_ARE_ANSI
#include <stdlib.h> /* to declare malloc(), free() */
#else
extern void * malloc PP((size_t size));
extern void free PP((void *ptr));
#endif
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
#define SEEK_SET 0 /* if not, assume 0 is correct */
#endif
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#define RW_BINARY "w+"
#else
#define READ_BINARY "rb"
#define RW_BINARY "w+b"
#endif
static external_methods_ptr methods; /* saved for access to error_exit */
static long total_used; /* total memory requested so far */
/*
* Selection of a file name for a temporary file.
* This is system-dependent!
*
* The code as given is suitable for most Unix systems, and it is easily
* modified for most non-Unix systems. Some notes:
* 1. The temp file is created in the directory named by TEMP_DIRECTORY.
* The default value is /usr/tmp, which is the conventional place for
* creating large temp files on Unix. On other systems you'll probably
* want to change the file location. You can do this by editing the
* #define, or by defining TEMP_DIRECTORY in CFLAGS in the Makefile.
* For example, you might say
* CFLAGS= ... '-DTEMP_DIRECTORY="/tmp/"'
* Note that double quotes are needed in the text of the macro.
* With most make systems you have to put single quotes around the
* -D construct to preserve the double quotes.
* (Amiga SAS C has trouble with ":" and such in command-line options,
* so we've put in a special case for the preferred Amiga temp directory.)
*
* 2. If you need to change the file name as well as its location,
* you can override the TEMP_FILE_NAME macro. (Note that this is
* actually a printf format string; it must contain %s and %d.)
* Few people should need to do this.
*
* 3. mktemp() is used to ensure that multiple processes running
* simultaneously won't select the same file names. If your system
* doesn't have mktemp(), define NO_MKTEMP to do it the hard way.
*
* 4. You probably want to define NEED_SIGNAL_CATCHER so that jcmain/jdmain
* will cause the temp files to be removed if you stop the program early.
*/
#ifndef TEMP_DIRECTORY /* so can override from Makefile */
#ifdef AMIGA
#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
#else
#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */
#endif
#endif
static int next_file_num; /* to distinguish among several temp files */
#ifdef NO_MKTEMP
#ifndef TEMP_FILE_NAME /* so can override from Makefile */
#define TEMP_FILE_NAME "%sJPG%03d.TMP"
#endif
LOCAL void
select_file_name (char * fname)
{
FILE * tfile;
/* Keep generating file names till we find one that's not in use */
for (;;) {
next_file_num++; /* advance counter */
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
if ((tfile = fopen(fname, READ_BINARY)) == NULL)
break;
fclose(tfile); /* oops, it's there; close tfile & try again */
}
}
#else /* ! NO_MKTEMP */
/* Note that mktemp() requires the initial filename to end in six X's */
#ifndef TEMP_FILE_NAME /* so can override from Makefile */
#define TEMP_FILE_NAME "%sJPG%dXXXXXX"
#endif
LOCAL void
select_file_name (char * fname)
{
next_file_num++; /* advance counter */
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
mktemp(fname); /* make sure file name is unique */
/* mktemp replaces the trailing XXXXXX with a unique string of characters */
}
#endif /* NO_MKTEMP */
/*
* Memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL void *
jget_small (size_t sizeofobject)
{
total_used += sizeofobject;
return (void *) malloc(sizeofobject);
}
GLOBAL void
jfree_small (void * object)
{
free(object);
}
/*
* We assume NEED_FAR_POINTERS is not defined and so the separate entry points
* jget_large, jfree_large are not needed.
*/
/*
* This routine computes the total memory space available for allocation.
* It's impossible to do this in a portable way; our current solution is
* to make the user tell us (with a default value set at compile time).
* If you can actually get the available space, it's a good idea to subtract
* a slop factor of 5% or so.
*/
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
#endif
GLOBAL long
jmem_available (long min_bytes_needed, long max_bytes_needed)
{
return methods->max_memory_to_use - total_used;
}
/*
* Backing store (temporary file) management.
* Backing store objects are only used when the value returned by
* jmem_available is less than the total space needed. You can dispense
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
*/
METHODDEF void
read_backing_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(methods, "fseek failed on temporary file");
if (JFREAD(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(methods, "fread failed on temporary file");
}
METHODDEF void
write_backing_store (backing_store_ptr info, void FAR * buffer_address,
long file_offset, long byte_count)
{
if (fseek(info->temp_file, file_offset, SEEK_SET))
ERREXIT(methods, "fseek failed on temporary file");
if (JFWRITE(info->temp_file, buffer_address, byte_count)
!= (size_t) byte_count)
ERREXIT(methods, "fwrite failed on temporary file --- out of disk space?");
}
METHODDEF void
close_backing_store (backing_store_ptr info)
{
fclose(info->temp_file); /* close the file */
unlink(info->temp_name); /* delete the file */
/* If your system doesn't have unlink(), use remove() instead.
* remove() is the ANSI-standard name for this function, but if
* your system was ANSI you'd be using jmemansi.c, right?
*/
}
GLOBAL void
jopen_backing_store (backing_store_ptr info, long total_bytes_needed)
{
char tracemsg[TEMP_NAME_LENGTH+40];
select_file_name(info->temp_name);
if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL)
ERREXIT(methods, "Failed to create temporary file");
info->read_backing_store = read_backing_store;
info->write_backing_store = write_backing_store;
info->close_backing_store = close_backing_store;
/* hack to get around TRACEMS' inability to handle string parameters */
sprintf(tracemsg, "Using temp file %s", info->temp_name);
TRACEMS(methods, 1, tracemsg);
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required. Keep in mind that jmem_term may be called more than
* once.
*/
GLOBAL void
jmem_init (external_methods_ptr emethods)
{
methods = emethods; /* save struct addr for error exit access */
emethods->max_memory_to_use = DEFAULT_MAX_MEM;
total_used = 0;
next_file_num = 0;
}
GLOBAL void
jmem_term (void)
{
/* no work */
}

96
jmemnobs.c Normal file
View File

@@ -0,0 +1,96 @@
/*
* jmemnobs.c (jmemsys.c)
*
* Copyright (C) 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides a really simple implementation of the system-
* dependent portion of the JPEG memory manager. This implementation
* assumes that no backing-store files are needed: all required space
* can be obtained from malloc().
* This is very portable in the sense that it'll compile on almost anything,
* but you'd better have lots of main memory (or virtual memory) if you want
* to process big images.
* Note that the max_memory_to_use option is ignored by this implementation.
*/
#include "jinclude.h"
#include "jmemsys.h"
#ifdef INCLUDES_ARE_ANSI
#include <stdlib.h> /* to declare malloc(), free() */
#else
extern void * malloc PP((size_t size));
extern void free PP((void *ptr));
#endif
static external_methods_ptr methods; /* saved for access to error_exit */
/*
* Memory allocation and freeing are controlled by the regular library
* routines malloc() and free().
*/
GLOBAL void *
jget_small (size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL void
jfree_small (void * object)
{
free(object);
}
/*
* We assume NEED_FAR_POINTERS is not defined and so the separate entry points
* jget_large, jfree_large are not needed.
*/
/*
* This routine computes the total memory space available for allocation.
* Here we always say, "we got all you want bud!"
*/
GLOBAL long
jmem_available (long min_bytes_needed, long max_bytes_needed)
{
return max_bytes_needed;
}
/*
* Backing store (temporary file) management.
* This should never be called and we just error out.
*/
GLOBAL void
jopen_backing_store (backing_store_ptr info, long total_bytes_needed)
{
ERREXIT(methods, "Backing store not supported");
}
/*
* These routines take care of any system-dependent initialization and
* cleanup required. Keep in mind that jmem_term may be called more than
* once.
*/
GLOBAL void
jmem_init (external_methods_ptr emethods)
{
methods = emethods; /* save struct addr for error exit access */
emethods->max_memory_to_use = 0;
}
GLOBAL void
jmem_term (void)
{
/* no work */
}

127
jmemsys.h Normal file
View File

@@ -0,0 +1,127 @@
/*
* jmemsys.h
*
* Copyright (C) 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This include file defines the interface between the system-independent
* and system-dependent portions of the JPEG memory manager. (The system-
* independent portion is jmemmgr.c; there are several different versions
* of the system-dependent portion, and of this file for that matter.)
*
* This is a "generic" skeleton that may need to be modified for particular
* systems. It should be usable as-is on the majority of non-MSDOS machines.
*/
/*
* These two functions are used to allocate and release small chunks of
* memory (typically the total amount requested through jget_small is
* no more than 20Kb or so). Behavior should be the same as for the
* standard library functions malloc and free; in particular, jget_small
* returns NULL on failure. On most systems, these ARE malloc and free.
* On an 80x86 machine using small-data memory model, these manage near heap.
*/
EXTERN void * jget_small PP((size_t sizeofobject));
EXTERN void jfree_small PP((void * object));
/*
* These two functions are used to allocate and release large chunks of
* memory (up to the total free space designated by jmem_available).
* The interface is the same as above, except that on an 80x86 machine,
* far pointers are used. On other systems these ARE the same as above.
*/
#ifdef NEED_FAR_POINTERS /* typically not needed except on 80x86 */
EXTERN void FAR * jget_large PP((size_t sizeofobject));
EXTERN void jfree_large PP((void FAR * object));
#else
#define jget_large(sizeofobject) jget_small(sizeofobject)
#define jfree_large(object) jfree_small(object)
#endif
/*
* The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
* be requested in a single call on jget_large (and jget_small for that
* matter, but that case should never come into play). This macro is needed
* to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
* On machines with flat address spaces, any large constant may be used here.
*/
#define MAX_ALLOC_CHUNK 1000000000L
/*
* This routine computes the total space available for allocation by
* jget_large. If more space than this is needed, backing store will be used.
* NOTE: any memory already allocated must not be counted.
*
* There is a minimum space requirement, corresponding to the minimum
* feasible buffer sizes; jmemmgr.c will request that much space even if
* jmem_available returns zero. The maximum space needed, enough to hold
* all working storage in memory, is also passed in case it is useful.
*
* It is OK for jmem_available to underestimate the space available (that'll
* just lead to more backing-store access than is really necessary).
* However, an overestimate will lead to failure. Hence it's wise to subtract
* a slop factor from the true available space, especially if jget_small space
* comes from the same pool. 5% should be enough.
*
* On machines with lots of virtual memory, any large constant may be returned.
* Conversely, zero may be returned to always use the minimum amount of memory.
*/
EXTERN long jmem_available PP((long min_bytes_needed, long max_bytes_needed));
/*
* This structure holds whatever state is needed to access a single
* backing-store object. The read/write/close method pointers are called
* by jmemmgr.c to manipulate the backing-store object; all other fields
* are private to the system-dependent backing store routines.
*/
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
typedef struct backing_store_struct * backing_store_ptr;
typedef struct backing_store_struct {
/* Methods for reading/writing/closing this backing-store object */
METHOD(void, read_backing_store, (backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count));
METHOD(void, write_backing_store, (backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count));
METHOD(void, close_backing_store, (backing_store_ptr info));
/* Private fields for system-dependent backing-store management */
/* For a typical implementation with temp files, we might need: */
FILE * temp_file; /* stdio reference to temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
} backing_store_info;
/*
* Initial opening of a backing-store object. This must fill in the
* read/write/close pointers in the object. The read/write routines
* may take an error exit if the specified maximum file size is exceeded.
* (If jmem_available always returns a large value, this routine can just
* take an error exit.)
*/
EXTERN void jopen_backing_store PP((backing_store_ptr info,
long total_bytes_needed));
/*
* These routines take care of any system-dependent initialization and
* cleanup required. The system methods struct address should be saved
* by jmem_init in case an error exit must be taken. jmem_term may assume
* that all requested memory has been freed and that all opened backing-
* store objects have been closed.
* NB: jmem_term may be called more than once, and must behave reasonably
* if that happens.
*/
EXTERN void jmem_init PP((external_methods_ptr emethods));
EXTERN void jmem_term PP((void));

View File

@@ -1,7 +1,7 @@
/* /*
* jpegdata.h * jpegdata.h
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -197,10 +197,13 @@ typedef struct { /* A Huffman coding table */
* coding and decoding. These fields should be considered private to the * coding and decoding. These fields should be considered private to the
* Huffman compression & decompression modules. * Huffman compression & decompression modules.
*/ */
/* encoding tables: */
UINT16 ehufco[256]; /* code for each symbol */ UINT16 ehufco[256]; /* code for each symbol */
char ehufsi[256]; /* length of code for each symbol */ char ehufsi[256]; /* length of code for each symbol */
/* decoding tables: (element [0] of each array is unused) */
UINT16 mincode[17]; /* smallest code of length k */ UINT16 mincode[17]; /* smallest code of length k */
INT32 maxcode[17]; /* largest code of length k (-1 if none) */ INT32 maxcode[18]; /* largest code of length k (-1 if none) */
/* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
short valptr[17]; /* huffval[] index of 1st symbol of length k */ short valptr[17]; /* huffval[] index of 1st symbol of length k */
} HUFF_TBL; } HUFF_TBL;
@@ -220,7 +223,7 @@ struct compress_info_struct {
* All of these fields shall be established by the user interface before * All of these fields shall be established by the user interface before
* calling jpeg_compress, or by the input_init or c_ui_method_selection * calling jpeg_compress, or by the input_init or c_ui_method_selection
* methods. * methods.
* Most parameters can be set to reasonable defaults by j_default_compression. * Most parameters can be set to reasonable defaults by j_c_defaults.
* Note that the UI must supply the storage for the main methods struct, * Note that the UI must supply the storage for the main methods struct,
* though it sets only a few of the methods there. * though it sets only a few of the methods there.
*/ */
@@ -279,6 +282,13 @@ struct compress_info_struct {
short max_h_samp_factor; /* largest h_samp_factor */ short max_h_samp_factor; /* largest h_samp_factor */
short max_v_samp_factor; /* largest v_samp_factor */ short max_v_samp_factor; /* largest v_samp_factor */
/*
* These fields may be useful for progress monitoring
*/
int total_passes; /* number of passes expected */
int completed_passes; /* number of passes completed so far */
/* /*
* These fields are valid during any one scan * These fields are valid during any one scan
*/ */
@@ -309,8 +319,10 @@ typedef struct compress_info_struct * compress_info_ptr;
struct decompress_info_struct { struct decompress_info_struct {
/* /*
* These fields shall be established by the user interface before * These fields shall be established by the user interface before
* calling jpeg_decompress. Note that the UI must supply the storage for * calling jpeg_decompress.
* the main methods struct, though it sets only a few of the methods there. * Most parameters can be set to reasonable defaults by j_d_defaults.
* Note that the UI must supply the storage for the main methods struct,
* though it sets only a few of the methods there.
*/ */
decompress_methods_ptr methods; /* Points to list of methods to use */ decompress_methods_ptr methods; /* Points to list of methods to use */
@@ -329,7 +341,7 @@ struct decompress_info_struct {
/* the following are ignored if not quantize_colors: */ /* the following are ignored if not quantize_colors: */
boolean two_pass_quantize; /* use two-pass color quantization? */ boolean two_pass_quantize; /* use two-pass color quantization? */
boolean use_dithering; /* want color dithering? */ boolean use_dithering; /* want color dithering? */
int desired_number_of_colors; /* number of colors to use */ int desired_number_of_colors; /* max number of colors to use */
boolean do_block_smoothing; /* T = apply cross-block smoothing */ boolean do_block_smoothing; /* T = apply cross-block smoothing */
boolean do_pixel_smoothing; /* T = apply post-subsampling smoothing */ boolean do_pixel_smoothing; /* T = apply post-subsampling smoothing */
@@ -342,7 +354,8 @@ struct decompress_info_struct {
* JGETC macro, below. * JGETC macro, below.
* Note: the user interface is expected to allocate the input_buffer and * Note: the user interface is expected to allocate the input_buffer and
* initialize bytes_in_buffer to 0. Also, for JFIF/raw-JPEG input, the UI * initialize bytes_in_buffer to 0. Also, for JFIF/raw-JPEG input, the UI
* actually supplies the read_jpeg_data method. * actually supplies the read_jpeg_data method. This is all handled by
* j_d_defaults in a typical implementation.
*/ */
char * input_buffer; /* start of buffer (private to input code) */ char * input_buffer; /* start of buffer (private to input code) */
char * next_input_byte; /* => next byte to read from buffer */ char * next_input_byte; /* => next byte to read from buffer */
@@ -392,9 +405,26 @@ struct decompress_info_struct {
short color_out_comps; /* # of color components output by color_convert */ short color_out_comps; /* # of color components output by color_convert */
/* (need not match num_components) */ /* (need not match num_components) */
short final_out_comps; /* # of color components in output image */ short final_out_comps; /* # of color components sent to put_pixel_rows */
/* (1 when quantizing colors, else same as color_out_comps) */ /* (1 when quantizing colors, else same as color_out_comps) */
/*
* When quantizing colors, the color quantizer leaves a pointer to the output
* colormap in these fields. The colormap is valid from the time put_color_map
* is called (must be before any put_pixel_rows calls) until shutdown (more
* specifically, until free_all is called to release memory).
*/
int actual_number_of_colors; /* actual number of entries */
JSAMPARRAY colormap; /* NULL if not valid */
/* map has color_out_comps rows * actual_number_of_colors columns */
/*
* These fields may be useful for progress monitoring
*/
int total_passes; /* number of passes expected */
int completed_passes; /* number of passes completed so far */
/* /*
* These fields are valid during any one scan * These fields are valid during any one scan
*/ */
@@ -425,7 +455,7 @@ typedef struct decompress_info_struct * decompress_info_ptr;
#ifdef CHAR_IS_UNSIGNED #ifdef CHAR_IS_UNSIGNED
#define JGETC(cinfo) ( --(cinfo)->bytes_in_buffer < 0 ? \ #define JGETC(cinfo) ( --(cinfo)->bytes_in_buffer < 0 ? \
(*(cinfo)->methods->read_jpeg_data) (cinfo) : \ (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
(int) *(cinfo)->next_input_byte++ ) (int) (*(cinfo)->next_input_byte++) )
#else #else
#define JGETC(cinfo) ( --(cinfo)->bytes_in_buffer < 0 ? \ #define JGETC(cinfo) ( --(cinfo)->bytes_in_buffer < 0 ? \
(*(cinfo)->methods->read_jpeg_data) (cinfo) : \ (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
@@ -435,17 +465,34 @@ typedef struct decompress_info_struct * decompress_info_ptr;
#define JUNGETC(ch,cinfo) ((cinfo)->bytes_in_buffer++, \ #define JUNGETC(ch,cinfo) ((cinfo)->bytes_in_buffer++, \
*(--((cinfo)->next_input_byte)) = (ch)) *(--((cinfo)->next_input_byte)) = (ch))
#define MIN_UNGET 2 /* may always do at least 2 JUNGETCs */ #define MIN_UNGET 4 /* may always do at least 4 JUNGETCs */
/* A virtual image has a control block whose contents are private to the /* A virtual image has a control block whose contents are private to the
* memory manager module (and may differ between managers). The rest of the * memory manager module (and may differ between managers). The rest of the
* code only refers to virtual images by these pointer types. * code only refers to virtual images by these pointer types, and never
* dereferences the pointer.
*/ */
typedef struct big_sarray_control * big_sarray_ptr; typedef struct big_sarray_control * big_sarray_ptr;
typedef struct big_barray_control * big_barray_ptr; typedef struct big_barray_control * big_barray_ptr;
/* Although a real ANSI C compiler can deal perfectly well with pointers to
* unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
* and pseudo-ANSI compilers get confused. To keep one of these bozos happy,
* add -DINCOMPLETE_TYPES_BROKEN to CFLAGS in your Makefile. Then we will
* pseudo-define the structs as containing a single "dummy" field.
* The memory managers #define AM_MEMORY_MANAGER before including this file,
* so that they can make their own definitions of the structs.
*/
#ifdef INCOMPLETE_TYPES_BROKEN
#ifndef AM_MEMORY_MANAGER
struct big_sarray_control { long dummy; };
struct big_barray_control { long dummy; };
#endif
#endif
/* Method types that need typedefs */ /* Method types that need typedefs */
@@ -490,8 +537,8 @@ struct external_methods_struct {
/* by an enumerated-type code so that non-English error messages */ /* by an enumerated-type code so that non-English error messages */
/* can be substituted easily. This will not be done until all the */ /* can be substituted easily. This will not be done until all the */
/* code is in place, so that we know what messages are needed. */ /* code is in place, so that we know what messages are needed. */
METHOD(void, error_exit, (char *msgtext)); METHOD(void, error_exit, (const char *msgtext));
METHOD(void, trace_message, (char *msgtext)); METHOD(void, trace_message, (const char *msgtext));
/* Working data for error/trace facility */ /* Working data for error/trace facility */
/* See macros below for the usage of these variables */ /* See macros below for the usage of these variables */
@@ -506,21 +553,14 @@ struct external_methods_struct {
/* error_exit if not successful. */ /* error_exit if not successful. */
METHOD(void *, alloc_small, (size_t sizeofobject)); METHOD(void *, alloc_small, (size_t sizeofobject));
METHOD(void, free_small, (void *ptr)); METHOD(void, free_small, (void *ptr));
#ifdef NEED_FAR_POINTERS /* routines for getting far-heap space */
METHOD(void FAR *, alloc_medium, (size_t sizeofobject)); METHOD(void FAR *, alloc_medium, (size_t sizeofobject));
METHOD(void, free_medium, (void FAR *ptr)); METHOD(void, free_medium, (void FAR *ptr));
#else
#define alloc_medium alloc_small
#define free_medium free_small
#endif
METHOD(JSAMPARRAY, alloc_small_sarray, (long samplesperrow, METHOD(JSAMPARRAY, alloc_small_sarray, (long samplesperrow,
long numrows)); long numrows));
METHOD(void, free_small_sarray, (JSAMPARRAY ptr, METHOD(void, free_small_sarray, (JSAMPARRAY ptr));
long numrows));
METHOD(JBLOCKARRAY, alloc_small_barray, (long blocksperrow, METHOD(JBLOCKARRAY, alloc_small_barray, (long blocksperrow,
long numrows)); long numrows));
METHOD(void, free_small_barray, (JBLOCKARRAY ptr, METHOD(void, free_small_barray, (JBLOCKARRAY ptr));
long numrows));
METHOD(big_sarray_ptr, request_big_sarray, (long samplesperrow, METHOD(big_sarray_ptr, request_big_sarray, (long samplesperrow,
long numrows, long numrows,
long unitheight)); long unitheight));
@@ -538,6 +578,9 @@ struct external_methods_struct {
boolean writable)); boolean writable));
METHOD(void, free_big_sarray, (big_sarray_ptr ptr)); METHOD(void, free_big_sarray, (big_sarray_ptr ptr));
METHOD(void, free_big_barray, (big_barray_ptr ptr)); METHOD(void, free_big_barray, (big_barray_ptr ptr));
METHOD(void, free_all, (void));
long max_memory_to_use; /* maximum amount of memory to use */
}; };
/* Macros to simplify using the error and trace message stuff */ /* Macros to simplify using the error and trace message stuff */
@@ -559,42 +602,36 @@ struct external_methods_struct {
(emeth)->message_parm[3] = (p4), \ (emeth)->message_parm[3] = (p4), \
(*(emeth)->error_exit) (msg)) (*(emeth)->error_exit) (msg))
#define MAKESTMT(stuff) do { stuff } while (0)
#define TRACEMS(emeth,lvl,msg) \ #define TRACEMS(emeth,lvl,msg) \
( (emeth)->trace_level >= (lvl) ? \ MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
((*(emeth)->trace_message) (msg), 0) : 0) (*(emeth)->trace_message) (msg); } )
#define TRACEMS1(emeth,lvl,msg,p1) \ #define TRACEMS1(emeth,lvl,msg,p1) \
( (emeth)->trace_level >= (lvl) ? \ MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
((emeth)->message_parm[0] = (p1), \ (emeth)->message_parm[0] = (p1); \
(*(emeth)->trace_message) (msg), 0) : 0) (*(emeth)->trace_message) (msg); } )
#define TRACEMS2(emeth,lvl,msg,p1,p2) \ #define TRACEMS2(emeth,lvl,msg,p1,p2) \
( (emeth)->trace_level >= (lvl) ? \ MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
((emeth)->message_parm[0] = (p1), \ (emeth)->message_parm[0] = (p1); \
(emeth)->message_parm[1] = (p2), \ (emeth)->message_parm[1] = (p2); \
(*(emeth)->trace_message) (msg), 0) : 0) (*(emeth)->trace_message) (msg); } )
#define TRACEMS3(emeth,lvl,msg,p1,p2,p3) \ #define TRACEMS3(emeth,lvl,msg,p1,p2,p3) \
( (emeth)->trace_level >= (lvl) ? \ MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
((emeth)->message_parm[0] = (p1), \ int * _mp = (emeth)->message_parm; \
(emeth)->message_parm[1] = (p2), \ *_mp++ = (p1); *_mp++ = (p2); *_mp = (p3); \
(emeth)->message_parm[2] = (p3), \ (*(emeth)->trace_message) (msg); } )
(*(emeth)->trace_message) (msg), 0) : 0)
#define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4) \ #define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4) \
( (emeth)->trace_level >= (lvl) ? \ MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
((emeth)->message_parm[0] = (p1), \ int * _mp = (emeth)->message_parm; \
(emeth)->message_parm[1] = (p2), \ *_mp++ = (p1); *_mp++ = (p2); *_mp++ = (p3); *_mp = (p4); \
(emeth)->message_parm[2] = (p3), \ (*(emeth)->trace_message) (msg); } )
(emeth)->message_parm[3] = (p4), \
(*(emeth)->trace_message) (msg), 0) : 0)
#define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8) \ #define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8) \
( (emeth)->trace_level >= (lvl) ? \ MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
((emeth)->message_parm[0] = (p1), \ int * _mp = (emeth)->message_parm; \
(emeth)->message_parm[1] = (p2), \ *_mp++ = (p1); *_mp++ = (p2); *_mp++ = (p3); *_mp++ = (p4); \
(emeth)->message_parm[2] = (p3), \ *_mp++ = (p5); *_mp++ = (p6); *_mp++ = (p7); *_mp = (p8); \
(emeth)->message_parm[3] = (p4), \ (*(emeth)->trace_message) (msg); } )
(emeth)->message_parm[4] = (p5), \
(emeth)->message_parm[5] = (p6), \
(emeth)->message_parm[6] = (p7), \
(emeth)->message_parm[7] = (p8), \
(*(emeth)->trace_message) (msg), 0) : 0)
/* Methods used during JPEG compression. */ /* Methods used during JPEG compression. */
@@ -602,12 +639,15 @@ struct external_methods_struct {
struct compress_methods_struct { struct compress_methods_struct {
/* Hook for user interface to get control after input_init */ /* Hook for user interface to get control after input_init */
METHOD(void, c_ui_method_selection, (compress_info_ptr cinfo)); METHOD(void, c_ui_method_selection, (compress_info_ptr cinfo));
/* Hook for user interface to do progress monitoring */
METHOD(void, progress_monitor, (compress_info_ptr cinfo,
long loopcounter, long looplimit));
/* Input image reading & conversion to standard form */ /* Input image reading & conversion to standard form */
METHOD(void, input_init, (compress_info_ptr cinfo)); METHOD(void, input_init, (compress_info_ptr cinfo));
METHOD(void, get_input_row, (compress_info_ptr cinfo, METHOD(void, get_input_row, (compress_info_ptr cinfo,
JSAMPARRAY pixel_row)); JSAMPARRAY pixel_row));
METHOD(void, input_term, (compress_info_ptr cinfo)); METHOD(void, input_term, (compress_info_ptr cinfo));
/* Gamma and color space conversion */ /* Color space and gamma conversion */
METHOD(void, colorin_init, (compress_info_ptr cinfo)); METHOD(void, colorin_init, (compress_info_ptr cinfo));
METHOD(void, get_sample_rows, (compress_info_ptr cinfo, METHOD(void, get_sample_rows, (compress_info_ptr cinfo,
int rows_to_read, int rows_to_read,
@@ -661,11 +701,10 @@ struct compress_methods_struct {
struct decompress_methods_struct { struct decompress_methods_struct {
/* Hook for user interface to get control after reading file header */ /* Hook for user interface to get control after reading file header */
METHOD(void, d_ui_method_selection, (decompress_info_ptr cinfo)); METHOD(void, d_ui_method_selection, (decompress_info_ptr cinfo));
/* Hook for user interface to do progress monitoring */
METHOD(void, progress_monitor, (decompress_info_ptr cinfo,
long loopcounter, long looplimit));
/* JPEG file scanning */ /* JPEG file scanning */
/* Note: user interface supplies read_jpeg_data for JFIF/raw-JPEG
* reading. For file formats that require random access (eg, TIFF)
* the JPEG file header module will override the UI read_jpeg_data.
*/
METHOD(void, read_file_header, (decompress_info_ptr cinfo)); METHOD(void, read_file_header, (decompress_info_ptr cinfo));
METHOD(boolean, read_scan_header, (decompress_info_ptr cinfo)); METHOD(boolean, read_scan_header, (decompress_info_ptr cinfo));
METHOD(int, read_jpeg_data, (decompress_info_ptr cinfo)); METHOD(int, read_jpeg_data, (decompress_info_ptr cinfo));
@@ -677,9 +716,13 @@ struct decompress_methods_struct {
JBLOCK *MCU_data)); JBLOCK *MCU_data));
METHOD(void, entropy_decoder_term, (decompress_info_ptr cinfo)); METHOD(void, entropy_decoder_term, (decompress_info_ptr cinfo));
/* MCU disassembly: fetch MCUs from entropy_decode, build coef array */ /* MCU disassembly: fetch MCUs from entropy_decode, build coef array */
/* The reverse_DCT step is in the same module for symmetry reasons */
METHOD(void, disassemble_init, (decompress_info_ptr cinfo)); METHOD(void, disassemble_init, (decompress_info_ptr cinfo));
METHOD(void, disassemble_MCU, (decompress_info_ptr cinfo, METHOD(void, disassemble_MCU, (decompress_info_ptr cinfo,
JBLOCKIMAGE image_data)); JBLOCKIMAGE image_data));
METHOD(void, reverse_DCT, (decompress_info_ptr cinfo,
JBLOCKIMAGE coeff_data,
JSAMPIMAGE output_data, int start_row));
METHOD(void, disassemble_term, (decompress_info_ptr cinfo)); METHOD(void, disassemble_term, (decompress_info_ptr cinfo));
/* Cross-block smoothing */ /* Cross-block smoothing */
METHOD(void, smooth_coefficients, (decompress_info_ptr cinfo, METHOD(void, smooth_coefficients, (decompress_info_ptr cinfo,
@@ -693,10 +736,10 @@ struct decompress_methods_struct {
METHOD(void, unsubsample_init, (decompress_info_ptr cinfo)); METHOD(void, unsubsample_init, (decompress_info_ptr cinfo));
unsubsample_ptr unsubsample[MAX_COMPS_IN_SCAN]; unsubsample_ptr unsubsample[MAX_COMPS_IN_SCAN];
METHOD(void, unsubsample_term, (decompress_info_ptr cinfo)); METHOD(void, unsubsample_term, (decompress_info_ptr cinfo));
/* Gamma and color space conversion */ /* Color space and gamma conversion */
METHOD(void, colorout_init, (decompress_info_ptr cinfo)); METHOD(void, colorout_init, (decompress_info_ptr cinfo));
METHOD(void, color_convert, (decompress_info_ptr cinfo, METHOD(void, color_convert, (decompress_info_ptr cinfo,
int num_rows, int num_rows, long num_cols,
JSAMPIMAGE input_data, JSAMPIMAGE input_data,
JSAMPIMAGE output_data)); JSAMPIMAGE output_data));
METHOD(void, colorout_term, (decompress_info_ptr cinfo)); METHOD(void, colorout_term, (decompress_info_ptr cinfo));
@@ -708,7 +751,8 @@ struct decompress_methods_struct {
JSAMPARRAY output_data)); JSAMPARRAY output_data));
METHOD(void, color_quant_prescan, (decompress_info_ptr cinfo, METHOD(void, color_quant_prescan, (decompress_info_ptr cinfo,
int num_rows, int num_rows,
JSAMPIMAGE image_data)); JSAMPIMAGE image_data,
JSAMPARRAY workspace));
METHOD(void, color_quant_doit, (decompress_info_ptr cinfo, METHOD(void, color_quant_doit, (decompress_info_ptr cinfo,
quantize_caller_ptr source_method)); quantize_caller_ptr source_method));
METHOD(void, color_quant_term, (decompress_info_ptr cinfo)); METHOD(void, color_quant_term, (decompress_info_ptr cinfo));
@@ -740,16 +784,21 @@ struct decompress_methods_struct {
/* main entry for compression */ /* main entry for compression */
EXTERN void jpeg_compress PP((compress_info_ptr cinfo)); EXTERN void jpeg_compress PP((compress_info_ptr cinfo));
/* default parameter setup for compression */ /* default parameter setup for compression */
EXTERN void j_default_compression PP((compress_info_ptr cinfo, int quality)); EXTERN void j_c_defaults PP((compress_info_ptr cinfo, int quality,
boolean force_baseline));
EXTERN void j_monochrome_default PP((compress_info_ptr cinfo)); EXTERN void j_monochrome_default PP((compress_info_ptr cinfo));
EXTERN void j_set_quality PP((compress_info_ptr cinfo, int quality, EXTERN void j_set_quality PP((compress_info_ptr cinfo, int quality,
boolean force_baseline)); boolean force_baseline));
EXTERN void j_free_defaults PP((compress_info_ptr cinfo));
/* main entry for decompression */ /* main entry for decompression */
EXTERN void jpeg_decompress PP((decompress_info_ptr cinfo)); EXTERN void jpeg_decompress PP((decompress_info_ptr cinfo));
/* default parameter setup for decompression */
EXTERN void j_d_defaults PP((decompress_info_ptr cinfo,
boolean standard_buffering));
/* forward DCT */ /* forward DCT */
EXTERN void j_fwd_dct PP((DCTBLOCK data)); EXTERN void j_fwd_dct PP((DCTBLOCK data));
/* inverse DCT */ /* inverse DCT */
@@ -775,6 +824,8 @@ EXTERN void jselccolor PP((compress_info_ptr cinfo)); /* jccolor.c */
/* The user interface should call one of these to select input format: */ /* The user interface should call one of these to select input format: */
EXTERN void jselrgif PP((compress_info_ptr cinfo)); /* jrdgif.c */ EXTERN void jselrgif PP((compress_info_ptr cinfo)); /* jrdgif.c */
EXTERN void jselrppm PP((compress_info_ptr cinfo)); /* jrdppm.c */ EXTERN void jselrppm PP((compress_info_ptr cinfo)); /* jrdppm.c */
EXTERN void jselrrle PP((compress_info_ptr cinfo)); /* jrdrle.c */
EXTERN void jselrtarga PP((compress_info_ptr cinfo)); /* jrdtarga.c */
/* and one of these to select output header format: */ /* and one of these to select output header format: */
EXTERN void jselwjfif PP((compress_info_ptr cinfo)); /* jwrjfif.c */ EXTERN void jselwjfif PP((compress_info_ptr cinfo)); /* jwrjfif.c */
@@ -793,19 +844,41 @@ EXTERN void jselrjfif PP((decompress_info_ptr cinfo)); /* jrdjfif.c */
/* and one of these to select output image format: */ /* and one of these to select output image format: */
EXTERN void jselwgif PP((decompress_info_ptr cinfo)); /* jwrgif.c */ EXTERN void jselwgif PP((decompress_info_ptr cinfo)); /* jwrgif.c */
EXTERN void jselwppm PP((decompress_info_ptr cinfo)); /* jwrppm.c */ EXTERN void jselwppm PP((decompress_info_ptr cinfo)); /* jwrppm.c */
EXTERN void jselwrle PP((decompress_info_ptr cinfo)); /* jwrrle.c */
EXTERN void jselwtarga PP((decompress_info_ptr cinfo)); /* jwrtarga.c */
/* method selection routines for system-dependent modules */ /* method selection routines for system-dependent modules */
EXTERN void jselerror PP((external_methods_ptr emethods)); /* jerror.c */ EXTERN void jselerror PP((external_methods_ptr emethods)); /* jerror.c */
EXTERN void jselvirtmem PP((external_methods_ptr emethods)); /* jvirtmem.c */ EXTERN void jselmemmgr PP((external_methods_ptr emethods)); /* jmemmgr.c */
/* debugging hook in jvirtmem.c */
#ifdef MEM_STATS /* We assume that right shift corresponds to signed division by 2 with
EXTERN void j_mem_stats PP((void)); * rounding towards minus infinity. This is correct for typical "arithmetic
* shift" instructions that shift in copies of the sign bit. But some
* C compilers implement >> with an unsigned shift. For these machines you
* must define RIGHT_SHIFT_IS_UNSIGNED.
* RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
* It is only applied with constant shift counts. SHIFT_TEMPS must be
* included in the variables of any routine using RIGHT_SHIFT.
*/
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define SHIFT_TEMPS INT32 shift_temp;
#define RIGHT_SHIFT(x,shft) \
((shift_temp = (x)) < 0 ? \
(shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
(shift_temp >> (shft)))
#else
#define SHIFT_TEMPS
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
#endif #endif
/* Miscellaneous useful macros */ /* Miscellaneous useful macros */
#undef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b))
#undef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b))

517
jquant1.c
View File

@@ -1,7 +1,7 @@
/* /*
* jquant1.c * jquant1.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -16,61 +16,251 @@
/* /*
* This implementation is a fairly dumb, quick-and-dirty quantizer; * The main purpose of 1-pass quantization is to provide a fast, if not very
* it's here mostly so that we can start working on colormapped output formats. * high quality, colormapped output capability. A 2-pass quantizer usually
* gives better visual quality; however, for quantized grayscale output this
* quantizer is perfectly adequate. Dithering is highly recommended with this
* quantizer, though you can turn it off if you really want to.
* *
* We quantize to a color map that is selected in advance of seeing the image; * This implementation quantizes in the output colorspace. This has a couple
* the map depends only on the requested number of colors (at least 8). * of disadvantages: each pixel must be individually color-converted, and if
* The map consists of all combinations of Ncolors[j] color values for each * the color conversion includes gamma correction then quantization is done in
* component j; we choose Ncolors[] based on the requested # of colors. * a nonlinear space, which is less desirable. The major advantage is that
* We always use 0 and MAXJSAMPLE in each color (hence the minimum 8 colors). * with the usual output color spaces (RGB, grayscale) an orthogonal grid of
* Any additional color values are equally spaced between these limits. * representative colors can be used, thus permitting the very simple and fast
* color lookup scheme used here. The standard JPEG colorspace (YCbCr) cannot
* be effectively handled this way, because only about a quarter of an
* orthogonal grid would fall within the gamut of realizable colors. Another
* advantage is that when the user wants quantized grayscale output from a
* color JPEG file, this quantizer can provide a high-quality result with no
* special hacking.
* *
* The result almost always needs dithering to look decent. * The gamma-correction problem could be eliminated by adjusting the grid
* spacing to counteract the gamma correction applied by color_convert.
* At this writing, gamma correction is not implemented by jdcolor, so
* nothing is done here.
*
* In 1-pass quantization the colormap must be chosen in advance of seeing the
* image. We use a map consisting of all combinations of Ncolors[i] color
* values for the i'th component. The Ncolors[] values are chosen so that
* their product, the total number of colors, is no more than that requested.
* (In most cases, the product will be somewhat less.)
*
* Since the colormap is orthogonal, the representative value for each color
* component can be determined without considering the other components;
* then these indexes can be combined into a colormap index by a standard
* N-dimensional-array-subscript calculation. Most of the arithmetic involved
* can be precalculated and stored in the lookup table colorindex[].
* colorindex[i][j] maps pixel value j in component i to the nearest
* representative value (grid plane) for that component; this index is
* multiplied by the array stride for component i, so that the
* index of the colormap entry closest to a given pixel value is just
* sum( colorindex[component-number][pixel-component-value] )
* Aside from being fast, this scheme allows for variable spacing between
* representative values with no additional lookup cost.
*/ */
#define MAX_COMPONENTS 4 /* max components I can handle */
static int total_colors; /* Number of distinct output colors */ #define MAX_COMPONENTS 4 /* max components I can handle */
static int Ncolors[MAX_COMPONENTS]; /* # of values alloced to each component */
/* total_colors is the product of the Ncolors[] values */
static JSAMPARRAY colormap; /* The actual color map */ static JSAMPARRAY colormap; /* The actual color map */
/* colormap[i][j] = value of i'th color component for output pixel value j */ /* colormap[i][j] = value of i'th color component for output pixel value j */
static JSAMPARRAY colorindex; /* Precomputed mapping for speed */ static JSAMPARRAY colorindex; /* Precomputed mapping for speed */
/* colorindex[i][j] = index of color closest to pixel value j in component i, /* colorindex[i][j] = index of color closest to pixel value j in component i,
* premultiplied so that the correct mapped value for a pixel (r,g,b) is: * premultiplied as described above. Since colormap indexes must fit into
* colorindex[0][r] + colorindex[1][g] + colorindex[2][b] * JSAMPLEs, the entries of this array will too.
*/
static JSAMPARRAY input_buffer; /* color conversion workspace */
/* Since our input data is presented in the JPEG colorspace, we have to call
* color_convert to get it into the output colorspace. input_buffer is a
* one-row-high workspace for the result of color_convert.
*/ */
/* Declarations for Floyd-Steinberg dithering. /* Declarations for Floyd-Steinberg dithering.
* Errors are accumulated into the arrays evenrowerrs[] and oddrowerrs[], *
* each of which have #colors * (#columns + 2) entries (so that first/last * Errors are accumulated into the arrays evenrowerrs[] and oddrowerrs[].
* pixels need not be special cases). These have resolutions of 1/16th of * These have resolutions of 1/16th of a pixel count. The error at a given
* a pixel count. The error at a given pixel is propagated to its unprocessed * pixel is propagated to its unprocessed neighbors using the standard F-S
* neighbors using the standard F-S fractions, * fractions,
* ... (here) 7/16 * ... (here) 7/16
* 3/16 5/16 1/16 * 3/16 5/16 1/16
* We work left-to-right on even rows, right-to-left on odd rows. * We work left-to-right on even rows, right-to-left on odd rows.
* *
* In each of the xxxrowerrs[] arrays, indexing is [component#][position].
* We provide (#columns + 2) entries per component; the extra entry at each
* end saves us from special-casing the first and last pixels.
* In evenrowerrs[], the entries for a component are stored left-to-right, but
* in oddrowerrs[] they are stored right-to-left. This means we always
* process the current row's error entries in increasing order and the next
* row's error entries in decreasing order, regardless of whether we are
* working L-to-R or R-to-L in the pixel data!
*
* Note: on a wide image, we might not have enough room in a PC's near data * Note: on a wide image, we might not have enough room in a PC's near data
* segment to hold the error arrays; so they are allocated with alloc_medium. * segment to hold the error arrays; so they are allocated with alloc_medium.
*/ */
#ifdef EIGHT_BIT_SAMPLES #ifdef EIGHT_BIT_SAMPLES
typedef short FSERROR; /* 16 bits should be enough */ typedef INT16 FSERROR; /* 16 bits should be enough */
#else #else
typedef INT32 FSERROR; /* may need more than 16 bits? */ typedef INT32 FSERROR; /* may need more than 16 bits? */
#endif #endif
typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
static FSERRPTR evenrowerrs, oddrowerrs; /* current-row and next-row errors */ static FSERRPTR evenrowerrs[MAX_COMPONENTS]; /* errors for even rows */
static FSERRPTR oddrowerrs[MAX_COMPONENTS]; /* errors for odd rows */
static boolean on_odd_row; /* flag to remember which row we are on */ static boolean on_odd_row; /* flag to remember which row we are on */
/*
* Policy-making subroutines for color_quant_init: these routines determine
* the colormap to be used. The rest of the module only assumes that the
* colormap is orthogonal.
*
* * select_ncolors decides how to divvy up the available colors
* among the components.
* * output_value defines the set of representative values for a component.
* * largest_input_value defines the mapping from input values to
* representative values for a component.
* Note that the latter two routines may impose different policies for
* different components, though this is not currently done.
*/
LOCAL int
select_ncolors (decompress_info_ptr cinfo, int Ncolors[])
/* Determine allocation of desired colors to components, */
/* and fill in Ncolors[] array to indicate choice. */
/* Return value is total number of colors (product of Ncolors[] values). */
{
int nc = cinfo->color_out_comps; /* number of color components */
int max_colors = cinfo->desired_number_of_colors;
int total_colors, iroot, i;
long temp;
boolean changed;
/* We can allocate at least the nc'th root of max_colors per component. */
/* Compute floor(nc'th root of max_colors). */
iroot = 1;
do {
iroot++;
temp = iroot; /* set temp = iroot ** nc */
for (i = 1; i < nc; i++)
temp *= iroot;
} while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
iroot--; /* now iroot = floor(root) */
/* Must have at least 2 color values per component */
if (iroot < 2)
ERREXIT1(cinfo->emethods, "Cannot quantize to fewer than %d colors",
(int) temp);
if (cinfo->out_color_space == CS_RGB && nc == 3) {
/* We provide a special policy for quantizing in RGB space.
* If 256 colors are requested, we allocate 8 red, 8 green, 4 blue levels;
* this corresponds to the common 3/3/2-bit scheme. For other totals,
* the counts are set so that the number of colors allocated to each
* component are roughly in the proportion R 3, G 4, B 2.
* For low color counts, it's easier to hardwire the optimal choices
* than try to tweak the algorithm to generate them.
*/
if (max_colors == 256) {
Ncolors[0] = 8; Ncolors[1] = 8; Ncolors[2] = 4;
return 256;
}
if (max_colors < 12) {
/* Fixed mapping for 8 colors */
Ncolors[0] = Ncolors[1] = Ncolors[2] = 2;
} else if (max_colors < 18) {
/* Fixed mapping for 12 colors */
Ncolors[0] = 2; Ncolors[1] = 3; Ncolors[2] = 2;
} else if (max_colors < 24) {
/* Fixed mapping for 18 colors */
Ncolors[0] = 3; Ncolors[1] = 3; Ncolors[2] = 2;
} else if (max_colors < 27) {
/* Fixed mapping for 24 colors */
Ncolors[0] = 3; Ncolors[1] = 4; Ncolors[2] = 2;
} else if (max_colors < 36) {
/* Fixed mapping for 27 colors */
Ncolors[0] = 3; Ncolors[1] = 3; Ncolors[2] = 3;
} else {
/* these weights are readily derived with a little algebra */
Ncolors[0] = (iroot * 266) >> 8; /* R weight is 1.0400 */
Ncolors[1] = (iroot * 355) >> 8; /* G weight is 1.3867 */
Ncolors[2] = (iroot * 177) >> 8; /* B weight is 0.6934 */
}
total_colors = Ncolors[0] * Ncolors[1] * Ncolors[2];
/* The above computation produces "floor" values, so we may be able to
* increment the count for one or more components without exceeding
* max_colors. We try in the order B, G, R.
*/
do {
changed = FALSE;
for (i = 2; i >= 0; i--) {
/* calculate new total_colors if Ncolors[i] is incremented */
temp = total_colors / Ncolors[i];
temp *= Ncolors[i]+1; /* done in long arith to avoid oflo */
if (temp <= (long) max_colors) {
Ncolors[i]++; /* OK, apply the increment */
total_colors = (int) temp;
changed = TRUE;
}
}
} while (changed); /* loop until no increment is possible */
} else {
/* For any colorspace besides RGB, treat all the components equally. */
/* Initialize to iroot color values for each component */
total_colors = 1;
for (i = 0; i < nc; i++) {
Ncolors[i] = iroot;
total_colors *= iroot;
}
/* 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.
*/
for (i = 0; i < nc; i++) {
/* calculate new total_colors if Ncolors[i] is incremented */
temp = total_colors / Ncolors[i];
temp *= Ncolors[i]+1; /* done in long arith to avoid oflo */
if (temp > (long) max_colors)
break; /* won't fit, done */
Ncolors[i]++; /* OK, apply the increment */
total_colors = (int) temp;
}
}
return total_colors;
}
LOCAL int
output_value (decompress_info_ptr cinfo, int ci, int j, int maxj)
/* Return j'th output value, where j will range from 0 to maxj */
/* The output values must fall in 0..MAXJSAMPLE in increasing order */
{
/* We always provide values 0 and MAXJSAMPLE for each component;
* any additional values are equally spaced between these limits.
* (Forcing the upper and lower values to the limits ensures that
* dithering can't produce a color outside the selected gamut.)
*/
return (j * MAXJSAMPLE + maxj/2) / maxj;
}
LOCAL int
largest_input_value (decompress_info_ptr cinfo, int ci, int j, int maxj)
/* Return largest input value that should map to j'th output value */
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
{
/* Breakpoints are halfway between values returned by output_value */
return ((2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj);
}
/* /*
* Initialize for one-pass color quantization. * Initialize for one-pass color quantization.
*/ */
@@ -78,37 +268,22 @@ static boolean on_odd_row; /* flag to remember which row we are on */
METHODDEF void METHODDEF void
color_quant_init (decompress_info_ptr cinfo) color_quant_init (decompress_info_ptr cinfo)
{ {
int max_colors = cinfo->desired_number_of_colors; int total_colors; /* Number of distinct output colors */
int i,j,k, ntc, nci, blksize, blkdist, ptr, val; int Ncolors[MAX_COMPONENTS]; /* # of values alloced to each component */
int i,j,k, nci, blksize, blkdist, ptr, val;
if (cinfo->color_out_comps > MAX_COMPONENTS) /* Make sure my internal arrays won't overflow */
if (cinfo->num_components > MAX_COMPONENTS ||
cinfo->color_out_comps > MAX_COMPONENTS)
ERREXIT1(cinfo->emethods, "Cannot quantize more than %d color components", ERREXIT1(cinfo->emethods, "Cannot quantize more than %d color components",
MAX_COMPONENTS); MAX_COMPONENTS);
if (max_colors > (MAXJSAMPLE+1)) /* Make sure colormap indexes can be represented by JSAMPLEs */
if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
ERREXIT1(cinfo->emethods, "Cannot request more than %d quantized colors", ERREXIT1(cinfo->emethods, "Cannot request more than %d quantized colors",
MAXJSAMPLE+1); MAXJSAMPLE+1);
/* Initialize to 2 color values for each component */ /* Select number of colors for each component */
total_colors = 1; total_colors = select_ncolors(cinfo, Ncolors);
for (i = 0; i < cinfo->color_out_comps; i++) {
Ncolors[i] = 2;
total_colors *= 2;
}
if (total_colors > max_colors)
ERREXIT1(cinfo->emethods, "Cannot quantize to fewer than %d colors",
total_colors);
/* Increase the number of color values until requested limit is reached. */
/* Note that for standard RGB color space, we will have at least as many */
/* red values as green, and at least as many green values as blue. */
i = 0; /* component index to increase next */
/* test calculates ntc = new total_colors if Ncolors[i] is incremented */
while ((ntc = (total_colors / Ncolors[i]) * (Ncolors[i]+1)) <= max_colors) {
Ncolors[i]++; /* OK, apply the increment */
total_colors = ntc;
i++; /* advance to next component */
if (i >= cinfo->color_out_comps) i = 0;
}
/* Report selected color counts */ /* Report selected color counts */
if (cinfo->color_out_comps == 3) if (cinfo->color_out_comps == 3)
@@ -135,42 +310,79 @@ color_quant_init (decompress_info_ptr cinfo)
nci = Ncolors[i]; /* # of distinct values for this color */ nci = Ncolors[i]; /* # of distinct values for this color */
blksize = blkdist / nci; blksize = blkdist / nci;
for (j = 0; j < nci; j++) { for (j = 0; j < nci; j++) {
val = (j * MAXJSAMPLE + (nci-1)/2) / (nci-1); /* j'th value of color */ /* Compute j'th output value (out of nci) for component */
val = output_value(cinfo, i, j, nci-1);
/* Fill in all colormap entries that have this value of this component */
for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
/* fill in blksize entries beginning at ptr */ /* fill in blksize entries beginning at ptr */
for (k = 0; k < blksize; k++) for (k = 0; k < blksize; k++)
colormap[i][ptr+k] = val; colormap[i][ptr+k] = (JSAMPLE) val;
} }
} }
blkdist = blksize; /* blksize of this color is blkdist of next */ blkdist = blksize; /* blksize of this color is blkdist of next */
/* fill in colorindex entries for i'th color component */ /* fill in colorindex entries for i'th color component */
/* in loop, val = index of current output value, */
/* and k = largest j that maps to current val */
val = 0;
k = largest_input_value(cinfo, i, 0, nci-1);
for (j = 0; j <= MAXJSAMPLE; j++) { for (j = 0; j <= MAXJSAMPLE; j++) {
/* compute index of color closest to pixel value j */ while (j > k) /* advance val if past boundary */
val = (j * (nci-1) + CENTERJSAMPLE) / MAXJSAMPLE; k = largest_input_value(cinfo, i, ++val, nci-1);
/* premultiply so that no multiplication needed in main processing */ /* premultiply so that no multiplication needed in main processing */
val *= blksize; colorindex[i][j] = (JSAMPLE) (val * blksize);
colorindex[i][j] = val;
} }
} }
/* Pass the colormap to the output module. Note that the output */ /* Pass the colormap to the output module. */
/* module is allowed to save this pointer and use the map during */ /* NB: the output module may continue to use the colormap until shutdown. */
/* any put_pixel_rows call! */ cinfo->colormap = colormap;
cinfo->actual_number_of_colors = total_colors;
(*cinfo->methods->put_color_map) (cinfo, total_colors, colormap); (*cinfo->methods->put_color_map) (cinfo, total_colors, colormap);
/* Allocate workspace to hold one row of color-converted data */
input_buffer = (*cinfo->emethods->alloc_small_sarray)
(cinfo->image_width, (long) cinfo->color_out_comps);
/* Allocate Floyd-Steinberg workspace if necessary */ /* Allocate Floyd-Steinberg workspace if necessary */
if (cinfo->use_dithering) { if (cinfo->use_dithering) {
size_t arraysize = (cinfo->image_width + 2L) * cinfo->color_out_comps size_t arraysize = (size_t) ((cinfo->image_width + 2L) * SIZEOF(FSERROR));
* SIZEOF(FSERROR);
evenrowerrs = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize); for (i = 0; i < cinfo->color_out_comps; i++) {
oddrowerrs = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize); evenrowerrs[i] = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
/* we only need to zero the forward contribution for current row. */ oddrowerrs[i] = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
jzero_far((void FAR *) evenrowerrs, arraysize); /* we only need to zero the forward contribution for current row. */
jzero_far((void FAR *) evenrowerrs[i], arraysize);
}
on_odd_row = FALSE; on_odd_row = FALSE;
} }
}
/*
* Subroutines for color conversion methods.
*/
LOCAL void
do_color_conversion (decompress_info_ptr cinfo, JSAMPIMAGE input_data, int row)
/* Convert the indicated row of the input data into output colorspace */
/* in input_buffer. This requires a little trickery since color_convert */
/* expects to deal with 3-D arrays; fortunately we can fake it out */
/* at fairly low cost. */
{
short ci;
JSAMPARRAY input_hack[MAX_COMPONENTS];
JSAMPARRAY output_hack[MAX_COMPONENTS];
/* create JSAMPIMAGE pointing at specified row of input_data */
for (ci = 0; ci < cinfo->num_components; ci++)
input_hack[ci] = input_data[ci] + row;
/* Create JSAMPIMAGE pointing at input_buffer */
for (ci = 0; ci < cinfo->color_out_comps; ci++)
output_hack[ci] = &(input_buffer[ci]);
(*cinfo->methods->color_convert) (cinfo, 1, cinfo->image_width,
input_hack, output_hack);
} }
@@ -184,19 +396,22 @@ color_quantize (decompress_info_ptr cinfo, int num_rows,
/* General case, no dithering */ /* General case, no dithering */
{ {
register int pixcode, ci; register int pixcode, ci;
register JSAMPROW ptrout;
register long col; register long col;
register int row; int row;
register long widthm1 = cinfo->image_width - 1; long width = cinfo->image_width;
register int nc = cinfo->color_out_comps; register int nc = cinfo->color_out_comps;
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
for (col = widthm1; col >= 0; col--) { do_color_conversion(cinfo, input_data, row);
ptrout = output_data[row];
for (col = 0; col < width; col++) {
pixcode = 0; pixcode = 0;
for (ci = 0; ci < nc; ci++) { for (ci = 0; ci < nc; ci++) {
pixcode += GETJSAMPLE(colorindex[ci] pixcode += GETJSAMPLE(colorindex[ci]
[GETJSAMPLE(input_data[ci][row][col])]); [GETJSAMPLE(input_buffer[ci][col])]);
} }
output_data[row][col] = pixcode; *ptrout++ = (JSAMPLE) pixcode;
} }
} }
} }
@@ -210,19 +425,20 @@ color_quantize3 (decompress_info_ptr cinfo, int num_rows,
register int pixcode; register int pixcode;
register JSAMPROW ptr0, ptr1, ptr2, ptrout; register JSAMPROW ptr0, ptr1, ptr2, ptrout;
register long col; register long col;
register int row; int row;
register long width = cinfo->image_width; long width = cinfo->image_width;
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
ptr0 = input_data[0][row]; do_color_conversion(cinfo, input_data, row);
ptr1 = input_data[1][row]; ptr0 = input_buffer[0];
ptr2 = input_data[2][row]; ptr1 = input_buffer[1];
ptr2 = input_buffer[2];
ptrout = output_data[row]; ptrout = output_data[row];
for (col = width; col > 0; col--) { for (col = width; col > 0; col--) {
pixcode = GETJSAMPLE(colorindex[0][GETJSAMPLE(*ptr0++)]); pixcode = GETJSAMPLE(colorindex[0][GETJSAMPLE(*ptr0++)]);
pixcode += GETJSAMPLE(colorindex[1][GETJSAMPLE(*ptr1++)]); pixcode += GETJSAMPLE(colorindex[1][GETJSAMPLE(*ptr1++)]);
pixcode += GETJSAMPLE(colorindex[2][GETJSAMPLE(*ptr2++)]); pixcode += GETJSAMPLE(colorindex[2][GETJSAMPLE(*ptr2++)]);
*ptrout++ = pixcode; *ptrout++ = (JSAMPLE) pixcode;
} }
} }
} }
@@ -233,86 +449,79 @@ color_quantize_dither (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE input_data, JSAMPARRAY output_data) JSAMPIMAGE input_data, JSAMPARRAY output_data)
/* General case, with Floyd-Steinberg dithering */ /* General case, with Floyd-Steinberg dithering */
{ {
register int pixcode, ci;
register FSERROR val; register FSERROR val;
FSERROR two_val;
register FSERRPTR thisrowerr, nextrowerr; register FSERRPTR thisrowerr, nextrowerr;
register long col; register JSAMPROW input_ptr;
register int row; register JSAMPROW output_ptr;
register long width = cinfo->image_width; JSAMPROW colorindex_ci;
register int nc = cinfo->color_out_comps; JSAMPROW colormap_ci;
register int pixcode;
int dir; /* 1 for left-to-right, -1 for right-to-left */
int ci;
int nc = cinfo->color_out_comps;
int row;
long col_counter;
long width = cinfo->image_width;
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
if (on_odd_row) { do_color_conversion(cinfo, input_data, row);
/* work right to left in this row */ /* Initialize output values to 0 so can process components separately */
thisrowerr = oddrowerrs + width*nc; jzero_far((void FAR *) output_data[row],
nextrowerr = evenrowerrs + width*nc; (size_t) (width * SIZEOF(JSAMPLE)));
for (ci = 0; ci < nc; ci++) /* need only initialize this one entry */ for (ci = 0; ci < nc; ci++) {
nextrowerr[ci] = 0; if (on_odd_row) {
for (col = width - 1; col >= 0; col--) { /* work right to left in this row */
/* select the output pixel value */ dir = -1;
pixcode = 0; input_ptr = input_buffer[ci] + (width-1);
for (ci = 0; ci < nc; ci++) { output_ptr = output_data[row] + (width-1);
/* compute pixel value + accumulated error */ thisrowerr = oddrowerrs[ci] + 1;
val = (((FSERROR) GETJSAMPLE(input_data[ci][row][col])) << 4) nextrowerr = evenrowerrs[ci] + width;
+ thisrowerr[ci]; } else {
if (val < 0) val = 0; /* must watch for range overflow! */ /* work left to right in this row */
else { dir = 1;
val += 8; /* divide by 16 with proper rounding */ input_ptr = input_buffer[ci];
val >>= 4; output_ptr = output_data[row];
if (val > MAXJSAMPLE) val = MAXJSAMPLE; thisrowerr = evenrowerrs[ci] + 1;
} nextrowerr = oddrowerrs[ci] + width;
thisrowerr[ci] = val; /* save for error propagation */
pixcode += GETJSAMPLE(colorindex[ci][val]);
}
output_data[row][col] = pixcode;
/* propagate error to adjacent pixels */
for (ci = 0; ci < nc; ci++) {
val = thisrowerr[ci] - GETJSAMPLE(colormap[ci][pixcode]);
thisrowerr[ci-nc] += val * 7;
nextrowerr[ci+nc] += val * 3;
nextrowerr[ci ] += val * 5;
nextrowerr[ci-nc] = val; /* not +=, since not initialized yet */
}
thisrowerr -= nc; /* advance error ptrs to next pixel entry */
nextrowerr -= nc;
} }
on_odd_row = FALSE; colorindex_ci = colorindex[ci];
} else { colormap_ci = colormap[ci];
/* work left to right in this row */ *nextrowerr = 0; /* need only initialize this one entry */
thisrowerr = evenrowerrs + nc; for (col_counter = width; col_counter > 0; col_counter--) {
nextrowerr = oddrowerrs + nc; /* Compute pixel value + accumulated error for this component */
for (ci = 0; ci < nc; ci++) /* need only initialize this one entry */ val = (((FSERROR) GETJSAMPLE(*input_ptr)) << 4) + *thisrowerr;
nextrowerr[ci] = 0; if (val < 0) val = 0; /* must watch for range overflow! */
for (col = 0; col < width; col++) { else {
/* select the output pixel value */ val += 8; /* divide by 16 with proper rounding */
pixcode = 0; val >>= 4;
for (ci = 0; ci < nc; ci++) { if (val > MAXJSAMPLE) val = MAXJSAMPLE;
/* compute pixel value + accumulated error */
val = (((FSERROR) GETJSAMPLE(input_data[ci][row][col])) << 4)
+ thisrowerr[ci];
if (val < 0) val = 0; /* must watch for range overflow! */
else {
val += 8; /* divide by 16 with proper rounding */
val >>= 4;
if (val > MAXJSAMPLE) val = MAXJSAMPLE;
}
thisrowerr[ci] = val; /* save for error propagation */
pixcode += GETJSAMPLE(colorindex[ci][val]);
} }
output_data[row][col] = pixcode; /* Select output value, accumulate into output code for this pixel */
/* propagate error to adjacent pixels */ pixcode = GETJSAMPLE(*output_ptr);
for (ci = 0; ci < nc; ci++) { pixcode += GETJSAMPLE(colorindex_ci[val]);
val = thisrowerr[ci] - GETJSAMPLE(colormap[ci][pixcode]); *output_ptr = (JSAMPLE) pixcode;
thisrowerr[ci+nc] += val * 7; /* Compute actual representation error at this pixel */
nextrowerr[ci-nc] += val * 3; /* Note: we can do this even though we don't yet have the final */
nextrowerr[ci ] += val * 5; /* value of pixcode, because the colormap is orthogonal. */
nextrowerr[ci+nc] = val; /* not +=, since not initialized yet */ val -= (FSERROR) GETJSAMPLE(colormap_ci[pixcode]);
} /* Propagate error to (same component of) adjacent pixels */
thisrowerr += nc; /* advance error ptrs to next pixel entry */ /* Remember that nextrowerr entries are in reverse order! */
nextrowerr += nc; two_val = val * 2;
nextrowerr[-1] = val; /* not +=, since not initialized yet */
val += two_val; /* form error * 3 */
nextrowerr[ 1] += val;
val += two_val; /* form error * 5 */
nextrowerr[ 0] += val;
val += two_val; /* form error * 7 */
thisrowerr[ 1] += val;
input_ptr += dir; /* advance input ptr to next column */
output_ptr += dir; /* advance output ptr to next column */
thisrowerr++; /* cur-row error ptr advances to right */
nextrowerr--; /* next-row error ptr advances to left */
} }
on_odd_row = TRUE;
} }
on_odd_row = (on_odd_row ? FALSE : TRUE);
} }
} }
@@ -324,15 +533,9 @@ color_quantize_dither (decompress_info_ptr cinfo, int num_rows,
METHODDEF void METHODDEF void
color_quant_term (decompress_info_ptr cinfo) color_quant_term (decompress_info_ptr cinfo)
{ {
/* We can't free the colormap until now, since output module may use it! */ /* no work (we let free_all release the workspace) */
(*cinfo->emethods->free_small_sarray) /* Note that we *mustn't* free the colormap before free_all, */
(colormap, (long) cinfo->color_out_comps); /* since output module may use it! */
(*cinfo->emethods->free_small_sarray)
(colorindex, (long) cinfo->color_out_comps);
if (cinfo->use_dithering) {
(*cinfo->emethods->free_medium) ((void FAR *) evenrowerrs);
(*cinfo->emethods->free_medium) ((void FAR *) oddrowerrs);
}
} }
@@ -343,7 +546,7 @@ color_quant_term (decompress_info_ptr cinfo)
METHODDEF void METHODDEF void
color_quant_prescan (decompress_info_ptr cinfo, int num_rows, color_quant_prescan (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE image_data) JSAMPIMAGE image_data, JSAMPARRAY workspace)
{ {
ERREXIT(cinfo->emethods, "Should not get here!"); ERREXIT(cinfo->emethods, "Should not get here!");
} }

1091
jquant2.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/* /*
* jrdgif.c * jrdgif.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -62,7 +62,7 @@ static JSAMPARRAY colormap; /* the colormap to use */
#define INTERLACE 0x40 /* mask for bit signifying interlaced image */ #define INTERLACE 0x40 /* mask for bit signifying interlaced image */
#define COLORMAPFLAG 0x80 /* mask for bit signifying colormap presence */ #define COLORMAPFLAG 0x80 /* mask for bit signifying colormap presence */
#define ReadOK(file,buffer,len) (fread(buffer, 1, len, file) == (len)) #define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
/* Static vars for GetCode and LZWReadByte */ /* Static vars for GetCode and LZWReadByte */
@@ -261,7 +261,7 @@ LZWReadByte (compress_info_ptr cinfo)
/* If any codes are stacked from a previously read symbol, return them */ /* If any codes are stacked from a previously read symbol, return them */
if (sp > symbol_stack) if (sp > symbol_stack)
return *(--sp); return (int) *(--sp);
code = GetCode(cinfo); code = GetCode(cinfo);
@@ -286,7 +286,7 @@ LZWReadByte (compress_info_ptr cinfo)
incode = code; /* save for a moment */ incode = code; /* save for a moment */
if (code >= max_code) { /* special case for not-yet-defined symbol */ if (code >= max_code) { /* special case for not-yet-defined symbol */
*sp++ = firstcode; /* it will be defined as oldcode/firstcode */ *sp++ = (UINT8) firstcode; /* it will be defined as oldcode/firstcode */
code = oldcode; code = oldcode;
} }
@@ -302,7 +302,7 @@ LZWReadByte (compress_info_ptr cinfo)
if ((code = max_code) < LZW_TABLE_SIZE) { if ((code = max_code) < LZW_TABLE_SIZE) {
/* Define a new symbol = prev sym + head of this sym's expansion */ /* Define a new symbol = prev sym + head of this sym's expansion */
symbol_head[code] = oldcode; symbol_head[code] = oldcode;
symbol_tail[code] = firstcode; symbol_tail[code] = (UINT8) firstcode;
max_code++; max_code++;
/* Is it time to increase code_size? */ /* Is it time to increase code_size? */
if ((max_code >= limit_code) && (code_size < MAX_LZW_BITS)) { if ((max_code >= limit_code) && (code_size < MAX_LZW_BITS)) {
@@ -323,9 +323,9 @@ ReadColorMap (compress_info_ptr cinfo, int cmaplen, JSAMPARRAY cmap)
int i; int i;
for (i = 0; i < cmaplen; i++) { for (i = 0; i < cmaplen; i++) {
cmap[CM_RED][i] = ReadByte(cinfo); cmap[CM_RED][i] = (JSAMPLE) ReadByte(cinfo);
cmap[CM_GREEN][i] = ReadByte(cinfo); cmap[CM_GREEN][i] = (JSAMPLE) ReadByte(cinfo);
cmap[CM_BLUE][i] = ReadByte(cinfo); cmap[CM_BLUE][i] = (JSAMPLE) ReadByte(cinfo);
} }
} }
@@ -457,8 +457,9 @@ input_init (compress_info_ptr cinfo)
* of get_input_row. * of get_input_row.
*/ */
interlaced_image = (*cinfo->emethods->request_big_sarray) interlaced_image = (*cinfo->emethods->request_big_sarray)
((long) width, (long) height, (long) 1); ((long) width, (long) height, 1L);
cinfo->methods->get_input_row = load_interlaced_image; cinfo->methods->get_input_row = load_interlaced_image;
cinfo->total_passes++; /* count file reading as separate pass */
} }
/* Return info about the image. */ /* Return info about the image. */
@@ -466,7 +467,7 @@ input_init (compress_info_ptr cinfo)
cinfo->in_color_space = CS_RGB; cinfo->in_color_space = CS_RGB;
cinfo->image_width = width; cinfo->image_width = width;
cinfo->image_height = height; cinfo->image_height = height;
cinfo->data_precision = 8; cinfo->data_precision = 8; /* always, even if 12-bit JSAMPLEs */
} }
@@ -513,15 +514,17 @@ load_interlaced_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* Read the interlaced image into the big array we've created. */ /* Read the interlaced image into the big array we've created. */
for (row = 0; row < cinfo->image_height; row++) { for (row = 0; row < cinfo->image_height; row++) {
(*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
image_ptr = (*cinfo->emethods->access_big_sarray) image_ptr = (*cinfo->emethods->access_big_sarray)
(interlaced_image, row, TRUE); (interlaced_image, row, TRUE);
sptr = image_ptr[0]; sptr = image_ptr[0];
for (col = cinfo->image_width; col > 0; col--) { for (col = cinfo->image_width; col > 0; col--) {
if ((c = LZWReadByte(cinfo)) < 0) if ((c = LZWReadByte(cinfo)) < 0)
ERREXIT(cinfo->emethods, "Premature end of GIF image"); ERREXIT(cinfo->emethods, "Premature end of GIF image");
*sptr++ = c; *sptr++ = (JSAMPLE) c;
} }
} }
cinfo->completed_passes++;
/* Replace method pointer so subsequent calls don't come here. */ /* Replace method pointer so subsequent calls don't come here. */
cinfo->methods->get_input_row = get_interlaced_row; cinfo->methods->get_input_row = get_interlaced_row;
@@ -590,14 +593,7 @@ get_interlaced_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
METHODDEF void METHODDEF void
input_term (compress_info_ptr cinfo) input_term (compress_info_ptr cinfo)
{ {
if (is_interlaced) { /* no work (we let free_all release the workspace) */
(*cinfo->emethods->free_big_sarray) (interlaced_image);
}
(*cinfo->emethods->free_small_sarray)
(colormap, (long) NUMCOLORS);
(*cinfo->emethods->free_medium) ((void FAR *) symbol_head);
(*cinfo->emethods->free_medium) ((void FAR *) symbol_tail);
(*cinfo->emethods->free_medium) ((void FAR *) symbol_stack);
} }

View File

@@ -1,23 +1,25 @@
/* /*
* jrdjfif.c * jrdjfif.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
* This file contains routines to decode standard JPEG file headers/markers. * This file contains routines to decode standard JPEG file headers/markers.
* This will handle baseline and JFIF-convention JPEG files. * This code will handle "raw JPEG" and JFIF-convention JPEG files.
*
* You can also use this module to decode a raw-JPEG or JFIF-standard data
* stream that is embedded within a larger file. To do that, you must
* position the file to the JPEG SOI marker (0xFF/0xD8) that begins the
* data sequence to be decoded. If nothing better is possible, you can scan
* the file until you see the SOI marker, then use JUNGETC to push it back.
* *
* This module relies on the JGETC macro and the read_jpeg_data method (which * This module relies on the JGETC macro and the read_jpeg_data method (which
* is provided by the user interface) to read from the JPEG data stream. * is provided by the user interface) to read from the JPEG data stream.
* Therefore, this module is NOT dependent on any particular assumption about * Therefore, this module is not dependent on any particular assumption about
* the data source. This fact does not carry over to more complex JPEG file * the data source; it need not be a stdio stream at all. (This fact does
* formats such as JPEG-in-TIFF; those format control modules may well need to * NOT carry over to more complex JPEG file formats such as JPEG-in-TIFF;
* assume stdio input. * those format control modules may well need to assume stdio input.)
*
* read_file_header assumes that reading begins at the JPEG SOI marker
* (although it will skip non-FF bytes looking for a JPEG marker).
* The user interface must position the data stream appropriately.
* *
* These routines are invoked via the methods read_file_header, * These routines are invoked via the methods read_file_header,
* read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer. * read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer.
@@ -98,11 +100,11 @@ typedef enum { /* JPEG marker codes */
METHODDEF int METHODDEF int
read_jpeg_data (decompress_info_ptr cinfo) read_jpeg_data (decompress_info_ptr cinfo)
{ {
cinfo->bytes_in_buffer = fread(cinfo->input_buffer + MIN_UNGET,
1, JPEG_BUF_SIZE,
cinfo->input_file);
cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET; cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
cinfo->next_input_byte,
JPEG_BUF_SIZE);
if (cinfo->bytes_in_buffer <= 0) if (cinfo->bytes_in_buffer <= 0)
ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file"); ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
@@ -138,7 +140,7 @@ skip_variable (decompress_info_ptr cinfo, int code)
length = get_2bytes(cinfo); length = get_2bytes(cinfo);
TRACEMS2(cinfo->emethods, 1, TRACEMS2(cinfo->emethods, 1,
"Skipping marker 0x%02x, length %d", code, length); "Skipping marker 0x%02x, length %u", code, (int) length);
for (length -= 2; length > 0; length--) for (length -= 2; length > 0; length--)
(void) JGETC(cinfo); (void) JGETC(cinfo);
@@ -165,7 +167,7 @@ get_dht (decompress_info_ptr cinfo)
bits[0] = 0; bits[0] = 0;
count = 0; count = 0;
for (i = 1; i <= 16; i++) { for (i = 1; i <= 16; i++) {
bits[i] = JGETC(cinfo); bits[i] = (UINT8) JGETC(cinfo);
count += bits[i]; count += bits[i];
} }
@@ -180,7 +182,7 @@ get_dht (decompress_info_ptr cinfo)
ERREXIT(cinfo->emethods, "Bogus DHT counts"); ERREXIT(cinfo->emethods, "Bogus DHT counts");
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
huffval[i] = JGETC(cinfo); huffval[i] = (UINT8) JGETC(cinfo);
length -= 1 + 16 + count; length -= 1 + 16 + count;
@@ -195,7 +197,7 @@ get_dht (decompress_info_ptr cinfo)
ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index); ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index);
if (*htblptr == NULL) if (*htblptr == NULL)
*htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL)); *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
memcpy((void *) (*htblptr)->bits, (void *) bits, memcpy((void *) (*htblptr)->bits, (void *) bits,
SIZEOF((*htblptr)->bits)); SIZEOF((*htblptr)->bits));
@@ -225,10 +227,10 @@ get_dac (decompress_info_ptr cinfo)
ERREXIT1(cinfo->emethods, "Bogus DAC index %d", index); ERREXIT1(cinfo->emethods, "Bogus DAC index %d", index);
if (index >= NUM_ARITH_TBLS) { /* define AC table */ if (index >= NUM_ARITH_TBLS) { /* define AC table */
cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = val; cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
} else { /* define DC table */ } else { /* define DC table */
cinfo->arith_dc_L[index] = val & 0x0F; cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
cinfo->arith_dc_U[index] = val >> 4; cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
ERREXIT1(cinfo->emethods, "Bogus DAC value 0x%x", val); ERREXIT1(cinfo->emethods, "Bogus DAC value 0x%x", val);
} }
@@ -261,7 +263,8 @@ get_dqt (decompress_info_ptr cinfo)
ERREXIT1(cinfo->emethods, "Bogus table number %d", n); ERREXIT1(cinfo->emethods, "Bogus table number %d", n);
if (cinfo->quant_tbl_ptrs[n] == NULL) if (cinfo->quant_tbl_ptrs[n] == NULL)
cinfo->quant_tbl_ptrs[n] = (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL)); cinfo->quant_tbl_ptrs[n] = (QUANT_TBL_PTR)
(*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
quant_ptr = cinfo->quant_tbl_ptrs[n]; quant_ptr = cinfo->quant_tbl_ptrs[n];
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
@@ -290,7 +293,7 @@ get_dri (decompress_info_ptr cinfo)
if (get_2bytes(cinfo) != 4) if (get_2bytes(cinfo) != 4)
ERREXIT(cinfo->emethods, "Bogus length in DRI"); ERREXIT(cinfo->emethods, "Bogus length in DRI");
cinfo->restart_interval = get_2bytes(cinfo); cinfo->restart_interval = (UINT16) get_2bytes(cinfo);
TRACEMS1(cinfo->emethods, 1, TRACEMS1(cinfo->emethods, 1,
"Define Restart Interval %d", cinfo->restart_interval); "Define Restart Interval %d", cinfo->restart_interval);
@@ -312,7 +315,7 @@ get_app0 (decompress_info_ptr cinfo)
if (length >= JFIF_LEN) { if (length >= JFIF_LEN) {
for (buffp = 0; buffp < JFIF_LEN; buffp++) for (buffp = 0; buffp < JFIF_LEN; buffp++)
b[buffp] = JGETC(cinfo); b[buffp] = (UINT8) JGETC(cinfo);
length -= JFIF_LEN; length -= JFIF_LEN;
if (b[0]=='J' && b[1]=='F' && b[2]=='I' && b[3]=='F' && b[4]==0) { if (b[0]=='J' && b[1]=='F' && b[2]=='I' && b[3]=='F' && b[4]==0) {
@@ -364,8 +367,8 @@ get_sof (decompress_info_ptr cinfo, int code)
cinfo->num_components = JGETC(cinfo); cinfo->num_components = JGETC(cinfo);
TRACEMS4(cinfo->emethods, 1, TRACEMS4(cinfo->emethods, 1,
"Start Of Frame 0x%02x: width=%d, height=%d, components=%d", "Start Of Frame 0x%02x: width=%u, height=%u, components=%d",
code, cinfo->image_width, cinfo->image_height, code, (int) cinfo->image_width, (int) cinfo->image_height,
cinfo->num_components); cinfo->num_components);
/* We don't support files in which the image height is initially specified */ /* We don't support files in which the image height is initially specified */
@@ -391,7 +394,7 @@ get_sof (decompress_info_ptr cinfo, int code)
if (length != (cinfo->num_components * 3 + 8)) if (length != (cinfo->num_components * 3 + 8))
ERREXIT(cinfo->emethods, "Bogus SOF length"); ERREXIT(cinfo->emethods, "Bogus SOF length");
cinfo->comp_info = (*cinfo->emethods->alloc_small) cinfo->comp_info = (jpeg_component_info *) (*cinfo->emethods->alloc_small)
(cinfo->num_components * SIZEOF(jpeg_component_info)); (cinfo->num_components * SIZEOF(jpeg_component_info));
for (ci = 0; ci < cinfo->num_components; ci++) { for (ci = 0; ci < cinfo->num_components; ci++) {
@@ -538,7 +541,7 @@ process_tables (decompress_info_ptr cinfo)
case M_SOI: case M_SOI:
case M_EOI: case M_EOI:
case M_SOS: case M_SOS:
return c; return ((JPEG_MARKER) c);
case M_DHT: case M_DHT:
get_dht(cinfo); get_dht(cinfo);
@@ -590,11 +593,15 @@ read_file_header (decompress_info_ptr cinfo)
{ {
int c; int c;
/* Expect an SOI marker first */ /* Demand an SOI marker at the start of the file --- otherwise it's
if (next_marker(cinfo) == M_SOI) * probably not a JPEG file at all. If the user interface wants to support
get_soi(cinfo); * nonstandard headers in front of the SOI, it must skip over them itself
else * before calling jpeg_decompress().
ERREXIT(cinfo->emethods, "File does not start with JPEG SOI marker"); */
if (JGETC(cinfo) != 0xFF || JGETC(cinfo) != M_SOI)
ERREXIT(cinfo->emethods, "Not a JPEG file");
get_soi(cinfo); /* OK, process SOI */
/* Process markers until SOF */ /* Process markers until SOF */
c = process_tables(cinfo); c = process_tables(cinfo);

282
jrdppm.c
View File

@@ -1,12 +1,13 @@
/* /*
* jrdppm.c * jrdppm.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
* This file contains routines to read input images in PPM format. * This file contains routines to read input images in PPM format.
* The PBMPLUS library is required (well, it will be in the real version). * The PBMPLUS library is NOT required to compile this software,
* but it is highly useful as a set of PPM image manipulation programs.
* *
* These routines may need modification for non-Unix environments or * These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume input from * specialized applications. As they stand, they assume input from
@@ -24,6 +25,194 @@
#ifdef PPM_SUPPORTED #ifdef PPM_SUPPORTED
static JSAMPLE * rescale; /* => maxval-remapping array, or NULL */
/* Portions of this code are based on the PBMPLUS library, which is:
**
** Copyright (C) 1988 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
LOCAL int
pbm_getc (FILE * file)
/* Read next char, skipping over any comments */
/* A comment/newline sequence is returned as a newline */
{
register int ch;
ch = getc(file);
if (ch == '#') {
do {
ch = getc(file);
} while (ch != '\n' && ch != EOF);
}
return ch;
}
LOCAL unsigned int
read_pbm_integer (compress_info_ptr cinfo)
/* Read an unsigned decimal integer from the PPM file */
/* Swallows one trailing character after the integer */
/* Note that on a 16-bit-int machine, only values up to 64k can be read. */
/* This should not be a problem in practice. */
{
register int ch;
register unsigned int val;
/* Skip any leading whitespace */
do {
ch = pbm_getc(cinfo->input_file);
if (ch == EOF)
ERREXIT(cinfo->emethods, "Premature EOF in PPM file");
} while (ch == ' ' || ch == '\t' || ch == '\n');
if (ch < '0' || ch > '9')
ERREXIT(cinfo->emethods, "Bogus data in PPM file");
val = ch - '0';
while ((ch = pbm_getc(cinfo->input_file)) >= '0' && ch <= '9') {
val *= 10;
val += ch - '0';
}
return val;
}
/*
* Read one row of pixels.
*
* We provide several different versions depending on input file format.
* In all cases, input is scaled to the size of JSAMPLE; it's possible that
* when JSAMPLE is 12 bits, this would not really be desirable.
*
* Note that a really fast path is provided for reading raw files with
* maxval = MAXJSAMPLE, which is the normal case (at least for 8-bit JSAMPLEs).
*/
METHODDEF void
get_text_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading text-format PGM files with any maxval */
{
register JSAMPROW ptr0;
register unsigned int val;
register long col;
ptr0 = pixel_row[0];
for (col = cinfo->image_width; col > 0; col--) {
val = read_pbm_integer(cinfo);
if (rescale != NULL)
val = rescale[val];
*ptr0++ = (JSAMPLE) val;
}
}
METHODDEF void
get_text_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading text-format PPM files with any maxval */
{
register JSAMPROW ptr0, ptr1, ptr2;
register unsigned int val;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
val = read_pbm_integer(cinfo);
if (rescale != NULL)
val = rescale[val];
*ptr0++ = (JSAMPLE) val;
val = read_pbm_integer(cinfo);
if (rescale != NULL)
val = rescale[val];
*ptr1++ = (JSAMPLE) val;
val = read_pbm_integer(cinfo);
if (rescale != NULL)
val = rescale[val];
*ptr2++ = (JSAMPLE) val;
}
}
METHODDEF void
get_scaled_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading raw-format PGM files with any maxval */
{
register FILE * infile = cinfo->input_file;
register JSAMPROW ptr0;
register long col;
ptr0 = pixel_row[0];
for (col = cinfo->image_width; col > 0; col--) {
*ptr0++ = rescale[getc(infile)];
}
}
METHODDEF void
get_scaled_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading raw-format PPM files with any maxval */
{
register FILE * infile = cinfo->input_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
*ptr0++ = rescale[getc(infile)];
*ptr1++ = rescale[getc(infile)];
*ptr2++ = rescale[getc(infile)];
}
}
METHODDEF void
get_raw_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading raw-format PGM files with maxval = MAXJSAMPLE */
{
register FILE * infile = cinfo->input_file;
register JSAMPROW ptr0;
register long col;
ptr0 = pixel_row[0];
for (col = cinfo->image_width; col > 0; col--) {
*ptr0++ = (JSAMPLE) getc(infile);
}
}
METHODDEF void
get_raw_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading raw-format PPM files with maxval = MAXJSAMPLE */
{
register FILE * infile = cinfo->input_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
*ptr0++ = (JSAMPLE) getc(infile);
*ptr1++ = (JSAMPLE) getc(infile);
*ptr2++ = (JSAMPLE) getc(infile);
}
}
/* /*
* Read the file header; return image size and component count. * Read the file header; return image size and component count.
*/ */
@@ -31,19 +220,45 @@
METHODDEF void METHODDEF void
input_init (compress_info_ptr cinfo) input_init (compress_info_ptr cinfo)
{ {
int c, w, h, prec; int c;
unsigned int w, h, maxval;
if (getc(cinfo->input_file) != 'P') if (getc(cinfo->input_file) != 'P')
ERREXIT(cinfo->emethods, "Not a PPM file"); ERREXIT(cinfo->emethods, "Not a PPM file");
c = getc(cinfo->input_file); c = getc(cinfo->input_file); /* save format discriminator for a sec */
w = read_pbm_integer(cinfo); /* while we fetch the header info */
h = read_pbm_integer(cinfo);
maxval = read_pbm_integer(cinfo);
switch (c) { switch (c) {
case '5': /* it's a PGM file */ case '2': /* it's a text-format PGM file */
cinfo->methods->get_input_row = get_text_gray_row;
cinfo->input_components = 1; cinfo->input_components = 1;
cinfo->in_color_space = CS_GRAYSCALE; cinfo->in_color_space = CS_GRAYSCALE;
break; break;
case '6': /* it's a PPM file */ case '3': /* it's a text-format PPM file */
cinfo->methods->get_input_row = get_text_rgb_row;
cinfo->input_components = 3;
cinfo->in_color_space = CS_RGB;
break;
case '5': /* it's a raw-format PGM file */
if (maxval == MAXJSAMPLE)
cinfo->methods->get_input_row = get_raw_gray_row;
else
cinfo->methods->get_input_row = get_scaled_gray_row;
cinfo->input_components = 1;
cinfo->in_color_space = CS_GRAYSCALE;
break;
case '6': /* it's a raw-format PPM file */
if (maxval == MAXJSAMPLE)
cinfo->methods->get_input_row = get_raw_rgb_row;
else
cinfo->methods->get_input_row = get_scaled_rgb_row;
cinfo->input_components = 3; cinfo->input_components = 3;
cinfo->in_color_space = CS_RGB; cinfo->in_color_space = CS_RGB;
break; break;
@@ -53,44 +268,29 @@ input_init (compress_info_ptr cinfo)
break; break;
} }
if (fscanf(cinfo->input_file, " %d %d %d", &w, &h, &prec) != 3) if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
ERREXIT(cinfo->emethods, "Not a PPM file"); ERREXIT(cinfo->emethods, "Not a PPM file");
if (getc(cinfo->input_file) != '\n' || w <= 0 || h <= 0 || prec != 255) /* Compute the rescaling array if necessary */
ERREXIT(cinfo->emethods, "Not a PPM file"); /* This saves per-pixel calculation */
if (maxval == MAXJSAMPLE)
rescale = NULL; /* no rescaling required */
else {
INT32 val, half_maxval;
/* On 16-bit-int machines we have to be careful of maxval = 65535 */
rescale = (JSAMPLE *) (*cinfo->emethods->alloc_small)
((size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
half_maxval = maxval / 2;
for (val = 0; val <= (INT32) maxval; val++) {
/* The multiplication here must be done in 32 bits to avoid overflow */
rescale[val] = (JSAMPLE) ((val * MAXJSAMPLE + half_maxval) / maxval);
}
}
cinfo->image_width = w; cinfo->image_width = w;
cinfo->image_height = h; cinfo->image_height = h;
cinfo->data_precision = 8; cinfo->data_precision = BITS_IN_JSAMPLE;
}
/*
* Read one row of pixels.
*/
METHODDEF void
get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
{
register FILE * infile = cinfo->input_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
if (cinfo->input_components == 1) {
ptr0 = pixel_row[0];
for (col = cinfo->image_width; col > 0; col--) {
*ptr0++ = getc(infile);
}
} else {
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
*ptr0++ = getc(infile);
*ptr1++ = getc(infile);
*ptr2++ = getc(infile);
}
}
} }
@@ -101,7 +301,7 @@ get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
METHODDEF void METHODDEF void
input_term (compress_info_ptr cinfo) input_term (compress_info_ptr cinfo)
{ {
/* no work required */ /* no work (we let free_all release the workspace) */
} }
@@ -117,7 +317,7 @@ GLOBAL void
jselrppm (compress_info_ptr cinfo) jselrppm (compress_info_ptr cinfo)
{ {
cinfo->methods->input_init = input_init; cinfo->methods->input_init = input_init;
cinfo->methods->get_input_row = get_input_row; /* cinfo->methods->get_input_row is set by input_init */
cinfo->methods->input_term = input_term; cinfo->methods->input_term = input_term;
} }

366
jrdrle.c Normal file
View File

@@ -0,0 +1,366 @@
/*
* jrdrle.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains routines to read input images in Utah RLE format.
* The Utah Raster Toolkit library is required (version 3.0).
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume input from
* an ordinary stdio stream. They further assume that reading begins
* at the start of the file; input_init may need work if the
* user interface has already read some data (e.g., to determine that
* the file is indeed RLE format).
*
* These routines are invoked via the methods get_input_row
* and input_init/term.
*
* Based on code contributed by Mike Lijewski.
*/
#include "jinclude.h"
#ifdef RLE_SUPPORTED
/* rle.h is provided by the Utah Raster Toolkit. */
#include <rle.h>
/*
* load_image assumes that JSAMPLE has the same representation as rle_pixel,
* to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples.
*/
#ifndef EIGHT_BIT_SAMPLES
Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
#endif
/*
* We support the following types of RLE files:
*
* GRAYSCALE - 8 bits, no colormap
* PSEUDOCOLOR - 8 bits, colormap
* TRUECOLOR - 24 bits, colormap
* DIRECTCOLOR - 24 bits, no colormap
*
* For now, we ignore any alpha channel in the image.
*/
typedef enum { GRAYSCALE, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
static rle_kind visual; /* actual type of input file */
/*
* Since RLE stores scanlines bottom-to-top, we have to invert the image
* to conform to JPEG's top-to-bottom order. To do this, we read the
* incoming image into a virtual array on the first get_input_row call,
* then fetch the required row from the virtual array on subsequent calls.
*/
static big_sarray_ptr image; /* single array for GRAYSCALE/PSEUDOCOLOR */
static big_sarray_ptr red_channel; /* three arrays for TRUECOLOR/DIRECTCOLOR */
static big_sarray_ptr green_channel;
static big_sarray_ptr blue_channel;
static long cur_row_number; /* last row# read from virtual array */
static rle_hdr header; /* Input file information */
static rle_map *colormap; /* RLE colormap, if any */
/*
* Read the file header; return image size and component count.
*/
METHODDEF void
input_init (compress_info_ptr cinfo)
{
long width, height;
/* Use RLE library routine to get the header info */
header.rle_file = cinfo->input_file;
switch (rle_get_setup(&header)) {
case RLE_SUCCESS:
/* A-OK */
break;
case RLE_NOT_RLE:
ERREXIT(cinfo->emethods, "Not an RLE file");
break;
case RLE_NO_SPACE:
ERREXIT(cinfo->emethods, "Insufficient memory for RLE header");
break;
case RLE_EMPTY:
ERREXIT(cinfo->emethods, "Empty RLE file");
break;
case RLE_EOF:
ERREXIT(cinfo->emethods, "Premature EOF in RLE header");
break;
default:
ERREXIT(cinfo->emethods, "Bogus RLE error code");
break;
}
/* Figure out what we have, set private vars and return values accordingly */
width = header.xmax - header.xmin + 1;
height = header.ymax - header.ymin + 1;
header.xmin = 0; /* realign horizontally */
header.xmax = width-1;
cinfo->image_width = width;
cinfo->image_height = height;
cinfo->data_precision = 8; /* we can only handle 8 bit data */
if (header.ncolors == 1 && header.ncmap == 0) {
visual = GRAYSCALE;
TRACEMS(cinfo->emethods, 1, "Gray-scale RLE file");
} else if (header.ncolors == 1 && header.ncmap == 3) {
visual = PSEUDOCOLOR;
colormap = header.cmap;
TRACEMS1(cinfo->emethods, 1, "Colormapped RLE file with map of length %d",
1 << header.cmaplen);
} else if (header.ncolors == 3 && header.ncmap == 3) {
visual = TRUECOLOR;
colormap = header.cmap;
TRACEMS1(cinfo->emethods, 1, "Full-color RLE file with map of length %d",
1 << header.cmaplen);
} else if (header.ncolors == 3 && header.ncmap == 0) {
visual = DIRECTCOLOR;
TRACEMS(cinfo->emethods, 1, "Full-color RLE file");
} else
ERREXIT(cinfo->emethods, "Can't handle this RLE setup");
switch (visual) {
case GRAYSCALE:
/* request one big array to hold the grayscale image */
image = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
cinfo->in_color_space = CS_GRAYSCALE;
cinfo->input_components = 1;
break;
case PSEUDOCOLOR:
/* request one big array to hold the pseudocolor image */
image = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
cinfo->in_color_space = CS_RGB;
cinfo->input_components = 3;
break;
case TRUECOLOR:
case DIRECTCOLOR:
/* request three big arrays to hold the RGB channels */
red_channel = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
green_channel = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
blue_channel = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
cinfo->in_color_space = CS_RGB;
cinfo->input_components = 3;
break;
}
cinfo->total_passes++; /* count file reading as separate pass */
}
/*
* Read one row of pixels.
* These are called only after load_image has read the image into
* the virtual array(s).
*/
METHODDEF void
get_grayscale_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for GRAYSCALE images */
{
JSAMPROW inputrows[1]; /* a pseudo JSAMPARRAY structure */
cur_row_number--; /* work down in array */
inputrows[0] = *((*cinfo->emethods->access_big_sarray)
(image, cur_row_number, FALSE));
jcopy_sample_rows(inputrows, 0, pixel_row, 0, 1, cinfo->image_width);
}
METHODDEF void
get_pseudocolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for PSEUDOCOLOR images */
{
long col;
JSAMPROW image_ptr, ptr0, ptr1, ptr2;
int val;
cur_row_number--; /* work down in array */
image_ptr = *((*cinfo->emethods->access_big_sarray)
(image, cur_row_number, FALSE));
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
val = GETJSAMPLE(*image_ptr++);
*ptr0++ = colormap[val ] >> 8;
*ptr1++ = colormap[val + 256] >> 8;
*ptr2++ = colormap[val + 512] >> 8;
}
}
METHODDEF void
get_truecolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for TRUECOLOR images */
/* The colormap consists of 3 independent lookup tables */
{
long col;
JSAMPROW red_ptr, green_ptr, blue_ptr, ptr0, ptr1, ptr2;
cur_row_number--; /* work down in array */
red_ptr = *((*cinfo->emethods->access_big_sarray)
(red_channel, cur_row_number, FALSE));
green_ptr = *((*cinfo->emethods->access_big_sarray)
(green_channel, cur_row_number, FALSE));
blue_ptr = *((*cinfo->emethods->access_big_sarray)
(blue_channel, cur_row_number, FALSE));
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
*ptr0++ = colormap[GETJSAMPLE(*red_ptr++) ] >> 8;
*ptr1++ = colormap[GETJSAMPLE(*green_ptr++) + 256] >> 8;
*ptr2++ = colormap[GETJSAMPLE(*blue_ptr++) + 512] >> 8;
}
}
METHODDEF void
get_directcolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This is used for DIRECTCOLOR images */
{
JSAMPROW inputrows[3]; /* a pseudo JSAMPARRAY structure */
cur_row_number--; /* work down in array */
inputrows[0] = *((*cinfo->emethods->access_big_sarray)
(red_channel, cur_row_number, FALSE));
inputrows[1] = *((*cinfo->emethods->access_big_sarray)
(green_channel, cur_row_number, FALSE));
inputrows[2] = *((*cinfo->emethods->access_big_sarray)
(blue_channel, cur_row_number, FALSE));
jcopy_sample_rows(inputrows, 0, pixel_row, 0, 3, cinfo->image_width);
}
/*
* Load the color channels into separate arrays. We have to do
* this because RLE files start at the lower left while the JPEG standard
* has them starting in the upper left. This is called the first time
* we want to get a row of input. What we do is load the RLE data into
* big arrays and then call the appropriate routine to read one row from
* the big arrays. We also change cinfo->methods->get_input_row so that
* subsequent calls go straight to the row-reading routine.
*/
METHODDEF void
load_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
{
long row;
rle_pixel *rle_row[3];
/* Read the RLE data into our virtual array(s).
* We assume here that (a) rle_pixel is represented the same as JSAMPLE,
* and (b) we are not on a machine where FAR pointers differ from regular.
*/
RLE_CLR_BIT(header, RLE_ALPHA); /* don't read the alpha channel */
switch (visual) {
case GRAYSCALE:
case PSEUDOCOLOR:
for (row = 0; row < cinfo->image_height; row++) {
(*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
/*
* Read a row of the image directly into our big array.
* Too bad this doesn't seem to return any indication of errors :-(.
*/
rle_row[0] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
(image, row, TRUE));
rle_getrow(&header, rle_row);
}
break;
case TRUECOLOR:
case DIRECTCOLOR:
for (row = 0; row < cinfo->image_height; row++) {
(*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
/*
* Read a row of the image directly into our big arrays.
* Too bad this doesn't seem to return any indication of errors :-(.
*/
rle_row[0] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
(red_channel, row, TRUE));
rle_row[1] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
(green_channel, row, TRUE));
rle_row[2] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
(blue_channel, row, TRUE));
rle_getrow(&header, rle_row);
}
break;
}
cinfo->completed_passes++;
/* Set up to call proper row-extraction routine in future */
switch (visual) {
case GRAYSCALE:
cinfo->methods->get_input_row = get_grayscale_row;
break;
case PSEUDOCOLOR:
cinfo->methods->get_input_row = get_pseudocolor_row;
break;
case TRUECOLOR:
cinfo->methods->get_input_row = get_truecolor_row;
break;
case DIRECTCOLOR:
cinfo->methods->get_input_row = get_directcolor_row;
break;
}
/* And fetch the topmost (bottommost) row */
cur_row_number = cinfo->image_height;
(*cinfo->methods->get_input_row) (cinfo, pixel_row);
}
/*
* Finish up at the end of the file.
*/
METHODDEF void
input_term (compress_info_ptr cinfo)
{
/* no work (we let free_all release the workspace) */
}
/*
* The method selection routine for RLE format input.
* Note that this must be called by the user interface before calling
* jpeg_compress. If multiple input formats are supported, the
* user interface is responsible for discovering the file format and
* calling the appropriate method selection routine.
*/
GLOBAL void
jselrrle (compress_info_ptr cinfo)
{
cinfo->methods->input_init = input_init;
cinfo->methods->get_input_row = load_image; /* until first call */
cinfo->methods->input_term = input_term;
}
#endif /* RLE_SUPPORTED */

464
jrdtarga.c Normal file
View File

@@ -0,0 +1,464 @@
/*
* jrdtarga.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains routines to read input images in Targa format.
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume input from
* an ordinary stdio stream. They further assume that reading begins
* at the start of the file; input_init may need work if the
* user interface has already read some data (e.g., to determine that
* the file is indeed Targa format).
*
* These routines are invoked via the methods get_input_row
* and input_init/term.
*
* Based on code contributed by Lee Daniel Crocker.
*/
#include "jinclude.h"
#ifdef TARGA_SUPPORTED
/* Macros to deal with unsigned chars as efficiently as compiler allows */
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char U_CHAR;
#define UCH(x) ((int) (x))
#else /* !HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char U_CHAR;
#define UCH(x) ((int) (x))
#else
typedef char U_CHAR;
#define UCH(x) ((int) (x) & 0xFF)
#endif
#endif /* HAVE_UNSIGNED_CHAR */
#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
static JSAMPARRAY colormap; /* Targa colormap (converted to my format) */
static big_sarray_ptr whole_image; /* Needed if funny input row order */
static long current_row; /* Current logical row number to read */
/* Pointer to routine to extract next Targa pixel from input file */
static void (*read_pixel) PP((compress_info_ptr cinfo));
/* Result of read_pixel is delivered here: */
static U_CHAR tga_pixel[4];
static int pixel_size; /* Bytes per Targa pixel (1 to 4) */
/* State info for reading RLE-coded pixels; both counts must be init to 0 */
static int block_count; /* # of pixels remaining in RLE block */
static int dup_pixel_count; /* # of times to duplicate previous pixel */
/* This saves the correct pixel-row-expansion method for preload_image */
static void (*get_pixel_row) PP((compress_info_ptr cinfo,
JSAMPARRAY pixel_row));
/* For expanding 5-bit pixel values to 8-bit with best rounding */
static const UINT8 c5to8bits[32] = {
0, 8, 16, 24, 32, 41, 49, 57,
65, 74, 82, 90, 98, 106, 115, 123,
131, 139, 148, 156, 164, 172, 180, 189,
197, 205, 213, 222, 230, 238, 246, 255
};
LOCAL int
read_byte (compress_info_ptr cinfo)
/* Read next byte from Targa file */
{
register FILE *infile = cinfo->input_file;
register int c;
if ((c = getc(infile)) == EOF)
ERREXIT(cinfo->emethods, "Premature EOF in Targa file");
return c;
}
LOCAL void
read_colormap (compress_info_ptr cinfo, int cmaplen, int mapentrysize)
/* Read the colormap from a Targa file */
{
int i;
/* Presently only handles 24-bit BGR format */
if (mapentrysize != 24)
ERREXIT(cinfo->emethods, "Unsupported Targa colormap format");
for (i = 0; i < cmaplen; i++) {
colormap[2][i] = (JSAMPLE) read_byte(cinfo);
colormap[1][i] = (JSAMPLE) read_byte(cinfo);
colormap[0][i] = (JSAMPLE) read_byte(cinfo);
}
}
/*
* read_pixel methods: get a single pixel from Targa file into tga_pixel[]
*/
LOCAL void
read_non_rle_pixel (compress_info_ptr cinfo)
/* Read one Targa pixel from the input file; no RLE expansion */
{
register FILE * infile = cinfo->input_file;
register int i;
for (i = 0; i < pixel_size; i++) {
tga_pixel[i] = (U_CHAR) getc(infile);
}
}
LOCAL void
read_rle_pixel (compress_info_ptr cinfo)
/* Read one Targa pixel from the input file, expanding RLE data as needed */
{
register FILE * infile = cinfo->input_file;
register int i;
/* Duplicate previously read pixel? */
if (dup_pixel_count > 0) {
dup_pixel_count--;
return;
}
/* Time to read RLE block header? */
if (--block_count < 0) { /* decrement pixels remaining in block */
i = read_byte(cinfo);
if (i & 0x80) { /* Start of duplicate-pixel block? */
dup_pixel_count = i & 0x7F; /* number of duplications after this one */
block_count = 0; /* then read new block header */
} else {
block_count = i & 0x7F; /* number of pixels after this one */
}
}
/* Read next pixel */
for (i = 0; i < pixel_size; i++) {
tga_pixel[i] = (U_CHAR) getc(infile);
}
}
/*
* Read one row of pixels.
*
* We provide several different versions depending on input file format.
*/
METHODDEF void
get_8bit_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 8-bit grayscale pixels */
{
register JSAMPROW ptr0;
register long col;
ptr0 = pixel_row[0];
for (col = cinfo->image_width; col > 0; col--) {
(*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
*ptr0++ = (JSAMPLE) UCH(tga_pixel[0]);
}
}
METHODDEF void
get_8bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 8-bit colormap indexes */
{
register int t;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
(*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
t = UCH(tga_pixel[0]);
*ptr0++ = colormap[0][t];
*ptr1++ = colormap[1][t];
*ptr2++ = colormap[2][t];
}
}
METHODDEF void
get_16bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 16-bit pixels */
{
register int t;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
(*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
t = UCH(tga_pixel[0]);
t += UCH(tga_pixel[1]) << 8;
/* We expand 5 bit data to 8 bit sample width.
* The format of the 16-bit (LSB first) input word is
* xRRRRRGGGGGBBBBB
*/
*ptr2++ = (JSAMPLE) c5to8bits[t & 0x1F];
t >>= 5;
*ptr1++ = (JSAMPLE) c5to8bits[t & 0x1F];
t >>= 5;
*ptr0++ = (JSAMPLE) c5to8bits[t & 0x1F];
}
}
METHODDEF void
get_24bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
/* This version is for reading 24-bit pixels */
{
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
ptr0 = pixel_row[0];
ptr1 = pixel_row[1];
ptr2 = pixel_row[2];
for (col = cinfo->image_width; col > 0; col--) {
(*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
*ptr0++ = (JSAMPLE) UCH(tga_pixel[2]); /* convert BGR to RGB order */
*ptr1++ = (JSAMPLE) UCH(tga_pixel[1]);
*ptr2++ = (JSAMPLE) UCH(tga_pixel[0]);
}
}
/*
* Targa also defines a 32-bit pixel format with order B,G,R,A.
* We presently ignore the attribute byte, so the code for reading
* these pixels is identical to the 24-bit routine above.
* This works because the actual pixel length is only known to read_pixel.
*/
#define get_32bit_row get_24bit_row
/*
* This method is for re-reading the input data in standard top-down
* row order. The entire image has already been read into whole_image
* with proper conversion of pixel format, but it's in a funny row order.
*/
METHODDEF void
get_memory_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
{
JSAMPARRAY image_ptr;
long source_row;
/* Compute row of source that maps to current_row of normal order */
/* For now, assume image is bottom-up and not interlaced. */
/* NEEDS WORK to support interlaced images! */
source_row = cinfo->image_height - current_row - 1;
/* Fetch that row from virtual array */
image_ptr = (*cinfo->emethods->access_big_sarray)
(whole_image, source_row * cinfo->input_components, FALSE);
jcopy_sample_rows(image_ptr, 0, pixel_row, 0,
cinfo->input_components, cinfo->image_width);
current_row++;
}
/*
* This method loads the image into whole_image during the first call on
* get_input_row. The get_input_row pointer is then adjusted to call
* get_memory_row on subsequent calls.
*/
METHODDEF void
preload_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
{
JSAMPARRAY image_ptr;
long row;
/* Read the data into a virtual array in input-file row order */
for (row = 0; row < cinfo->image_height; row++) {
(*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
image_ptr = (*cinfo->emethods->access_big_sarray)
(whole_image, row * cinfo->input_components, TRUE);
(*get_pixel_row) (cinfo, image_ptr);
}
cinfo->completed_passes++;
/* Set up to read from the virtual array in unscrambled order */
cinfo->methods->get_input_row = get_memory_row;
current_row = 0;
/* And read the first row */
get_memory_row(cinfo, pixel_row);
}
/*
* Read the file header; return image size and component count.
*/
METHODDEF void
input_init (compress_info_ptr cinfo)
{
U_CHAR targaheader[18];
int idlen, cmaptype, subtype, flags, interlace_type, components;
UINT16 width, height, maplen;
boolean is_bottom_up;
#define GET_2B(offset) ((unsigned int) UCH(targaheader[offset]) + \
(((unsigned int) UCH(targaheader[offset+1])) << 8))
if (! ReadOK(cinfo->input_file, targaheader, 18))
ERREXIT(cinfo->emethods, "Unexpected end of file");
/* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */
if (targaheader[16] == 15)
targaheader[16] = 16;
idlen = UCH(targaheader[0]);
cmaptype = UCH(targaheader[1]);
subtype = UCH(targaheader[2]);
maplen = GET_2B(5);
width = GET_2B(12);
height = GET_2B(14);
pixel_size = UCH(targaheader[16]) >> 3;
flags = UCH(targaheader[17]); /* Image Descriptor byte */
is_bottom_up = ((flags & 0x20) == 0); /* bit 5 set => top-down */
interlace_type = flags >> 6; /* bits 6/7 are interlace code */
if (cmaptype > 1 || /* cmaptype must be 0 or 1 */
pixel_size < 1 || pixel_size > 4 ||
(UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */
interlace_type != 0) /* currently don't allow interlaced image */
ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
if (subtype > 8) {
/* It's an RLE-coded file */
read_pixel = read_rle_pixel;
block_count = dup_pixel_count = 0;
subtype -= 8;
} else {
/* Non-RLE file */
read_pixel = read_non_rle_pixel;
}
/* Now should have subtype 1, 2, or 3 */
components = 3; /* until proven different */
cinfo->in_color_space = CS_RGB;
switch (subtype) {
case 1: /* colormapped image */
if (pixel_size == 1 && cmaptype == 1)
get_pixel_row = get_8bit_row;
else
ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
break;
case 2: /* RGB image */
switch (pixel_size) {
case 2:
get_pixel_row = get_16bit_row;
break;
case 3:
get_pixel_row = get_24bit_row;
break;
case 4:
get_pixel_row = get_32bit_row;
break;
default:
ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
break;
}
break;
case 3: /* Grayscale image */
components = 1;
cinfo->in_color_space = CS_GRAYSCALE;
if (pixel_size == 1)
get_pixel_row = get_8bit_gray_row;
else
ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
break;
default:
ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
break;
}
if (is_bottom_up) {
whole_image = (*cinfo->emethods->request_big_sarray)
((long) width, (long) height * components,
(long) components);
cinfo->methods->get_input_row = preload_image;
cinfo->total_passes++; /* count file reading as separate pass */
} else {
whole_image = NULL;
cinfo->methods->get_input_row = get_pixel_row;
}
while (idlen--) /* Throw away ID field */
(void) read_byte(cinfo);
if (maplen > 0) {
if (maplen > 256 || GET_2B(3) != 0)
ERREXIT(cinfo->emethods, "Colormap too large");
/* Allocate space to store the colormap */
colormap = (*cinfo->emethods->alloc_small_sarray)
((long) maplen, 3L);
/* and read it from the file */
read_colormap(cinfo, (int) maplen, UCH(targaheader[7]));
} else {
if (cmaptype) /* but you promised a cmap! */
ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
colormap = NULL;
}
cinfo->input_components = components;
cinfo->image_width = width;
cinfo->image_height = height;
cinfo->data_precision = 8; /* always, even if 12-bit JSAMPLEs */
}
/*
* Finish up at the end of the file.
*/
METHODDEF void
input_term (compress_info_ptr cinfo)
{
/* no work (we let free_all release the workspace) */
}
/*
* The method selection routine for Targa format input.
* Note that this must be called by the user interface before calling
* jpeg_compress. If multiple input formats are supported, the
* user interface is responsible for discovering the file format and
* calling the appropriate method selection routine.
*/
GLOBAL void
jselrtarga (compress_info_ptr cinfo)
{
cinfo->methods->input_init = input_init;
/* cinfo->methods->get_input_row is set by input_init */
cinfo->methods->input_term = input_term;
}
#endif /* TARGA_SUPPORTED */

266
jrevdct.c
View File

@@ -1,7 +1,7 @@
/* /*
* jrevdct.c * jrevdct.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -15,157 +15,207 @@
#include "jinclude.h" #include "jinclude.h"
/*
* This routine is specialized to the case DCTSIZE = 8.
*/
#if DCTSIZE != 8
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
#endif
/* The poop on this scaling stuff is as follows: /* The poop on this scaling stuff is as follows:
* *
* Most of the numbers (after multiplication by the constants) are * We have to do addition and subtraction of the integer inputs, which
* (logically) shifted left by LG2_DCT_SCALE. This is undone by UNFIXH * is no problem, and multiplication by fractional constants, which is
* before assignment to the output array. Note that we want an additional * a problem to do in integer arithmetic. We multiply all the constants
* division by 2 on the output (required by the equations). * by DCT_SCALE and convert them to integer constants (thus retaining
* LG2_DCT_SCALE bits of precision in the constants). After doing a
* multiplication we have to divide the product by DCT_SCALE, with proper
* rounding, to produce the correct output. The division can be implemented
* cheaply as a right shift of LG2_DCT_SCALE bits. The DCT equations also
* specify an additional division by 2 on the final outputs; this can be
* folded into the right-shift by shifting one more bit (see UNFIXH).
* *
* If right shifts are unsigned, then there is a potential problem. * If you are planning to recode this in assembler, you might want to set
* However, shifting right by 16 and then assigning to a short * LG2_DCT_SCALE to 15. This loses a bit of precision, but then all the
* (assuming short = 16 bits) will keep the sign right!! * multiplications are between 16-bit quantities (given 8-bit JSAMPLEs!)
* * so you could use a signed 16x16=>32 bit multiply instruction instead of
* For other shifts, * full 32x32 multiply. Unfortunately there's no way to describe such a
* * multiply portably in C, so we've gone for the extra bit of accuracy here.
* ((x + (1 << 30)) >> shft) - (1 << (30 - shft))
*
* gives a nice right shift with sign (assuming no overflow). However, all the
* scaling is such that this isn't a problem. (Is this true?)
*/ */
#ifdef EIGHT_BIT_SAMPLES
#define ONE 1L /* remove L if long > 32 bits */
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define LG2_DCT_SCALE 15
#define RIGHT_SHIFT(_x,_shft) ((((_x) + (ONE << 30)) >> (_shft)) - (ONE << (30 - (_shft))))
#else
#define LG2_DCT_SCALE 16 #define LG2_DCT_SCALE 16
#define RIGHT_SHIFT(_x,_shft) ((_x) >> (_shft)) #else
#define LG2_DCT_SCALE 15 /* lose a little precision to avoid overflow */
#endif #endif
#define ONE ((INT32) 1)
#define DCT_SCALE (ONE << LG2_DCT_SCALE) #define DCT_SCALE (ONE << LG2_DCT_SCALE)
/* In some places we shift the inputs left by a couple more bits, */
/* so that they can be added to fractional results without too much */
/* loss of precision. */
#define LG2_OVERSCALE 2 #define LG2_OVERSCALE 2
#define OVERSCALE (ONE << LG2_OVERSCALE) #define OVERSCALE (ONE << LG2_OVERSCALE)
#define OVERSHIFT(x) ((x) <<= LG2_OVERSCALE)
#define FIX(x) ((INT32) ((x) * DCT_SCALE + 0.5)) /* Scale a fractional constant by DCT_SCALE */
#define FIX(x) ((INT32) ((x) * DCT_SCALE + 0.5))
/* Scale a fractional constant by DCT_SCALE/OVERSCALE */
/* Such a constant can be multiplied with an overscaled input */
/* to produce something that's scaled by DCT_SCALE */
#define FIXO(x) ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5)) #define FIXO(x) ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5))
#define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
#define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
#define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)), LG2_DCT_SCALE-LG2_OVERSCALE)
#define OVERSH(x) ((x) << LG2_OVERSCALE)
#define SIN_1_4 FIX(0.7071067811856476) /* Descale and correctly round a value that's scaled by DCT_SCALE */
#define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
/* Same with an additional division by 2, ie, correctly rounded UNFIX(x/2) */
#define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
/* Take a value scaled by DCT_SCALE and round to integer scaled by OVERSCALE */
#define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)),\
LG2_DCT_SCALE-LG2_OVERSCALE)
/* Here are the constants we need */
/* SIN_i_j is sine of i*pi/j, scaled by DCT_SCALE */
/* COS_i_j is cosine of i*pi/j, scaled by DCT_SCALE */
#define SIN_1_4 FIX(0.707106781)
#define COS_1_4 SIN_1_4 #define COS_1_4 SIN_1_4
#define SIN_1_8 FIX(0.3826834323650898) #define SIN_1_8 FIX(0.382683432)
#define COS_1_8 FIX(0.9238795325112870) #define COS_1_8 FIX(0.923879533)
#define SIN_3_8 COS_1_8 #define SIN_3_8 COS_1_8
#define COS_3_8 SIN_1_8 #define COS_3_8 SIN_1_8
#define SIN_1_16 FIX(0.1950903220161282) #define SIN_1_16 FIX(0.195090322)
#define COS_1_16 FIX(0.9807852804032300) #define COS_1_16 FIX(0.980785280)
#define SIN_7_16 COS_1_16 #define SIN_7_16 COS_1_16
#define COS_7_16 SIN_1_16 #define COS_7_16 SIN_1_16
#define SIN_3_16 FIX(0.5555702330196022) #define SIN_3_16 FIX(0.555570233)
#define COS_3_16 FIX(0.8314696123025450) #define COS_3_16 FIX(0.831469612)
#define SIN_5_16 COS_3_16 #define SIN_5_16 COS_3_16
#define COS_5_16 SIN_3_16 #define COS_5_16 SIN_3_16
#define OSIN_1_4 FIXO(0.707106781185647) /* OSIN_i_j is sine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
/* OCOS_i_j is cosine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
#define OSIN_1_4 FIXO(0.707106781)
#define OCOS_1_4 OSIN_1_4 #define OCOS_1_4 OSIN_1_4
#define OSIN_1_8 FIXO(0.3826834323650898) #define OSIN_1_8 FIXO(0.382683432)
#define OCOS_1_8 FIXO(0.9238795325112870) #define OCOS_1_8 FIXO(0.923879533)
#define OSIN_3_8 OCOS_1_8 #define OSIN_3_8 OCOS_1_8
#define OCOS_3_8 OSIN_1_8 #define OCOS_3_8 OSIN_1_8
#define OSIN_1_16 FIXO(0.1950903220161282) #define OSIN_1_16 FIXO(0.195090322)
#define OCOS_1_16 FIXO(0.9807852804032300) #define OCOS_1_16 FIXO(0.980785280)
#define OSIN_7_16 OCOS_1_16 #define OSIN_7_16 OCOS_1_16
#define OCOS_7_16 OSIN_1_16 #define OCOS_7_16 OSIN_1_16
#define OSIN_3_16 FIXO(0.5555702330196022) #define OSIN_3_16 FIXO(0.555570233)
#define OCOS_3_16 FIXO(0.8314696123025450) #define OCOS_3_16 FIXO(0.831469612)
#define OSIN_5_16 OCOS_3_16 #define OSIN_5_16 OCOS_3_16
#define OCOS_5_16 OSIN_3_16 #define OCOS_5_16 OSIN_3_16
INLINE
LOCAL void
fast_idct_8 (DCTELEM *in, int stride)
{
/* tmp1x are new values of tmpx -- flashy register colourers
* should be able to do this lot very well
*/
INT32 tmp10, tmp11, tmp12, tmp13;
INT32 tmp20, tmp21, tmp22, tmp23;
INT32 tmp30, tmp31;
INT32 tmp40, tmp41, tmp42, tmp43;
INT32 tmp50, tmp51, tmp52, tmp53;
INT32 in0, in1, in2, in3, in4, in5, in6, in7;
in0 = in[ 0];
in1 = in[stride ];
in2 = in[stride*2];
in3 = in[stride*3];
in4 = in[stride*4];
in5 = in[stride*5];
in6 = in[stride*6];
in7 = in[stride*7];
tmp10 = (in0 + in4) * COS_1_4;
tmp11 = (in0 - in4) * COS_1_4;
tmp12 = in2 * SIN_1_8 - in6 * COS_1_8;
tmp13 = in6 * SIN_1_8 + in2 * COS_1_8;
tmp20 = tmp10 + tmp13;
tmp21 = tmp11 + tmp12;
tmp22 = tmp11 - tmp12;
tmp23 = tmp10 - tmp13;
tmp30 = UNFIXO((in3 + in5) * COS_1_4);
tmp31 = UNFIXO((in3 - in5) * COS_1_4);
tmp40 = OVERSH(in1) + tmp30;
tmp41 = OVERSH(in7) + tmp31;
tmp42 = OVERSH(in1) - tmp30;
tmp43 = OVERSH(in7) - tmp31;
tmp50 = tmp40 * OCOS_1_16 + tmp41 * OSIN_1_16;
tmp51 = tmp40 * OSIN_1_16 - tmp41 * OCOS_1_16;
tmp52 = tmp42 * OCOS_5_16 + tmp43 * OSIN_5_16;
tmp53 = tmp42 * OSIN_5_16 - tmp43 * OCOS_5_16;
in[ 0] = UNFIXH(tmp20 + tmp50);
in[stride ] = UNFIXH(tmp21 + tmp53);
in[stride*2] = UNFIXH(tmp22 + tmp52);
in[stride*3] = UNFIXH(tmp23 + tmp51);
in[stride*4] = UNFIXH(tmp23 - tmp51);
in[stride*5] = UNFIXH(tmp22 - tmp52);
in[stride*6] = UNFIXH(tmp21 - tmp53);
in[stride*7] = UNFIXH(tmp20 - tmp50);
}
/* /*
* Perform the inverse DCT on one block of coefficients. * Perform the inverse DCT on one block of coefficients.
* *
* Note that this code is specialized to the case DCTSIZE = 8. * A 2-D IDCT can be done by 1-D IDCT on each row
* followed by 1-D IDCT on each column.
*/ */
GLOBAL void GLOBAL void
j_rev_dct (DCTBLOCK data) j_rev_dct (DCTBLOCK data)
{ {
int i; int pass, rowctr;
register DCTELEM *inptr, *outptr;
for (i = 0; i < DCTSIZE; i++) DCTBLOCK workspace;
fast_idct_8(data+i*DCTSIZE, 1);
/* Each iteration of the inner loop performs one 8-point 1-D IDCT.
for (i = 0; i < DCTSIZE; i++) * It reads from a *row* of the input matrix and stores into a *column*
fast_idct_8(data+i, DCTSIZE); * of the output matrix. In the first pass, we read from the data[] array
* and store into the local workspace[]. In the second pass, we read from
* the workspace[] array and store into data[], thus performing the
* equivalent of a columnar IDCT pass with no variable array indexing.
*/
inptr = data; /* initialize pointers for first pass */
outptr = workspace;
for (pass = 1; pass >= 0; pass--) {
for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
/* many tmps have nonoverlapping lifetime -- flashy register colourers
* should be able to do this lot very well
*/
INT32 in0, in1, in2, in3, in4, in5, in6, in7;
INT32 tmp10, tmp11, tmp12, tmp13;
INT32 tmp20, tmp21, tmp22, tmp23;
INT32 tmp30, tmp31;
INT32 tmp40, tmp41, tmp42, tmp43;
INT32 tmp50, tmp51, tmp52, tmp53;
SHIFT_TEMPS
in0 = inptr[0];
in1 = inptr[1];
in2 = inptr[2];
in3 = inptr[3];
in4 = inptr[4];
in5 = inptr[5];
in6 = inptr[6];
in7 = inptr[7];
/* These values are scaled by DCT_SCALE */
tmp10 = (in0 + in4) * COS_1_4;
tmp11 = (in0 - in4) * COS_1_4;
tmp12 = in2 * SIN_1_8 - in6 * COS_1_8;
tmp13 = in6 * SIN_1_8 + in2 * COS_1_8;
tmp20 = tmp10 + tmp13;
tmp21 = tmp11 + tmp12;
tmp22 = tmp11 - tmp12;
tmp23 = tmp10 - tmp13;
/* These values are scaled by OVERSCALE */
tmp30 = UNFIXO((in3 + in5) * COS_1_4);
tmp31 = UNFIXO((in3 - in5) * COS_1_4);
OVERSHIFT(in1);
OVERSHIFT(in7);
tmp40 = in1 + tmp30;
tmp41 = in7 + tmp31;
tmp42 = in1 - tmp30;
tmp43 = in7 - tmp31;
/* And these are scaled by DCT_SCALE */
tmp50 = tmp40 * OCOS_1_16 + tmp41 * OSIN_1_16;
tmp51 = tmp40 * OSIN_1_16 - tmp41 * OCOS_1_16;
tmp52 = tmp42 * OCOS_5_16 + tmp43 * OSIN_5_16;
tmp53 = tmp42 * OSIN_5_16 - tmp43 * OCOS_5_16;
outptr[ 0] = (DCTELEM) UNFIXH(tmp20 + tmp50);
outptr[DCTSIZE ] = (DCTELEM) UNFIXH(tmp21 + tmp53);
outptr[DCTSIZE*2] = (DCTELEM) UNFIXH(tmp22 + tmp52);
outptr[DCTSIZE*3] = (DCTELEM) UNFIXH(tmp23 + tmp51);
outptr[DCTSIZE*4] = (DCTELEM) UNFIXH(tmp23 - tmp51);
outptr[DCTSIZE*5] = (DCTELEM) UNFIXH(tmp22 - tmp52);
outptr[DCTSIZE*6] = (DCTELEM) UNFIXH(tmp21 - tmp53);
outptr[DCTSIZE*7] = (DCTELEM) UNFIXH(tmp20 - tmp50);
inptr += DCTSIZE; /* advance inptr to next row */
outptr++; /* advance outptr to next column */
}
/* end of pass; in case it was pass 1, set up for pass 2 */
inptr = workspace;
outptr = data;
}
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jutils.c * jutils.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -40,7 +40,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
#ifdef NEED_FAR_POINTERS #ifdef NEED_FAR_POINTERS
register long count; register long count;
#else #else
register size_t count = num_cols * SIZEOF(JSAMPLE); register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
#endif #endif
register int row; register int row;
@@ -69,14 +69,12 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, long num_blocks)
*/ */
#ifdef NEED_FAR_POINTERS #ifdef NEED_FAR_POINTERS
register JCOEFPTR inptr, outptr; register JCOEFPTR inptr, outptr;
register int i;
register long count; register long count;
for (count = num_blocks; count > 0; count--) { inptr = (JCOEFPTR) input_row;
inptr = *input_row++; outptr = (JCOEFPTR) output_row;
outptr = *output_row++; for (count = num_blocks * DCTSIZE2; count > 0; count--) {
for (i = DCTSIZE2; i > 0; i--) *outptr++ = *inptr++;
*outptr++ = *inptr++;
} }
#else #else
memcpy((void *) output_row, (void *) input_row, memcpy((void *) output_row, (void *) input_row,

14
jversion.h Normal file
View File

@@ -0,0 +1,14 @@
/*
* jversion.h
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains software version identification.
*/
#define JVERSION "3 17-Mar-92"
#define JCOPYRIGHT "Copyright (C) 1992, Thomas G. Lane"

View File

@@ -1,548 +0,0 @@
/*
* jvirtmem.c
*
* Copyright (C) 1991, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file provides the system-dependent memory allocation routines
* for the case where we can rely on virtual memory to handle large arrays.
*
* This includes some MS-DOS code just for trial purposes; "big" arrays will
* have to be handled with temp files on MS-DOS, so a real implementation of
* a DOS memory manager will probably be a separate file. (See additional
* comments about big arrays, below.)
*
* NB: allocation routines never return NULL.
* They should exit to error_exit if unsuccessful.
*/
#include "jinclude.h"
#ifdef __STDC__
#include <stdlib.h> /* to declare malloc(), free() */
#else
extern void * malloc PP((size_t size));
extern void free PP((void *ptr));
#endif
/* Insert system-specific definitions of far_malloc, far_free here. */
#ifndef NEED_FAR_POINTERS /* Generic for non-braindamaged CPUs */
#define far_malloc(x) malloc(x)
#define far_free(x) free(x)
#else /* NEED_FAR_POINTERS */
#ifdef __TURBOC__
/* These definitions work for Turbo C */
#include <alloc.h> /* need farmalloc(), farfree() */
#define far_malloc(x) farmalloc(x)
#define far_free(x) farfree(x)
#else
#ifdef MSDOS
/* These definitions work for Microsoft C and compatible compilers */
#include <malloc.h> /* need _fmalloc(), _ffree() */
#define far_malloc(x) _fmalloc(x)
#define far_free(x) _ffree(x)
#endif
#endif
#endif /* NEED_FAR_POINTERS */
/*
* Some important notes:
* The array alloc/dealloc routines are not merely a convenience;
* on 80x86 machines the bottom-level pointers in an array are FAR
* and thus may not be allocatable by alloc_small.
*
* Also, it's not a good idea to try to merge the sarray and barray
* routines, even though they are textually almost the same, because
* samples are usually stored as bytes while coefficients are shorts.
* Thus, in machines where byte pointers have a different representation
* from word pointers, the resulting machine code could not be the same.
*/
static external_methods_ptr methods; /* saved for access to error_exit */
#ifdef MEM_STATS /* optional extra stuff for statistics */
#define MALLOC_OVERHEAD (SIZEOF(char *)) /* assumed overhead per request */
#define MALLOC_FAR_OVERHEAD (SIZEOF(char FAR *)) /* for "far" storage */
static long total_num_small = 0; /* total # of small objects alloced */
static long total_bytes_small = 0; /* total bytes requested */
static long cur_num_small = 0; /* # currently alloced */
static long max_num_small = 0; /* max simultaneously alloced */
#ifdef NEED_FAR_POINTERS
static long total_num_medium = 0; /* total # of medium objects alloced */
static long total_bytes_medium = 0; /* total bytes requested */
static long cur_num_medium = 0; /* # currently alloced */
static long max_num_medium = 0; /* max simultaneously alloced */
#endif
static long total_num_sarray = 0; /* total # of sarray objects alloced */
static long total_bytes_sarray = 0; /* total bytes requested */
static long cur_num_sarray = 0; /* # currently alloced */
static long max_num_sarray = 0; /* max simultaneously alloced */
static long total_num_barray = 0; /* total # of barray objects alloced */
static long total_bytes_barray = 0; /* total bytes requested */
static long cur_num_barray = 0; /* # currently alloced */
static long max_num_barray = 0; /* max simultaneously alloced */
GLOBAL void
j_mem_stats (void)
{
/* since this is only a debugging stub, we can cheat a little on the
* trace message mechanism... helps 'cuz trace can't handle longs.
*/
fprintf(stderr, "total_num_small = %ld\n", total_num_small);
fprintf(stderr, "total_bytes_small = %ld\n", total_bytes_small);
if (cur_num_small)
fprintf(stderr, "CUR_NUM_SMALL = %ld\n", cur_num_small);
fprintf(stderr, "max_num_small = %ld\n", max_num_small);
#ifdef NEED_FAR_POINTERS
fprintf(stderr, "total_num_medium = %ld\n", total_num_medium);
fprintf(stderr, "total_bytes_medium = %ld\n", total_bytes_medium);
if (cur_num_medium)
fprintf(stderr, "CUR_NUM_MEDIUM = %ld\n", cur_num_medium);
fprintf(stderr, "max_num_medium = %ld\n", max_num_medium);
#endif
fprintf(stderr, "total_num_sarray = %ld\n", total_num_sarray);
fprintf(stderr, "total_bytes_sarray = %ld\n", total_bytes_sarray);
if (cur_num_sarray)
fprintf(stderr, "CUR_NUM_SARRAY = %ld\n", cur_num_sarray);
fprintf(stderr, "max_num_sarray = %ld\n", max_num_sarray);
fprintf(stderr, "total_num_barray = %ld\n", total_num_barray);
fprintf(stderr, "total_bytes_barray = %ld\n", total_bytes_barray);
if (cur_num_barray)
fprintf(stderr, "CUR_NUM_BARRAY = %ld\n", cur_num_barray);
fprintf(stderr, "max_num_barray = %ld\n", max_num_barray);
}
#endif /* MEM_STATS */
LOCAL void
out_of_memory (int which)
/* Report an out-of-memory error and stop execution */
/* If we compiled MEM_STATS support, report alloc requests before dying */
{
#ifdef MEM_STATS
j_mem_stats();
#endif
ERREXIT1(methods, "Insufficient memory (case %d)", which);
}
METHODDEF void *
alloc_small (size_t sizeofobject)
/* Allocate a "small" (all-in-memory) object */
{
void * result;
#ifdef MEM_STATS
total_num_small++;
total_bytes_small += sizeofobject + MALLOC_OVERHEAD;
cur_num_small++;
if (cur_num_small > max_num_small) max_num_small = cur_num_small;
#endif
result = malloc(sizeofobject);
if (result == NULL)
out_of_memory(1);
return result;
}
METHODDEF void
free_small (void *ptr)
/* Free a "small" (all-in-memory) object */
{
free(ptr);
#ifdef MEM_STATS
cur_num_small--;
#endif
}
#ifdef NEED_FAR_POINTERS
METHODDEF void FAR *
alloc_medium (size_t sizeofobject)
/* Allocate a "medium" (all in memory, but in far heap) object */
{
void FAR * result;
#ifdef MEM_STATS
total_num_medium++;
total_bytes_medium += sizeofobject + MALLOC_FAR_OVERHEAD;
cur_num_medium++;
if (cur_num_medium > max_num_medium) max_num_medium = cur_num_medium;
#endif
result = far_malloc(sizeofobject);
if (result == NULL)
out_of_memory(2);
return result;
}
METHODDEF void
free_medium (void FAR *ptr)
/* Free a "medium" (all in memory, but in far heap) object */
{
far_free(ptr);
#ifdef MEM_STATS
cur_num_medium--;
#endif
}
#endif /* NEED_FAR_POINTERS */
METHODDEF JSAMPARRAY
alloc_small_sarray (long samplesperrow, long numrows)
/* Allocate a "small" (all-in-memory) 2-D sample array */
{
JSAMPARRAY result;
long i;
#ifdef MEM_STATS
total_num_sarray++;
total_bytes_sarray += (samplesperrow * SIZEOF(JSAMPLE) + MALLOC_FAR_OVERHEAD)
* numrows;
cur_num_sarray++;
if (cur_num_sarray > max_num_sarray) max_num_sarray = cur_num_sarray;
#endif
/* Get space for row pointers; this is always "near" on 80x86 */
result = (JSAMPARRAY) alloc_small((size_t) (numrows * SIZEOF(JSAMPROW)));
/* Get the rows themselves; on 80x86 these are "far" */
for (i = 0; i < numrows; i++) {
result[i] = (JSAMPROW) far_malloc((size_t) (samplesperrow * SIZEOF(JSAMPLE)));
if (result[i] == NULL)
out_of_memory(3);
}
return result;
}
METHODDEF void
free_small_sarray (JSAMPARRAY ptr, long numrows)
/* Free a "small" (all-in-memory) 2-D sample array */
{
long i;
/* Free the rows themselves; on 80x86 these are "far" */
for (i = 0; i < numrows; i++) {
far_free((void FAR *) ptr[i]);
}
/* Free space for row pointers; this is always "near" on 80x86 */
free_small((void *) ptr);
#ifdef MEM_STATS
cur_num_sarray--;
#endif
}
METHODDEF JBLOCKARRAY
alloc_small_barray (long blocksperrow, long numrows)
/* Allocate a "small" (all-in-memory) 2-D coefficient-block array */
{
JBLOCKARRAY result;
long i;
#ifdef MEM_STATS
total_num_barray++;
total_bytes_barray += (blocksperrow * SIZEOF(JBLOCK) + MALLOC_FAR_OVERHEAD)
* numrows;
cur_num_barray++;
if (cur_num_barray > max_num_barray) max_num_barray = cur_num_barray;
#endif
/* Get space for row pointers; this is always "near" on 80x86 */
result = (JBLOCKARRAY) alloc_small((size_t) (numrows * SIZEOF(JBLOCKROW)));
/* Get the rows themselves; on 80x86 these are "far" */
for (i = 0; i < numrows; i++) {
result[i] = (JBLOCKROW) far_malloc((size_t) (blocksperrow * SIZEOF(JBLOCK)));
if (result[i] == NULL)
out_of_memory(4);
}
return result;
}
METHODDEF void
free_small_barray (JBLOCKARRAY ptr, long numrows)
/* Free a "small" (all-in-memory) 2-D coefficient-block array */
{
long i;
/* Free the rows themselves; on 80x86 these are "far" */
for (i = 0; i < numrows; i++) {
far_free((void FAR *) ptr[i]);
}
/* Free space for row pointers; this is always "near" on 80x86 */
free_small((void *) ptr);
#ifdef MEM_STATS
cur_num_barray--;
#endif
}
/*
* About "big" array management:
*
* To allow machines with limited memory to handle large images,
* all processing in the JPEG system is done a few pixel or block rows
* at a time. The above "small" array routines are only used to allocate
* strip buffers (as wide as the image, but just a few rows high).
* In some cases multiple passes must be made over the data. In these
* cases the "big" array routines are used. The array is still accessed
* a strip at a time, but the memory manager must save the whole array
* for repeated accesses. The intended implementation is that there is
* a strip buffer in memory (as high as is possible given the desired memory
* limit), plus a backing file that holds the rest of the array.
*
* The request_big_array routines are told the total size of the image (in case
* it is useful to know the total file size that will be needed). They are
* also given the unit height, which is the number of rows that will be
* accessed at once; the in-memory buffer should usually be made a multiple of
* this height for best efficiency.
*
* The request routines create control blocks (and may open backing files),
* but they don't create the in-memory buffers. This is postponed until
* alloc_big_arrays is called. At that time the total amount of space needed
* is known (approximately, anyway), so free memory can be divided up fairly.
*
* The access_big_array routines are responsible for making a specific strip
* area accessible (after reading or writing the backing file, if necessary).
* Note that the access routines are told whether the caller intends to modify
* the accessed strip; during a read-only pass this saves having to rewrite
* data to disk.
*
* The typical access pattern is one top-to-bottom pass to write the data,
* followed by one or more read-only top-to-bottom passes. However, other
* access patterns may occur while reading. For example, translation of image
* formats that use bottom-to-top scan order will require bottom-to-top read
* passes. The memory manager need not support multiple write passes nor
* funny write orders (meaning that rearranging rows must be handled while
* reading data out of the big array, not while putting it in).
*
* In current usage, the access requests are always for nonoverlapping strips;
* that is, successive access start_row numbers always differ by exactly the
* unitheight. This allows fairly simple buffer dump/reload logic if the
* in-memory buffer is made a multiple of the unitheight. It would be
* possible to keep subsampled rather than fullsize data in the "big" arrays,
* thus reducing temp file size, if we supported overlapping strip access
* (access requests differing by less than the unitheight). At the moment
* I don't believe this is worth the extra complexity.
*
* This particular implementation doesn't use temp files; the whole of a big
* array is allocated in (virtual) memory, and any swapping is done behind the
* scenes by the operating system.
*/
/* The control blocks for virtual arrays.
* These are pretty minimal in this implementation.
* Note: in this implementation we could realize big arrays
* at request time and make alloc_big_arrays a no-op;
* however, doing it separately keeps callers honest.
*/
struct big_sarray_control {
JSAMPARRAY mem_buffer; /* memory buffer (the whole thing, here) */
long rows_in_mem; /* Height of memory buffer */
long samplesperrow; /* Width of memory buffer */
long unitheight; /* # of rows accessed by access_big_sarray() */
big_sarray_ptr next; /* list link for unrealized arrays */
};
struct big_barray_control {
JBLOCKARRAY mem_buffer; /* memory buffer (the whole thing, here) */
long rows_in_mem; /* Height of memory buffer */
long blocksperrow; /* Width of memory buffer */
long unitheight; /* # of rows accessed by access_big_barray() */
big_barray_ptr next; /* list link for unrealized arrays */
};
/* Headers of lists of control blocks for unrealized big arrays */
static big_sarray_ptr unalloced_sarrays;
static big_barray_ptr unalloced_barrays;
METHODDEF big_sarray_ptr
request_big_sarray (long samplesperrow, long numrows, long unitheight)
/* Request a "big" (virtual-memory) 2-D sample array */
{
big_sarray_ptr result;
/* get control block */
result = (big_sarray_ptr) alloc_small(SIZEOF(struct big_sarray_control));
result->mem_buffer = NULL; /* lets access routine spot premature access */
result->rows_in_mem = numrows;
result->samplesperrow = samplesperrow;
result->unitheight = unitheight;
result->next = unalloced_sarrays; /* add to list of unallocated arrays */
unalloced_sarrays = result;
return result;
}
METHODDEF big_barray_ptr
request_big_barray (long blocksperrow, long numrows, long unitheight)
/* Request a "big" (virtual-memory) 2-D coefficient-block array */
{
big_barray_ptr result;
/* get control block */
result = (big_barray_ptr) alloc_small(SIZEOF(struct big_barray_control));
result->mem_buffer = NULL; /* lets access routine spot premature access */
result->rows_in_mem = numrows;
result->blocksperrow = blocksperrow;
result->unitheight = unitheight;
result->next = unalloced_barrays; /* add to list of unallocated arrays */
unalloced_barrays = result;
return result;
}
METHODDEF void
alloc_big_arrays (long extra_small_samples, long extra_small_blocks,
long extra_medium_space)
/* Allocate the in-memory buffers for any unrealized "big" arrays */
/* 'extra' values are upper bounds for total future small-array requests */
/* and far-heap requests */
{
/* In this implementation we just malloc the whole arrays */
/* and expect the system's virtual memory to worry about swapping them */
big_sarray_ptr sptr;
big_barray_ptr bptr;
for (sptr = unalloced_sarrays; sptr != NULL; sptr = sptr->next) {
sptr->mem_buffer = alloc_small_sarray(sptr->samplesperrow,
sptr->rows_in_mem);
}
for (bptr = unalloced_barrays; bptr != NULL; bptr = bptr->next) {
bptr->mem_buffer = alloc_small_barray(bptr->blocksperrow,
bptr->rows_in_mem);
}
unalloced_sarrays = NULL; /* reset for possible future cycles */
unalloced_barrays = NULL;
}
METHODDEF JSAMPARRAY
access_big_sarray (big_sarray_ptr ptr, long start_row, boolean writable)
/* Access the part of a "big" sample array starting at start_row */
/* and extending for ptr->unitheight rows. writable is true if */
/* caller intends to modify the accessed area. */
{
/* debugging check */
if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_mem ||
ptr->mem_buffer == NULL)
ERREXIT(methods, "Bogus access_big_sarray request");
return ptr->mem_buffer + start_row;
}
METHODDEF JBLOCKARRAY
access_big_barray (big_barray_ptr ptr, long start_row, boolean writable)
/* Access the part of a "big" coefficient-block array starting at start_row */
/* and extending for ptr->unitheight rows. writable is true if */
/* caller intends to modify the accessed area. */
{
/* debugging check */
if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_mem ||
ptr->mem_buffer == NULL)
ERREXIT(methods, "Bogus access_big_barray request");
return ptr->mem_buffer + start_row;
}
METHODDEF void
free_big_sarray (big_sarray_ptr ptr)
/* Free a "big" (virtual-memory) 2-D sample array */
{
free_small_sarray(ptr->mem_buffer, ptr->rows_in_mem);
free_small((void *) ptr); /* free the control block too */
}
METHODDEF void
free_big_barray (big_barray_ptr ptr)
/* Free a "big" (virtual-memory) 2-D coefficient-block array */
{
free_small_barray(ptr->mem_buffer, ptr->rows_in_mem);
free_small((void *) ptr); /* free the control block too */
}
/*
* The method selection routine for virtual memory systems.
* The system-dependent setup routine should call this routine
* to install the necessary method pointers in the supplied struct.
*/
GLOBAL void
jselvirtmem (external_methods_ptr emethods)
{
methods = emethods; /* save struct addr for error exit access */
emethods->alloc_small = alloc_small;
emethods->free_small = free_small;
#ifdef NEED_FAR_POINTERS
emethods->alloc_medium = alloc_medium;
emethods->free_medium = free_medium;
#endif
emethods->alloc_small_sarray = alloc_small_sarray;
emethods->free_small_sarray = free_small_sarray;
emethods->alloc_small_barray = alloc_small_barray;
emethods->free_small_barray = free_small_barray;
emethods->request_big_sarray = request_big_sarray;
emethods->request_big_barray = request_big_barray;
emethods->alloc_big_arrays = alloc_big_arrays;
emethods->access_big_sarray = access_big_sarray;
emethods->access_big_barray = access_big_barray;
emethods->free_big_sarray = free_big_sarray;
emethods->free_big_barray = free_big_barray;
unalloced_sarrays = NULL; /* make sure list headers are empty */
unalloced_barrays = NULL;
}

View File

@@ -1,7 +1,7 @@
/* /*
* jwrgif.c * jwrgif.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -97,22 +97,21 @@ flush_packet (void)
/* flush any accumulated data */ /* flush any accumulated data */
{ {
if (bytesinpkt > 0) { /* never write zero-length packet */ if (bytesinpkt > 0) { /* never write zero-length packet */
packetbuf[0] = bytesinpkt++; packetbuf[0] = (char) bytesinpkt++;
if (fwrite(packetbuf, 1, bytesinpkt, dcinfo->output_file) != bytesinpkt) if (JFWRITE(dcinfo->output_file, packetbuf, bytesinpkt)
!= (size_t) bytesinpkt)
ERREXIT(dcinfo->emethods, "Output file write error"); ERREXIT(dcinfo->emethods, "Output file write error");
bytesinpkt = 0; bytesinpkt = 0;
} }
} }
LOCAL void
char_out (int c)
/* Add a character to current packet; flush to disk if necessary */ /* Add a character to current packet; flush to disk if necessary */
{ #define CHAR_OUT(c) \
packetbuf[++bytesinpkt] = c; { packetbuf[++bytesinpkt] = (char) (c); \
if (bytesinpkt >= 255) if (bytesinpkt >= 255) \
flush_packet(); flush_packet(); \
} }
/* Routine to convert variable-width codes into a byte stream */ /* Routine to convert variable-width codes into a byte stream */
@@ -126,14 +125,11 @@ output (code_int code)
/* Emit a code of n_bits bits */ /* Emit a code of n_bits bits */
/* Uses cur_accum and cur_bits to reblock into 8-bit bytes */ /* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
{ {
if (cur_bits > 0) cur_accum |= ((INT32) code) << cur_bits;
cur_accum |= ((INT32) code << cur_bits);
else
cur_accum = code;
cur_bits += n_bits; cur_bits += n_bits;
while (cur_bits >= 8) { while (cur_bits >= 8) {
char_out((int) (cur_accum & 0xFF)); CHAR_OUT(cur_accum & 0xFF);
cur_accum >>= 8; cur_accum >>= 8;
cur_bits -= 8; cur_bits -= 8;
} }
@@ -225,7 +221,7 @@ compress_byte (int c)
i -= HSIZE; i -= HSIZE;
if (hash_code[i] != 0) { /* is first probed slot empty? */ if (hash_code[i] != 0) { /* is first probed slot empty? */
if (hash_prefix[i] == waiting_code && hash_suffix[i] == c) { if (hash_prefix[i] == waiting_code && hash_suffix[i] == (UINT8) c) {
waiting_code = hash_code[i]; waiting_code = hash_code[i];
return; return;
} }
@@ -239,7 +235,7 @@ compress_byte (int c)
i += HSIZE; i += HSIZE;
if (hash_code[i] == 0) if (hash_code[i] == 0)
break; /* hit empty slot */ break; /* hit empty slot */
if (hash_prefix[i] == waiting_code && hash_suffix[i] == c) { if (hash_prefix[i] == waiting_code && hash_suffix[i] == (UINT8) c) {
waiting_code = hash_code[i]; waiting_code = hash_code[i];
return; return;
} }
@@ -251,7 +247,7 @@ compress_byte (int c)
if (free_code < LZW_TABLE_SIZE) { if (free_code < LZW_TABLE_SIZE) {
hash_code[i] = free_code++; /* add symbol to hashtable */ hash_code[i] = free_code++; /* add symbol to hashtable */
hash_prefix[i] = waiting_code; hash_prefix[i] = waiting_code;
hash_suffix[i] = c; hash_suffix[i] = (UINT8) c;
} else } else
clear_block(); clear_block();
waiting_code = c; waiting_code = c;
@@ -269,7 +265,7 @@ compress_term (void)
output(EOFCode); output(EOFCode);
/* Flush the bit-packing buffer */ /* Flush the bit-packing buffer */
if (cur_bits > 0) { if (cur_bits > 0) {
char_out((int) (cur_accum & 0xFF)); CHAR_OUT(cur_accum & 0xFF);
} }
/* Flush the packet buffer */ /* Flush the packet buffer */
flush_packet(); flush_packet();
@@ -304,27 +300,15 @@ emit_header (int num_colors, JSAMPARRAY colormap)
/* If colormap==NULL, synthesize a gray-scale colormap */ /* If colormap==NULL, synthesize a gray-scale colormap */
{ {
int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte; int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte;
int cshift = dcinfo->data_precision - 8;
int i; int i;
if (num_colors > 256) if (num_colors > 256)
ERREXIT(dcinfo->emethods, "GIF can only handle 256 colors"); ERREXIT(dcinfo->emethods, "GIF can only handle 256 colors");
/* Compute bits/pixel and related values */ /* Compute bits/pixel and related values */
if (num_colors <= 2) BitsPerPixel = 1;
BitsPerPixel = 1; while (num_colors > (1 << BitsPerPixel))
else if (num_colors <= 4) BitsPerPixel++;
BitsPerPixel = 2;
else if (num_colors <= 8)
BitsPerPixel = 3;
else if (num_colors <= 16)
BitsPerPixel = 4;
else if (num_colors <= 32)
BitsPerPixel = 5;
else if (num_colors <= 64)
BitsPerPixel = 6;
else if (num_colors <= 128)
BitsPerPixel = 7;
else
BitsPerPixel = 8;
ColorMapSize = 1 << BitsPerPixel; ColorMapSize = 1 << BitsPerPixel;
if (BitsPerPixel <= 1) if (BitsPerPixel <= 1)
InitCodeSize = 2; InitCodeSize = 2;
@@ -334,7 +318,7 @@ emit_header (int num_colors, JSAMPARRAY colormap)
* Write the GIF header. * Write the GIF header.
* Note that we generate a plain GIF87 header for maximum compatibility. * Note that we generate a plain GIF87 header for maximum compatibility.
*/ */
fwrite("GIF87a", 1, 6, dcinfo->output_file); (void) JFWRITE(dcinfo->output_file, "GIF87a", 6);
/* Write the Logical Screen Descriptor */ /* Write the Logical Screen Descriptor */
put_word((UINT16) dcinfo->image_width); put_word((UINT16) dcinfo->image_width);
put_word((UINT16) dcinfo->image_height); put_word((UINT16) dcinfo->image_height);
@@ -345,17 +329,19 @@ emit_header (int num_colors, JSAMPARRAY colormap)
putc(0, dcinfo->output_file); /* Background color index */ putc(0, dcinfo->output_file); /* Background color index */
putc(0, dcinfo->output_file); /* Reserved in GIF87 (aspect ratio in GIF89) */ putc(0, dcinfo->output_file); /* Reserved in GIF87 (aspect ratio in GIF89) */
/* Write the Global Color Map */ /* Write the Global Color Map */
/* If the color map is more than 8 bits precision, */
/* we reduce it to 8 bits by shifting */
for (i=0; i < ColorMapSize; i++) { for (i=0; i < ColorMapSize; i++) {
if (i < num_colors) { if (i < num_colors) {
if (colormap != NULL) { if (colormap != NULL) {
if (dcinfo->out_color_space == CS_RGB) { if (dcinfo->out_color_space == CS_RGB) {
/* Normal case: RGB color map */ /* Normal case: RGB color map */
putc(GETJSAMPLE(colormap[0][i]), dcinfo->output_file); putc(GETJSAMPLE(colormap[0][i]) >> cshift, dcinfo->output_file);
putc(GETJSAMPLE(colormap[1][i]), dcinfo->output_file); putc(GETJSAMPLE(colormap[1][i]) >> cshift, dcinfo->output_file);
putc(GETJSAMPLE(colormap[2][i]), dcinfo->output_file); putc(GETJSAMPLE(colormap[2][i]) >> cshift, dcinfo->output_file);
} else { } else {
/* Grayscale "color map": possible if quantizing grayscale image */ /* Grayscale "color map": possible if quantizing grayscale image */
put_3bytes(GETJSAMPLE(colormap[0][i])); put_3bytes(GETJSAMPLE(colormap[0][i]) >> cshift);
} }
} else { } else {
/* Create a gray-scale map of num_colors values, range 0..255 */ /* Create a gray-scale map of num_colors values, range 0..255 */
@@ -462,9 +448,7 @@ output_term (decompress_info_ptr cinfo)
if (ferror(cinfo->output_file)) if (ferror(cinfo->output_file))
ERREXIT(cinfo->emethods, "Output file write error"); ERREXIT(cinfo->emethods, "Output file write error");
/* Free space */ /* Free space */
(*cinfo->emethods->free_medium) ((void FAR *) hash_code); /* no work (we let free_all release the workspace) */
(*cinfo->emethods->free_medium) ((void FAR *) hash_prefix);
(*cinfo->emethods->free_medium) ((void FAR *) hash_suffix);
} }

View File

@@ -1,7 +1,7 @@
/* /*
* jwrjfif.c * jwrjfif.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -36,7 +36,8 @@
/* Write some bytes from a (char *) buffer */ /* Write some bytes from a (char *) buffer */
#define WRITE_BYTES(cinfo,dataptr,datacount) \ #define WRITE_BYTES(cinfo,dataptr,datacount) \
{ if (fwrite((dataptr), 1, (datacount), cinfo->output_file) != (datacount)) \ { if (JFWRITE(cinfo->output_file, dataptr, datacount) \
!= (size_t) (datacount)) \
ERREXIT(cinfo->emethods, "Output file write error"); } ERREXIT(cinfo->emethods, "Output file write error"); }
/* Clean up and verify successful output */ /* Clean up and verify successful output */
@@ -164,6 +165,9 @@ emit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
} else { } else {
htbl = cinfo->dc_huff_tbl_ptrs[index]; htbl = cinfo->dc_huff_tbl_ptrs[index];
} }
if (htbl == NULL)
ERREXIT1(cinfo->emethods, "Huffman table 0x%02x was not defined", index);
if (! htbl->sent_table) { if (! htbl->sent_table) {
emit_marker(cinfo, M_DHT); emit_marker(cinfo, M_DHT);
@@ -247,6 +251,9 @@ emit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
if (cinfo->image_height > 65535L || cinfo->image_width > 65535L)
ERREXIT(cinfo->emethods, "Maximum image dimension for JFIF is 65535 pixels");
emit_byte(cinfo, cinfo->data_precision); emit_byte(cinfo, cinfo->data_precision);
emit_2bytes(cinfo, (int) cinfo->image_height); emit_2bytes(cinfo, (int) cinfo->image_height);
emit_2bytes(cinfo, (int) cinfo->image_width); emit_2bytes(cinfo, (int) cinfo->image_width);

View File

@@ -1,7 +1,7 @@
/* /*
* jwrppm.c * jwrppm.c
* *
* Copyright (C) 1991, Thomas G. Lane. * Copyright (C) 1991, 1992, 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.
* *
@@ -21,7 +21,14 @@
#ifdef PPM_SUPPORTED #ifdef PPM_SUPPORTED
static JSAMPARRAY color_map; /* saves color map passed by quantizer */ /*
* Haven't yet got around to making this work with text-format output,
* hence cannot handle pixels wider than 8 bits.
*/
#ifndef EIGHT_BIT_SAMPLES
Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
#endif
/* /*
@@ -94,10 +101,11 @@ put_demapped_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data) JSAMPIMAGE pixel_data)
{ {
register FILE * outfile = cinfo->output_file; register FILE * outfile = cinfo->output_file;
register JSAMPARRAY color_map = cinfo->colormap;
register JSAMPROW ptr; register JSAMPROW ptr;
register long col; register long col;
register long width = cinfo->image_width; long width = cinfo->image_width;
register int row; int row;
if (cinfo->out_color_space == CS_GRAYSCALE) { if (cinfo->out_color_space == CS_GRAYSCALE) {
for (row = 0; row < num_rows; row++) { for (row = 0; row < num_rows; row++) {
@@ -131,7 +139,6 @@ put_demapped_rows (decompress_info_ptr cinfo, int num_rows,
METHODDEF void METHODDEF void
put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap) put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
{ {
color_map = colormap; /* save for use in output */
cinfo->methods->put_pixel_rows = put_demapped_rows; cinfo->methods->put_pixel_rows = put_demapped_rows;
} }

232
jwrrle.c Normal file
View File

@@ -0,0 +1,232 @@
/*
* jwrrle.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains routines to write output images in RLE format.
* The Utah Raster Toolkit library is required (version 3.0).
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume output to
* an ordinary stdio stream.
*
* These routines are invoked via the methods put_pixel_rows, put_color_map,
* and output_init/term.
*
* Based on code contributed by Mike Lijewski.
*/
#include "jinclude.h"
#ifdef RLE_SUPPORTED
/* rle.h is provided by the Utah Raster Toolkit. */
#include <rle.h>
/*
* output_term assumes that JSAMPLE has the same representation as rle_pixel,
* to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples.
*/
#ifndef EIGHT_BIT_SAMPLES
Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
#endif
/*
* Since RLE stores scanlines bottom-to-top, we have to invert the image
* from JPEG's top-to-bottom order. To do this, we save the outgoing data
* in virtual array(s) during put_pixel_row calls, then actually emit the
* RLE file during output_term. We use one virtual array if the output is
* grayscale or colormapped, more if it is full color.
*/
#define MAX_CHANS 4 /* allow up to four color components */
static big_sarray_ptr channels[MAX_CHANS]; /* Virtual arrays for saved data */
static long cur_output_row; /* next row# to write to virtual array(s) */
/*
* For now, if we emit an RLE color map then it is always 256 entries long,
* though not all of the entries need be used.
*/
#define CMAPBITS 8
#define CMAPLENGTH (1<<(CMAPBITS))
static rle_map *output_colormap; /* RLE-style color map, or NULL if none */
static int number_colors; /* Number of colors actually used */
/*
* Write the file header.
*
* In this module it's easier to wait till output_term to actually write
* anything; here we just request the big arrays we'll need.
*/
METHODDEF void
output_init (decompress_info_ptr cinfo)
{
short ci;
if (cinfo->final_out_comps > MAX_CHANS)
ERREXIT1(cinfo->emethods, "Cannot handle %d output channels for RLE",
cinfo->final_out_comps);
for (ci = 0; ci < cinfo->final_out_comps; ci++) {
channels[ci] = (*cinfo->emethods->request_big_sarray)
(cinfo->image_width, cinfo->image_height, 1L);
}
output_colormap = NULL; /* No output colormap as yet */
number_colors = 0;
cur_output_row = 0; /* Start filling virtual arrays at row 0 */
cinfo->total_passes++; /* count file writing as separate pass */
}
/*
* Write some pixel data.
*
* This routine just saves the data away in virtual arrays.
*/
METHODDEF void
put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
{
JSAMPROW outputrow[1]; /* a pseudo JSAMPARRAY structure */
int row;
short ci;
for (row = 0; row < num_rows; row++) {
for (ci = 0; ci < cinfo->final_out_comps; ci++) {
outputrow[0] = *((*cinfo->emethods->access_big_sarray)
(channels[ci], cur_output_row, TRUE));
jcopy_sample_rows(pixel_data[ci], row, outputrow, 0,
1, cinfo->image_width);
}
cur_output_row++;
}
}
/*
* Write the color map.
*
* For RLE output we just save the colormap for the output stage.
*/
METHODDEF void
put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
{
size_t cmapsize;
short ci;
int i;
if (num_colors > CMAPLENGTH)
ERREXIT1(cinfo->emethods, "Cannot handle %d colormap entries for RLE",
num_colors);
/* Allocate storage for RLE-style cmap, zero any extra entries */
cmapsize = cinfo->color_out_comps * CMAPLENGTH * SIZEOF(rle_map);
output_colormap = (rle_map *) (*cinfo->emethods->alloc_small) (cmapsize);
MEMZERO((void *) output_colormap, cmapsize);
/* Save away data in RLE format --- note 8-bit left shift! */
/* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
for (ci = 0; ci < cinfo->color_out_comps; ci++) {
for (i = 0; i < num_colors; i++) {
output_colormap[ci * CMAPLENGTH + i] = GETJSAMPLE(colormap[ci][i]) << 8;
}
}
number_colors = num_colors;
}
/*
* Finish up at the end of the file.
*
* Here is where we really output the RLE file.
*/
METHODDEF void
output_term (decompress_info_ptr cinfo)
{
rle_hdr header; /* Output file information */
rle_pixel *output_rows[MAX_CHANS];
char cmapcomment[80];
short ci;
long row;
/* Initialize the header info */
MEMZERO((void *) &header, SIZEOF(rle_hdr)); /* make sure all bits are 0 */
header.rle_file = cinfo->output_file;
header.xmin = 0;
header.xmax = cinfo->image_width - 1;
header.ymin = 0;
header.ymax = cinfo->image_height - 1;
header.alpha = 0;
header.ncolors = cinfo->final_out_comps;
for (ci = 0; ci < cinfo->final_out_comps; ci++) {
RLE_SET_BIT(header, ci);
}
if (number_colors > 0) {
header.ncmap = cinfo->color_out_comps;
header.cmaplen = CMAPBITS;
header.cmap = output_colormap;
/* Add a comment to the output image with the true colormap length. */
sprintf(cmapcomment, "color_map_length=%d", number_colors);
rle_putcom(cmapcomment, &header);
}
/* Emit the RLE header and color map (if any) */
rle_put_setup(&header);
/* Now output the RLE data from our virtual array(s).
* We assume here that (a) rle_pixel is represented the same as JSAMPLE,
* and (b) we are not on a machine where FAR pointers differ from regular.
*/
for (row = cinfo->image_height-1; row >= 0; row--) {
(*cinfo->methods->progress_monitor) (cinfo, cinfo->image_height-row-1,
cinfo->image_height);
for (ci = 0; ci < cinfo->final_out_comps; ci++) {
output_rows[ci] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
(channels[ci], row, FALSE));
}
rle_putrow(output_rows, (int) cinfo->image_width, &header);
}
cinfo->completed_passes++;
/* Emit file trailer */
rle_puteof(&header);
fflush(cinfo->output_file);
if (ferror(cinfo->output_file))
ERREXIT(cinfo->emethods, "Output file write error");
/* Release memory */
/* no work (we let free_all release the workspace) */
}
/*
* The method selection routine for RLE format output.
* This should be called from d_ui_method_selection if RLE output is wanted.
*/
GLOBAL void
jselwrle (decompress_info_ptr cinfo)
{
cinfo->methods->output_init = output_init;
cinfo->methods->put_color_map = put_color_map;
cinfo->methods->put_pixel_rows = put_pixel_rows;
cinfo->methods->output_term = output_term;
}
#endif /* RLE_SUPPORTED */

220
jwrtarga.c Normal file
View File

@@ -0,0 +1,220 @@
/*
* jwrtarga.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains routines to write output images in Targa format.
*
* These routines may need modification for non-Unix environments or
* specialized applications. As they stand, they assume output to
* an ordinary stdio stream.
*
* These routines are invoked via the methods put_pixel_rows, put_color_map,
* and output_init/term.
*
* Based on code contributed by Lee Daniel Crocker.
*/
#include "jinclude.h"
#ifdef TARGA_SUPPORTED
/*
* To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
* This is not yet implemented.
*/
#ifndef EIGHT_BIT_SAMPLES
Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
#endif
LOCAL void
write_header (decompress_info_ptr cinfo, int num_colors)
/* Create and write a Targa header */
{
char targaheader[18];
/* Set unused fields of header to 0 */
MEMZERO((void *) targaheader, SIZEOF(targaheader));
if (num_colors > 0) {
targaheader[1] = 1; /* color map type 1 */
targaheader[5] = (char) (num_colors & 0xFF);
targaheader[6] = (char) (num_colors >> 8);
targaheader[7] = 24; /* 24 bits per cmap entry */
}
targaheader[12] = (char) (cinfo->image_width & 0xFF);
targaheader[13] = (char) (cinfo->image_width >> 8);
targaheader[14] = (char) (cinfo->image_height & 0xFF);
targaheader[15] = (char) (cinfo->image_height >> 8);
targaheader[17] = 0x20; /* Top-down, non-interlaced */
if (cinfo->out_color_space == CS_GRAYSCALE) {
targaheader[2] = 3; /* image type = uncompressed gray-scale */
targaheader[16] = 8; /* bits per pixel */
} else { /* must be RGB */
if (num_colors > 0) {
targaheader[2] = 1; /* image type = colormapped RGB */
targaheader[16] = 8;
} else {
targaheader[2] = 2; /* image type = uncompressed RGB */
targaheader[16] = 24;
}
}
if (JFWRITE(cinfo->output_file, targaheader, 18) != (size_t) 18)
ERREXIT(cinfo->emethods, "Could not write Targa header");
}
/*
* Write the file header.
*/
METHODDEF void
output_init (decompress_info_ptr cinfo)
{
if (cinfo->out_color_space == CS_GRAYSCALE) {
/* Targa doesn't have a mapped grayscale format, so we will */
/* demap quantized gray output. Never emit a colormap. */
write_header(cinfo, 0);
} else if (cinfo->out_color_space == CS_RGB) {
/* For quantized output, defer writing header until put_color_map time. */
if (! cinfo->quantize_colors)
write_header(cinfo, 0);
} else {
ERREXIT(cinfo->emethods, "Targa output must be grayscale or RGB");
}
}
/*
* Write some pixel data.
*/
METHODDEF void
put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
{
register FILE * outfile = cinfo->output_file;
register JSAMPROW ptr0, ptr1, ptr2;
register long col;
register long width = cinfo->image_width;
register int row;
if (cinfo->final_out_comps == 1) {
/* here for grayscale or quantized color output */
for (row = 0; row < num_rows; row++) {
ptr0 = pixel_data[0][row];
for (col = width; col > 0; col--) {
putc(GETJSAMPLE(*ptr0), outfile);
ptr0++;
}
}
} else {
/* here for unquantized color output */
for (row = 0; row < num_rows; row++) {
ptr0 = pixel_data[0][row];
ptr1 = pixel_data[1][row];
ptr2 = pixel_data[2][row];
for (col = width; col > 0; col--) {
putc(GETJSAMPLE(*ptr2), outfile); /* write in BGR order */
ptr2++;
putc(GETJSAMPLE(*ptr1), outfile);
ptr1++;
putc(GETJSAMPLE(*ptr0), outfile);
ptr0++;
}
}
}
}
/*
* Write some demapped pixel data when color quantization is in effect.
* For Targa, this is only applied to grayscale data.
*/
METHODDEF void
put_demapped_rows (decompress_info_ptr cinfo, int num_rows,
JSAMPIMAGE pixel_data)
{
register FILE * outfile = cinfo->output_file;
register JSAMPARRAY color_map = cinfo->colormap;
register JSAMPROW ptr;
register long col;
long width = cinfo->image_width;
int row;
for (row = 0; row < num_rows; row++) {
ptr = pixel_data[0][row];
for (col = width; col > 0; col--) {
putc(GETJSAMPLE(color_map[0][GETJSAMPLE(*ptr)]), outfile);
ptr++;
}
}
}
/*
* Write the color map.
*/
METHODDEF void
put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
{
register FILE * outfile = cinfo->output_file;
int i;
if (cinfo->out_color_space == CS_RGB) {
/* We only support 8-bit colormap indexes, so only 256 colors */
if (num_colors > 256)
ERREXIT(cinfo->emethods, "Too many colors for Targa output");
/* Time to write the header */
write_header(cinfo, num_colors);
/* Write the colormap. Note Targa uses BGR byte order */
for (i = 0; i < num_colors; i++) {
putc(GETJSAMPLE(colormap[2][i]), outfile);
putc(GETJSAMPLE(colormap[1][i]), outfile);
putc(GETJSAMPLE(colormap[0][i]), outfile);
}
} else {
cinfo->methods->put_pixel_rows = put_demapped_rows;
}
}
/*
* Finish up at the end of the file.
*/
METHODDEF void
output_term (decompress_info_ptr cinfo)
{
/* No work except to make sure we wrote the output file OK */
fflush(cinfo->output_file);
if (ferror(cinfo->output_file))
ERREXIT(cinfo->emethods, "Output file write error");
}
/*
* The method selection routine for Targa format output.
* This should be called from d_ui_method_selection if Targa output is wanted.
*/
GLOBAL void
jselwtarga (decompress_info_ptr cinfo)
{
cinfo->methods->output_init = output_init;
cinfo->methods->put_color_map = put_color_map;
cinfo->methods->put_pixel_rows = put_pixel_rows;
cinfo->methods->output_term = output_term;
}
#endif /* TARGA_SUPPORTED */

View File

@@ -1,5 +1,6 @@
L jcmain.mix jerror.mix jcdeflts.mix jrdgif.mix jrdppm.mix jwrjfif.mix L jcmain.mix jcmaster.mix jcdeflts.mix jcarith.mix jccolor.mix jcexpand.mix
L jcarith.mix jccolor.mix jcexpand.mix jchuff.mix jcmaster.mix jcmcu.mix L jchuff.mix jcmcu.mix jcpipe.mix jcsample.mix jfwddct.mix jwrjfif.mix
L jcpipe.mix jcsample.mix jfwddct.mix jutils.mix jvirtmem.mix L jrdgif.mix jrdppm.mix jrdrle.mix jrdtarga.mix jutils.mix jerror.mix
L jmemmgr.mix jmemsys.mix jmemdosa.mix
fa; fa;
b cjpeg,8K,48K, b cjpeg,8K,48K,

View File

@@ -1,20 +1,24 @@
jcmain.obj + jcmain.obj +
jerror.obj + jcmaster.obj +
jcdeflts.obj + jcdeflts.obj +
jrdgif.obj +
jrdppm.obj +
jwrjfif.obj +
jcarith.obj + jcarith.obj +
jccolor.obj + jccolor.obj +
jcexpand.obj + jcexpand.obj +
jchuff.obj + jchuff.obj +
jcmaster.obj +
jcmcu.obj + jcmcu.obj +
jcpipe.obj + jcpipe.obj +
jcsample.obj + jcsample.obj +
jfwddct.obj + jfwddct.obj +
jwrjfif.obj +
jrdgif.obj +
jrdppm.obj +
jrdrle.obj +
jrdtarga.obj +
jutils.obj + jutils.obj +
jvirtmem.obj jerror.obj +
jmemmgr.obj +
jmemsys.obj +
jmemdosa.obj
cjpeg.exe /NOI cjpeg.exe /NOI
nul.map nul.map

4
makcjpeg.lst Normal file
View File

@@ -0,0 +1,4 @@
jcmain.obj jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj
jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj jwrjfif.obj
jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj jutils.obj jerror.obj
jmemmgr.obj jmemsys.obj jmemdosa.obj

View File

@@ -1,6 +1,6 @@
L jdmain.mix jerror.mix jrdjfif.mix jwrgif.mix jwrppm.mix L jdmain.mix jdmaster.mix jddeflts.mix jbsmooth.mix jdarith.mix jdcolor.mix
L jbsmooth.mix jdarith.mix jdcolor.mix jdhuff.mix jdmaster.mix jdmcu.mix L jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix
L jdpipe.mix jdsample.mix jquant1.mix jquant2.mix jrevdct.mix jutils.mix L jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jwrrle.mix jwrtarga.mix
L jvirtmem.mix L jutils.mix jerror.mix jmemmgr.mix jmemsys.mix jmemdosa.mix
fa; fa;
b djpeg,8K,48K, b djpeg,8K,48K,

View File

@@ -1,22 +1,27 @@
jdmain.obj + jdmain.obj +
jerror.obj + jdmaster.obj +
jrdjfif.obj + jddeflts.obj +
jwrgif.obj +
jwrppm.obj +
jbsmooth.obj + jbsmooth.obj +
jdarith.obj + jdarith.obj +
jdcolor.obj + jdcolor.obj +
jdhuff.obj + jdhuff.obj +
jdmaster.obj +
jdmcu.obj + jdmcu.obj +
jdpipe.obj + jdpipe.obj +
jdsample.obj + jdsample.obj +
jquant1.obj + jquant1.obj +
jquant2.obj + jquant2.obj +
jrevdct.obj + jrevdct.obj +
jrdjfif.obj +
jwrgif.obj +
jwrppm.obj +
jwrrle.obj +
jwrtarga.obj +
jutils.obj + jutils.obj +
jvirtmem.obj /NOI jerror.obj +
djpeg.exe jmemmgr.obj +
jmemsys.obj +
jmemdosa.obj
djpeg.exe /NOI
nul.map nul.map
nul.def nul.def

4
makdjpeg.lst Normal file
View File

@@ -0,0 +1,4 @@
jdmain.obj jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj
jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj jquant2.obj
jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj jwrrle.obj jwrtarga.obj
jutils.obj jerror.obj jmemmgr.obj jmemsys.obj jmemdosa.obj

View File

@@ -1,143 +0,0 @@
# Makefile for Independent JPEG Group's software
# This makefile is suitable for Amiga systems using Manx Aztec C ver 5.x.
# Thanks to D.J. James for this version.
# See README and edit jconfig.h before saying "make" !!
CC= cc
# You may need to adjust these cc options:
CFLAGS= -MC -MD -DTWO_FILE_COMMANDLINE
LDFLAGS=
LDLIBS= -lml -lcl
# miscellaneous OS-dependent stuff
LN= ln # linker
RM= delete quiet # file deletion command
AR= lb # library (.lib) file creation command
# source files
INCLUDES= jinclude.h jconfig.h jpegdata.h
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c \
jchuff.c jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c \
jdarith.c jdcolor.c jdhuff.c jdmain.c jdmaster.c jdmcu.c \
jdpipe.c jdsample.c jerror.c jfwddct.c jquant1.c jquant2.c \
jrdjfif.c jrdgif.c jrdppm.c jrevdct.c jutils.c jvirtmem.c \
jwrjfif.c jwrgif.c jwrppm.c egetopt.c
DOCS= README architecture codingrules
MAKEFILES= makefile.unix makefile.amiga \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk \
makefile.pwc makcjpeg.cf makdjpeg.cf makljpeg.cf
TESTFILES= testorig.jpg testimg.ppm testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) ansi2knr.c $(SOURCES) $(INCLUDES) $(TESTFILES)
# compression objectfiles
COBJECTS = jcmain.o jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \
jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \
jrdgif.o jrdppm.o jwrjfif.o \
jutils.o jvirtmem.o jerror.o
# decompression objectfiles
DOBJECTS = jdmain.o jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \
jrdjfif.o jwrgif.o jwrppm.o \
jutils.o jvirtmem.o jerror.o
# These objectfiles are included in libjpeg.lib (all but jcmain.o, jdmain.o)
LIBOBJECTS = jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \
jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \
jrdgif.o jrdppm.o jwrjfif.o \
jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \
jrdjfif.o jwrgif.o jwrppm.o \
jutils.o jvirtmem.o jerror.o
all: cjpeg djpeg
# By default, libjpeg.lib is not built unless you explicitly request it.
# If you have a C compiler that doesn't understand function prototypes,
# uncomment the 5 lines below and make sure PROTO is not defined by jconfig.h.
# Then say "make ansi2knr" before "make".
#.c.o:
# ./ansi2knr $*.c tmpansi.c
# $(CC) $(CFLAGS) -c tmpansi.c
# mv tmpansi.o $*.o
# $(RM) tmpansi.c
ansi2knr: ansi2knr.c
$(CC) -o ansi2knr ansi2knr.c
# You may need to add one of -DBSD, -DVMS, or -DMSDOS to the line above.
cjpeg: $(COBJECTS)
$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
djpeg: $(DOBJECTS)
$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
# libjpeg.lib is useful if you are including the JPEG software in a larger
# program; you'd include it in your link, rather than the individual modules.
libjpeg.lib: $(LIBOBJECTS)
-$(RM) libjpeg.lib
$(AR) libjpeg.lib $(LIBOBJECTS)
# Use the following to test the built library
#cjpeg: jcmain.o libjpeg.lib
# $(LN) $(LDFLAGS) -o cjpeg jcmain.o -llibjpeg $(LDLIBS)
#
#djpeg: jdmain.o libjpeg.lib
# $(LN) $(LDFLAGS) -o djpeg jdmain.o -llibjpeg $(LDLIBS)
clean:
-$(RM) *.o cjpeg djpeg libjpeg.lib ansi2knr core tmpansi.* testout.ppm testout.jpg
distribute:
-$(RM) jpegsrc.tar*
tar cvf jpegsrc.tar $(DISTFILES)
list jpegsrc.tar
compress -v jpegsrc.tar
list jpegsrc.tar*
test: cjpeg djpeg
-$(RM) testout.ppm testout.jpg
./djpeg testorig.jpg testout.ppm
./cjpeg testimg.ppm testout.jpg
cmp testimg.ppm testout.ppm
cmp testimg.jpg testout.jpg
jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c
jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c
jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
jvirtmem.o : jvirtmem.c jinclude.h jconfig.h jpegdata.h
jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h

152
makefile.ansi Normal file
View File

@@ -0,0 +1,152 @@
# Makefile for Independent JPEG Group's software
# This makefile is suitable for Unix-like systems with ANSI-capable compilers.
# If you have a non-ANSI compiler, makefile.unix is a better starting point.
# Read SETUP instructions before saying "make" !!
# The name of your C compiler:
CC= cc
# You may need to adjust these cc options:
CFLAGS= -O
# In particular:
# Add -DBSD if on a pure BSD system (see jinclude.h).
# Add -DMEM_STATS to enable gathering of memory usage statistics.
# You may also want to add -DTWO_FILE_COMMANDLINE or -D switches for other
# symbols listed in jconfig.h, if you prefer not to change jconfig.h.
# Link-time cc options:
LDFLAGS=
# To link any special libraries, add the necessary -l commands here.
# In particular, on some versions of HP-UX (and probably other SysV-derived
# systems) there is a faster alternate malloc(3) library that you can use
# by adding "-lmalloc" to this line.
LDLIBS=
# miscellaneous OS-dependent stuff
# linker
LN= $(CC)
# file deletion command
RM= rm -f
# library (.a) file creation command
AR= ar rc
# second step in .a creation (use "touch" if not needed)
AR2= ranlib
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
# compression objectfiles
CLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
jrdrle.o jrdtarga.o
COBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles
DLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
DOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.a
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
all: cjpeg djpeg
# By default, libjpeg.a is not built unless you explicitly request it.
# You can add libjpeg.a to the line above if you want it built by default.
cjpeg: $(COBJECTS)
$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
djpeg: $(DOBJECTS)
$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
# libjpeg.a is useful if you are including the JPEG software in a larger
# program; you'd include it in your link, rather than the individual modules.
libjpeg.a: $(LIBOBJECTS)
$(RM) libjpeg.a
$(AR) libjpeg.a $(LIBOBJECTS)
$(AR2) libjpeg.a
clean:
$(RM) *.o cjpeg djpeg libjpeg.a core testout.*
distribute:
$(RM) jpegsrc.tar*
tar cvf jpegsrc.tar $(DISTFILES)
compress -v jpegsrc.tar
test: cjpeg djpeg
$(RM) testout.ppm testout.gif testout.jpg
./djpeg testorig.jpg >testout.ppm
./djpeg -G testorig.jpg >testout.gif
./cjpeg testimg.ppm >testout.jpg
cmp testimg.ppm testout.ppm
cmp testimg.gif testout.gif
cmp testimg.jpg testout.jpg
jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
jddeflts.o : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
jmemmgr.o : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
jrdrle.o : jrdrle.c jinclude.h jconfig.h jpegdata.h
jrdtarga.o : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.o : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.o : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.o : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h

139
makefile.bcc Normal file
View File

@@ -0,0 +1,139 @@
# Makefile for Independent JPEG Group's software
# This makefile is suitable for Borland C (Turbo C) on MS-DOS.
# It is set up for Borland C++, revision 3.0 or later.
# For older versions (pre-3.0), replace "-O2" with "-O -G -Z" in CFLAGS.
# If you have an even older version of Turbo C, you may be able to make it
# work by saying "CC= tcc" below. (Very early versions of Turbo C++,
# like 1.01, are so buggy that you may as well forget it.)
# Thanks to Tom Wright and Ge' Weijers for this file.
# Read SETUP instructions before saying "make" !!
# The name of your C compiler:
CC= bcc
# You may need to adjust these cc options:
CFLAGS= -DHAVE_STDC -DINCLUDES_ARE_ANSI \
-ms -DMSDOS -DINCOMPLETE_TYPES_BROKEN -w-par -O2
# -DHAVE_STDC -DINCLUDES_ARE_ANSI enable ANSI-C features (we DON'T want -A)
# -ms selects small memory model for most efficient code
# -DMSDOS enables DOS-specific code
# -DINCOMPLETE_TYPES_BROKEN suppresses bogus warning about undefined structures
# -w-par suppresses warnings about unused function parameters
# -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z)
# Link-time cc options:
LDFLAGS= -ms
# memory model option here must match CFLAGS!
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.obj jerror.obj jmemmgr.obj jmemsys.obj jmemdosa.obj
# compression objectfiles
CLIBOBJECTS= jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
jwrjfif.obj jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj
COBJECTS= jcmain.obj $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles
DLIBOBJECTS= jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj \
jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj \
jquant2.obj jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj \
jwrrle.obj jwrtarga.obj
DOBJECTS= jdmain.obj $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.lib
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
all: cjpeg.exe djpeg.exe
cjpeg.exe: $(COBJECTS)
$(CC) $(LDFLAGS) -ecjpeg.exe @makcjpeg.lst
djpeg.exe: $(DOBJECTS)
$(CC) $(LDFLAGS) -edjpeg.exe @makdjpeg.lst
.c.obj:
$(CC) $(CFLAGS) -c $<
clean:
del *.obj
del cjpeg.exe
del djpeg.exe
del testout.*
test:
del testout.*
djpeg testorig.jpg testout.ppm
djpeg -G testorig.jpg testout.gif
cjpeg testimg.ppm testout.jpg
fc testimg.ppm testout.ppm
fc testimg.gif testout.gif
fc testimg.jpg testout.jpg
jbsmooth.obj : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.obj : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.obj : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.obj : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.obj : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.obj : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.obj : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.obj : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.obj : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.obj : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.obj : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.obj : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.obj : jdcolor.c jinclude.h jconfig.h jpegdata.h
jddeflts.obj : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdhuff.obj : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.obj : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmaster.obj : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdmcu.obj : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdpipe.obj : jdpipe.c jinclude.h jconfig.h jpegdata.h
jdsample.obj : jdsample.c jinclude.h jconfig.h jpegdata.h
jerror.obj : jerror.c jinclude.h jconfig.h jpegdata.h
jquant1.obj : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.obj : jquant2.c jinclude.h jconfig.h jpegdata.h
jfwddct.obj : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrevdct.obj : jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.obj : jutils.c jinclude.h jconfig.h jpegdata.h
jmemmgr.obj : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jrdjfif.obj : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jrdgif.obj : jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.obj : jrdppm.c jinclude.h jconfig.h jpegdata.h
jrdrle.obj : jrdrle.c jinclude.h jconfig.h jpegdata.h
jrdtarga.obj : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jwrjfif.obj : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.obj : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.obj : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.obj : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.obj : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.obj : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jmemdosa.obj : jmemdosa.asm
tasm /mx jmemdosa.asm

143
makefile.manx Normal file
View File

@@ -0,0 +1,143 @@
# Makefile for Independent JPEG Group's software
# This makefile is for Amiga systems using Manx Aztec C ver 5.x.
# Use jmemname.c as the system-dependent memory manager.
# Thanks to D.J. James (djjames@cup.portal.com) for this version.
# Read SETUP instructions before saying "make" !!
# The name of your C compiler:
CC= cc
# You may need to adjust these cc options:
CFLAGS= -MC -MD -sf -sn -sp -DAMIGA -DTWO_FILE_COMMANDLINE \
-DNEED_SIGNAL_CATCHER -Dsignal_catcher=_abort
# Link-time cc options:
LDFLAGS=
# To link any special libraries, add the necessary -l commands here.
LDLIBS= -lml -lcl
# miscellaneous OS-dependent stuff
# linker
LN= ln
# file deletion command
RM= delete quiet
# library (.lib) file creation command
AR= lb
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
# compression objectfiles
CLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
jrdrle.o jrdtarga.o
COBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles
DLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
DOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.lib
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
all: cjpeg djpeg
# By default, libjpeg.lib is not built unless you explicitly request it.
# You can add libjpeg.lib to the line above if you want it built by default.
cjpeg: $(COBJECTS)
$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
djpeg: $(DOBJECTS)
$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
# libjpeg.lib is useful if you are including the JPEG software in a larger
# program; you'd include it in your link, rather than the individual modules.
libjpeg.lib: $(LIBOBJECTS)
-$(RM) libjpeg.lib
$(AR) libjpeg.lib $(LIBOBJECTS)
clean:
-$(RM) *.o cjpeg djpeg libjpeg.lib core testout.*
distribute:
-$(RM) jpegsrc.tar*
tar cvf jpegsrc.tar $(DISTFILES)
compress -v jpegsrc.tar
test: cjpeg djpeg
-$(RM) testout.ppm testout.gif testout.jpg
djpeg testorig.jpg testout.ppm
djpeg -G testorig.jpg testout.gif
cjpeg testimg.ppm testout.jpg
cmp testimg.ppm testout.ppm
cmp testimg.gif testout.gif
cmp testimg.jpg testout.jpg
jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
jddeflts.o : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
jmemmgr.o : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
jrdrle.o : jrdrle.c jinclude.h jconfig.h jpegdata.h
jrdtarga.o : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.o : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.o : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.o : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h

View File

@@ -2,7 +2,7 @@
# This makefile is for Microsoft C for MS-DOS, version 5.x. # This makefile is for Microsoft C for MS-DOS, version 5.x.
# See README and edit jconfig.h before saying "make" !! # Read SETUP instructions before saying "make" !!
# Microsoft's brain-damaged version of make uses nonstandard syntax (a blank # Microsoft's brain-damaged version of make uses nonstandard syntax (a blank
# line is needed to terminate a command list) and it simply scans the rules # line is needed to terminate a command list) and it simply scans the rules
@@ -13,23 +13,53 @@
# from the library. The objectfiles are also kept separately as timestamps. # from the library. The objectfiles are also kept separately as timestamps.
# You may need to adjust these cc options: # You may need to adjust these cc options:
CFLAGS= /AS /I. /W3 /Oail /Gs /DMEM_STATS # NB: /Gs turns off stack oflo checks CFLAGS= /AS /I. /W3 /Oail /Gs # NB: /Gs turns off stack oflo checks
LDFLAGS= /Fm /F 2000 # /F hhhh sets stack size (in hex) LDFLAGS= /Fm /F 2000 # /F hhhh sets stack size (in hex)
# In particular: # In particular:
# Add /DMSDOS if your compiler doesn't automatically #define MSDOS. # Add /DMSDOS if your compiler doesn't automatically #define MSDOS.
# Add /DHAVE_GETOPT if your library includes getopt(3) (see jcmain.c, jdmain.c). # Add /DMEM_STATS to enable gathering of memory usage statistics.
# /DMEM_STATS is optional -- it enables gathering of memory usage statistics. # You might also want to add /G2 if you have an 80286, etc.
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.obj jerror.obj jmemmgr.obj jmemsys.obj jmemdosa.obj
# compression objectfiles # compression objectfiles
COBJECTS = jcmain.obj jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \ CLIBOBJECTS= jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \ jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
jrdgif.obj jrdppm.obj jwrjfif.obj \ jwrjfif.obj jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj
jutils.obj jvirtmem.obj jerror.obj COBJECTS= jcmain.obj $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles # decompression objectfiles
DOBJECTS = jdmain.obj jdmaster.obj jbsmooth.obj jdarith.obj jdcolor.obj jdhuff.obj \ DLIBOBJECTS= jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj \
jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj jquant2.obj jrevdct.obj \ jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj \
jrdjfif.obj jwrgif.obj jwrppm.obj \ jquant2.obj jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj \
jutils.obj jvirtmem.obj jerror.obj jwrrle.obj jwrtarga.obj
DOBJECTS= jdmain.obj $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.lib
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
# inference rule used for all compilations except jcmain.c, jdmain.c # inference rule used for all compilations except jcmain.c, jdmain.c
@@ -38,74 +68,91 @@ DOBJECTS = jdmain.obj jdmaster.obj jbsmooth.obj jdarith.obj jdcolor.obj jdhuff.o
cl $(CFLAGS) /c $*.c cl $(CFLAGS) /c $*.c
lib libjpeg -+$*.obj; lib libjpeg -+$*.obj;
# these two objectfiles are not inserted into libjpeg # inference rule for assembly code
# because they have duplicate global symbol names (notably main()). .asm.obj:
jcmain.obj: jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c masm /mx $*;
lib libjpeg -+$*.obj;
jbsmooth.obj : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.obj : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.obj : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.obj : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.obj : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.obj : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.obj : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
cl $(CFLAGS) /c $*.c cl $(CFLAGS) /c $*.c
jdmain.obj: jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c jcmaster.obj : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.obj : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.obj : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.obj : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.obj : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.obj : jdcolor.c jinclude.h jconfig.h jpegdata.h
jddeflts.obj : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdhuff.obj : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.obj : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
cl $(CFLAGS) /c $*.c cl $(CFLAGS) /c $*.c
jdmaster.obj : jdmaster.c jinclude.h jconfig.h jpegdata.h
jbsmooth.obj: jbsmooth.c jinclude.h jconfig.h jpegdata.h jdmcu.obj : jdmcu.c jinclude.h jconfig.h jpegdata.h
jcarith.obj: jcarith.c jinclude.h jconfig.h jpegdata.h jdpipe.obj : jdpipe.c jinclude.h jconfig.h jpegdata.h
jccolor.obj: jccolor.c jinclude.h jconfig.h jpegdata.h jdsample.obj : jdsample.c jinclude.h jconfig.h jpegdata.h
jcdeflts.obj: jcdeflts.c jinclude.h jconfig.h jpegdata.h jerror.obj : jerror.c jinclude.h jconfig.h jpegdata.h
jcexpand.obj: jcexpand.c jinclude.h jconfig.h jpegdata.h jquant1.obj : jquant1.c jinclude.h jconfig.h jpegdata.h
jchuff.obj: jchuff.c jinclude.h jconfig.h jpegdata.h jquant2.obj : jquant2.c jinclude.h jconfig.h jpegdata.h
jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpegdata.h jfwddct.obj : jfwddct.c jinclude.h jconfig.h jpegdata.h
jcmcu.obj: jcmcu.c jinclude.h jconfig.h jpegdata.h jrevdct.obj : jrevdct.c jinclude.h jconfig.h jpegdata.h
jcpipe.obj: jcpipe.c jinclude.h jconfig.h jpegdata.h jutils.obj : jutils.c jinclude.h jconfig.h jpegdata.h
jcsample.obj: jcsample.c jinclude.h jconfig.h jpegdata.h jmemmgr.obj : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jdarith.obj: jdarith.c jinclude.h jconfig.h jpegdata.h jrdjfif.obj : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpegdata.h jrdgif.obj : jrdgif.c jinclude.h jconfig.h jpegdata.h
jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpegdata.h jrdppm.obj : jrdppm.c jinclude.h jconfig.h jpegdata.h
jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpegdata.h jrdrle.obj : jrdrle.c jinclude.h jconfig.h jpegdata.h
jdmcu.obj: jdmcu.c jinclude.h jconfig.h jpegdata.h jrdtarga.obj : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jdpipe.obj: jdpipe.c jinclude.h jconfig.h jpegdata.h jwrjfif.obj : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jdsample.obj: jdsample.c jinclude.h jconfig.h jpegdata.h jwrgif.obj : jwrgif.c jinclude.h jconfig.h jpegdata.h
jerror.obj: jerror.c jinclude.h jconfig.h jpegdata.h jwrppm.obj : jwrppm.c jinclude.h jconfig.h jpegdata.h
jfwddct.obj: jfwddct.c jinclude.h jconfig.h jpegdata.h jwrrle.obj : jwrrle.c jinclude.h jconfig.h jpegdata.h
jquant1.obj: jquant1.c jinclude.h jconfig.h jpegdata.h jwrtarga.obj : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jquant2.obj: jquant2.c jinclude.h jconfig.h jpegdata.h jmemsys.obj : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jrdjfif.obj: jrdjfif.c jinclude.h jconfig.h jpegdata.h jmemdosa.obj : jmemdosa.asm
jrdgif.obj: jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.obj: jrdppm.c jinclude.h jconfig.h jpegdata.h
jrevdct.obj: jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.obj: jutils.c jinclude.h jconfig.h jpegdata.h
jvirtmem.obj: jvirtmem.c jinclude.h jconfig.h jpegdata.h
jwrjfif.obj: jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.obj: jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.obj: jwrppm.c jinclude.h jconfig.h jpegdata.h
cjpeg.exe: $(COBJECTS) cjpeg.exe: $(COBJECTS)

View File

@@ -3,71 +3,109 @@
# This makefile is for Microsoft C for MS-DOS, version 6.x (use NMAKE). # This makefile is for Microsoft C for MS-DOS, version 6.x (use NMAKE).
# Thanks to Alan Wright and Chris Turner of Olivetti Research Ltd. # Thanks to Alan Wright and Chris Turner of Olivetti Research Ltd.
# See README and edit jconfig.h before saying "make" !! # Read SETUP instructions before saying "make" !!
all: cjpeg.exe djpeg.exe
# compiler flags. -D gives a #define to the sources: # compiler flags. -D gives a #define to the sources:
# -O default optimisation # -O default optimisation
# -W3 warning level 3 # -W3 warning level 3
# -Za ANSI conformance, defines__STDC__ but undefines far # -Za ANSI conformance, defines __STDC__ but undefines far
# and near! # and near, so we DON'T use it.
# -D__STDC__ pretend we have full ANSI compliance. MSC is near # -DHAVE_STDC indicate we do have all the ANSI language features
# enough anyway # -DINCLUDES_ARE_ANSI and all the ANSI include files.
# -DMSDOS we are on an MSDOS machine # -DMSDOS we are on an MSDOS machine
# -DMEM_STATS enable memory usage statistics (optional) # -DMEM_STATS enable memory usage statistics (optional)
# -DHAVE_GETOPT library has getopt routine to parse cmnd line options
# -c compile, don't link (implicit in inference rules) # -c compile, don't link (implicit in inference rules)
# You might also want to add -G2 if you have an 80286, etc.
CFLAGS = -c -O -W3 -DMSDOS -D__STDC__ -DMEM_STATS CFLAGS = -c -O -W3 -DHAVE_STDC -DINCLUDES_ARE_ANSI -DMSDOS
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.obj jerror.obj jmemmgr.obj jmemsys.obj jmemdosa.obj
# compression objectfiles # compression objectfiles
COBJECTS = jcmain.obj jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \ CLIBOBJECTS= jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \ jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
jrdgif.obj jrdppm.obj jwrjfif.obj \ jwrjfif.obj jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj
jutils.obj jvirtmem.obj jerror.obj COBJECTS= jcmain.obj $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles # decompression objectfiles
DOBJECTS = jdmain.obj jdmaster.obj jbsmooth.obj jdarith.obj jdcolor.obj jdhuff.obj \ DLIBOBJECTS= jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj \
jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj jquant2.obj jrevdct.obj \ jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj \
jrdjfif.obj jwrgif.obj jwrppm.obj \ jquant2.obj jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj \
jutils.obj jvirtmem.obj jerror.obj jwrrle.obj jwrtarga.obj
DOBJECTS= jdmain.obj $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.lib
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
all: cjpeg.exe djpeg.exe
# default rules in nmake will use cflags and compile the list below # default rules in nmake will use cflags and compile the list below
jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h jbsmooth.obj : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h jcarith.obj : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h jccolor.obj : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h jcdeflts.obj : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h jcexpand.obj : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h jchuff.obj : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c jcmain.obj : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h jcmaster.obj : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h jcmcu.obj : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h jcpipe.obj : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h jcsample.obj : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h jdarith.obj : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h jdcolor.obj : jdcolor.c jinclude.h jconfig.h jpegdata.h
jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h jddeflts.obj : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c jdhuff.obj : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h jdmain.obj : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h jdmaster.obj : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h jdmcu.obj : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h jdpipe.obj : jdpipe.c jinclude.h jconfig.h jpegdata.h
jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h jdsample.obj : jdsample.c jinclude.h jconfig.h jpegdata.h
jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h jerror.obj : jerror.c jinclude.h jconfig.h jpegdata.h
jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h jquant1.obj : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h jquant2.obj : jquant2.c jinclude.h jconfig.h jpegdata.h
jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h jfwddct.obj : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h jrevdct.obj : jrevdct.c jinclude.h jconfig.h jpegdata.h
jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h jutils.obj : jutils.c jinclude.h jconfig.h jpegdata.h
jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h jmemmgr.obj : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h jrdjfif.obj : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jvirtmem.o : jvirtmem.c jinclude.h jconfig.h jpegdata.h jrdgif.obj : jrdgif.c jinclude.h jconfig.h jpegdata.h
jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h jrdppm.obj : jrdppm.c jinclude.h jconfig.h jpegdata.h
jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h jrdrle.obj : jrdrle.c jinclude.h jconfig.h jpegdata.h
jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h jrdtarga.obj : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jwrjfif.obj : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.obj : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.obj : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.obj : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.obj : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.obj : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jmemdosa.obj : jmemdosa.asm
masm /mx $*;
# use linker response files because file list > 128 chars # use linker response files because file list > 128 chars
@@ -77,3 +115,12 @@ cjpeg.exe: $(COBJECTS)
djpeg.exe: $(DOBJECTS) djpeg.exe: $(DOBJECTS)
link /STACK:8192 @makdjpeg.lnk link /STACK:8192 @makdjpeg.lnk
test:
del testout.*
djpeg testorig.jpg testout.ppm
djpeg -G testorig.jpg testout.gif
cjpeg testimg.ppm testout.jpg
fc testimg.ppm testout.ppm
fc testimg.gif testout.gif
fc testimg.jpg testout.jpg

134
makefile.mms Normal file
View File

@@ -0,0 +1,134 @@
# Makefile for Independent JPEG Group's software
# This makefile is for use with MMS on VAX/VMS systems.
# Thanks to Rick Dyson (dyson@iowasp.physics.uiowa.edu) for his help.
# Read SETUP instructions before saying "MMS" !!
CFLAGS= $(CFLAGS) /NoDebug /Optimize /Define = (TWO_FILE_COMMANDLINE,HAVE_STDC,INCLUDES_ARE_ANSI)
OPT= Sys$Disk:[]MAKVMS.OPT
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.obj jerror.obj jmemmgr.obj jmemsys.obj
# compression objectfiles
CLIBOBJECTS= jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
jwrjfif.obj jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj
COBJECTS= jcmain.obj $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles
DLIBOBJECTS= jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj \
jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj \
jquant2.obj jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj \
jwrrle.obj jwrtarga.obj
DOBJECTS= jdmain.obj $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.olb
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
# objectfile lists with commas --- what a crock
COBJLIST= jcmain.obj,jcmaster.obj,jcdeflts.obj,jcarith.obj,jccolor.obj,\
jcexpand.obj,jchuff.obj,jcmcu.obj,jcpipe.obj,jcsample.obj,\
jfwddct.obj,jwrjfif.obj,jrdgif.obj,jrdppm.obj,jrdrle.obj,\
jrdtarga.obj,jutils.obj,jerror.obj,jmemmgr.obj,jmemsys.obj
DOBJLIST= jdmain.obj,jdmaster.obj,jddeflts.obj,jbsmooth.obj,jdarith.obj,\
jdcolor.obj,jdhuff.obj,jdmcu.obj,jdpipe.obj,jdsample.obj,\
jquant1.obj,jquant2.obj,jrevdct.obj,jrdjfif.obj,jwrgif.obj,\
jwrppm.obj,jwrrle.obj,jwrtarga.obj,jutils.obj,jerror.obj,\
jmemmgr.obj,jmemsys.obj
LIBOBJLIST= jcmaster.obj,jcdeflts.obj,jcarith.obj,jccolor.obj,jcexpand.obj,\
jchuff.obj,jcmcu.obj,jcpipe.obj,jcsample.obj,jfwddct.obj,\
jwrjfif.obj,jrdgif.obj,jrdppm.obj,jrdrle.obj,jrdtarga.obj,\
jdmaster.obj,jddeflts.obj,jbsmooth.obj,jdarith.obj,jdcolor.obj,\
jdhuff.obj,jdmcu.obj,jdpipe.obj,jdsample.obj,jquant1.obj,\
jquant2.obj,jrevdct.obj,jrdjfif.obj,jwrgif.obj,jwrppm.obj,\
jwrrle.obj,jwrtarga.obj,jutils.obj,jerror.obj,jmemmgr.obj,\
jmemsys.obj
.first
@ Define Sys Sys$Library
# By default, libjpeg.olb is not built unless you explicitly request it.
# You can add libjpeg.olb to the next line if you want it built by default.
ALL : cjpeg.exe djpeg.exe
@ Continue
cjpeg.exe : $(COBJECTS)
$(LINK) $(LFLAGS) /Executable = cjpeg.exe $(COBJLIST),$(OPT)/Option
djpeg.exe : $(DOBJECTS)
$(LINK) $(LFLAGS) /Executable = djpeg.exe $(DOBJLIST),$(OPT)/Option
# libjpeg.olb is useful if you are including the JPEG software in a larger
# program; you'd include it in your link, rather than the individual modules.
libjpeg.olb : $(LIBOBJECTS)
Library /Create libjpeg.olb $(LIBOBJLIST)
clean :
@- Set Protection = Owner:RWED *.*;-1
@- Set Protection = Owner:RWED *.OBJ
- Purge /NoLog /NoConfirm *.*
- Delete /NoLog /NoConfirm *.OBJ;
jbsmooth.obj : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.obj : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.obj : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.obj : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.obj : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.obj : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.obj : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.obj : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.obj : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.obj : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.obj : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.obj : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.obj : jdcolor.c jinclude.h jconfig.h jpegdata.h
jddeflts.obj : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdhuff.obj : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.obj : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmaster.obj : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdmcu.obj : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdpipe.obj : jdpipe.c jinclude.h jconfig.h jpegdata.h
jdsample.obj : jdsample.c jinclude.h jconfig.h jpegdata.h
jerror.obj : jerror.c jinclude.h jconfig.h jpegdata.h
jquant1.obj : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.obj : jquant2.c jinclude.h jconfig.h jpegdata.h
jfwddct.obj : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrevdct.obj : jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.obj : jutils.c jinclude.h jconfig.h jpegdata.h
jmemmgr.obj : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jrdjfif.obj : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jrdgif.obj : jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.obj : jrdppm.c jinclude.h jconfig.h jpegdata.h
jrdrle.obj : jrdrle.c jinclude.h jconfig.h jpegdata.h
jrdtarga.obj : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jwrjfif.obj : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.obj : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.obj : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.obj : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.obj : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.obj : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h

View File

@@ -2,24 +2,24 @@
# This makefile is for Mix Software's Power C, v2.1.1 # This makefile is for Mix Software's Power C, v2.1.1
# and Dan Grayson's pd make 2.14 under MS-DOS. # and Dan Grayson's pd make 2.14 under MS-DOS.
# This file assumes that you have Microsoft's MASM or a compatible assembler
# to handle the jmemdosa.asm file. If not, you will need to use jmemname.c
# and go to a large-data memory model.
# Thanks to Bob Hardy for this version. # Thanks to Bob Hardy for this version.
# See README and edit jconfig.h before saying "make" !! # Read SETUP instructions before saying "make" !!
# NOTE: make sure you have converted end-of-line markers to CR/LF in this file
# and in the three mak*.cf files; otherwise pd make and the Mix linker will
# choke. Power C doesn't seem to care whether end-of-lines are CR/LF or just
# LF in the *.h and *.c files. If you blindly converted LF to CR/LF in ALL
# the files, then you broke the test*.* files, which contain binary data.
# The name of your C compiler:
CC=pc CC=pc
# You may need to adjust these cc options: # You may need to adjust these cc options:
MODEL=m MODEL=m
CFLAGS=-dMEM_STATS -dMSDOS -m$(MODEL) CFLAGS= -dMSDOS -m$(MODEL)
LDFLAGS=
# In particular: # In particular:
# -dMEM_STATS is optional -- it enables gathering of memory usage statistics. # Add -dMEM_STATS to enable gathering of memory usage statistics.
# Link-time cc options:
LDFLAGS=
LDLIBS= LDLIBS=
# miscellaneous OS-dependent stuff # miscellaneous OS-dependent stuff
@@ -31,16 +31,35 @@ RM=del
AR=merge AR=merge
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) $(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.mix jerror.mix jmemmgr.mix jmemsys.mix jmemdosa.mix
# compression objectfiles # compression objectfiles
COBJECTS = jcmain.mix jcmaster.mix jcdeflts.mix jcarith.mix jccolor.mix jcexpand.mix jchuff.mix jcmcu.mix jcpipe.mix jcsample.mix jfwddct.mix jrdgif.mix jrdppm.mix jwrjfif.mix jutils.mix jvirtmem.mix jerror.mix CLIBOBJECTS= jcmaster.mix jcdeflts.mix jcarith.mix jccolor.mix jcexpand.mix jchuff.mix jcmcu.mix jcpipe.mix jcsample.mix jfwddct.mix jwrjfif.mix jrdgif.mix jrdppm.mix jrdrle.mix jrdtarga.mix
COBJECTS= jcmain.mix $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles # decompression objectfiles
DOBJECTS = jdmain.mix jdmaster.mix jbsmooth.mix jdarith.mix jdcolor.mix jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jutils.mix jvirtmem.mix jerror.mix DLIBOBJECTS= jdmaster.mix jddeflts.mix jbsmooth.mix jdarith.mix jdcolor.mix jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jwrrle.mix jwrtarga.mix
# These objectfiles are included in libjpeg.mix (all but jcmain, jdmain) DOBJECTS= jdmain.mix $(DLIBOBJECTS) $(COMOBJECTS)
LIBOBJECTS = jcmaster.mix jcdeflts.mix jcarith.mix jccolor.mix jcexpand.mix jchuff.mix jcmcu.mix jcpipe.mix jcsample.mix jfwddct.mix jrdgif.mix jrdppm.mix jwrjfif.mix jdmaster.mix jbsmooth.mix jdarith.mix jdcolor.mix jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jutils.mix jvirtmem.mix jerror.mix # These objectfiles are included in libjpeg.mix
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
all: cjpeg.exe djpeg.exe test all: cjpeg.exe djpeg.exe
# By default, libjpeg.mix is not built unless you explicitly request it. # By default, libjpeg.mix is not built unless you explicitly request it.
# You can add libjpeg.mix to the line above if you want it built by default.
cjpeg.exe: $(COBJECTS) cjpeg.exe: $(COBJECTS)
@@ -61,40 +80,51 @@ clean:
test: test:
@$(RM) testout.* @$(RM) testout.*
+djpeg testorig.jpg testout.ppm +djpeg testorig.jpg testout.ppm
+djpeg -G testorig.jpg testout.gif
+cjpeg testimg.ppm testout.jpg +cjpeg testimg.ppm testout.jpg
fc testimg.ppm testout.ppm fc testimg.ppm testout.ppm
fc testimg.gif testout.gif
fc testimg.jpg testout.jpg fc testimg.jpg testout.jpg
jbsmooth.mix : jbsmooth.c jinclude.h jconfig.h jpegdata.h jbsmooth.mix : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.mix : jcarith.c jinclude.h jconfig.h jpegdata.h jcarith.mix : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.mix : jccolor.c jinclude.h jconfig.h jpegdata.h jccolor.mix : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.mix : jcdeflts.c jinclude.h jconfig.h jpegdata.h jcdeflts.mix : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.mix : jcexpand.c jinclude.h jconfig.h jpegdata.h jcexpand.mix : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.mix : jchuff.c jinclude.h jconfig.h jpegdata.h jchuff.mix : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.mix : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c jcmain.mix : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.mix : jcmaster.c jinclude.h jconfig.h jpegdata.h jcmaster.mix : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.mix : jcmcu.c jinclude.h jconfig.h jpegdata.h jcmcu.mix : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.mix : jcpipe.c jinclude.h jconfig.h jpegdata.h jcpipe.mix : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.mix : jcsample.c jinclude.h jconfig.h jpegdata.h jcsample.mix : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.mix : jdarith.c jinclude.h jconfig.h jpegdata.h jdarith.mix : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.mix : jdcolor.c jinclude.h jconfig.h jpegdata.h jdcolor.mix : jdcolor.c jinclude.h jconfig.h jpegdata.h
jdhuff.mix : jdhuff.c jinclude.h jconfig.h jpegdata.h jddeflts.mix : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdmain.mix : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c jdhuff.mix : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmaster.mix : jdmaster.c jinclude.h jconfig.h jpegdata.h jdmain.mix : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmcu.mix : jdmcu.c jinclude.h jconfig.h jpegdata.h jdmaster.mix : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdpipe.mix : jdpipe.c jinclude.h jconfig.h jpegdata.h jdmcu.mix : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdsample.mix : jdsample.c jinclude.h jconfig.h jpegdata.h jdpipe.mix : jdpipe.c jinclude.h jconfig.h jpegdata.h
jerror.mix : jerror.c jinclude.h jconfig.h jpegdata.h jdsample.mix : jdsample.c jinclude.h jconfig.h jpegdata.h
jfwddct.mix : jfwddct.c jinclude.h jconfig.h jpegdata.h jerror.mix : jerror.c jinclude.h jconfig.h jpegdata.h
jquant1.mix : jquant1.c jinclude.h jconfig.h jpegdata.h jquant1.mix : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.mix : jquant2.c jinclude.h jconfig.h jpegdata.h jquant2.mix : jquant2.c jinclude.h jconfig.h jpegdata.h
jrdjfif.mix : jrdjfif.c jinclude.h jconfig.h jpegdata.h jfwddct.mix : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrdgif.mix : jrdgif.c jinclude.h jconfig.h jpegdata.h jrevdct.mix : jrevdct.c jinclude.h jconfig.h jpegdata.h
jrdppm.mix : jrdppm.c jinclude.h jconfig.h jpegdata.h jutils.mix : jutils.c jinclude.h jconfig.h jpegdata.h
jrevdct.mix : jrevdct.c jinclude.h jconfig.h jpegdata.h jmemmgr.mix : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jutils.mix : jutils.c jinclude.h jconfig.h jpegdata.h jrdjfif.mix : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jvirtmem.mix : jvirtmem.c jinclude.h jconfig.h jpegdata.h jrdgif.mix : jrdgif.c jinclude.h jconfig.h jpegdata.h
jwrjfif.mix : jwrjfif.c jinclude.h jconfig.h jpegdata.h jrdppm.mix : jrdppm.c jinclude.h jconfig.h jpegdata.h
jwrgif.mix : jwrgif.c jinclude.h jconfig.h jpegdata.h jrdrle.mix : jrdrle.c jinclude.h jconfig.h jpegdata.h
jwrppm.mix : jwrppm.c jinclude.h jconfig.h jpegdata.h jrdtarga.mix : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jwrjfif.mix : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.mix : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.mix : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.mix : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.mix : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.mix : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jmemdosa.mix : jmemdosa.asm
masm /mx jmemdosa;
mix jmemdosa.obj

163
makefile.sas Normal file
View File

@@ -0,0 +1,163 @@
# Makefile for Independent JPEG Group's software
# This makefile is for Amiga systems using SAS C 5.10b.
# Use jmemname.c as the system-dependent memory manager.
# Contributed by Ed Hanway (sisd!jeh@uunet.uu.net).
# Read SETUP instructions before saying "make" !!
# The name of your C compiler:
CC= lc
# Uncomment the following lines for generic 680x0 version
ARCHFLAGS=
SUFFIX=
# Uncomment the following lines for 68030-only version
#ARCHFLAGS= -m3
#SUFFIX=.030
# You may need to adjust these cc options:
CFLAGS= -v -b -rr -O -j104 $(ARCHFLAGS) -DHAVE_STDC -DINCLUDES_ARE_ANSI \
-DAMIGA -DTWO_FILE_COMMANDLINE -DINCOMPLETE_TYPES_BROKEN \
-DNO_MKTEMP -DNEED_SIGNAL_CATCHER
# -j104 disables warnings for mismatched const qualifiers
# Link-time cc options:
LDFLAGS= SC SD ND BATCH
# To link any special libraries, add the necessary commands here.
LDLIBS= LIB LIB:lcr.lib
# miscellaneous OS-dependent stuff
# linker
LN= blink
# file deletion command
RM= delete quiet
# library (.lib) file creation command
AR= oml
# source files (independently compilable files)
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jwrppm.c jwrrle.c jwrtarga.c
# virtual source files (not present in distribution file)
VIRTSOURCES= jmemsys.c
# system-dependent implementations of source files
SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
jmemdosa.asm
# files included by source files
INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
# compression objectfiles
CLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
jrdrle.o jrdtarga.o
COBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles
DLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
DOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.lib
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
all: cjpeg$(SUFFIX) djpeg$(SUFFIX)
# By default, libjpeg.lib is not built unless you explicitly request it.
# You can add libjpeg.lib to the line above if you want it built by default.
cjpeg$(SUFFIX): $(COBJECTS)
$(LN) <WITH <
$(LDFLAGS)
TO cjpeg$(SUFFIX)
FROM LIB:c.o $(COBJECTS)
$(LDLIBS)
<
djpeg$(SUFFIX): $(DOBJECTS)
$(LN) <WITH <
$(LDFLAGS)
TO djpeg$(SUFFIX)
FROM LIB:c.o $(DOBJECTS)
$(LDLIBS)
<
# libjpeg.lib is useful if you are including the JPEG software in a larger
# program; you'd include it in your link, rather than the individual modules.
libjpeg.lib: $(LIBOBJECTS)
-$(RM) libjpeg.lib
$(AR) libjpeg.lib r $(LIBOBJECTS)
clean:
-$(RM) *.o cjpeg djpeg cjpeg.030 djpeg.030 libjpeg.lib core testout.*
distribute:
-$(RM) jpegsrc.tar*
tar cvf jpegsrc.tar $(DISTFILES)
compress -v jpegsrc.tar
test: cjpeg djpeg
-$(RM) testout.ppm testout.gif testout.jpg
djpeg testorig.jpg testout.ppm
djpeg -G testorig.jpg testout.gif
cjpeg testimg.ppm testout.jpg
cmp testimg.ppm testout.ppm
cmp testimg.gif testout.gif
cmp testimg.jpg testout.jpg
jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h
jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h
jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
jddeflts.o : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
jmemmgr.o : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
jrdrle.o : jrdrle.c jinclude.h jconfig.h jpegdata.h
jrdtarga.o : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.o : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.o : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.o : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h

View File

@@ -1,120 +1,129 @@
# Makefile for Independent JPEG Group's software # Makefile for Independent JPEG Group's software
# This makefile is suitable for Unix-like systems. # This makefile is suitable for Unix-like systems with non-ANSI compilers.
# If you have an ANSI compiler, makefile.ansi is a better starting point.
# See README and edit jconfig.h before saying "make" !! # Read SETUP instructions before saying "make" !!
# Comment out this line if you don't have gcc: # The name of your C compiler:
CC=gcc CC= cc
# You may need to adjust these cc options: # You may need to adjust these cc options:
CFLAGS= -O -g -Wall -DHAVE_GETOPT -DMEM_STATS CFLAGS= -O
LDFLAGS= -g
# In particular: # In particular:
# Remove -g and -Wall if not using gcc.
# Add -DBSD if on a pure BSD system (see jinclude.h). # Add -DBSD if on a pure BSD system (see jinclude.h).
# Remove -DHAVE_GETOPT if you don't have getopt(3) (see jcmain.c, jdmain.c). # Add -DVMS if on a VMS system (see ansi2knr.c).
# -DMEM_STATS is optional -- it enables gathering of memory usage statistics. # Add -DMSDOS if on an MSDOS system (see ansi2knr.c).
# Add -DMEM_STATS to enable gathering of memory usage statistics.
# You may also want to add -DTWO_FILE_COMMANDLINE or -D switches for other # You may also want to add -DTWO_FILE_COMMANDLINE or -D switches for other
# symbols listed in jconfig.h, if you prefer not to change jconfig.h. # symbols listed in jconfig.h, if you prefer not to change jconfig.h.
# If your compiler is non-ANSI, also see the .c.o rule below.
# On HP-UX (and probably other SysV systems) the alternate malloc(3X) is a lot # Link-time cc options:
# faster than the standard malloc; this makes a noticeable difference in the LDFLAGS=
# startup time when handling big noninterleaved images. I say "-lmalloc" to
# get the alternate allocator. On most non-SysV systems you can just # To link any special libraries, add the necessary -l commands here.
# define LDLIBS as empty. # In particular, on some versions of HP-UX (and probably other SysV-derived
LDLIBS= -lmalloc # systems) there is a faster alternate malloc(3) library that you can use
# by adding "-lmalloc" to this line.
LDLIBS=
# miscellaneous OS-dependent stuff # miscellaneous OS-dependent stuff
LN= $(CC) # linker # linker
RM= rm -f # file deletion command LN= $(CC)
AR= ar rc # library (.a) file creation command # file deletion command
AR2= ranlib # second step in .a creation (use "touch" if not needed) RM= rm -f
# library (.a) file creation command
AR= ar rc
# second step in .a creation (use "touch" if not needed)
AR2= ranlib
# source files # source files (independently compilable files)
INCLUDES= jinclude.h jconfig.h jpegdata.h SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c \ jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
jchuff.c jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c \ jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
jdarith.c jdcolor.c jdhuff.c jdmain.c jdmaster.c jdmcu.c \ jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
jdpipe.c jdsample.c jerror.c jfwddct.c jquant1.c jquant2.c \ jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
jrdjfif.c jrdgif.c jrdppm.c jrevdct.c jutils.c jvirtmem.c \ jwrppm.c jwrrle.c jwrtarga.c
jwrjfif.c jwrgif.c jwrppm.c egetopt.c # virtual source files (not present in distribution file)
DOCS= README architecture codingrules VIRTSOURCES= jmemsys.c
MAKEFILES= makefile.unix makefile.amiga \ # system-dependent implementations of source files
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk \ SYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
makefile.pwc makcjpeg.cf makdjpeg.cf makljpeg.cf jmemdosa.asm
TESTFILES= testorig.jpg testimg.ppm testimg.jpg # files included by source files
DISTFILES= $(DOCS) $(MAKEFILES) ansi2knr.c $(SOURCES) $(INCLUDES) $(TESTFILES) INCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
# documentation, test, and support files
DOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
MAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
makljpeg.cf makefile.mms makefile.vms makvms.opt
OTHERFILES= ansi2knr.c ckconfig.c example.c
TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
DISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
$(OTHERFILES) $(TESTFILES)
# objectfiles common to cjpeg and djpeg
COMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
# compression objectfiles # compression objectfiles
COBJECTS = jcmain.o jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \ CLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \ jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
jrdgif.o jrdppm.o jwrjfif.o \ jrdrle.o jrdtarga.o
jutils.o jvirtmem.o jerror.o COBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
# decompression objectfiles # decompression objectfiles
DOBJECTS = jdmain.o jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \ DLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \ jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
jrdjfif.o jwrgif.o jwrppm.o \ jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
jutils.o jvirtmem.o jerror.o DOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
# These objectfiles are included in libjpeg.a (all but jcmain.o, jdmain.o) # These objectfiles are included in libjpeg.a
LIBOBJECTS = jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \ LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \
jrdgif.o jrdppm.o jwrjfif.o \
jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \
jrdjfif.o jwrgif.o jwrppm.o \
jutils.o jvirtmem.o jerror.o
all: cjpeg djpeg all: ansi2knr cjpeg djpeg
# By default, libjpeg.a is not built unless you explicitly request it. # By default, libjpeg.a is not built unless you explicitly request it.
# You can add libjpeg.a to the line above if you want it built by default.
# If you have a C compiler that doesn't understand function prototypes, # This rule causes ansi2knr to be invoked. If you use this makefile,
# uncomment the 5 lines below and make sure PROTO is not defined by jconfig.h. # make sure PROTO is not defined by jconfig.h.
# Then say "make ansi2knr" before "make".
#.c.o: .c.o:
# ./ansi2knr $*.c tmpansi.c ./ansi2knr $*.c tmpansi.c
# $(CC) $(CFLAGS) -c tmpansi.c $(CC) $(CFLAGS) -c tmpansi.c
# mv tmpansi.o $*.o mv tmpansi.o $*.o
# $(RM) tmpansi.c $(RM) tmpansi.c
ansi2knr: ansi2knr.c ansi2knr: ansi2knr.c
$(CC) -o ansi2knr ansi2knr.c $(CC) $(CFLAGS) -o ansi2knr ansi2knr.c
# You may need to add one of -DBSD, -DVMS, or -DMSDOS to the line above.
cjpeg: $(COBJECTS) cjpeg: ansi2knr $(COBJECTS)
$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS) $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
djpeg: $(DOBJECTS) djpeg: ansi2knr $(DOBJECTS)
$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS) $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
# libjpeg.a is useful if you are including the JPEG software in a larger # libjpeg.a is useful if you are including the JPEG software in a larger
# program; you'd include it in your link, rather than the individual modules. # program; you'd include it in your link, rather than the individual modules.
libjpeg.a: $(LIBOBJECTS) libjpeg.a: ansi2knr $(LIBOBJECTS)
$(RM) libjpeg.a $(RM) libjpeg.a
$(AR) libjpeg.a $(LIBOBJECTS) $(AR) libjpeg.a $(LIBOBJECTS)
$(AR2) libjpeg.a $(AR2) libjpeg.a
clean: clean:
$(RM) *.o cjpeg djpeg libjpeg.a ansi2knr core tmpansi.* testout.ppm testout.jpg $(RM) *.o cjpeg djpeg libjpeg.a ansi2knr core tmpansi.* testout.*
distribute: distribute:
$(RM) jpegsrc.tar* $(RM) jpegsrc.tar*
tar cvf jpegsrc.tar $(DISTFILES) tar cvf jpegsrc.tar $(DISTFILES)
ls -l jpegsrc.tar
compress -v jpegsrc.tar compress -v jpegsrc.tar
ls -l jpegsrc.tar*
test: cjpeg djpeg test: cjpeg djpeg
$(RM) testout.ppm testout.jpg $(RM) testout.ppm testout.gif testout.jpg
./djpeg testorig.jpg >testout.ppm ./djpeg testorig.jpg >testout.ppm
./djpeg -G testorig.jpg >testout.gif
./cjpeg testimg.ppm >testout.jpg ./cjpeg testimg.ppm >testout.jpg
cmp testimg.ppm testout.ppm cmp testimg.ppm testout.ppm
cmp testimg.gif testout.gif
cmp testimg.jpg testout.jpg cmp testimg.jpg testout.jpg
@@ -124,29 +133,35 @@ jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
jddeflts.o : jddeflts.c jinclude.h jconfig.h jpegdata.h
jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
jmemmgr.o : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h jrdrle.o : jrdrle.c jinclude.h jconfig.h jpegdata.h
jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h jrdtarga.o : jrdtarga.c jinclude.h jconfig.h jpegdata.h
jvirtmem.o : jvirtmem.c jinclude.h jconfig.h jpegdata.h
jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h
jwrrle.o : jwrrle.c jinclude.h jconfig.h jpegdata.h
jwrtarga.o : jwrtarga.c jinclude.h jconfig.h jpegdata.h
jmemsys.o : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h

64
makefile.vms Normal file
View File

@@ -0,0 +1,64 @@
$! Makefile for Independent JPEG Group's software
$!
$! This is a command procedure for use on VAX/VMS systems that do not have MMS.
$! It builds the JPEG software by brute force, recompiling everything whether
$! or not it is necessary.
$! Thanks to Rick Dyson (dyson@iowasp.physics.uiowa.edu) for his help.
$!
$! Read SETUP instructions before running this!!
$!
$ DoCompile := CC /NoDebug /Optimize /Define = (TWO_FILE_COMMANDLINE,HAVE_STDC,INCLUDES_ARE_ANSI)
$!
$ DoCompile jcmain.c
$ DoCompile jdmain.c
$ DoCompile jcmaster.c
$ DoCompile jcdeflts.c
$ DoCompile jcarith.c
$ DoCompile jccolor.c
$ DoCompile jcexpand.c
$ DoCompile jchuff.c
$ DoCompile jcmcu.c
$ DoCompile jcpipe.c
$ DoCompile jcsample.c
$ DoCompile jfwddct.c
$ DoCompile jwrjfif.c
$ DoCompile jrdgif.c
$ DoCompile jrdppm.c
$ DoCompile jrdrle.c
$ DoCompile jrdtarga.c
$ DoCompile jdmaster.c
$ DoCompile jddeflts.c
$ DoCompile jbsmooth.c
$ DoCompile jdarith.c
$ DoCompile jdcolor.c
$ DoCompile jdhuff.c
$ DoCompile jdmcu.c
$ DoCompile jdpipe.c
$ DoCompile jdsample.c
$ DoCompile jquant1.c
$ DoCompile jquant2.c
$ DoCompile jrevdct.c
$ DoCompile jrdjfif.c
$ DoCompile jwrgif.c
$ DoCompile jwrppm.c
$ DoCompile jwrrle.c
$ DoCompile jwrtarga.c
$ DoCompile jutils.c
$ DoCompile jerror.c
$ DoCompile jmemmgr.c
$ DoCompile jmemsys.c
$!
$ Library /Create libjpeg.olb jcmaster.obj,jcdeflts.obj,jcarith.obj, -
jccolor.obj,jcexpand.obj,jchuff.obj,jcmcu.obj,jcpipe.obj, -
jcsample.obj,jfwddct.obj,jwrjfif.obj,jrdgif.obj,jrdppm.obj, -
jrdrle.obj,jrdtarga.obj,jdmaster.obj,jddeflts.obj,jbsmooth.obj, -
jdarith.obj,jdcolor.obj,jdhuff.obj,jdmcu.obj,jdpipe.obj, -
jdsample.obj,jquant1.obj,jquant2.obj,jrevdct.obj,jrdjfif.obj, -
jwrgif.obj,jwrppm.obj,jwrrle.obj,jwrtarga.obj,jutils.obj, -
jerror.obj,jmemmgr.obj,jmemsys.obj
$!
$ Link /Executable = cjpeg.exe jcmain.obj,libjpeg.olb/Library,Sys$Disk:[]MAKVMS.OPT/Option
$!
$ Link /Executable = djpeg.exe jdmain.obj,libjpeg.olb/Library,Sys$Disk:[]MAKVMS.OPT/Option
$!
$ Exit

View File

@@ -1,5 +1,7 @@
jbsmooth.mix,jcarith.mix,jccolor.mix,jcdeflts.mix,jcexpand.mix,jchuff.mix jcmaster.mix,jcdeflts.mix,jcarith.mix,jccolor.mix,jcexpand.mix,jchuff.mix
jcmaster.mix,jcmcu.mix,jcpipe.mix,jcsample.mix,jdarith.mix,jdcolor.mix jcmcu.mix,jcpipe.mix,jcsample.mix,jfwddct.mix,jwrjfif.mix,jrdgif.mix
jdhuff.mix,jdmaster.mix,jdmcu.mix,jdpipe.mix,jdsample.mix,jerror.mix jrdppm.mix,jrdrle.mix,jrdtarga.mix,jdmaster.mix,jddeflts.mix,jbsmooth.mix
jfwddct.mix,jquant1.mix,jquant2.mix,jrdgif.mix,jrdjfif.mix,jrdppm.mix jdarith.mix,jdcolor.mix,jdhuff.mix,jdmcu.mix,jdpipe.mix,jdsample.mix
jrevdct.mix,jutils.mix,jvirtmem.mix,jwrgif.mix,jwrjfif.mix,jwrppm.mix jquant1.mix,jquant2.mix,jrevdct.mix,jrdjfif.mix,jwrgif.mix,jwrppm.mix
jwrrle.mix,jwrtarga.mix,jutils.mix,jerror.mix,jmemmgr.mix,jmemsys.mix
jmemdosa.mix

3
makvms.opt Normal file
View File

@@ -0,0 +1,3 @@
! a pointer to the VAX/VMS C Run-Time Shareable Library
! This file is needed by makefile.mms and makefile.vms
Sys$Library:VAXCRTL.EXE /Share

BIN
testimg.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB