This package contains C software to implement JPEG image compression and
decompression. JPEG is a standardized compression method for full-color
and gray-scale images. JPEG is intended for "real-world" scenes; cartoons
and other non-realistic images are not its strong suit. JPEG is lossy,
meaning that the output image is not identical to the input image.
The user can trade off output image quality against compressed file size by
adjusting a compression parameter.
The distributed programs provide conversion between JPEG "JFIF" format and
image files in PBMPLUS PPM/PGM, Utah RLE, Truevision Targa, and GIF file
formats. The core compression and decompression modules can easily be
reused in other programs, such as image viewers. The package is highly
portable C code; we have tested it on many machines ranging from PCs to Crays.
We are releasing this software for both noncommercial and commercial use.
Companies are welcome to use it as the basis for JPEG-related products.
We do not ask a royalty, although we do ask for an acknowledgement in
product literature (see the README file in the distribution for details).
We hope to make this software industrial-quality --- although, as with
anything that's free, we offer no warranty and accept no liability.
Tom Lane
--------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: README arch.a makefile.vms
# Wrapped by kent@sparky on Mon Mar 23 16:02:39 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 18)."'
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(18730 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThe Independent JPEG Group's JPEG software
X==========================================
X
XREADME for release 3 of 17-Mar-92
X==================================
X
XThis distribution contains the third official release of the Independent JPEG
XGroup's free JPEG software. You are welcome to redistribute this software and
Xto use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
X
XFor installation instructions, see file SETUP; for usage instructions, see
Xfile USAGE (or the cjpeg.1 and djpeg.1 manual pages).
X
XThis software is still undergoing revision. Updated versions may be obtained
Xby FTP or UUCP to UUNET and other archive sites; see ARCHIVE LOCATIONS below
Xfor details.
X
XIf you intend to become a serious user of this software, please contact
Xjpeg...@uunet.uu.net to be added to our electronic mailing list. Then
Xyou'll be notified of updates and have a chance to participate in discussions,
Xetc.
X
XThis software is the work of Tom Lane, Philip Gladstone, Luis Ortiz,
XLee Crocker, Ge' Weijers, and other members of the Independent JPEG Group.
X
X
XDISCLAIMER
X==========
X
XTHIS SOFTWARE IS NOT COMPLETE NOR FULLY DEBUGGED. It is not guaranteed to be
Xuseful for anything, nor to be compatible with subsequent releases, nor to be
Xan accurate implementation of the JPEG standard. (See LEGAL ISSUES for even
Xmore disclaimers.)
X
XPlease report any problems with this software to jpeg...@uunet.uu.net.
X
X
XWHAT'S HERE
X===========
X
XThis distribution contains C software to implement JPEG image compression and
Xdecompression. JPEG (pronounced "jay-peg") is a standardized compression
Xmethod for full-color and gray-scale images. JPEG is intended for
X"real-world" scenes; cartoons and other non-realistic images are not its
Xstrong suit. JPEG is lossy, meaning that the output image is not necessarily
Xidentical to the input image. Hence you should not use JPEG if you have to
Xhave identical output bits. However, on typical images of real-world scenes,
Xvery good compression levels can be obtained with no visible change, and
Xamazingly high compression levels can be obtained if you can tolerate a
Xlow-quality image. For more details, see the references, or just experiment
Xwith various compression settings.
X
XThe software implements JPEG baseline and extended-sequential compression
Xprocesses. Provision is made for supporting all variants of these processes,
Xalthough some uncommon parameter settings aren't implemented yet. For legal
Xreasons, we are not distributing code for the arithmetic-coding process; see
XLEGAL ISSUES. At present we have made no provision for supporting the
Xprogressive, hierarchical, or lossless processes defined in the standard.
X
XThe present software is not far beyond the prototype stage. It does not
Xsupport all possible variants of the JPEG standard, and some functions have
Xrather slow and/or crude implementations. However, it is useful already.
X
XThe emphasis in designing this software has been on achieving portability and
Xflexibility, while also making it fast enough to be useful. We have not yet
Xundertaken serious performance measurement or tuning; we intend to do so in
Xthe future.
X
X
XThis software can be used on several levels:
X
X* As canned software for JPEG compression and decompression. Just edit the
X Makefile and configuration files as needed (see file SETUP), compile and go.
X Members of the Independent JPEG Group will improve the out-of-the-box
X functionality and speed as time goes on.
X
X* As the basis for other JPEG programs. For example, you could incorporate
X the decompressor into a general image viewing package by replacing the
X output module with write-to-screen functions. For an implementation on
X specific hardware, you might want to replace some of the inner loops with
X assembly code. For a non-command-line-driven system, you might want a
X different user interface. (Members of the group will be producing Macintosh
X and Amiga versions with more appropriate user interfaces, for example.)
X
X* As a toolkit for experimentation with JPEG and JPEG-like algorithms. Most
X of the individual decisions you might want to mess with are packaged up into
X separate modules. For example, the details of color-space conversion and
X subsampling techniques are each localized in one compressor and one
X decompressor module. You'd probably also want to extend the user interface
X to give you more detailed control over the JPEG compression parameters.
X
XIn particular, we welcome the use of this software as a component of commercial
Xproducts; no royalty is required.
X
X
XARCHIVE LOCATIONS
X=================
X
XThe "official" archive site for this software is ftp.uu.net (Internet
Xaddress 137.39.1.9 or 192.48.96.9). The most recent released version can
Xalways be found there in directory graphics/jpeg. This particular version
Xwill be archived as jpegsrc.v3.tar.Z. If you are on the Internet, you can
Xretrieve files from UUNET by anonymous FTP. If you don't have FTP access,
XUUNET's archives are also available via UUCP; contact postm...@uunet.uu.net
Xfor information on retrieving files that way.
X
XVarious other Internet sites maintain copies of the UUNET file, which may or
Xmay not be up-to-date. In Europe, try nic.funet.fi (128.214.6.100; look in
Xdirectory pub/graphics/programs/jpeg).
X
XYou can also obtain this software from CompuServe, in the GRAPHSUPPORT forum
X(GO PICS), library 10; this version will be file jpsrc3.zip.
X
XIf you are not reasonably handy at configuring and installing portable C
Xprograms, you may have some difficulty installing this package. You may
Xprefer to obtain a pre-built executable version. A collection of pre-built
Xexecutables for various machines is currently available for anonymous FTP at
Xprocyon.cis.ksu.edu (129.130.10.80 --- this number is due to change soon);
Xlook under /pub/JPEG. The administrators of this system ask that FTP traffic
Xbe limited to non-prime hours. For more information on this archive, please
Xcontact Steve Davis (st...@cis.ksu.edu). This collection is not maintained by
Xthe Independent JPEG Group, and programs in it may not be the latest version.
X
X
XSUPPORTING SOFTWARE
X===================
X
XYou will probably want Jef Poskanzer's PBMPLUS image software, which provides
Xmany useful operations on PPM-format image files. In particular, it can
Xconvert PPM images to and from a wide range of other formats. You can FTP
Xthis free software from export.lcs.mit.edu (contrib/pbmplus*.tar.Z) or
Xftp.ee.lbl.gov (pbmplus*.tar.Z). Unfortunately PBMPLUS is not nearly as
Xportable as the JPEG software is; you are likely to have difficulty making it
Xwork on any non-Unix machine.
X
XIf you are using X Windows you might want to use the xv or xloadimage viewers
Xto save yourself the trouble of converting PPM to some other format. Both of
Xthese can be found in the contrib directory at export.lcs.mit.edu. Actually,
Xxv version 2.00 and up incorporates our software and thus can read and write
XJPEG files directly. (NOTE: since xv internally reduces all images to 8
Xbits/pixel, a JPEG file written by xv will not be very high quality; you may
Xalso prefer xloadimage for viewing if you have a 24-bit display. Caveat user.)
X
XFor DOS machines, Lee Crocker's free Piclab program is a useful companion to
Xthe JPEG software. The latest version, currently 1.91, is available by FTP
Xfrom SIMTEL20 and its various mirror sites, file <msdos.graphics>piclb191.zip.
XCompuServe also has it, in the same library as the JPEG software.
X
X
XSOFTWARE THAT'S NO HELP AT ALL
X==============================
X
XHandmade Software's shareware PC program GIF2JPG produces files that are
Xtotally incompatible with our programs. They use a proprietary format that is
Xan amalgam of GIF and JPEG representations. However, you can force GIF2JPG
Xto produce compatible files with its -j switch, and their decompression
Xprogram JPG2GIF can read our files (at least ones produced with our default
Xoption settings).
X
XUnfortunately, many commercial JPEG implementations are also incompatible as
Xof this writing, especially programs released before summer 1991. The root of
Xthe problem is that the ISO JPEG committee failed to specify a concrete file
Xformat. Some vendors "filled in the blanks" on their own, creating
Xproprietary formats that no one else could read. (For example, none of the
Xearly commercial JPEG implementations for the Macintosh were able to exchange
Xcompressed files.)
X
XThe file format we have adopted is called JFIF (see REFERENCES). This format
Xhas been agreed to by a number of major commercial JPEG vendors, and we expect
Xthat it will become the de facto standard. JFIF is a minimal representation;
Xwork is also going forward to incorporate JPEG compression into the TIFF
Xstandard, for use in "high end" applications that need to record a lot of
Xadditional data about an image. We intend to support JPEG-in-TIFF in the
Xfuture. We hope that these two formats will be sufficient and that other,
Xincompatible JPEG file formats will not proliferate.
X
XIndeed, part of the reason for developing and releasing this free software is
Xto help force rapid convergence to de facto standards for JPEG file formats.
XSUPPORT STANDARD, NON-PROPRIETARY FORMATS: demand JFIF or JPEG-in-TIFF!
X
X
XUSING JPEG AS A SUBROUTINE IN A LARGER PROGRAM
X==============================================
X
XYou can readily incorporate the JPEG compression and decompression routines in
Xa larger program. The file example.c provides a skeleton of the interface
Xroutines you'll need for this purpose. Essentially, you replace jcmain.c (for
Xcompression) and/or jdmain.c (for decompression) with your own code. Note
Xthat the fewer JPEG options you allow the user to twiddle, the less code you
Xneed; all the default options are set up automatically. (Alternately, if you
Xknow a lot about JPEG or have a special application, you may want to twiddle
Xthe default options even more extensively than jcmain/jdmain do.)
X
XMost likely, you will want the uncompressed image to come from memory (for
Xcompression) or go to memory or the screen (for decompression). For this
Xpurpose you must provide image reading or writing routines that match the
Xinterface used by the image file I/O modules (jrdXXX or jwrXXX); again,
Xexample.c shows a skeleton of what is required.
X
XBy default, any error detected inside the JPEG routines will cause a message
Xto be printed on stderr, followed by exit(). You can override this behavior
Xby supplying your own message-printing and/or error-exit routines; again,
Xexample.c shows how.
X
XMechanics: we recommend you create libjpeg.a as shown in the Makefile, then
Xlink that with your surrounding program. (If your linker is at all
Xreasonable, only the code you actually need will get loaded.) Include the
Xfiles jconfig.h and jpegdata.h in C files that need to call the JPEG routines.
X
XCAUTION: some people have tried to compile JPEG and their surrounding code
Xwith different compilers, e.g., cc for JPEG and c++ or gcc for the rest. This
Xis a Real Bad Move and you will deserve what happens to you if you try it.
X(Hint: the parameter structures can get laid out differently with no warning.)
X
XRead our "architecture" file for more info. If it seems to you that the
Xsoftware structure doesn't accommodate what you want to do, please contact
Xthe authors.
X
XBeginning with version 3, we will endeavor to hold the interface described by
Xexample.c constant, so that you can plug in updated versions of the JPEG code
Xjust by recompiling. However, we can't guarantee this, especially if you
Xchoose to twiddle any JPEG options not listed in example.c. Check the
XCHANGELOG when installing any new version, and compare example.c against the
Xprior version. Recompile your calling software (don't just relink), as we may
Xadd or subtract fields in the parameter structures.
X
X
XREFERENCES
X==========
X
XThe best and most readily available introduction to the JPEG compression
Xalgorithm is Wallace's article in the April '91 CACM:
X Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
X Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
X(Adjacent articles in that issue discuss MPEG motion picture compression,
Xapplications of JPEG, and related topics.) We highly recommend reading that
Xarticle before trying to understand the innards of any JPEG software.
XIf you don't have the CACM issue handy, a PostScript file containing a revised
Xversion of the article is available at ftp.uu.net, graphics/jpeg/wallace.ps.Z.
XThe file (actually a preprint for an article to appear in IEEE Trans. Consumer
XElectronics) omits the sample images that appeared in CACM, but it includes
Xcorrections and some added material. Note: the Wallace article is copyright
XACM and IEEE, and it may not be used for commercial purposes.
X
XFor more detail about the JPEG standard you pretty much have to go to the
Xdraft standard (which is not nearly as intelligible as Wallace's article).
XThe standard is not now available electronically; you must order a paper copy
Xthrough ISO. In the US, copies may be ordered from ANSI Sales at (212)
X642-4900. The standard is divided into two parts: Part 1 is the actual
Xspecification, and Part 2 covers compliance testing methods. The current
X"committee draft" version of Part 1 is titled "Digital Compression and Coding
Xof Continuous-tone Still Images, Part 1: Requirements and guidelines" and has
Xdocument number ISO/IEC CD 10918-1. (The alternate number SC2 N2215 should
Xalso be mentioned when ordering.) This draft is expected to be superseded by
Xthe Draft International Standard version around the end of November 1991.
XOrdering info will be the same as above, but replace "CD" with "DIS" in the
Xdocument number (alternate number not yet known). The committee draft of
XPart 2 is expected to be available around the end of December 1991. It will
Xbe titled "Digital Compression and Coding of Continuous-tone Still Images,
XPart 2: Compliance testing" and will have document number ISO/IEC CD 10918-2
X(alternate number not yet known).
X
XThe JPEG standard does not specify all details of an interchangeable file
Xformat. For the omitted details we follow the "JFIF" conventions, revision
X1.01. A copy of the JFIF spec is available from:
X Literature Department
X C-Cube Microsystems, Inc.
X 399A West Trimble Road
X San Jose, CA 95131
X (408) 944-6300
XThe same source can supply copies of the draft JPEG-in-TIFF documents
X(Appendixes O and P to the TIFF spec). PostScript versions of these
Xdocuments can also be obtained by e-mail from the C-Cube mail server,
Xne...@c3.pla.ca.us. Send the message "send jfif_ps from jpeg" to obtain the
XJFIF document; "send app_o_ps from jpeg" and "send app_p_ps from jpeg" will
Xproduce the TIFF documents. Send the message "help" if you have trouble.
X
XIf you want to understand this implementation, start by reading the
X"architecture" documentation file. Please read "codingrules" if you want to
Xcontribute any code.
X
X
XLEGAL ISSUES
X============
X
XThe authors make NO WARRANTY or representation, either express or implied,
Xwith respect to this software, its quality, accuracy, merchantability, or
Xfitness for a particular purpose. This software is provided "AS IS", and you,
Xits user, assume the entire risk as to its quality and accuracy.
X
XThis software is copyright (C) 1991, 1992, Thomas G. Lane.
XAll Rights Reserved except as specified below.
X
XPermission is hereby granted to use, copy, modify, and distribute this
Xsoftware (or portions thereof) for any purpose, without fee, subject to these
Xconditions:
X(1) If any part of the source code for this software is distributed, then this
XREADME file must be included, with this copyright and no-warranty notice
Xunaltered; and any additions, deletions, or changes to the original files
Xmust be clearly indicated in accompanying documentation.
X(2) If only executable code is distributed, then the accompanying
Xdocumentation must state that "this software is based in part on the work of
Xthe Independent JPEG Group".
X(3) Permission for use of this software is granted only if the user accepts
Xfull responsibility for any undesirable consequences; the authors accept
XNO LIABILITY for damages of any kind.
X
XPermission is NOT granted for the use of any author's name or author's company
Xname in advertising or publicity relating to this software or products derived
Xfrom it. This software may be referred to only as "the Independent JPEG
XGroup's software".
X
XWe specifically permit and encourage the use of this software as the basis of
Xcommercial products, provided that all warranty or liability claims are
Xassumed by the product vendor.
X
X
Xansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
Xsole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
Xansi2knr.c is NOT covered by the above copyright and conditions, but instead
Xby the usual distribution terms of the Free Software Foundation; principally,
Xthat you must include source code if you redistribute it. (See the file
Xansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
Xof any product generated from the JPEG code, this does not limit you more than
Xthe foregoing paragraphs do.
X
X
XIt appears that the arithmetic coding option of the JPEG spec is covered by
Xpatents owned by IBM and AT&T, as well as a pending Japanese patent of
XMitsubishi. Hence arithmetic coding cannot legally be used without obtaining
Xone or more licenses. For this reason, support for arithmetic coding has been
Xremoved from the free JPEG software. (Since arithmetic coding provides only a
Xmarginal gain over the unpatented Huffman mode, it is unlikely that very many
Xpeople will choose to use it. If you do obtain the necessary licenses,
Xcontact jpeg...@uunet.uu.net for a copy of our arithmetic coding modules.)
XSo far as we are aware, there are no patent restrictions on the remaining
Xcode.
X
X
XWe are required to state that
X "The Graphics Interchange Format(c) is the Copyright property of
X CompuServe Incorporated. GIF(sm) is a Service Mark property of
X CompuServe Incorporated."
X
X
XTO DO
X=====
X
XMany of the modules need fleshing out to provide more complete
Ximplementations, or to provide faster paths for common cases.
XImproving the speed will be the next big work item for the JPEG group.
X
XWe'd appreciate it if people would compile and check out the code on as wide a
Xvariety of systems as possible, and report any portability problems
Xencountered (with solutions, if possible). Checks of file compatibility with
Xother JPEG implementations would also be of interest. Finally, we would
Xappreciate code profiles showing where the most time is spent, especially on
Xunusual systems.
X
XPlease send bug reports, offers of help, etc. to jpeg...@uunet.uu.net.
END_OF_FILE
if test 18730 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'arch.a' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'arch.a'\"
else
echo shar: Extracting \"'arch.a'\" \(29060 characters\)
sed "s/^X//" >'arch.a' <<'END_OF_FILE'
X
X JPEG SYSTEM ARCHITECTURE 29-FEB-92
X
X
XThis file provides an overview of the "architecture" of the portable JPEG
Xsoftware; that is, the functions of the various modules in the system and the
Xinterfaces between modules. For more precise details about any data structure
Xor calling convention, see the header files.
X
XImportant note: when I say "module" I don't mean "a C function", which is what
Xsome people seem to think the term means. A separate C source file is closer
Xto the mark. Also, it is frequently the case that several different modules
Xpresent a common interface to callers; the term "object" or "method" refers to
Xthis common interface (see "Poor man's object-oriented programming", below).
X
XJPEG-specific terminology follows the JPEG standard:
X A "component" means a color channel, e.g., Red or Luminance.
X A "sample" is a pixel component value (i.e., one number in the image data).
X A "coefficient" is a frequency coefficient (a DCT transform output number).
X The term "block" refers to an 8x8 group of samples or coefficients.
X "MCU" (minimum coded unit) is the same as "MDU" of the R8 draft; i.e., an
X interleaved set of blocks of size determined by the sampling factors,
X or a single block in a noninterleaved scan.
X
X
X*** System requirements ***
X
XWe must support compression and decompression of both Huffman and
Xarithmetic-coded JPEG files. Any set of compression parameters allowed by the
XJPEG spec should be readable for decompression. (We can be more restrictive
Xabout what formats we can generate.) (Note: for legal reasons no arithmetic
Xcoding implementation is currently included in the publicly available sources.
XHowever, the architecture still supports it.)
X
XWe need to be able to handle both raw JPEG files (more specifically, the JFIF
Xformat) and JPEG-in-TIFF (C-cubed's format, and perhaps Kodak's). Even if we
Xdon't implement TIFF ourselves, other people will want to use our code for
Xthat. This means that generation and scanning of the file header has to be
Xseparated out.
X
XPerhaps we should be prepared to support the JPEG lossless mode (also referred
Xto in the spec as spatial DPCM coding). A lot of people seem to believe they
Xneed this... whether they really do is debatable, but the customer is always
Xright. On the other hand, there will not be much sharable code between the
Xlossless and lossy modes! At best, a lossless program could be derived from
Xparts of the lossy version. For now we will only worry about the lossy mode.
X
XI see no real value in supporting the JPEG progressive modes (note that
Xspectral selection and successive approximation are two different progressive
Xmodes). These are only of interest when painting the decompressed image in
Xreal-time, which nobody is going to do with a pure software implementation.
X
XThere is some value in supporting the hierarchical mode, which allows for
Xsuccessive frames of higher resolution. This could be of use for including
X"thumbnail" representations. However, this appears to add a lot more
Xcomplexity than it is worth.
X
XA variety of uncompressed image file formats and user interfaces must be
Xsupported. These aspects therefore have to be kept separate from the rest of
Xthe system. A particularly important issue is whether color quantization of
Xthe output is needed (i.e., whether a colormap is used). We should be able to
Xsupport both adaptive quantization (which requires two or more passes over the
Ximage) and nonadaptive (quantization to a prespecified colormap, which can be
Xdone in one pass).
X
XMemory usage is an important concern, since we will port this code to 80x86
Xand other limited-memory machines. For large intermediate structures, we
Xshould be able to use either virtual memory or temporary files.
X
XIt should be possible to build programs that handle compression only,
Xdecompression only, or both, without much duplicate or unused code in any
Xversion. (In particular, a decompression-only version should have no extra
Xbaggage.)
X
X
X*** Compression overview ***
X
XThe *logical* steps needed in (non-lossless) JPEG compression are:
X
X1. Conversion from incoming image format to a standardized internal form
X (either RGB or grayscale).
X
X2. Color space conversion (e.g., RGB to YCbCr). This is a null step for
X grayscale (unless we support mapping color inputs to grayscale, which
X would most easily be done here). Gamma adjustment may also be needed here.
X
X3. Subsampling (reduction of number of samples in some color components).
X This step operates independently on each color component.
X
X4. MCU extraction (creation of a single sequence of 8x8 sample blocks).
X This step and the following ones are performed once for each scan
X in the output JPEG file, i.e., once if making an interleaved file and more
X than once for a noninterleaved file.
X Note: both this step and the previous one must deal with edge conditions
X for pictures that aren't a multiple of the MCU dimensions. Alternately,
X we could expand the picture to a multiple of an MCU before doing these
X two steps. (The latter seems better and has been adopted below.)
X
X5. DCT transformation of each 8x8 block.
X
X6. Quantization scaling and zigzag reordering of the elements in each 8x8
X block.
X
X7. Huffman or arithmetic encoding of the transformed block sequence.
X
X8. Output of the JPEG file with whatever headers/markers are wanted.
X
XOf course, the actual implementation will combine some of these logical steps
Xfor efficiency. The trick is to keep these logical functions as separate as
Xpossible without losing too much performance.
X
XIn addition to these logical pipeline steps, we need various modules that
Xaren't part of the data pipeline. These are:
X
XA. Overall control (sequencing of other steps & management of data passing).
X
XB. User interface; this will determine the input and output files, and supply
X values for some compression parameters. Note that this module is highly
X platform-dependent.
X
XC. Compression parameter selection: some parameters should be chosen
X automatically rather than requiring the user to find a good value.
X The prototype only does this for the back-end (Huffman or arithmetic)
X parameters, but further in the future, more might be done. A
X straightforward approach to selection is to try several values; this
X requires being able to repeatedly apply some portion of the pipeline and
X inspect the results (without actually outputting them). Probably only
X entropy encoding parameters can reasonably be done this way; optimizing
X earlier steps would require too much data to be reprocessed (not to mention
X the problem of interactions between parameters for different steps).
X What other facilities do we need to support automatic parameter selection?
X
XD. A memory management module to deal with small-memory machines. This must
X create the illusion of virtual memory for certain large data structures
X (e.g., the subsampled image or the transformed coefficients).
X The interface to this must be defined to minimize the overhead incurred,
X especially on virtual-memory machines where the module won't do much.
X
XIn many cases we can arrange things so that a data stream is produced in
Xsegments by one module and consumed by another without the need to hold it all
Xin (virtual) memory. This is obviously not possible for any data that must be
Xscanned more than once, so it won't work everywhere.
X
XThe major variable at this level of detail is whether the JPEG file is to be
Xinterleaved or not; that affects the order of processing so fundamentally that
Xthe central control module must know about it. Some of the other modules may
Xneed to know it too. It would simplify life if we didn't need to support
Xnoninterleaved images, but that is not reasonable.
X
XMany of these steps operate independently on each color component; the
Xknowledge of how many components there are, and how they are interleaved,
Xought to be confined to the central control module. (Color space conversion
Xand MCU extraction probably have to know it too.)
X
X
X*** Decompression overview ***
X
XDecompression is roughly the inverse process from compression, but there are
Xsome additional steps needed to produce a good output image.
X
XThe *logical* steps needed in (non-lossless) JPEG decompression are:
X
X1. Scanning of the JPEG file, decoding of headers/markers etc.
X
X2. Huffman or arithmetic decoding of the coefficient sequence.
X
X3. Quantization descaling and zigzag reordering of the elements in each 8x8
X block.
X
X4. MCU disassembly (conversion of a possibly interleaved sequence of 8x8
X blocks back to separate components in pixel map order).
X
X5. (Optional) Cross-block smoothing per JPEG section K.8 or a similar
X algorithm. (Steps 5-8 operate independently on each component.)
X
X6. Inverse DCT transformation of each 8x8 block.
X
X7. De-subsampling. At this point a pixel image of the original dimensions
X has been recreated.
X
X8. Post-subsampling smoothing. This can be combined with de-subsampling,
X by using a convolution-like calculation to generate each output pixel
X directly from one or more input pixels.
X
X9. Cropping to the original pixel dimensions (throwing away duplicated
X pixels at the edges). It is most convenient to do this now, as the
X preceding steps are simplified by not having to worry about odd picture
X sizes.
X
X10. Color space reconversion (e.g., YCbCr to RGB). This is a null step for
X grayscale. (Note that mapping a color JPEG to grayscale output is most
X easily done in this step.) Gamma adjustment may also be needed here.
X
X11. Color quantization (only if a colormapped output format is requested).
X NOTE: it is probably preferable to perform quantization in the internal
X (JPEG) colorspace rather than the output colorspace. Doing it that way,
X color conversion need only be applied to the colormap entries, not to
X every pixel; and quantization gets to operate in a non-gamma-corrected
X space. But the internal space may not be suitable for some algorithms.
X The system design is such that only the color quantizer module knows
X whether color conversion happens before or after quantization.
X
X12. Writing of the desired image format.
X
XAs before, some of these will be combined into single steps. When dealing
Xwith a noninterleaved JPEG file, steps 2-9 will be performed once for each
Xscan; the resulting data will need to be buffered up so that steps 10-12 can
Xprocess all the color components together.
X
XThe same auxiliary modules are needed as before, except for compression
Xparameter selection. Note that rerunning a pipeline stage should never be
Xneeded during decompression. This may allow a simpler control module. The
Xuser interface might also be simpler since it need not supply any compression
Xparameters.
X
XAs before, not all of these steps require the whole image to be stored.
XActually, two-pass color quantization is the only step that logically requires
Xthis; everything else could be done a few raster lines at a time (at least for
Xinterleaved images). We might want to make color quantization be a separate
Xprogram because of this fact.
X
XAgain, many of the steps should be able to work on one color component in
Xignorance of the other components.
X
X
X*** Implications of noninterleaved formats ***
X
XMuch of the work can be done in a single pass if an interleaved JPEG file
Xformat is used. With a noninterleaved JPEG file, separating or recombining
Xthe components will force use of virtual memory (on a small-memory machine,
Xwe probably would want one temp file per color component).
X
XIf any of the image formats we read or write are noninterleaved, the opposite
Xcondition might apply: processing a noninterleaved JPEG file would be more
Xefficient. Offhand, though, I can't think of any popular image formats that
Xwork that way; besides the win would only come if the same color space were
Xused in JPEG and non-JPEG files. It's not worth the complexity to make the
Xsystem design accommodate that case efficiently.
X
XAn argument against interleaving is that it makes the decompressor need more
Xmemory for cross-block smoothing (since the minimum processable chunk of the
Ximage gets bigger). With images more than 1000 pixels across, 80x86 machines
Xare likely to have difficulty in handling this feature.
X
XAnother argument against interleaving is that the noninterleaved format allows
Xa wider range of sampling factors, since the limit of ten blocks per MCU no
Xlonger applies. We could get around this by blithely ignoring the spec's
Xlimit of ten blocks, but that seems like a bad idea (especially since it makes
Xthe above problem worse).
X
XThe upshot is that we need to support both interleaved and noninterleaved JPEG
Xformats, since for any given machine and picture size one may be much more
Xefficient than the other. However, the non-JPEG format we convert to or from
Xwill be assumed to be an interleaved format (i.e., it produces or stores all
Xthe components of a pixel together).
X
XI do not think it is necessary for the compressor to be able to output
Xpartially-interleaved formats (multiple scans, some of which interleave a
Xsubset of the components). However, the decompressor must be able to read
Xsuch files to conform to the spec.
X
X
X*** Data formats ***
X
XPipeline steps that work on pixel sample values will use the following data
Xstructure:
X
X typedef something JSAMPLE; a pixel component value, 0..MAXJSAMPLE
X typedef JSAMPLE *JSAMPROW; ptr to a row of samples
X typedef JSAMPROW *JSAMPARRAY; ptr to a list of rows
X typedef JSAMPARRAY *JSAMPIMAGE; ptr to a list of color-component arrays
X
XThe basic element type JSAMPLE will be one of unsigned char, (signed) char, or
Xunsigned short. Unsigned short will be used if samples wider than 8 bits are
Xto be supported (this is a compile-time option). Otherwise, unsigned char is
Xused if possible. If the compiler only supports signed chars, then it is
Xnecessary to mask off the value when reading. Thus, all reads of sample
Xvalues should be coded as "GETJSAMPLE(value)", where the macro will be defined
Xas "((value)&0xFF)" on signed-char machines and "(value)" elsewhere.
X
XWith these conventions, JSAMPLE values can be assumed to be >= 0. This should
Xsimplify correct rounding during subsampling, etc. The JPEG draft's
Xspecification that sample values run from -128..127 will be accommodated by
Xsubtracting 128 just as the sample value is copied into the source array for
Xthe DCT step (this will be an array of signed shorts or longs). Similarly,
Xduring decompression the output of the IDCT step will be immediately shifted
Xback to 0..255. (NB: different values are required when 12-bit samples are in
Xuse. The code should be written in terms of MAXJSAMPLE and CENTERJSAMPLE,
Xwhich will be #defined as 255 and 128 respectively in an 8-bit implementation,
Xand as 4095 and 2048 in a 12-bit implementation.)
X
XOn compilers that don't support "unsigned short", signed short can be used for
Xa 12-bit implementation. To support lossless coding (which allows up to
X16-bit data precision) masking with 0xFFFF in GETJSAMPLE might be necessary.
X(But if "int" is 16 bits then using "unsigned int" is the best solution.)
X
XNotice that we use a pointer per row, rather than a two-dimensional JSAMPLE
Xarray. This choice costs only a small amount of memory and has several
Xbenefits:
X
X* Code using the data structure doesn't need to know the allocated width of
Xthe rows. This will simplify edge expansion/compression, since we can work
Xin an array that's wider than the logical picture width.
X
X* The rows forming a component array may be allocated at different times
Xwithout extra copying. This will simplify working a few scanlines at a time,
Xespecially in smoothing steps that need access to the previous and next rows.
X
X* Indexing doesn't require multiplication; this is a performance win on many
Xmachines.
X
XNote that each color component is stored in a separate array; we don't use the
Xtraditional structure in which the components of a pixel are stored together.
XThis simplifies coding of steps that work on each component independently,
Xbecause they don't need to know how many components there are. Furthermore,
Xwe can read or write each component to a temp file independently, which is
Xhelpful when dealing with noninterleaved JPEG files.
X
XA specific sample value will be accessed by code such as
X GETJSAMPLE(image[colorcomponent][row][col])
Xwhere col is measured from the image left edge, but row is measured from the
Xfirst sample row currently in memory. Either of the first two indexings can
Xbe precomputed by copying the relevant pointer.
X
X
XPipeline steps that work on frequency-coefficient values will use the
Xfollowing data structure:
X
X typedef short JCOEF; a 16-bit signed integer
X typedef JCOEF JBLOCK[64]; an 8x8 block of coefficients
X typedef JBLOCK *JBLOCKROW; ptr to one horizontal row of 8x8 blocks
X typedef JBLOCKROW *JBLOCKARRAY; ptr to a list of such rows
X typedef JBLOCKARRAY *JBLOCKIMAGE; ptr to a list of color component arrays
X
XThe underlying type is always a 16-bit signed integer (this is "short" on all
Xmachines of interest, but let's use the typedef name anyway). These are
Xgrouped into 8x8 blocks (we should use #defines DCTSIZE and DCTSIZE2 rather
Xthan "8" and "64"). The contents of a block may be either in "natural" or
Xzigzagged order, and may be true values or divided by the quantization
Xcoefficients, depending on where the block is in the pipeline.
X
XNotice that the allocation unit is now a row of 8x8 blocks, corresponding to
Xeight rows of samples. Otherwise the structure is much the same as for
Xsamples, and for the same reasons.
X
XOn machines where malloc() can't handle a request bigger than 64Kb, this data
Xstructure limits us to rows of less than 512 JBLOCKs, which would be a picture
Xwidth of 4000 pixels. This seems an acceptable restriction.
X
X
XOn 80x86 machines, the bottom-level pointer types (JSAMPROW and JBLOCKROW)
Xmust be declared as "far" pointers, but the upper levels can be "near"
X(implying that the pointer lists are allocated in the DS segment).
XTo simplify sharing code, we'll have a #define symbol FAR, which expands to
Xthe "far" keyword when compiling on 80x86 machines and to nothing elsewhere.
X
X
XThe data arrays used as input and output of the DCT transform subroutine will
Xbe declared using a separate typedef; they could be arrays of "short", "int"
Xor "long" independently of the above choices. This would depend on what is
Xneeded to make the compiler generate correct and efficient multiply/add code
Xin the DCT inner loops. No significant speed or memory penalty will be paid
Xto have a different representation than is used in the main image storage
Xarrays, since some additional value-by-value processing is done at the time of
Xcreation or extraction of the DCT data anyway (e.g., add/subtract 128).
X
X
X*** Poor man's object-oriented programming ***
X
XIt should be pretty clear by now that we have a lot of quasi-independent
Xsteps, many of which have several possible behaviors. To avoid cluttering the
Xcode with lots of switch statements, we'll use a simple form of object-style
Xprogramming to separate out the different possibilities.
X
XFor example, Huffman and arithmetic coding will be implemented as two separate
Xmodules that present the same external interface; at runtime, the calling code
Xwill access the proper module indirectly through an "object".
X
XWe can get the limited features we need while staying within portable C. The
Xbasic tool is a function pointer. An "object" is just a struct containing one
Xor more function pointer fields, each of which corresponds to a method name in
Xreal object-oriented languages. During initialization we fill in the function
Xpointers with references to whichever module we have determined we need to use
Xin this run. Then invocation of the module is done by indirecting through a
Xfunction pointer; on most architectures this is no more expensive (and
Xpossibly cheaper) than a switch, which would be the only other way of making
Xthe required run-time choice. The really significant benefit, of course, is
Xkeeping the source code clean and well structured.
X
XFor example, the interface for entropy decoding (Huffman or arithmetic
Xdecoding) might look like this:
X
X struct function_ptr_struct {
X ...
X /* Entropy decoding methods */
X void (*prepare_for_scan) ();
X void (*get_next_mcu) ();
X ...
X };
X
X typedef struct function_ptr_struct * function_ptrs;
X
XThe struct pointer is what will actually be passed around. A call site might
Xlook like this:
X
X some_function (function_ptrs fptrs)
X {
X ...
X (*fptrs->get_next_mcu) (...);
X ...
X }
X
X(It might be worth inventing some specialized macros to hide the rather ugly
Xsyntax for method definition and call.) Note that the caller doesn't know how
Xmany different get_next_mcu procedures there are, what their real names are,
Xnor how to choose which one to call.
X
XAn important benefit of this scheme is that it is easy to provide multiple
Xversions of any method, each tuned to a particular case. While a lot of
Xprecalculation might be done to select an optimal implementation of a method,
Xthe cost per invocation is constant. For example, the MCU extraction step
Xmight have a "generic" method, plus one or more "hardwired" methods for the
Xmost popular sampling factors; the hardwired methods would be faster because
Xthey'd use straight-line code instead of for-loops. The cost to determine
Xwhich method to use is paid only once, at startup, and the selection criteria
Xare hidden from the callers of the method.
X
XThis plan differs a little bit from usual object-oriented structures, in that
Xonly one instance of each object class will exist during execution. The
Xreason for having the class structure is that on different runs we may create
Xdifferent instances (choose to execute different modules).
X
XTo minimize the number of object pointers that have to be passed around, it
Xwill be easiest to have just a few big structs containing all the method
Xpointers. We'll actually use two such structs, one for "system-dependent"
Xmethods (memory allocation and error handling) and one for everything else.
X
XBecause of this choice, it's best not to think of an "object" as a specific
Xdata structure. Rather, an "object" is just a group of related methods.
XThere would typically be one or more C modules (source files) providing
Xconcrete implementations of those methods. You can think of the term
X"method" as denoting the common interface presented by some set of functions,
Xand "object" as denoting a group of common method interfaces, or the total
Xshared interface behavior of a group of modules.
X
X
X*** Data chunk sizes ***
X
XTo make the cost of this object-oriented style really minimal, we should make
Xsure that each method call does a fair amount of computation. To do that we
Xshould pass large chunks of data around; for example, the colorspace
Xconversion method should process much more than one pixel per call.
X
XFor many steps, the most natural unit of data seems to be an "MCU row".
XThis consists of one complete horizontal strip of the image, as high as an
XMCU. In a noninterleaved scan, an MCU row is always eight samples high (when
Xlooking at samples) or one 8x8 block high (when looking at coefficients). In
Xan interleaved scan, an MCU row consists of all the data for one horizontal
Xrow of MCUs; this may be from one to four blocks high (eight to thirty-two
Xsamples) depending on the sampling factors. The height and width of an MCU
Xrow may be different in each component. (Note that the height and width of an
XMCU row changes at the subsampling and de-subsampling steps. An unsubsampled
Ximage has the same size in each component. The preceding statements apply to
Xthe subsampled dimensions.)
X
XFor example, consider a 1024-pixel-wide image using (2h:2v)(1h:1v)(1h:1v)
Xsubsampling. In the noninterleaved case, an MCU row of Y would contain 8x1024
Xsamples or the same number of frequency coefficients, so it would occupy
X8K bytes (samples) or 16K bytes (coefficients). An MCU row of Cb or Cr would
Xcontain 8x512 samples and occupy half as much space. In the interleaved case,
Xan MCU row would contain 16x1024 Y samples, 8x512 Cb and 8x512 Cr samples, so
Xa total of 24K (samples) or 48K (coefficients) would be needed. This is a
Xreasonable amount of data to expect to retain in memory at one time. (Bear in
Xmind that we'll usually need to have several MCU rows resident in memory at
Xonce, at the inputs and outputs to various pipeline steps.)
X
XThe worst case is probably (2h:4v)(1h:1v)(1h:1v) interleaving (this uses 10
Xblocks per MCU, which is the maximum allowed by the spec). An MCU will then
Xcontain 32 sample rows worth of Y, so it would occupy 40K or 80K bytes for a
X1024-pixel-wide image. The most memory-intensive step is probably cross-block
Xsmoothing, for which we'd need 3 MCU rows of coefficients as input and another
Xone as output; that would be 320K of working storage. Anything much larger
Xwould not fit in an 80x86 machine. (To decompress wider pictures on an 80x86,
Xwe'll have to skip cross-block smoothing or else use temporary files.)
X
XThis unit is thus a reasonable-sized chunk for passing through the pipeline.
XOf course, its major advantage is that it is a natural chunk size for the MCU
Xassembly and disassembly steps to work with.
X
XFor the entropy (Huffman or arithmetic) encoding/decoding steps, the most
Xconvenient chunk is a single MCU: one 8x8 block if not interleaved, three to
Xten such blocks if interleaved. The advantage of this is that when handling
Xinterleaved data, the blocks have the same sequence of component membership on
Xeach call. (For example, Y,Y,Y,Y,Cb,Cr when using (2h:2v)(1h:1v)(1h:1v)
Xsubsampling.) The code needs to know component membership so that it can
Xapply the right set of compression coefficients to each block. A prebuilt
Xarray describing this membership can be used during each call. This chunk
Xsize also makes it easy to handle restart intervals: just count off one MCU
Xper call and reinitialize when the count reaches zero (restart intervals are
Xspecified in numbers of MCU).
X
XFor similar reasons, one MCU is also the best chunk size for the frequency
Xcoefficient quantization and dequantization steps.
X
XFor subsampling and desubsampling, the best chunk size is to have each call
Xtransform Vk sample rows from or to Vmax sample rows (Vk = this component's
Xvertical sampling factor, Vmax = largest vertical sampling factor). There are
Xeight such chunks in each MCU row. Using a whole MCU row as the chunk size
Xwould reduce function call overhead a fraction, but would imply more buffering
Xto provide context for cross-pixel smoothing.
X
X
X*** Compression object structure ***
X
XI propose the following set of objects for the compressor. Here an "object"
Xis the common interface for one or more modules having comparable functions.
X
XMost of these objects can be justified as information-hiding modules.
XI've indicated what information is private to each object/module.
X
XNote that in all cases, the caller of a method is expected to have allocated
Xany storage needed for it to return its result. (Typically this storage can
Xbe re-used in successive calls, so malloc'ing and free'ing once per call is
Xnot reasonable.) Also, much of the context required (compression parameters,
Ximage size, etc) will be passed around in large common data structures, which
Xaren't described here; see the header files. Notice that any object that
Xmight need to allocate working storage receives an "init" and a "term" call;
X"term" should be careful to free all allocated storage so that the JPEG system
Xcan be used multiple times during a program run. (For the same reason,
Xdepending on static initialization of variables is a no-no. The only
Xexception to the free-all-allocated-storage rule is that storage allocated for
Xthe entire processing of an image need not be explicitly freed, since the
Xmemory manager's free_all cleanup will free it.)
X
X1. Input file conversion to standardized form. This provides these methods:
X input_init: read the file header, report image size & component count.
X get_input_row: read one pixel row, return it in our standard format.
X input_term: finish up at the end.
X In implementations that support multiple input formats, input_init could
X set up an appropriate get_input_row method depending on the format it
X finds. Note that in most applications, the selection and opening of the
X input file will be under the control of the user interface module; and
X indeed the user interface may have already read the input header, so that
X all that input_init may have to do is return previously saved values. The
X behind-the-scenes interaction between this object and the user interface is
X not specified by this architecture.
X (Hides format of input image and mechanism used to read it. This code is
X likely to vary considerably from one implementation to another. Note that
X the color space and number of color components of the source are not hidden;
X but they are used only by the next object.)
X
END_OF_FILE
if test 29060 -ne `wc -c <'arch.a'`; then
echo shar: \"'arch.a'\" unpacked with wrong size!
elif [ -f arch.b ]; then
echo shar: Combining \"'arch.a'\" and \"'arch.b'\" into \"'architecture'\"
cat arch.a arch.b > architecture
echo shar: Removing \"'arch.a'\" and \"'arch.b'\"
rm arch.a arch.b
# end of 'arch.a'
fi
fi
if test -f 'makefile.vms' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.vms'\"
else
echo shar: Extracting \"'makefile.vms'\" \(2044 characters\)
sed "s/^X//" >'makefile.vms' <<'END_OF_FILE'
X$! Makefile for Independent JPEG Group's software
X$!
X$! This is a command procedure for use on VAX/VMS systems that do not have MMS.
X$! It builds the JPEG software by brute force, recompiling everything whether
X$! or not it is necessary.
X$! Thanks to Rick Dyson (dy...@iowasp.physics.uiowa.edu) for his help.
X$!
X$! Read SETUP instructions before running this!!
X$!
X$ DoCompile := CC /NoDebug /Optimize /Define = (TWO_FILE_COMMANDLINE,HAVE_STDC,INCLUDES_ARE_ANSI)
X$!
X$ DoCompile jcmain.c
X$ DoCompile jdmain.c
X$ DoCompile jcmaster.c
X$ DoCompile jcdeflts.c
X$ DoCompile jcarith.c
X$ DoCompile jccolor.c
X$ DoCompile jcexpand.c
X$ DoCompile jchuff.c
X$ DoCompile jcmcu.c
X$ DoCompile jcpipe.c
X$ DoCompile jcsample.c
X$ DoCompile jfwddct.c
X$ DoCompile jwrjfif.c
X$ DoCompile jrdgif.c
X$ DoCompile jrdppm.c
X$ DoCompile jrdrle.c
X$ DoCompile jrdtarga.c
X$ DoCompile jdmaster.c
X$ DoCompile jddeflts.c
X$ DoCompile jbsmooth.c
X$ DoCompile jdarith.c
X$ DoCompile jdcolor.c
X$ DoCompile jdhuff.c
X$ DoCompile jdmcu.c
X$ DoCompile jdpipe.c
X$ DoCompile jdsample.c
X$ DoCompile jquant1.c
X$ DoCompile jquant2.c
X$ DoCompile jrevdct.c
X$ DoCompile jrdjfif.c
X$ DoCompile jwrgif.c
X$ DoCompile jwrppm.c
X$ DoCompile jwrrle.c
X$ DoCompile jwrtarga.c
X$ DoCompile jutils.c
X$ DoCompile jerror.c
X$ DoCompile jmemmgr.c
X$ DoCompile jmemsys.c
X$!
X$ Library /Create libjpeg.olb jcmaster.obj,jcdeflts.obj,jcarith.obj, -
X jccolor.obj,jcexpand.obj,jchuff.obj,jcmcu.obj,jcpipe.obj, -
X jcsample.obj,jfwddct.obj,jwrjfif.obj,jrdgif.obj,jrdppm.obj, -
X jrdrle.obj,jrdtarga.obj,jdmaster.obj,jddeflts.obj,jbsmooth.obj, -
X jdarith.obj,jdcolor.obj,jdhuff.obj,jdmcu.obj,jdpipe.obj, -
X jdsample.obj,jquant1.obj,jquant2.obj,jrevdct.obj,jrdjfif.obj, -
X jwrgif.obj,jwrppm.obj,jwrrle.obj,jwrtarga.obj,jutils.obj, -
X jerror.obj,jmemmgr.obj,jmemsys.obj
X$!
X$ Link /Executable = cjpeg.exe jcmain.obj,libjpeg.olb/Library,Sys$Disk:[]MAKVMS.OPT/Option
X$!
X$ Link /Executable = djpeg.exe jdmain.obj,libjpeg.olb/Library,Sys$Disk:[]MAKVMS.OPT/Option
X$!
X$ Exit
END_OF_FILE
if test 2044 -ne `wc -c <'makefile.vms'`; then
echo shar: \"'makefile.vms'\" unpacked with wrong size!
fi
# end of 'makefile.vms'
fi
echo shar: End of archive 1 \(of 18\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 18 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jquant2.c jrdppm.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:40 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 2 (of 18)."'
if test -f 'jquant2.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jquant2.c'\"
else
echo shar: Extracting \"'jquant2.c'\" \(42181 characters\)
sed "s/^X//" >'jquant2.c' <<'END_OF_FILE'
X/*
X * jquant2.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains 2-pass color quantization (color mapping) routines.
X * These routines are invoked via the methods color_quant_prescan,
X * color_quant_doit, and color_quant_init/term.
X */
X
X#include "jinclude.h"
X
X#ifdef QUANT_2PASS_SUPPORTED
X
X
X/*
X * This module implements the well-known Heckbert paradigm for color
X * quantization. Most of the ideas used here can be traced back to
X * Heckbert's seminal paper
X * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display",
X * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
X *
X * In the first pass over the image, we accumulate a histogram showing the
X * usage count of each possible color. (To keep the histogram to a reasonable
X * size, we reduce the precision of the input; typical practice is to retain
X * 5 or 6 bits per color, so that 8 or 4 different input values are counted
X * in the same histogram cell.) Next, the color-selection step begins with a
X * box representing the whole color space, and repeatedly splits the "largest"
X * remaining box until we have as many boxes as desired colors. Then the mean
X * color in each remaining box becomes one of the possible output colors.
X * The second pass over the image maps each input pixel to the closest output
X * color (optionally after applying a Floyd-Steinberg dithering correction).
X * This mapping is logically trivial, but making it go fast enough requires
X * considerable care.
X *
X * Heckbert-style quantizers vary a good deal in their policies for choosing
X * the "largest" box and deciding where to cut it. The particular policies
X * used here have proved out well in experimental comparisons, but better ones
X * may yet be found.
X *
X * The most significant difference between this quantizer and others is that
X * this one is intended to operate in YCbCr colorspace, rather than RGB space
X * as is usually done. Actually we work in scaled YCbCr colorspace, where
X * Y distances are inflated by a factor of 2 relative to Cb or Cr distances.
X * The empirical evidence is that distances in this space correspond to
X * perceptual color differences more closely than do distances in RGB space;
X * and working in this space is inexpensive within a JPEG decompressor, since
X * the input data is already in YCbCr form. (We could transform to an even
X * more perceptually linear space such as Lab or Luv, but that is very slow
X * and doesn't yield much better results than scaled YCbCr.)
X */
X
X#define Y_SCALE 2 /* scale Y distances up by this much */
X
X#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */
X
X
X/*
X * First we have the histogram data structure and routines for creating it.
X *
X * For work in YCbCr space, it is useful to keep more precision for Y than
X * for Cb or Cr. We recommend keeping 6 bits for Y and 5 bits each for Cb/Cr.
X * If you have plenty of memory and cycles, 6 bits all around gives marginally
X * better results; if you are short of memory, 5 bits all around will save
X * some space but degrade the results.
X * To maintain a fully accurate histogram, we'd need to allocate a "long"
X * (preferably unsigned long) for each cell. In practice this is overkill;
X * we can get by with 16 bits per cell. Few of the cell counts will overflow,
X * and clamping those that do overflow to the maximum value will give close-
X * enough results. This reduces the recommended histogram size from 256Kb
X * to 128Kb, which is a useful savings on PC-class machines.
X * (In the second pass the histogram space is re-used for pixel mapping data;
X * in that capacity, each cell must be able to store zero to the number of
X * desired colors. 16 bits/cell is plenty for that too.)
X * Since the JPEG code is intended to run in small memory model on 80x86
X * machines, we can't just allocate the histogram in one chunk. Instead
X * of a true 3-D array, we use a row of pointers to 2-D arrays. Each
X * pointer corresponds to a Y value (typically 2^6 = 64 pointers) and
X * each 2-D array has 2^5^2 = 1024 or 2^6^2 = 4096 entries. Note that
X * on 80x86 machines, the pointer row is in near memory but the actual
X * arrays are in far memory (same arrangement as we use for image arrays).
X */
X
X#ifndef HIST_Y_BITS /* so you can override from Makefile */
X#define HIST_Y_BITS 6 /* bits of precision in Y histogram */
X#endif
X#ifndef HIST_C_BITS /* so you can override from Makefile */
X#define HIST_C_BITS 5 /* bits of precision in Cb/Cr histogram */
X#endif
X
X#define HIST_Y_ELEMS (1<<HIST_Y_BITS) /* # of elements along histogram axes */
X#define HIST_C_ELEMS (1<<HIST_C_BITS)
X
X/* These are the amounts to shift an input value to get a histogram index.
X * For a combination 8/12 bit implementation, would need variables here...
X */
X
X#define Y_SHIFT (BITS_IN_JSAMPLE-HIST_Y_BITS)
X#define C_SHIFT (BITS_IN_JSAMPLE-HIST_C_BITS)
X
X
Xtypedef UINT16 histcell; /* histogram cell; MUST be an unsigned type */
X
Xtypedef histcell FAR * histptr; /* for pointers to histogram cells */
X
Xtypedef histcell hist1d[HIST_C_ELEMS]; /* typedefs for the array */
Xtypedef hist1d FAR * hist2d; /* type for the Y-level pointers */
Xtypedef hist2d * hist3d; /* type for top-level pointer */
X
Xstatic hist3d histogram; /* pointer to the histogram */
X
X
X/*
X * Prescan some rows of pixels.
X * In this module the prescan simply updates the histogram, which has been
X * initialized to zeroes by color_quant_init.
X * Note: workspace is probably not useful for this routine, but it is passed
X * anyway to allow some code sharing within the pipeline controller.
X */
X
XMETHODDEF void
Xcolor_quant_prescan (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE image_data, JSAMPARRAY workspace)
X{
X register JSAMPROW ptr0, ptr1, ptr2;
X register histptr histp;
X register int c0, c1, c2;
X int row;
X long col;
X long width = cinfo->image_width;
X
X for (row = 0; row < num_rows; row++) {
X ptr0 = image_data[0][row];
X ptr1 = image_data[1][row];
X ptr2 = image_data[2][row];
X for (col = width; col > 0; col--) {
X /* get pixel value and index into the histogram */
X c0 = GETJSAMPLE(*ptr0++) >> Y_SHIFT;
X c1 = GETJSAMPLE(*ptr1++) >> C_SHIFT;
X c2 = GETJSAMPLE(*ptr2++) >> C_SHIFT;
X histp = & histogram[c0][c1][c2];
X /* increment, check for overflow and undo increment if so. */
X /* We assume unsigned representation here! */
X if (++(*histp) == 0)
X (*histp)--;
X }
X }
X}
X
X
X/*
X * Now we have the really interesting routines: selection of a colormap
X * given the completed histogram.
X * These routines work with a list of "boxes", each representing a rectangular
X * subset of the input color space (to histogram precision).
X */
X
Xtypedef struct {
X /* The bounds of the box (inclusive); expressed as histogram indexes */
X int c0min, c0max;
X int c1min, c1max;
X int c2min, c2max;
X /* The number of nonzero histogram cells within this box */
X long colorcount;
X } box;
Xtypedef box * boxptr;
X
Xstatic boxptr boxlist; /* array with room for desired # of boxes */
Xstatic int numboxes; /* number of boxes currently in boxlist */
X
Xstatic JSAMPARRAY my_colormap; /* the finished colormap (in YCbCr space) */
X
X
XLOCAL boxptr
Xfind_biggest_color_pop (void)
X/* Find the splittable box with the largest color population */
X/* Returns NULL if no splittable boxes remain */
X{
X register boxptr boxp;
X register int i;
X register long max = 0;
X boxptr which = NULL;
X
X for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
X if (boxp->colorcount > max) {
X if (boxp->c0max > boxp->c0min || boxp->c1max > boxp->c1min ||
X boxp->c2max > boxp->c2min) {
X which = boxp;
X max = boxp->colorcount;
X }
X }
X }
X return which;
X}
X
X
XLOCAL boxptr
Xfind_biggest_volume (void)
X/* Find the splittable box with the largest (scaled) volume */
X/* Returns NULL if no splittable boxes remain */
X{
X register boxptr boxp;
X register int i;
X register INT32 max = 0;
X register INT32 norm, c0,c1,c2;
X boxptr which = NULL;
X
X /* We use 2-norm rather than real volume here.
X * Some care is needed since the differences are expressed in
X * histogram-cell units; if HIST_Y_BITS != HIST_C_BITS, we have to
X * adjust the scaling to get the proper scaled-YCbCr-space distance.
X * This code won't work right if HIST_Y_BITS < HIST_C_BITS,
X * but that shouldn't ever be true.
X * Note norm > 0 iff box is splittable, so need not check separately.
X */
X
X for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
X c0 = (boxp->c0max - boxp->c0min) * Y_SCALE;
X c1 = (boxp->c1max - boxp->c1min) << (HIST_Y_BITS-HIST_C_BITS);
X c2 = (boxp->c2max - boxp->c2min) << (HIST_Y_BITS-HIST_C_BITS);
X norm = c0*c0 + c1*c1 + c2*c2;
X if (norm > max) {
X which = boxp;
X max = norm;
X }
X }
X return which;
X}
X
X
XLOCAL void
Xupdate_box (boxptr boxp)
X/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
X/* and recompute its population */
X{
X histptr histp;
X int c0,c1,c2;
X int c0min,c0max,c1min,c1max,c2min,c2max;
X long ccount;
X
X c0min = boxp->c0min; c0max = boxp->c0max;
X c1min = boxp->c1min; c1max = boxp->c1max;
X c2min = boxp->c2min; c2max = boxp->c2max;
X
X if (c0max > c0min)
X for (c0 = c0min; c0 <= c0max; c0++)
X for (c1 = c1min; c1 <= c1max; c1++) {
X histp = & histogram[c0][c1][c2min];
X for (c2 = c2min; c2 <= c2max; c2++)
X if (*histp++ != 0) {
X boxp->c0min = c0min = c0;
X goto have_c0min;
X }
X }
X have_c0min:
X if (c0max > c0min)
X for (c0 = c0max; c0 >= c0min; c0--)
X for (c1 = c1min; c1 <= c1max; c1++) {
X histp = & histogram[c0][c1][c2min];
X for (c2 = c2min; c2 <= c2max; c2++)
X if (*histp++ != 0) {
X boxp->c0max = c0max = c0;
X goto have_c0max;
X }
X }
X have_c0max:
X if (c1max > c1min)
X for (c1 = c1min; c1 <= c1max; c1++)
X for (c0 = c0min; c0 <= c0max; c0++) {
X histp = & histogram[c0][c1][c2min];
X for (c2 = c2min; c2 <= c2max; c2++)
X if (*histp++ != 0) {
X boxp->c1min = c1min = c1;
X goto have_c1min;
X }
X }
X have_c1min:
X if (c1max > c1min)
X for (c1 = c1max; c1 >= c1min; c1--)
X for (c0 = c0min; c0 <= c0max; c0++) {
X histp = & histogram[c0][c1][c2min];
X for (c2 = c2min; c2 <= c2max; c2++)
X if (*histp++ != 0) {
X boxp->c1max = c1max = c1;
X goto have_c1max;
X }
X }
X have_c1max:
X if (c2max > c2min)
X for (c2 = c2min; c2 <= c2max; c2++)
X for (c0 = c0min; c0 <= c0max; c0++) {
X histp = & histogram[c0][c1min][c2];
X for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C_ELEMS)
X if (*histp != 0) {
X boxp->c2min = c2min = c2;
X goto have_c2min;
X }
X }
X have_c2min:
X if (c2max > c2min)
X for (c2 = c2max; c2 >= c2min; c2--)
X for (c0 = c0min; c0 <= c0max; c0++) {
X histp = & histogram[c0][c1min][c2];
X for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C_ELEMS)
X if (*histp != 0) {
X boxp->c2max = c2max = c2;
X goto have_c2max;
X }
X }
X have_c2max:
X
X /* Now scan remaining volume of box and compute population */
X ccount = 0;
X for (c0 = c0min; c0 <= c0max; c0++)
X for (c1 = c1min; c1 <= c1max; c1++) {
X histp = & histogram[c0][c1][c2min];
X for (c2 = c2min; c2 <= c2max; c2++, histp++)
X if (*histp != 0) {
X ccount++;
X }
X }
X boxp->colorcount = ccount;
X}
X
X
XLOCAL void
Xmedian_cut (int desired_colors)
X/* Repeatedly select and split the largest box until we have enough boxes */
X{
X int n,lb;
X int c0,c1,c2,cmax;
X register boxptr b1,b2;
X
X while (numboxes < desired_colors) {
X /* Select box to split */
X /* Current algorithm: by population for first half, then by volume */
X if (numboxes*2 <= desired_colors) {
X b1 = find_biggest_color_pop();
X } else {
X b1 = find_biggest_volume();
X }
X if (b1 == NULL) /* no splittable boxes left! */
X break;
X b2 = &boxlist[numboxes]; /* where new box will go */
X /* Copy the color bounds to the new box. */
X b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
X b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
X /* Choose which axis to split the box on.
X * Current algorithm: longest scaled axis.
X * See notes in find_biggest_volume about scaling...
X */
X c0 = (b1->c0max - b1->c0min) * Y_SCALE;
X c1 = (b1->c1max - b1->c1min) << (HIST_Y_BITS-HIST_C_BITS);
X c2 = (b1->c2max - b1->c2min) << (HIST_Y_BITS-HIST_C_BITS);
X cmax = c0; n = 0;
X if (c1 > cmax) { cmax = c1; n = 1; }
X if (c2 > cmax) { n = 2; }
X /* Choose split point along selected axis, and update box bounds.
X * Current algorithm: split at halfway point.
X * (Since the box has been shrunk to minimum volume,
X * any split will produce two nonempty subboxes.)
X * Note that lb value is max for lower box, so must be < old max.
X */
X switch (n) {
X case 0:
X lb = (b1->c0max + b1->c0min) / 2;
X b1->c0max = lb;
X b2->c0min = lb+1;
X break;
X case 1:
X lb = (b1->c1max + b1->c1min) / 2;
X b1->c1max = lb;
X b2->c1min = lb+1;
X break;
X case 2:
X lb = (b1->c2max + b1->c2min) / 2;
X b1->c2max = lb;
X b2->c2min = lb+1;
X break;
X }
X /* Update stats for boxes */
X update_box(b1);
X update_box(b2);
X numboxes++;
X }
X}
X
X
XLOCAL void
Xcompute_color (boxptr boxp, int icolor)
X/* Compute representative color for a box, put it in my_colormap[icolor] */
X{
X /* Current algorithm: mean weighted by pixels (not colors) */
X /* Note it is important to get the rounding correct! */
X histptr histp;
X int c0,c1,c2;
X int c0min,c0max,c1min,c1max,c2min,c2max;
X long count;
X long total = 0;
X long c0total = 0;
X long c1total = 0;
X long c2total = 0;
X
X c0min = boxp->c0min; c0max = boxp->c0max;
X c1min = boxp->c1min; c1max = boxp->c1max;
X c2min = boxp->c2min; c2max = boxp->c2max;
X
X for (c0 = c0min; c0 <= c0max; c0++)
X for (c1 = c1min; c1 <= c1max; c1++) {
X histp = & histogram[c0][c1][c2min];
X for (c2 = c2min; c2 <= c2max; c2++) {
X if ((count = *histp++) != 0) {
X total += count;
X c0total += ((c0 << Y_SHIFT) + ((1<<Y_SHIFT)>>1)) * count;
X c1total += ((c1 << C_SHIFT) + ((1<<C_SHIFT)>>1)) * count;
X c2total += ((c2 << C_SHIFT) + ((1<<C_SHIFT)>>1)) * count;
X }
X }
X }
X
X my_colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
X my_colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
X my_colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
X}
X
X
XLOCAL void
Xremap_colormap (decompress_info_ptr cinfo)
X/* Remap the internal colormap to the output colorspace */
X{
X /* This requires a little trickery since color_convert expects to
X * deal with 3-D arrays (a 2-D sample array for each component).
X * We must promote the colormaps into one-row 3-D arrays.
X */
X short ci;
X JSAMPARRAY input_hack[3];
X JSAMPARRAY output_hack[10]; /* assume no more than 10 output components */
X
X for (ci = 0; ci < 3; ci++)
X input_hack[ci] = &(my_colormap[ci]);
X for (ci = 0; ci < cinfo->color_out_comps; ci++)
X output_hack[ci] = &(cinfo->colormap[ci]);
X
X (*cinfo->methods->color_convert) (cinfo, 1,
X (long) cinfo->actual_number_of_colors,
X input_hack, output_hack);
X}
X
X
XLOCAL void
Xselect_colors (decompress_info_ptr cinfo)
X/* Master routine for color selection */
X{
X int desired = cinfo->desired_number_of_colors;
X int i;
X
X /* Allocate workspace for box list */
X boxlist = (boxptr) (*cinfo->emethods->alloc_small) (desired * SIZEOF(box));
X /* Initialize one box containing whole space */
X numboxes = 1;
X boxlist[0].c0min = 0;
X boxlist[0].c0max = MAXJSAMPLE >> Y_SHIFT;
X boxlist[0].c1min = 0;
X boxlist[0].c1max = MAXJSAMPLE >> C_SHIFT;
X boxlist[0].c2min = 0;
X boxlist[0].c2max = MAXJSAMPLE >> C_SHIFT;
X /* Shrink it to actually-used volume and set its statistics */
X update_box(& boxlist[0]);
X /* Perform median-cut to produce final box list */
X median_cut(desired);
X /* Compute the representative color for each box, fill my_colormap[] */
X for (i = 0; i < numboxes; i++)
X compute_color(& boxlist[i], i);
X cinfo->actual_number_of_colors = numboxes;
X /* Produce an output colormap in the desired output colorspace */
X remap_colormap(cinfo);
X TRACEMS1(cinfo->emethods, 1, "Selected %d colors for quantization",
X numboxes);
X /* Done with the box list */
X (*cinfo->emethods->free_small) ((void *) boxlist);
X}
X
X
X/*
X * These routines are concerned with the time-critical task of mapping input
X * colors to the nearest color in the selected colormap.
X *
X * We re-use the histogram space as an "inverse color map", essentially a
X * cache for the results of nearest-color searches. All colors within a
X * histogram cell will be mapped to the same colormap entry, namely the one
X * closest to the cell's center. This may not be quite the closest entry to
X * the actual input color, but it's almost as good. A zero in the cache
X * indicates we haven't found the nearest color for that cell yet; the array
X * is cleared to zeroes before starting the mapping pass. When we find the
X * nearest color for a cell, its colormap index plus one is recorded in the
X * cache for future use. The pass2 scanning routines call fill_inverse_cmap
X * when they need to use an unfilled entry in the cache.
X *
X * Our method of efficiently finding nearest colors is based on the "locally
X * sorted search" idea described by Heckbert and on the incremental distance
X * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
X * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that
X * the distances from a given colormap entry to each cell of the histogram can
X * be computed quickly using an incremental method: the differences between
X * distances to adjacent cells themselves differ by a constant. This allows a
X * fairly fast implementation of the "brute force" approach of computing the
X * distance from every colormap entry to every histogram cell. Unfortunately,
X * it needs a work array to hold the best-distance-so-far for each histogram
X * cell (because the inner loop has to be over cells, not colormap entries).
X * The work array elements have to be INT32s, so the work array would need
X * 256Kb at our recommended precision. This is not feasible in DOS machines.
X * Another disadvantage of the brute force approach is that it computes
X * distances to every cell of the cubical histogram. When working with YCbCr
X * input, only about a quarter of the cube represents realizable colors, so
X * many of the cells will never be used and filling them is wasted effort.
X *
X * To get around these problems, we apply Thomas' method to compute the
X * nearest colors for only the cells within a small subbox of the histogram.
X * The work array need be only as big as the subbox, so the memory usage
X * problem is solved. A subbox is processed only when some cell in it is
X * referenced by the pass2 routines, so we will never bother with cells far
X * outside the realizable color volume. An additional advantage of this
X * approach is that we can apply Heckbert's locality criterion to quickly
X * eliminate colormap entries that are far away from the subbox; typically
X * three-fourths of the colormap entries are rejected by Heckbert's criterion,
X * and we need not compute their distances to individual cells in the subbox.
X * The speed of this approach is heavily influenced by the subbox size: too
X * small means too much overhead, too big loses because Heckbert's criterion
X * can't eliminate as many colormap entries. Empirically the best subbox
X * size seems to be about 1/512th of the histogram (1/8th in each direction).
X *
X * Thomas' article also describes a refined method which is asymptotically
X * faster than the brute-force method, but it is also far more complex and
X * cannot efficiently be applied to small subboxes. It is therefore not
X * useful for programs intended to be portable to DOS machines. On machines
X * with plenty of memory, filling the whole histogram in one shot with Thomas'
X * refined method might be faster than the present code --- but then again,
X * it might not be any faster, and it's certainly more complicated.
X */
X
X
X#ifndef BOX_Y_LOG /* so you can override from Makefile */
X#define BOX_Y_LOG (HIST_Y_BITS-3) /* log2(hist cells in update box, Y axis) */
X#endif
X#ifndef BOX_C_LOG /* so you can override from Makefile */
X#define BOX_C_LOG (HIST_C_BITS-3) /* log2(hist cells in update box, C axes) */
X#endif
X
X#define BOX_Y_ELEMS (1<<BOX_Y_LOG) /* # of hist cells in update box */
X#define BOX_C_ELEMS (1<<BOX_C_LOG)
X
X#define BOX_Y_SHIFT (Y_SHIFT + BOX_Y_LOG)
X#define BOX_C_SHIFT (C_SHIFT + BOX_C_LOG)
X
X
X/*
X * The next three routines implement inverse colormap filling. They could
X * all be folded into one big routine, but splitting them up this way saves
X * some stack space (the mindist[] and bestdist[] arrays need not coexist)
X * and may allow some compilers to produce better code by registerizing more
X * inner-loop variables.
X */
X
XLOCAL int
Xfind_nearby_colors (decompress_info_ptr cinfo, int minc0, int minc1, int minc2,
X JSAMPLE colorlist[])
X/* Locate the colormap entries close enough to an update box to be candidates
X * for the nearest entry to some cell(s) in the update box. The update box
X * is specified by the center coordinates of its first cell. The number of
X * candidate colormap entries is returned, and their colormap indexes are
X * placed in colorlist[].
X * This routine uses Heckbert's "locally sorted search" criterion to select
X * the colors that need further consideration.
X */
X{
X int numcolors = cinfo->actual_number_of_colors;
X int maxc0, maxc1, maxc2;
X int centerc0, centerc1, centerc2;
X int i, x, ncolors;
X INT32 minmaxdist, min_dist, max_dist, tdist;
X INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */
X
X /* Compute true coordinates of update box's upper corner and center.
X * Actually we compute the coordinates of the center of the upper-corner
X * histogram cell, which are the upper bounds of the volume we care about.
X * Note that since ">>" rounds down, the "center" values may be closer to
X * min than to max; hence comparisons to them must be "<=", not "<".
X */
X maxc0 = minc0 + ((1 << BOX_Y_SHIFT) - (1 << Y_SHIFT));
X centerc0 = (minc0 + maxc0) >> 1;
X maxc1 = minc1 + ((1 << BOX_C_SHIFT) - (1 << C_SHIFT));
X centerc1 = (minc1 + maxc1) >> 1;
X maxc2 = minc2 + ((1 << BOX_C_SHIFT) - (1 << C_SHIFT));
X centerc2 = (minc2 + maxc2) >> 1;
X
X /* For each color in colormap, find:
X * 1. its minimum squared-distance to any point in the update box
X * (zero if color is within update box);
X * 2. its maximum squared-distance to any point in the update box.
X * Both of these can be found by considering only the corners of the box.
X * We save the minimum distance for each color in mindist[];
X * only the smallest maximum distance is of interest.
X * Note we have to scale Y to get correct distance in scaled space.
X */
X minmaxdist = 0x7FFFFFFFL;
X
X for (i = 0; i < numcolors; i++) {
X /* We compute the squared-c0-distance term, then add in the other two. */
X x = GETJSAMPLE(my_colormap[0][i]);
X if (x < minc0) {
X tdist = (x - minc0) * Y_SCALE;
X min_dist = tdist*tdist;
X tdist = (x - maxc0) * Y_SCALE;
X max_dist = tdist*tdist;
X } else if (x > maxc0) {
X tdist = (x - maxc0) * Y_SCALE;
X min_dist = tdist*tdist;
X tdist = (x - minc0) * Y_SCALE;
X max_dist = tdist*tdist;
X } else {
X /* within cell range so no contribution to min_dist */
X min_dist = 0;
X if (x <= centerc0) {
X tdist = (x - maxc0) * Y_SCALE;
X max_dist = tdist*tdist;
X } else {
X tdist = (x - minc0) * Y_SCALE;
X max_dist = tdist*tdist;
X }
X }
X
X x = GETJSAMPLE(my_colormap[1][i]);
X if (x < minc1) {
X tdist = x - minc1;
X min_dist += tdist*tdist;
X tdist = x - maxc1;
X max_dist += tdist*tdist;
X } else if (x > maxc1) {
X tdist = x - maxc1;
X min_dist += tdist*tdist;
X tdist = x - minc1;
X max_dist += tdist*tdist;
X } else {
X /* within cell range so no contribution to min_dist */
X if (x <= centerc1) {
X tdist = x - maxc1;
X max_dist += tdist*tdist;
X } else {
X tdist = x - minc1;
X max_dist += tdist*tdist;
X }
X }
X
X x = GETJSAMPLE(my_colormap[2][i]);
X if (x < minc2) {
X tdist = x - minc2;
X min_dist += tdist*tdist;
X tdist = x - maxc2;
X max_dist += tdist*tdist;
X } else if (x > maxc2) {
X tdist = x - maxc2;
X min_dist += tdist*tdist;
X tdist = x - minc2;
X max_dist += tdist*tdist;
X } else {
X /* within cell range so no contribution to min_dist */
X if (x <= centerc2) {
X tdist = x - maxc2;
X max_dist += tdist*tdist;
X } else {
X tdist = x - minc2;
X max_dist += tdist*tdist;
X }
X }
X
X mindist[i] = min_dist; /* save away the results */
X if (max_dist < minmaxdist)
X minmaxdist = max_dist;
X }
X
X /* Now we know that no cell in the update box is more than minmaxdist
X * away from some colormap entry. Therefore, only colors that are
X * within minmaxdist of some part of the box need be considered.
X */
X ncolors = 0;
X for (i = 0; i < numcolors; i++) {
X if (mindist[i] <= minmaxdist)
X colorlist[ncolors++] = (JSAMPLE) i;
X }
X return ncolors;
X}
X
X
XLOCAL void
Xfind_best_colors (decompress_info_ptr cinfo, int minc0, int minc1, int minc2,
X int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
X/* Find the closest colormap entry for each cell in the update box,
X * given the list of candidate colors prepared by find_nearby_colors.
X * Return the indexes of the closest entries in the bestcolor[] array.
X * This routine uses Thomas' incremental distance calculation method to
X * find the distance from a colormap entry to successive cells in the box.
X */
X{
X int ic0, ic1, ic2;
X int i, icolor;
X register INT32 * bptr; /* pointer into bestdist[] array */
X JSAMPLE * cptr; /* pointer into bestcolor[] array */
X INT32 dist0, dist1; /* initial distance values */
X register INT32 dist2; /* current distance in inner loop */
X INT32 xx0, xx1; /* distance increments */
X register INT32 xx2;
X INT32 inc0, inc1, inc2; /* initial values for increments */
X /* This array holds the distance to the nearest-so-far color for each cell */
X INT32 bestdist[BOX_Y_ELEMS * BOX_C_ELEMS * BOX_C_ELEMS];
X
X /* Initialize best-distance for each cell of the update box */
X bptr = bestdist;
X for (i = BOX_Y_ELEMS*BOX_C_ELEMS*BOX_C_ELEMS-1; i >= 0; i--)
X *bptr++ = 0x7FFFFFFFL;
X
X /* For each color selected by find_nearby_colors,
X * compute its distance to the center of each cell in the box.
X * If that's less than best-so-far, update best distance and color number.
X * Note we have to scale Y to get correct distance in scaled space.
X */
X
X /* Nominal steps between cell centers ("x" in Thomas article) */
X#define STEP_Y ((1 << Y_SHIFT) * Y_SCALE)
X#define STEP_C (1 << C_SHIFT)
X
X for (i = 0; i < numcolors; i++) {
X icolor = GETJSAMPLE(colorlist[i]);
X /* Compute (square of) distance from minc0/c1/c2 to this color */
X inc0 = (minc0 - (int) GETJSAMPLE(my_colormap[0][icolor])) * Y_SCALE;
X dist0 = inc0*inc0;
X inc1 = minc1 - (int) GETJSAMPLE(my_colormap[1][icolor]);
X dist0 += inc1*inc1;
X inc2 = minc2 - (int) GETJSAMPLE(my_colormap[2][icolor]);
X dist0 += inc2*inc2;
X /* Form the initial difference increments */
X inc0 = inc0 * (2 * STEP_Y) + STEP_Y * STEP_Y;
X inc1 = inc1 * (2 * STEP_C) + STEP_C * STEP_C;
X inc2 = inc2 * (2 * STEP_C) + STEP_C * STEP_C;
X /* Now loop over all cells in box, updating distance per Thomas method */
X bptr = bestdist;
X cptr = bestcolor;
X xx0 = inc0;
X for (ic0 = BOX_Y_ELEMS-1; ic0 >= 0; ic0--) {
X dist1 = dist0;
X xx1 = inc1;
X for (ic1 = BOX_C_ELEMS-1; ic1 >= 0; ic1--) {
X dist2 = dist1;
X xx2 = inc2;
X for (ic2 = BOX_C_ELEMS-1; ic2 >= 0; ic2--) {
X if (dist2 < *bptr) {
X *bptr = dist2;
X *cptr = (JSAMPLE) icolor;
X }
X dist2 += xx2;
X xx2 += 2 * STEP_C * STEP_C;
X bptr++;
X cptr++;
X }
X dist1 += xx1;
X xx1 += 2 * STEP_C * STEP_C;
X }
X dist0 += xx0;
X xx0 += 2 * STEP_Y * STEP_Y;
X }
X }
X}
X
X
XLOCAL void
Xfill_inverse_cmap (decompress_info_ptr cinfo, int c0, int c1, int c2)
X/* Fill the inverse-colormap entries in the update box that contains */
X/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */
X/* we can fill as many others as we wish.) */
X{
X int minc0, minc1, minc2; /* lower left corner of update box */
X int ic0, ic1, ic2;
X register JSAMPLE * cptr; /* pointer into bestcolor[] array */
X register histptr cachep; /* pointer into main cache array */
X /* This array lists the candidate colormap indexes. */
X JSAMPLE colorlist[MAXNUMCOLORS];
X int numcolors; /* number of candidate colors */
X /* This array holds the actually closest colormap index for each cell. */
X JSAMPLE bestcolor[BOX_Y_ELEMS * BOX_C_ELEMS * BOX_C_ELEMS];
X
X /* Convert cell coordinates to update box ID */
X c0 >>= BOX_Y_LOG;
X c1 >>= BOX_C_LOG;
X c2 >>= BOX_C_LOG;
X
X /* Compute true coordinates of update box's origin corner.
X * Actually we compute the coordinates of the center of the corner
X * histogram cell, which are the lower bounds of the volume we care about.
X */
X minc0 = (c0 << BOX_Y_SHIFT) + ((1 << Y_SHIFT) >> 1);
X minc1 = (c1 << BOX_C_SHIFT) + ((1 << C_SHIFT) >> 1);
X minc2 = (c2 << BOX_C_SHIFT) + ((1 << C_SHIFT) >> 1);
X
X /* Determine which colormap entries are close enough to be candidates
X * for the nearest entry to some cell in the update box.
X */
X numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
X
X /* Determine the actually nearest colors. */
X find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
X bestcolor);
X
X /* Save the best color numbers (plus 1) in the main cache array */
X c0 <<= BOX_Y_LOG; /* convert ID back to base cell indexes */
X c1 <<= BOX_C_LOG;
X c2 <<= BOX_C_LOG;
X cptr = bestcolor;
X for (ic0 = 0; ic0 < BOX_Y_ELEMS; ic0++) {
X for (ic1 = 0; ic1 < BOX_C_ELEMS; ic1++) {
X cachep = & histogram[c0+ic0][c1+ic1][c2];
X for (ic2 = 0; ic2 < BOX_C_ELEMS; ic2++) {
X *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
X }
X }
X }
X}
X
X
X/*
X * These routines perform second-pass scanning of the image: map each pixel to
X * the proper colormap index, and output the indexes to the output file.
X *
X * output_workspace is a one-component array of pixel dimensions at least
X * as large as the input image strip; it can be used to hold the converted
X * pixels' colormap indexes.
X */
X
XMETHODDEF void
Xpass2_nodither (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE image_data, JSAMPARRAY output_workspace)
X/* This version performs no dithering */
X{
X register JSAMPROW ptr0, ptr1, ptr2, outptr;
X register histptr cachep;
X register int c0, c1, c2;
X int row;
X long col;
X long width = cinfo->image_width;
X
X /* Convert data to colormap indexes, which we save in output_workspace */
X for (row = 0; row < num_rows; row++) {
X ptr0 = image_data[0][row];
X ptr1 = image_data[1][row];
X ptr2 = image_data[2][row];
X outptr = output_workspace[row];
X for (col = width; col > 0; col--) {
X /* get pixel value and index into the cache */
X c0 = GETJSAMPLE(*ptr0++) >> Y_SHIFT;
X c1 = GETJSAMPLE(*ptr1++) >> C_SHIFT;
X c2 = GETJSAMPLE(*ptr2++) >> C_SHIFT;
X cachep = & histogram[c0][c1][c2];
X /* If we have not seen this color before, find nearest colormap entry */
X /* and update the cache */
X if (*cachep == 0)
X fill_inverse_cmap(cinfo, c0,c1,c2);
X /* Now emit the colormap index for this cell */
X *outptr++ = (JSAMPLE) (*cachep - 1);
X }
X }
X /* Emit converted rows to the output file */
X (*cinfo->methods->put_pixel_rows) (cinfo, num_rows, &output_workspace);
X}
X
X
X/* Declarations for Floyd-Steinberg dithering.
X *
X * Errors are accumulated into the arrays evenrowerrs[] and oddrowerrs[].
X * These have resolutions of 1/16th of a pixel count. The error at a given
X * pixel is propagated to its unprocessed neighbors using the standard F-S
X * fractions,
X * ... (here) 7/16
X * 3/16 5/16 1/16
X * We work left-to-right on even rows, right-to-left on odd rows.
X *
X * Each of the arrays has (#columns + 2) entries; the extra entry
X * at each end saves us from special-casing the first and last pixels.
X * Each entry is three values long.
X * In evenrowerrs[], the entries for a component are stored left-to-right, but
X * in oddrowerrs[] they are stored right-to-left. This means we always
X * process the current row's error entries in increasing order and the next
X * row's error entries in decreasing order, regardless of whether we are
X * working L-to-R or R-to-L in the pixel data!
X *
X * Note: on a wide image, we might not have enough room in a PC's near data
X * segment to hold the error arrays; so they are allocated with alloc_medium.
X */
X
X#ifdef EIGHT_BIT_SAMPLES
Xtypedef INT16 FSERROR; /* 16 bits should be enough */
X#else
Xtypedef INT32 FSERROR; /* may need more than 16 bits? */
X#endif
X
Xtypedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
X
Xstatic FSERRPTR evenrowerrs, oddrowerrs; /* current-row and next-row errors */
Xstatic boolean on_odd_row; /* flag to remember which row we are on */
X
X
XMETHODDEF void
Xpass2_dither (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE image_data, JSAMPARRAY output_workspace)
X/* This version performs Floyd-Steinberg dithering */
X{
X register FSERROR val;
X register FSERRPTR thisrowerr, nextrowerr;
X register FSERROR c0, c1, c2;
X register int pixcode;
X JSAMPROW ptr0, ptr1, ptr2, outptr;
X histptr cachep;
X int dir;
X long col;
X int row;
X long width = cinfo->image_width;
X
X /* Convert data to colormap indexes, which we save in output_workspace */
X for (row = 0; row < num_rows; row++) {
X ptr0 = image_data[0][row];
X ptr1 = image_data[1][row];
X ptr2 = image_data[2][row];
X outptr = output_workspace[row];
X if (on_odd_row) {
X /* work right to left in this row */
X ptr0 += width - 1;
X ptr1 += width - 1;
X ptr2 += width - 1;
X outptr += width - 1;
X dir = -1;
X thisrowerr = oddrowerrs + 3;
X nextrowerr = evenrowerrs + width*3;
X on_odd_row = FALSE; /* flip for next time */
X } else {
X /* work left to right in this row */
X dir = 1;
X thisrowerr = evenrowerrs + 3;
X nextrowerr = oddrowerrs + width*3;
X on_odd_row = TRUE; /* flip for next time */
X }
X /* need only initialize this one entry in nextrowerr */
X nextrowerr[0] = nextrowerr[1] = nextrowerr[2] = 0;
X for (col = width; col > 0; col--) {
X /* Get this pixel's value and add accumulated errors */
X /* The errors are in units of 1/16th pixel value */
X val = (GETJSAMPLE(*ptr0) << 4) + thisrowerr[0];
X if (val <= 0) val = 0; /* must watch for range overflow! */
X else {
X val += 8; /* divide by 16 with proper rounding */
X val >>= 4;
X if (val > MAXJSAMPLE) val = MAXJSAMPLE;
X }
X c0 = val;
X val = (GETJSAMPLE(*ptr1) << 4) + thisrowerr[1];
X if (val <= 0) val = 0; /* must watch for range overflow! */
X else {
X val += 8; /* divide by 16 with proper rounding */
X val >>= 4;
X if (val > MAXJSAMPLE) val = MAXJSAMPLE;
X }
X c1 = val;
X val = (GETJSAMPLE(*ptr2) << 4) + thisrowerr[2];
X if (val <= 0) val = 0; /* must watch for range overflow! */
X else {
X val += 8; /* divide by 16 with proper rounding */
X val >>= 4;
X if (val > MAXJSAMPLE) val = MAXJSAMPLE;
X }
X c2 = val;
X /* Index into the cache with adjusted value */
X cachep = & histogram[c0 >> Y_SHIFT][c1 >> C_SHIFT][c2 >> C_SHIFT];
X /* If we have not seen this color before, find nearest colormap */
X /* entry and update the cache */
X if (*cachep == 0)
X fill_inverse_cmap(cinfo, c0 >> Y_SHIFT, c1 >> C_SHIFT, c2 >> C_SHIFT);
X /* Now emit the colormap index for this cell */
X pixcode = *cachep - 1;
X *outptr = (JSAMPLE) pixcode;
X /* Compute representation error for this pixel */
X c0 -= (FSERROR) GETJSAMPLE(my_colormap[0][pixcode]);
X c1 -= (FSERROR) GETJSAMPLE(my_colormap[1][pixcode]);
X c2 -= (FSERROR) GETJSAMPLE(my_colormap[2][pixcode]);
X /* Propagate error to adjacent pixels */
X /* Remember that nextrowerr entries are in reverse order! */
X val = c0 * 2;
X nextrowerr[0-3] = c0; /* not +=, since not initialized yet */
X c0 += val; /* form error * 3 */
X nextrowerr[0+3] += c0;
X c0 += val; /* form error * 5 */
X nextrowerr[0 ] += c0;
X c0 += val; /* form error * 7 */
X thisrowerr[0+3] += c0;
X val = c1 * 2;
X nextrowerr[1-3] = c1; /* not +=, since not initialized yet */
X c1 += val; /* form error * 3 */
X nextrowerr[1+3] += c1;
X c1 += val; /* form error * 5 */
X nextrowerr[1 ] += c1;
X c1 += val; /* form error * 7 */
X thisrowerr[1+3] += c1;
X val = c2 * 2;
X nextrowerr[2-3] = c2; /* not +=, since not initialized yet */
X c2 += val; /* form error * 3 */
X nextrowerr[2+3] += c2;
X c2 += val; /* form error * 5 */
X nextrowerr[2 ] += c2;
X c2 += val; /* form error * 7 */
X thisrowerr[2+3] += c2;
X /* Advance to next column */
X ptr0 += dir;
X ptr1 += dir;
X ptr2 += dir;
X outptr += dir;
X thisrowerr += 3; /* cur-row error ptr advances to right */
X nextrowerr -= 3; /* next-row error ptr advances to left */
X }
X }
X /* Emit converted rows to the output file */
X (*cinfo->methods->put_pixel_rows) (cinfo, num_rows, &output_workspace);
X}
X
X
X/*
X * Initialize for two-pass color quantization.
X */
X
XMETHODDEF void
Xcolor_quant_init (decompress_info_ptr cinfo)
X{
X int i;
X
X /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
X if (cinfo->desired_number_of_colors < 8)
X ERREXIT(cinfo->emethods, "Cannot request less than 8 quantized colors");
X /* Make sure colormap indexes can be represented by JSAMPLEs */
X if (cinfo->desired_number_of_colors > MAXNUMCOLORS)
X ERREXIT1(cinfo->emethods, "Cannot request more than %d quantized colors",
X MAXNUMCOLORS);
X
X /* Allocate and zero the histogram */
X histogram = (hist3d) (*cinfo->emethods->alloc_small)
X (HIST_Y_ELEMS * SIZEOF(hist2d));
X for (i = 0; i < HIST_Y_ELEMS; i++) {
X histogram[i] = (hist2d) (*cinfo->emethods->alloc_medium)
X (HIST_C_ELEMS*HIST_C_ELEMS * SIZEOF(histcell));
X jzero_far((void FAR *) histogram[i],
X HIST_C_ELEMS*HIST_C_ELEMS * SIZEOF(histcell));
X }
X
X /* Allocate storage for the internal and external colormaps. */
X /* We do this now since it is FAR storage and may affect the memory */
X /* manager's space calculations. */
X my_colormap = (*cinfo->emethods->alloc_small_sarray)
X ((long) cinfo->desired_number_of_colors,
X (long) 3);
X cinfo->colormap = (*cinfo->emethods->alloc_small_sarray)
X ((long) cinfo->desired_number_of_colors,
X (long) cinfo->color_out_comps);
X
X /* Allocate Floyd-Steinberg workspace if necessary */
X /* This isn't needed until pass 2, but again it is FAR storage. */
X if (cinfo->use_dithering) {
X size_t arraysize = (size_t) ((cinfo->image_width + 2L) * 3L * SIZEOF(FSERROR));
X
X evenrowerrs = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
X oddrowerrs = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
X /* we only need to zero the forward contribution for current row. */
X jzero_far((void FAR *) evenrowerrs, arraysize);
X on_odd_row = FALSE;
X }
X
X /* Indicate number of passes needed, excluding the prescan pass. */
X cinfo->total_passes++; /* I always use one pass */
X}
X
X
X/*
X * Perform two-pass quantization: rescan the image data and output the
X * converted data via put_color_map and put_pixel_rows.
X * The source_method is a routine that can scan the image data; it can
X * be called as many times as desired. The processing routine called by
X * source_method has the same interface as color_quantize does in the
X * one-pass case, except it must call put_pixel_rows itself. (This allows
X * me to use multiple passes in which earlier passes don't output anything.)
X */
X
XMETHODDEF void
Xcolor_quant_doit (decompress_info_ptr cinfo, quantize_caller_ptr source_method)
X{
X int i;
X
X /* Select the representative colors */
X select_colors(cinfo);
X /* Pass the external colormap to the output module. */
X /* NB: the output module may continue to use the colormap until shutdown. */
X (*cinfo->methods->put_color_map) (cinfo, cinfo->actual_number_of_colors,
X cinfo->colormap);
X /* Re-zero the histogram so pass 2 can use it as nearest-color cache */
X for (i = 0; i < HIST_Y_ELEMS; i++) {
X jzero_far((void FAR *) histogram[i],
X HIST_C_ELEMS*HIST_C_ELEMS * SIZEOF(histcell));
X }
X /* Perform pass 2 */
X if (cinfo->use_dithering)
X (*source_method) (cinfo, pass2_dither);
X else
X (*source_method) (cinfo, pass2_nodither);
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xcolor_quant_term (decompress_info_ptr cinfo)
X{
X /* no work (we let free_all release the histogram/cache and colormaps) */
X /* Note that we *mustn't* free the external colormap before free_all, */
X /* since output module may use it! */
X}
X
X
X/*
X * Map some rows of pixels to the output colormapped representation.
X * Not used in two-pass case.
X */
X
XMETHODDEF void
Xcolor_quantize (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE input_data, JSAMPARRAY output_data)
X{
X ERREXIT(cinfo->emethods, "Should not get here!");
X}
X
X
X/*
X * The method selection routine for 2-pass color quantization.
X */
X
XGLOBAL void
Xjsel2quantize (decompress_info_ptr cinfo)
X{
X if (cinfo->two_pass_quantize) {
X /* Make sure jdmaster didn't give me a case I can't handle */
X if (cinfo->num_components != 3 || cinfo->jpeg_color_space != CS_YCbCr)
X ERREXIT(cinfo->emethods, "2-pass quantization only handles YCbCr input");
X cinfo->methods->color_quant_init = color_quant_init;
X cinfo->methods->color_quant_prescan = color_quant_prescan;
X cinfo->methods->color_quant_doit = color_quant_doit;
X cinfo->methods->color_quant_term = color_quant_term;
X cinfo->methods->color_quantize = color_quantize;
X }
X}
X
X#endif /* QUANT_2PASS_SUPPORTED */
END_OF_FILE
if test 42181 -ne `wc -c <'jquant2.c'`; then
echo shar: \"'jquant2.c'\" unpacked with wrong size!
fi
# end of 'jquant2.c'
fi
if test -f 'jrdppm.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jrdppm.c'\"
else
echo shar: Extracting \"'jrdppm.c'\" \(8944 characters\)
sed "s/^X//" >'jrdppm.c' <<'END_OF_FILE'
X/*
X * jrdppm.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to read input images in PPM format.
X * The PBMPLUS library is NOT required to compile this software,
X * but it is highly useful as a set of PPM image manipulation programs.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume input from
X * an ordinary stdio stream. They further assume that reading begins
X * at the start of the file; input_init may need work if the
X * user interface has already read some data (e.g., to determine that
X * the file is indeed PPM format).
X *
X * These routines are invoked via the methods get_input_row
X * and input_init/term.
X */
X
X#include "jinclude.h"
X
X#ifdef PPM_SUPPORTED
X
X
Xstatic JSAMPLE * rescale; /* => maxval-remapping array, or NULL */
X
X
X/* Portions of this code are based on the PBMPLUS library, which is:
X**
X** Copyright (C) 1988 by Jef Poskanzer.
X**
X** Permission to use, copy, modify, and distribute this software and its
X** documentation for any purpose and without fee is hereby granted, provided
X** that the above copyright notice appear in all copies and that both that
X** copyright notice and this permission notice appear in supporting
X** documentation. This software is provided "as is" without express or
X** implied warranty.
X*/
X
X
XLOCAL int
Xpbm_getc (FILE * file)
X/* Read next char, skipping over any comments */
X/* A comment/newline sequence is returned as a newline */
X{
X register int ch;
X
X ch = getc(file);
X if (ch == '#') {
X do {
X ch = getc(file);
X } while (ch != '\n' && ch != EOF);
X }
X return ch;
X}
X
X
XLOCAL unsigned int
Xread_pbm_integer (compress_info_ptr cinfo)
X/* Read an unsigned decimal integer from the PPM file */
X/* Swallows one trailing character after the integer */
X/* Note that on a 16-bit-int machine, only values up to 64k can be read. */
X/* This should not be a problem in practice. */
X{
X register int ch;
X register unsigned int val;
X
X /* Skip any leading whitespace */
X do {
X ch = pbm_getc(cinfo->input_file);
X if (ch == EOF)
X ERREXIT(cinfo->emethods, "Premature EOF in PPM file");
X } while (ch == ' ' || ch == '\t' || ch == '\n');
X
X if (ch < '0' || ch > '9')
X ERREXIT(cinfo->emethods, "Bogus data in PPM file");
X
X val = ch - '0';
X while ((ch = pbm_getc(cinfo->input_file)) >= '0' && ch <= '9') {
X val *= 10;
X val += ch - '0';
X }
X return val;
X}
X
X
X/*
X * Read one row of pixels.
X *
X * We provide several different versions depending on input file format.
X * In all cases, input is scaled to the size of JSAMPLE; it's possible that
X * when JSAMPLE is 12 bits, this would not really be desirable.
X *
X * Note that a really fast path is provided for reading raw files with
X * maxval = MAXJSAMPLE, which is the normal case (at least for 8-bit JSAMPLEs).
X */
X
X
XMETHODDEF void
Xget_text_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading text-format PGM files with any maxval */
X{
X register JSAMPROW ptr0;
X register unsigned int val;
X register long col;
X
X ptr0 = pixel_row[0];
X for (col = cinfo->image_width; col > 0; col--) {
X val = read_pbm_integer(cinfo);
X if (rescale != NULL)
X val = rescale[val];
X *ptr0++ = (JSAMPLE) val;
X }
X}
X
X
XMETHODDEF void
Xget_text_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading text-format PPM files with any maxval */
X{
X register JSAMPROW ptr0, ptr1, ptr2;
X register unsigned int val;
X register long col;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X val = read_pbm_integer(cinfo);
X if (rescale != NULL)
X val = rescale[val];
X *ptr0++ = (JSAMPLE) val;
X val = read_pbm_integer(cinfo);
X if (rescale != NULL)
X val = rescale[val];
X *ptr1++ = (JSAMPLE) val;
X val = read_pbm_integer(cinfo);
X if (rescale != NULL)
X val = rescale[val];
X *ptr2++ = (JSAMPLE) val;
X }
X}
X
X
XMETHODDEF void
Xget_scaled_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading raw-format PGM files with any maxval */
X{
X register FILE * infile = cinfo->input_file;
X register JSAMPROW ptr0;
X register long col;
X
X ptr0 = pixel_row[0];
X for (col = cinfo->image_width; col > 0; col--) {
X *ptr0++ = rescale[getc(infile)];
X }
X}
X
X
XMETHODDEF void
Xget_scaled_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading raw-format PPM files with any maxval */
X{
X register FILE * infile = cinfo->input_file;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X *ptr0++ = rescale[getc(infile)];
X *ptr1++ = rescale[getc(infile)];
X *ptr2++ = rescale[getc(infile)];
X }
X}
X
X
XMETHODDEF void
Xget_raw_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading raw-format PGM files with maxval = MAXJSAMPLE */
X{
X register FILE * infile = cinfo->input_file;
X register JSAMPROW ptr0;
X register long col;
X
X ptr0 = pixel_row[0];
X for (col = cinfo->image_width; col > 0; col--) {
X *ptr0++ = (JSAMPLE) getc(infile);
X }
X}
X
X
XMETHODDEF void
Xget_raw_rgb_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading raw-format PPM files with maxval = MAXJSAMPLE */
X{
X register FILE * infile = cinfo->input_file;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X *ptr0++ = (JSAMPLE) getc(infile);
X *ptr1++ = (JSAMPLE) getc(infile);
X *ptr2++ = (JSAMPLE) getc(infile);
X }
X}
X
X
X/*
X * Read the file header; return image size and component count.
X */
X
XMETHODDEF void
Xinput_init (compress_info_ptr cinfo)
X{
X int c;
X unsigned int w, h, maxval;
X
X if (getc(cinfo->input_file) != 'P')
X ERREXIT(cinfo->emethods, "Not a PPM file");
X
X c = getc(cinfo->input_file); /* save format discriminator for a sec */
X
X w = read_pbm_integer(cinfo); /* while we fetch the header info */
X h = read_pbm_integer(cinfo);
X maxval = read_pbm_integer(cinfo);
X
X switch (c) {
X case '2': /* it's a text-format PGM file */
X cinfo->methods->get_input_row = get_text_gray_row;
X cinfo->input_components = 1;
X cinfo->in_color_space = CS_GRAYSCALE;
X break;
X
X case '3': /* it's a text-format PPM file */
X cinfo->methods->get_input_row = get_text_rgb_row;
X cinfo->input_components = 3;
X cinfo->in_color_space = CS_RGB;
X break;
X
X case '5': /* it's a raw-format PGM file */
X if (maxval == MAXJSAMPLE)
X cinfo->methods->get_input_row = get_raw_gray_row;
X else
X cinfo->methods->get_input_row = get_scaled_gray_row;
X cinfo->input_components = 1;
X cinfo->in_color_space = CS_GRAYSCALE;
X break;
X
X case '6': /* it's a raw-format PPM file */
X if (maxval == MAXJSAMPLE)
X cinfo->methods->get_input_row = get_raw_rgb_row;
X else
X cinfo->methods->get_input_row = get_scaled_rgb_row;
X cinfo->input_components = 3;
X cinfo->in_color_space = CS_RGB;
X break;
X
X default:
X ERREXIT(cinfo->emethods, "Not a PPM file");
X break;
X }
X
X if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
X ERREXIT(cinfo->emethods, "Not a PPM file");
X
X /* Compute the rescaling array if necessary */
X /* This saves per-pixel calculation */
X if (maxval == MAXJSAMPLE)
X rescale = NULL; /* no rescaling required */
X else {
X INT32 val, half_maxval;
X
X /* On 16-bit-int machines we have to be careful of maxval = 65535 */
X rescale = (JSAMPLE *) (*cinfo->emethods->alloc_small)
X ((size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
X half_maxval = maxval / 2;
X for (val = 0; val <= (INT32) maxval; val++) {
X /* The multiplication here must be done in 32 bits to avoid overflow */
X rescale[val] = (JSAMPLE) ((val * MAXJSAMPLE + half_maxval) / maxval);
X }
X }
X
X cinfo->image_width = w;
X cinfo->image_height = h;
X cinfo->data_precision = BITS_IN_JSAMPLE;
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xinput_term (compress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for PPM format input.
X * Note that this must be called by the user interface before calling
X * jpeg_compress. If multiple input formats are supported, the
X * user interface is responsible for discovering the file format and
X * calling the appropriate method selection routine.
X */
X
XGLOBAL void
Xjselrppm (compress_info_ptr cinfo)
X{
X cinfo->methods->input_init = input_init;
X /* cinfo->methods->get_input_row is set by input_init */
X cinfo->methods->input_term = input_term;
X}
X
X#endif /* PPM_SUPPORTED */
END_OF_FILE
if test 8944 -ne `wc -c <'jrdppm.c'`; then
echo shar: \"'jrdppm.c'\" unpacked with wrong size!
fi
# end of 'jrdppm.c'
fi
echo shar: End of archive 2 \(of 18\).
cp /dev/null ark2isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jcdeflts.c jdpipe.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:41 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 3 (of 18)."'
if test -f 'jcdeflts.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcdeflts.c'\"
else
echo shar: Extracting \"'jcdeflts.c'\" \(14213 characters\)
sed "s/^X//" >'jcdeflts.c' <<'END_OF_FILE'
X/*
X * jcdeflts.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains optional default-setting code for the JPEG compressor.
X * User interfaces do not have to use this file, but those that don't use it
X * must know a lot more about the innards of the JPEG code.
X */
X
X#include "jinclude.h"
X
X
X/* Default do-nothing progress monitoring routine.
X * This can be overridden by a user interface that wishes to
X * provide progress monitoring; just set methods->progress_monitor
X * after j_c_defaults is done. The routine will be called periodically
X * during the compression process.
X *
X * During any one pass, loopcounter increases from 0 up to (not including)
X * looplimit; the step size is not necessarily 1. Both the step size and
X * the limit may differ between passes. The expected total number of passes
X * is in cinfo->total_passes, and the number of passes already completed is
X * in cinfo->completed_passes. Thus the fraction of work completed may be
X * estimated as
X * completed_passes + (loopcounter/looplimit)
X * ------------------------------------------
X * total_passes
X * ignoring the fact that the passes may not be equal amounts of work.
X */
X
XMETHODDEF void
Xprogress_monitor (compress_info_ptr cinfo, long loopcounter, long looplimit)
X{
X /* do nothing */
X}
X
X
X/*
X * Table setup routines
X */
X
XLOCAL void
Xadd_huff_table (compress_info_ptr cinfo,
X HUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
X/* Define a Huffman table */
X{
X if (*htblptr == NULL)
X *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
X
X memcpy((void *) (*htblptr)->bits, (const void *) bits,
X SIZEOF((*htblptr)->bits));
X memcpy((void *) (*htblptr)->huffval, (const void *) val,
X SIZEOF((*htblptr)->huffval));
X
X /* Initialize sent_table FALSE so table will be written to JPEG file.
X * In an application where we are writing non-interchange JPEG files,
X * it might be desirable to save space by leaving default Huffman tables
X * out of the file. To do that, just initialize sent_table = TRUE...
X */
X
X (*htblptr)->sent_table = FALSE;
X}
X
X
XLOCAL void
Xstd_huff_tables (compress_info_ptr cinfo)
X/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
X/* IMPORTANT: these are only valid for 8-bit data precision! */
X{
X static const UINT8 dc_luminance_bits[17] =
X { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
X static const UINT8 dc_luminance_val[] =
X { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
X
X static const UINT8 dc_chrominance_bits[17] =
X { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
X static const UINT8 dc_chrominance_val[] =
X { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
X
X static const UINT8 ac_luminance_bits[17] =
X { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
X static const UINT8 ac_luminance_val[] =
X { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
X 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
X 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
X 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
X 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
X 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
X 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
X 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
X 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
X 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
X 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
X 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
X 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
X 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
X 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
X 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
X 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
X 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
X 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
X 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
X 0xf9, 0xfa };
X
X static const UINT8 ac_chrominance_bits[17] =
X { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
X static const UINT8 ac_chrominance_val[] =
X { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
X 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
X 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
X 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
X 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
X 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
X 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
X 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
X 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
X 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
X 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
X 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
X 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
X 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
X 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
X 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
X 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
X 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
X 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
X 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
X 0xf9, 0xfa };
X
X add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
X dc_luminance_bits, dc_luminance_val);
X add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
X ac_luminance_bits, ac_luminance_val);
X add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
X dc_chrominance_bits, dc_chrominance_val);
X add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
X ac_chrominance_bits, ac_chrominance_val);
X}
X
X
X/* This is the sample quantization table given in the JPEG spec section K.1,
X * but expressed in zigzag order (as are all of our quant. tables).
X * The spec says that the values given produce "good" quality, and
X * when divided by 2, "very good" quality. (These two settings are
X * selected by quality=50 and quality=75 in j_set_quality, below.)
X */
X
X
Xstatic const QUANT_VAL std_luminance_quant_tbl[DCTSIZE2] = {
X 16, 11, 12, 14, 12, 10, 16, 14,
X 13, 14, 18, 17, 16, 19, 24, 40,
X 26, 24, 22, 22, 24, 49, 35, 37,
X 29, 40, 58, 51, 61, 60, 57, 51,
X 56, 55, 64, 72, 92, 78, 64, 68,
X 87, 69, 55, 56, 80, 109, 81, 87,
X 95, 98, 103, 104, 103, 62, 77, 113,
X 121, 112, 100, 120, 92, 101, 103, 99
X};
X
Xstatic const QUANT_VAL std_chrominance_quant_tbl[DCTSIZE2] = {
X 17, 18, 18, 24, 21, 24, 47, 26,
X 26, 47, 99, 66, 56, 66, 99, 99,
X 99, 99, 99, 99, 99, 99, 99, 99,
X 99, 99, 99, 99, 99, 99, 99, 99,
X 99, 99, 99, 99, 99, 99, 99, 99,
X 99, 99, 99, 99, 99, 99, 99, 99,
X 99, 99, 99, 99, 99, 99, 99, 99,
X 99, 99, 99, 99, 99, 99, 99, 99
X};
X
X
XLOCAL void
Xadd_quant_table (compress_info_ptr cinfo, int which_tbl,
X const QUANT_VAL *basic_table, int scale_factor,
X boolean force_baseline)
X/* Define a quantization table equal to the basic_table times */
X/* a scale factor (given as a percentage) */
X{
X QUANT_TBL_PTR * qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
X int i;
X long temp;
X
X if (*qtblptr == NULL)
X *qtblptr = (QUANT_TBL_PTR) (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
X
X for (i = 0; i < DCTSIZE2; i++) {
X temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
X /* limit the values to the valid range */
X if (temp <= 0L) temp = 1L;
X#ifdef EIGHT_BIT_SAMPLES
X if (temp > 32767L) temp = 32767L; /* QUANT_VALs are 'short' */
X#else
X if (temp > 65535L) temp = 65535L; /* QUANT_VALs are 'UINT16' */
X#endif
X if (force_baseline && temp > 255L)
X temp = 255L; /* limit to baseline range if requested */
X (*qtblptr)[i] = (QUANT_VAL) temp;
X }
X}
X
X
XGLOBAL void
Xj_set_quality (compress_info_ptr cinfo, int quality, boolean force_baseline)
X/* Set or change the 'quality' (quantization) setting. */
X/* The 'quality' factor should be 0 (terrible) to 100 (very good). */
X/* Quality 50 corresponds to the JPEG basic tables given above; */
X/* quality 100 results in no quantization scaling at all. */
X/* If force_baseline is TRUE, quantization table entries are limited */
X/* to 0..255 for JPEG baseline compatibility; this is only an issue */
X/* for quality settings below 24. */
X{
X /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
X if (quality <= 0) quality = 1;
X if (quality > 100) quality = 100;
X
X /* Convert quality rating to a percentage scaling of the basic tables.
X * The basic table is used as-is (scaling 100) for a quality of 50.
X * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
X * note that at Q=100 the scaling is 0, which will cause add_quant_table
X * to make all the table entries 1 (hence, no quantization loss).
X * Qualities 1..50 are converted to scaling percentage 5000/Q.
X */
X if (quality < 50)
X quality = 5000 / quality;
X else
X quality = 200 - quality*2;
X
X /* Set up two quantization tables using the specified quality scaling */
X add_quant_table(cinfo, 0, std_luminance_quant_tbl, quality, force_baseline);
X add_quant_table(cinfo, 1, std_chrominance_quant_tbl, quality, force_baseline);
X}
X
X
X
X/* Default parameter setup for compression.
X *
X * User interfaces that don't choose to use this routine must do their
X * own setup of all these parameters. Alternately, you can call this
X * to establish defaults and then alter parameters selectively. This
X * is the recommended approach since, if we add any new parameters,
X * your code will still work (they'll be set to reasonable defaults).
X *
X * See above for the meaning of the 'quality' and 'force_baseline' parameters.
X * Typically, the application's default quality setting will be passed to this
X * routine. A later call on j_set_quality() can be used to change to a
X * user-specified quality setting.
X *
X * This routine sets up for a color image; to output a grayscale image,
X * do this first and call j_monochrome_default() afterwards.
X * (The latter can be called within c_ui_method_selection, so the
X * choice can depend on the input file header.)
X * Note that if you want a JPEG colorspace other than GRAYSCALE or YCbCr,
X * you should also change the component ID codes, and you should NOT emit
X * a JFIF header (set write_JFIF_header = FALSE).
X *
X * CAUTION: if you want to compress multiple images per run, it's necessary
X * to call j_c_defaults before *each* call to jpeg_compress, since subsidiary
X * structures like the Huffman tables are automatically freed during cleanup.
X */
X
XGLOBAL void
Xj_c_defaults (compress_info_ptr cinfo, int quality, boolean force_baseline)
X/* NB: the external methods must already be set up. */
X{
X short i;
X jpeg_component_info * compptr;
X
X /* Initialize pointers as needed to mark stuff unallocated. */
X cinfo->comp_info = NULL;
X for (i = 0; i < NUM_QUANT_TBLS; i++)
X cinfo->quant_tbl_ptrs[i] = NULL;
X for (i = 0; i < NUM_HUFF_TBLS; i++) {
X cinfo->dc_huff_tbl_ptrs[i] = NULL;
X cinfo->ac_huff_tbl_ptrs[i] = NULL;
X }
X
X cinfo->data_precision = BITS_IN_JSAMPLE; /* default; can be overridden by input_init */
X cinfo->density_unit = 0; /* Pixel size is unknown by default */
X cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
X cinfo->Y_density = 1;
X
X cinfo->input_gamma = 1.0; /* no gamma correction by default */
X
X /* Prepare three color components; first is luminance which is also usable */
X /* for grayscale. The others are assumed to be UV or similar chrominance. */
X cinfo->write_JFIF_header = TRUE;
X cinfo->jpeg_color_space = CS_YCbCr;
X cinfo->num_components = 3;
X cinfo->comp_info = (jpeg_component_info *)
X (*cinfo->emethods->alloc_small) (4 * SIZEOF(jpeg_component_info));
X /* Note: we allocate a 4-entry comp_info array so that user interface can
X * easily change over to CMYK color space if desired.
X */
X
X compptr = &cinfo->comp_info[0];
X compptr->component_index = 0;
X compptr->component_id = 1; /* JFIF specifies IDs 1,2,3 */
X compptr->h_samp_factor = 2; /* default to 2x2 subsamples of chrominance */
X compptr->v_samp_factor = 2;
X compptr->quant_tbl_no = 0; /* use tables 0 for luminance */
X compptr->dc_tbl_no = 0;
X compptr->ac_tbl_no = 0;
X
X compptr = &cinfo->comp_info[1];
X compptr->component_index = 1;
X compptr->component_id = 2;
X compptr->h_samp_factor = 1;
X compptr->v_samp_factor = 1;
X compptr->quant_tbl_no = 1; /* use tables 1 for chrominance */
X compptr->dc_tbl_no = 1;
X compptr->ac_tbl_no = 1;
X
X compptr = &cinfo->comp_info[2];
X compptr->component_index = 2;
X compptr->component_id = 3;
X compptr->h_samp_factor = 1;
X compptr->v_samp_factor = 1;
X compptr->quant_tbl_no = 1; /* use tables 1 for chrominance */
X compptr->dc_tbl_no = 1;
X compptr->ac_tbl_no = 1;
X
X /* Set up two quantization tables using the specified quality scaling */
X j_set_quality(cinfo, quality, force_baseline);
X
X /* Set up two Huffman tables in case user interface wants Huffman coding */
X std_huff_tables(cinfo);
X
X /* Initialize default arithmetic coding conditioning */
X for (i = 0; i < NUM_ARITH_TBLS; i++) {
X cinfo->arith_dc_L[i] = 0;
X cinfo->arith_dc_U[i] = 1;
X cinfo->arith_ac_K[i] = 5;
X }
X
X /* Use Huffman coding, not arithmetic coding, by default */
X cinfo->arith_code = FALSE;
X
X /* Color images are interleaved by default */
X cinfo->interleave = TRUE;
X
X /* By default, don't do extra passes to optimize entropy coding */
X cinfo->optimize_coding = FALSE;
X
X /* By default, use the simpler non-cosited sampling alignment */
X cinfo->CCIR601_sampling = FALSE;
X
X /* No restart markers */
X cinfo->restart_interval = 0;
X
X /* Install default do-nothing progress monitoring method. */
X cinfo->methods->progress_monitor = progress_monitor;
X}
X
X
X
XGLOBAL void
Xj_monochrome_default (compress_info_ptr cinfo)
X/* Change the j_c_defaults() values to emit a monochrome JPEG file. */
X{
X jpeg_component_info * compptr;
X
X cinfo->jpeg_color_space = CS_GRAYSCALE;
X cinfo->num_components = 1;
X /* Set single component to 1x1 subsampling */
X compptr = &cinfo->comp_info[0];
X compptr->h_samp_factor = 1;
X compptr->v_samp_factor = 1;
X}
END_OF_FILE
if test 14213 -ne `wc -c <'jcdeflts.c'`; then
echo shar: \"'jcdeflts.c'\" unpacked with wrong size!
fi
# end of 'jcdeflts.c'
fi
if test -f 'jdpipe.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdpipe.c'\"
else
echo shar: Extracting \"'jdpipe.c'\" \(36733 characters\)
sed "s/^X//" >'jdpipe.c' <<'END_OF_FILE'
X/*
X * jdpipe.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains decompression pipeline controllers.
X * These routines are invoked via the d_pipeline_controller method.
X *
X * There are two basic pipeline controllers. The simpler one handles a
X * single-scan JPEG file (single component or fully interleaved) with no
X * color quantization or 1-pass quantization. In this case, the file can
X * be processed in one top-to-bottom pass. The more complex controller is
X * used when 2-pass color quantization is requested and/or the JPEG file
X * has multiple scans (noninterleaved or partially interleaved). In this
X * case, the entire image must be buffered up in a "big" array.
X *
X * If you need to make a minimal implementation, the more complex controller
X * can be compiled out by disabling the appropriate configuration options.
X * We don't recommend this, since then you can't handle all legal JPEG files.
X */
X
X#include "jinclude.h"
X
X
X#ifdef MULTISCAN_FILES_SUPPORTED /* wish we could assume ANSI's defined() */
X#define NEED_COMPLEX_CONTROLLER
X#else
X#ifdef QUANT_2PASS_SUPPORTED
X#define NEED_COMPLEX_CONTROLLER
X#endif
X#endif
X
X
X/*
X * About the data structures:
X *
X * The processing chunk size for unsubsampling is referred to in this file as
X * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
X * any component while subsampled, or Vmax (max_v_samp_factor) unsubsampled
X * rows. In an interleaved scan each MCU row contains exactly DCTSIZE row
X * groups of each component in the scan. In a noninterleaved scan an MCU row
X * is one row of blocks, which might not be an integral number of row groups;
X * therefore, we read in Vk MCU rows to obtain the same amount of data as we'd
X * have in an interleaved scan.
X * To provide context for the unsubsampling step, we have to retain the last
X * two row groups of the previous MCU row while reading in the next MCU row
X * (or set of Vk MCU rows). To do this without copying data about, we create
X * a rather strange data structure. Exactly DCTSIZE+2 row groups of samples
X * are allocated, but we create two different sets of pointers to this array.
X * The second set swaps the last two pairs of row groups. By working
X * alternately with the two sets of pointers, we can access the data in the
X * desired order.
X *
X * Cross-block smoothing also needs context above and below the "current" row.
X * Since this is an optional feature, I've implemented it in a way that is
X * much simpler but requires more than the minimum amount of memory. We
X * simply allocate three extra MCU rows worth of coefficient blocks and use
X * them to "read ahead" one MCU row in the file. For a typical 1000-pixel-wide
X * image with 2x2,1x1,1x1 sampling, each MCU row is about 50Kb; an 80x86
X * machine may be unable to apply cross-block smoothing to wider images.
X */
X
X
X/*
X * These variables are logically local to the pipeline controller,
X * but we make them static so that scan_big_image can use them
X * without having to pass them through the quantization routines.
X */
X
Xstatic int rows_in_mem; /* # of sample rows in full-size buffers */
X/* Work buffer for data being passed to output module. */
X/* This has color_out_comps components if not quantizing, */
X/* but only one component when quantizing. */
Xstatic JSAMPIMAGE output_workspace;
X
X#ifdef NEED_COMPLEX_CONTROLLER
X/* Full-size image array holding desubsampled, but not color-processed data. */
Xstatic big_sarray_ptr *fullsize_image;
Xstatic JSAMPIMAGE fullsize_ptrs; /* workspace for access_big_sarray() result */
X#endif
X
X
X/*
X * Utility routines: common code for pipeline controllers
X */
X
XLOCAL void
Xinterleaved_scan_setup (decompress_info_ptr cinfo)
X/* Compute all derived info for an interleaved (multi-component) scan */
X/* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
X{
X short ci, mcublks;
X jpeg_component_info *compptr;
X
X if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
X ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
X
X cinfo->MCUs_per_row = (cinfo->image_width
X + cinfo->max_h_samp_factor*DCTSIZE - 1)
X / (cinfo->max_h_samp_factor*DCTSIZE);
X
X cinfo->MCU_rows_in_scan = (cinfo->image_height
X + cinfo->max_v_samp_factor*DCTSIZE - 1)
X / (cinfo->max_v_samp_factor*DCTSIZE);
X
X cinfo->blocks_in_MCU = 0;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X /* for interleaved scan, sampling factors give # of blocks per component */
X compptr->MCU_width = compptr->h_samp_factor;
X compptr->MCU_height = compptr->v_samp_factor;
X compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
X /* compute physical dimensions of component */
X compptr->subsampled_width = jround_up(compptr->true_comp_width,
X (long) (compptr->MCU_width*DCTSIZE));
X compptr->subsampled_height = jround_up(compptr->true_comp_height,
X (long) (compptr->MCU_height*DCTSIZE));
X /* Sanity check */
X if (compptr->subsampled_width !=
X (cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
X ERREXIT(cinfo->emethods, "I'm confused about the image width");
X /* Prepare array describing MCU composition */
X mcublks = compptr->MCU_blocks;
X if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
X ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
X while (mcublks-- > 0) {
X cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
X }
X }
X
X (*cinfo->methods->d_per_scan_method_selection) (cinfo);
X}
X
X
XLOCAL void
Xnoninterleaved_scan_setup (decompress_info_ptr cinfo)
X/* Compute all derived info for a noninterleaved (single-component) scan */
X/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
X{
X jpeg_component_info *compptr = cinfo->cur_comp_info[0];
X
X /* for noninterleaved scan, always one block per MCU */
X compptr->MCU_width = 1;
X compptr->MCU_height = 1;
X compptr->MCU_blocks = 1;
X /* compute physical dimensions of component */
X compptr->subsampled_width = jround_up(compptr->true_comp_width,
X (long) DCTSIZE);
X compptr->subsampled_height = jround_up(compptr->true_comp_height,
X (long) DCTSIZE);
X
X cinfo->MCUs_per_row = compptr->subsampled_width / DCTSIZE;
X cinfo->MCU_rows_in_scan = compptr->subsampled_height / DCTSIZE;
X
X /* Prepare array describing MCU composition */
X cinfo->blocks_in_MCU = 1;
X cinfo->MCU_membership[0] = 0;
X
X (*cinfo->methods->d_per_scan_method_selection) (cinfo);
X}
X
X
X
XLOCAL JSAMPIMAGE
Xalloc_sampimage (decompress_info_ptr cinfo,
X int num_comps, long num_rows, long num_cols)
X/* Allocate an in-memory sample image (all components same size) */
X{
X JSAMPIMAGE image;
X int ci;
X
X image = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (num_comps * SIZEOF(JSAMPARRAY));
X for (ci = 0; ci < num_comps; ci++) {
X image[ci] = (*cinfo->emethods->alloc_small_sarray) (num_cols, num_rows);
X }
X return image;
X}
X
X
X#if 0 /* this routine not currently needed */
X
XLOCAL void
Xfree_sampimage (decompress_info_ptr cinfo, JSAMPIMAGE image, int num_comps)
X/* Release a sample image created by alloc_sampimage */
X{
X int ci;
X
X for (ci = 0; ci < num_comps; ci++) {
X (*cinfo->emethods->free_small_sarray) (image[ci]);
X }
X (*cinfo->emethods->free_small) ((void *) image);
X}
X
X#endif
X
X
XLOCAL JBLOCKIMAGE
Xalloc_MCU_row (decompress_info_ptr cinfo)
X/* Allocate one MCU row's worth of coefficient blocks */
X{
X JBLOCKIMAGE image;
X int ci;
X
X image = (JBLOCKIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->comps_in_scan * SIZEOF(JBLOCKARRAY));
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X image[ci] = (*cinfo->emethods->alloc_small_barray)
X (cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE,
X (long) cinfo->cur_comp_info[ci]->MCU_height);
X }
X return image;
X}
X
X
X#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
X
XLOCAL void
Xfree_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image)
X/* Release a coefficient block array created by alloc_MCU_row */
X{
X int ci;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X (*cinfo->emethods->free_small_barray) (image[ci]);
X }
X (*cinfo->emethods->free_small) ((void *) image);
X}
X
X#endif
X
X
XLOCAL void
Xalloc_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
X/* Create a subsampled-data buffer having the desired structure */
X/* (see comments at head of file) */
X{
X short ci, vs, i;
X
X /* Get top-level space for array pointers */
X subsampled_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
X subsampled_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X vs = cinfo->cur_comp_info[ci]->v_samp_factor; /* row group height */
X /* Allocate the real storage */
X subsampled_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
X (cinfo->cur_comp_info[ci]->subsampled_width,
X (long) (vs * (DCTSIZE+2)));
X /* Create space for the scrambled-order pointers */
X subsampled_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
X (vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
X /* Duplicate the first DCTSIZE-2 row groups */
X for (i = 0; i < vs * (DCTSIZE-2); i++) {
X subsampled_data[1][ci][i] = subsampled_data[0][ci][i];
X }
X /* Copy the last four row groups in swapped order */
X for (i = 0; i < vs * 2; i++) {
X subsampled_data[1][ci][vs*DCTSIZE + i] = subsampled_data[0][ci][vs*(DCTSIZE-2) + i];
X subsampled_data[1][ci][vs*(DCTSIZE-2) + i] = subsampled_data[0][ci][vs*DCTSIZE + i];
X }
X }
X}
X
X
X#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
X
XLOCAL void
Xfree_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
X/* Release a sampling buffer created by alloc_sampling_buffer */
X{
X short ci;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X /* Free the real storage */
X (*cinfo->emethods->free_small_sarray) (subsampled_data[0][ci]);
X /* Free the scrambled-order pointers */
X (*cinfo->emethods->free_small) ((void *) subsampled_data[1][ci]);
X }
X
X /* Free the top-level space */
X (*cinfo->emethods->free_small) ((void *) subsampled_data[0]);
X (*cinfo->emethods->free_small) ((void *) subsampled_data[1]);
X}
X
X#endif
X
X
XLOCAL void
Xduplicate_row (JSAMPARRAY image_data,
X long num_cols, int source_row, int num_rows)
X/* Duplicate the source_row at source_row+1 .. source_row+num_rows */
X/* This happens only at the bottom of the image, */
X/* so it needn't be super-efficient */
X{
X register int row;
X
X for (row = 1; row <= num_rows; row++) {
X jcopy_sample_rows(image_data, source_row, image_data, source_row + row,
X 1, num_cols);
X }
X}
X
X
XLOCAL void
Xexpand (decompress_info_ptr cinfo,
X JSAMPIMAGE subsampled_data, JSAMPIMAGE fullsize_data,
X long fullsize_width,
X short above, short current, short below, short out)
X/* Do unsubsampling expansion of a single row group (of each component). */
X/* above, current, below are indexes of row groups in subsampled_data; */
X/* out is the index of the target row group in fullsize_data. */
X/* Special case: above, below can be -1 to indicate top, bottom of image. */
X{
X jpeg_component_info *compptr;
X JSAMPARRAY above_ptr, below_ptr;
X JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for subsample expansion at top/bottom */
X short ci, vs, i;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X vs = compptr->v_samp_factor; /* row group height */
X
X if (above >= 0)
X above_ptr = subsampled_data[ci] + above * vs;
X else {
X /* Top of image: make a dummy above-context with copies of 1st row */
X /* We assume current=0 in this case */
X for (i = 0; i < vs; i++)
X dummy[i] = subsampled_data[ci][0];
X above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
X }
X
X if (below >= 0)
X below_ptr = subsampled_data[ci] + below * vs;
X else {
X /* Bot of image: make a dummy below-context with copies of last row */
X for (i = 0; i < vs; i++)
X dummy[i] = subsampled_data[ci][(current+1)*vs-1];
X below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
X }
X
X (*cinfo->methods->unsubsample[ci])
X (cinfo, (int) ci,
X compptr->subsampled_width, (int) vs,
X fullsize_width, (int) cinfo->max_v_samp_factor,
X above_ptr,
X subsampled_data[ci] + current * vs,
X below_ptr,
X fullsize_data[ci] + out * cinfo->max_v_samp_factor);
X }
X}
X
X
XLOCAL void
Xemit_1pass (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE fullsize_data,
X JSAMPARRAY dummy)
X/* Do color processing and output of num_rows full-size rows. */
X/* This is not used when doing 2-pass color quantization. */
X/* The dummy argument simply lets this be called via scan_big_image. */
X{
X if (cinfo->quantize_colors) {
X (*cinfo->methods->color_quantize) (cinfo, num_rows, fullsize_data,
X output_workspace[0]);
X } else {
X (*cinfo->methods->color_convert) (cinfo, num_rows, cinfo->image_width,
X fullsize_data, output_workspace);
X }
X
X (*cinfo->methods->put_pixel_rows) (cinfo, num_rows, output_workspace);
X}
X
X
X/*
X * Support routines for complex controller.
X */
X
X#ifdef NEED_COMPLEX_CONTROLLER
X
XMETHODDEF void
Xscan_big_image (decompress_info_ptr cinfo, quantize_method_ptr quantize_method)
X/* Apply quantize_method to entire image stored in fullsize_image[]. */
X/* This is the "iterator" routine used by the 2-pass color quantizer. */
X/* We also use it directly in some cases. */
X{
X long pixel_rows_output;
X short ci;
X
X for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height;
X pixel_rows_output += rows_in_mem) {
X (*cinfo->methods->progress_monitor) (cinfo, pixel_rows_output,
X cinfo->image_height);
X /* Realign the big buffers */
X for (ci = 0; ci < cinfo->num_components; ci++) {
X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
X (fullsize_image[ci], pixel_rows_output, FALSE);
X }
X /* Let the quantizer have its way with the data.
X * Note that output_workspace is simply workspace for the quantizer;
X * when it's ready to output, it must call put_pixel_rows itself.
X */
X (*quantize_method) (cinfo,
X (int) MIN((long) rows_in_mem,
X cinfo->image_height - pixel_rows_output),
X fullsize_ptrs, output_workspace[0]);
X }
X
X cinfo->completed_passes++;
X}
X
X#endif /* NEED_COMPLEX_CONTROLLER */
X
X
X/*
X * Support routines for cross-block smoothing.
X */
X
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X
X
XLOCAL void
Xsmooth_mcu_row (decompress_info_ptr cinfo,
X JBLOCKIMAGE above, JBLOCKIMAGE input, JBLOCKIMAGE below,
X JBLOCKIMAGE output)
X/* Apply cross-block smoothing to one MCU row's worth of coefficient blocks. */
X/* above,below are NULL if at top/bottom of image. */
X{
X jpeg_component_info *compptr;
X short ci, ri, last;
X JBLOCKROW prev;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X last = compptr->MCU_height - 1;
X
X if (above == NULL)
X prev = NULL;
X else
X prev = above[ci][last];
X
X for (ri = 0; ri < last; ri++) {
X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
X prev, input[ci][ri], input[ci][ri+1],
X output[ci][ri]);
X prev = input[ci][ri];
X }
X
X if (below == NULL)
X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
X prev, input[ci][last], (JBLOCKROW) NULL,
X output[ci][last]);
X else
X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
X prev, input[ci][last], below[ci][0],
X output[ci][last]);
X }
X}
X
X
XLOCAL void
Xget_smoothed_row (decompress_info_ptr cinfo, JBLOCKIMAGE coeff_data,
X JBLOCKIMAGE bsmooth[3], int * whichb, long cur_mcu_row)
X/* Get an MCU row of coefficients, applying cross-block smoothing. */
X/* The output row is placed in coeff_data. bsmooth and whichb hold */
X/* working state, and cur_row is needed to check for image top/bottom. */
X/* This routine just takes care of the buffering logic. */
X{
X int prev, cur, next;
X
X /* Special case for top of image: need to pre-fetch a row & init whichb */
X if (cur_mcu_row == 0) {
X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[0]);
X if (cinfo->MCU_rows_in_scan > 1) {
X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[1]);
X smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], bsmooth[1],
X coeff_data);
X } else {
X smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], (JBLOCKIMAGE) NULL,
X coeff_data);
X }
X *whichb = 1; /* points to next bsmooth[] element to use */
X return;
X }
X
X cur = *whichb; /* set up references */
X prev = (cur == 0 ? 2 : cur - 1);
X next = (cur == 2 ? 0 : cur + 1);
X *whichb = next; /* advance whichb for next time */
X
X /* Special case for bottom of image: don't read another row */
X if (cur_mcu_row >= cinfo->MCU_rows_in_scan - 1) {
X smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], (JBLOCKIMAGE) NULL,
X coeff_data);
X return;
X }
X
X /* Normal case: read ahead a new row, smooth the one I got before */
X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[next]);
X smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], bsmooth[next],
X coeff_data);
X}
X
X
X#endif /* BLOCK_SMOOTHING_SUPPORTED */
X
X
X
X/*
X * Decompression pipeline controller used for single-scan files
X * without 2-pass color quantization.
X */
X
XMETHODDEF void
Xsimple_dcontroller (decompress_info_ptr cinfo)
X{
X long fullsize_width; /* # of samples per row in full-size buffers */
X long cur_mcu_row; /* counts # of MCU rows processed */
X long pixel_rows_output; /* # of pixel rows actually emitted */
X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
X /* Work buffer for dequantized coefficients (IDCT input) */
X JBLOCKIMAGE coeff_data;
X /* Work buffer for cross-block smoothing input */
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X JBLOCKIMAGE bsmooth[3]; /* this is optional */
X int whichb;
X#endif
X /* Work buffer for subsampled image data (see comments at head of file) */
X JSAMPIMAGE subsampled_data[2];
X /* Work buffer for desubsampled data */
X JSAMPIMAGE fullsize_data;
X int whichss, ri;
X short i;
X
X /* Compute dimensions of full-size pixel buffers */
X /* Note these are the same whether interleaved or not. */
X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
X fullsize_width = jround_up(cinfo->image_width,
X (long) (cinfo->max_h_samp_factor * DCTSIZE));
X
X /* Prepare for single scan containing all components */
X if (cinfo->comps_in_scan == 1) {
X noninterleaved_scan_setup(cinfo);
X /* Need to read Vk MCU rows to obtain Vk block rows */
X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
X } else {
X interleaved_scan_setup(cinfo);
X /* in an interleaved scan, one MCU row provides Vk block rows */
X mcu_rows_per_loop = 1;
X }
X cinfo->total_passes++;
X
X /* Allocate working memory: */
X /* coeff_data holds a single MCU row of coefficient blocks */
X coeff_data = alloc_MCU_row(cinfo);
X /* if doing cross-block smoothing, need extra space for its input */
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X if (cinfo->do_block_smoothing) {
X bsmooth[0] = alloc_MCU_row(cinfo);
X bsmooth[1] = alloc_MCU_row(cinfo);
X bsmooth[2] = alloc_MCU_row(cinfo);
X }
X#endif
X /* subsampled_data is sample data before unsubsampling */
X alloc_sampling_buffer(cinfo, subsampled_data);
X /* fullsize_data is sample data after unsubsampling */
X fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
X (long) rows_in_mem, fullsize_width);
X /* output_workspace is the color-processed data */
X output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
X (long) rows_in_mem, fullsize_width);
X
X /* Tell the memory manager to instantiate big arrays.
X * We don't need any big arrays in this controller,
X * but some other module (like the output file writer) may need one.
X */
X (*cinfo->emethods->alloc_big_arrays)
X ((long) 0, /* no more small sarrays */
X (long) 0, /* no more small barrays */
X (long) 0); /* no more "medium" objects */
X /* NB: if quantizer needs any "medium" size objects, it must get them */
X /* at color_quant_init time */
X
X /* Initialize to read scan data */
X
X (*cinfo->methods->entropy_decoder_init) (cinfo);
X (*cinfo->methods->unsubsample_init) (cinfo);
X (*cinfo->methods->disassemble_init) (cinfo);
X
X /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
X
X pixel_rows_output = 0;
X whichss = 1; /* arrange to start with subsampled_data[0] */
X
X for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
X cur_mcu_row += mcu_rows_per_loop) {
X (*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
X cinfo->MCU_rows_in_scan);
X
X whichss ^= 1; /* switch to other subsample buffer */
X
X /* Obtain v_samp_factor block rows of each component in the scan. */
X /* This is a single MCU row if interleaved, multiple MCU rows if not. */
X /* In the noninterleaved case there might be fewer than v_samp_factor */
X /* block rows remaining; if so, pad with copies of the last pixel row */
X /* so that unsubsampling doesn't have to treat it as a special case. */
X
X for (ri = 0; ri < mcu_rows_per_loop; ri++) {
X if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
X /* OK to actually read an MCU row. */
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X if (cinfo->do_block_smoothing)
X get_smoothed_row(cinfo, coeff_data,
X bsmooth, &whichb, cur_mcu_row + ri);
X else
X#endif
X (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
X
X (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
X subsampled_data[whichss],
X ri * DCTSIZE);
X } else {
X /* Need to pad out with copies of the last subsampled row. */
X /* This can only happen if there is just one component. */
X duplicate_row(subsampled_data[whichss][0],
X cinfo->cur_comp_info[0]->subsampled_width,
X ri * DCTSIZE - 1, DCTSIZE);
X }
X }
X
X /* Unsubsample the data */
X /* First time through is a special case */
X
X if (cur_mcu_row) {
X /* Expand last row group of previous set */
X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
X (short) (DCTSIZE-1));
X /* and dump the previous set's expanded data */
X emit_1pass (cinfo, rows_in_mem, fullsize_data, NULL);
X pixel_rows_output += rows_in_mem;
X /* Expand first row group of this set */
X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
X (short) (DCTSIZE+1), (short) 0, (short) 1,
X (short) 0);
X } else {
X /* Expand first row group with dummy above-context */
X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
X (short) (-1), (short) 0, (short) 1,
X (short) 0);
X }
X /* Expand second through next-to-last row groups of this set */
X for (i = 1; i <= DCTSIZE-2; i++) {
X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
X (short) (i-1), (short) i, (short) (i+1),
X (short) i);
X }
X } /* end of outer loop */
X
X /* Expand the last row group with dummy below-context */
X /* Note whichss points to last buffer side used */
X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
X (short) (DCTSIZE-1));
X /* and dump the remaining data (may be less than full height) */
X emit_1pass (cinfo, (int) (cinfo->image_height - pixel_rows_output),
X fullsize_data, NULL);
X
X /* Clean up after the scan */
X (*cinfo->methods->disassemble_term) (cinfo);
X (*cinfo->methods->unsubsample_term) (cinfo);
X (*cinfo->methods->entropy_decoder_term) (cinfo);
X (*cinfo->methods->read_scan_trailer) (cinfo);
X cinfo->completed_passes++;
X
X /* Verify that we've seen the whole input file */
X if ((*cinfo->methods->read_scan_header) (cinfo))
X ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
X
X /* Release working memory */
X /* (no work -- we let free_all release what's needful) */
X}
X
X
X/*
X * Decompression pipeline controller used for multiple-scan files
X * and/or 2-pass color quantization.
X *
X * The current implementation places the "big" buffer at the stage of
X * desubsampled, non-color-processed data. This is the only place that
X * makes sense when doing 2-pass quantization. For processing multiple-scan
X * files without 2-pass quantization, it would be possible to develop another
X * controller that buffers the subsampled data instead, thus reducing the size
X * of the temp files (by about a factor of 2 in typical cases). However,
X * our present unsubsampling logic is dependent on the assumption that
X * unsubsampling occurs during a scan, so it's much easier to do the
X * enlargement as the JPEG file is read. This also simplifies life for the
X * memory manager, which would otherwise have to deal with overlapping
X * access_big_sarray() requests.
X * At present it appears that most JPEG files will be single-scan,
X * so it doesn't seem worthwhile to worry about this optimization.
X */
X
X#ifdef NEED_COMPLEX_CONTROLLER
X
XMETHODDEF void
Xcomplex_dcontroller (decompress_info_ptr cinfo)
X{
X long fullsize_width; /* # of samples per row in full-size buffers */
X long cur_mcu_row; /* counts # of MCU rows processed */
X long pixel_rows_output; /* # of pixel rows actually emitted */
X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
X /* Work buffer for dequantized coefficients (IDCT input) */
X JBLOCKIMAGE coeff_data;
X /* Work buffer for cross-block smoothing input */
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X JBLOCKIMAGE bsmooth[3]; /* this is optional */
X int whichb;
X#endif
X /* Work buffer for subsampled image data (see comments at head of file) */
X JSAMPIMAGE subsampled_data[2];
X int whichss, ri;
X short ci, i;
X boolean single_scan;
X
X /* Compute dimensions of full-size pixel buffers */
X /* Note these are the same whether interleaved or not. */
X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
X fullsize_width = jround_up(cinfo->image_width,
X (long) (cinfo->max_h_samp_factor * DCTSIZE));
X
X /* Allocate all working memory that doesn't depend on scan info */
X /* output_workspace is the color-processed data */
X output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
X (long) rows_in_mem, fullsize_width);
X
X /* Get a big image: fullsize_image is sample data after unsubsampling. */
X fullsize_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
X (cinfo->num_components * SIZEOF(big_sarray_ptr));
X for (ci = 0; ci < cinfo->num_components; ci++) {
X fullsize_image[ci] = (*cinfo->emethods->request_big_sarray)
X (fullsize_width,
X jround_up(cinfo->image_height, (long) rows_in_mem),
X (long) rows_in_mem);
X }
X /* Also get an area for pointers to currently accessible chunks */
X fullsize_ptrs = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->num_components * SIZEOF(JSAMPARRAY));
X
X /* Tell the memory manager to instantiate big arrays */
X (*cinfo->emethods->alloc_big_arrays)
X /* extra sarray space is for subsampled-data buffers: */
X ((long) (fullsize_width /* max width in samples */
X * cinfo->max_v_samp_factor*(DCTSIZE+2) /* max height */
X * cinfo->num_components), /* max components per scan */
X /* extra barray space is for MCU-row buffers: */
X (long) ((fullsize_width / DCTSIZE) /* max width in blocks */
X * cinfo->max_v_samp_factor /* max height */
X * cinfo->num_components /* max components per scan */
X * (cinfo->do_block_smoothing ? 4 : 1)),/* how many of these we need */
X /* no extra "medium"-object space */
X (long) 0);
X /* NB: if quantizer needs any "medium" size objects, it must get them */
X /* at color_quant_init time */
X
X /* If file is single-scan, we can do color quantization prescan on-the-fly
X * during the scan (we must be doing 2-pass quantization, else this method
X * would not have been selected). If it is multiple scans, we have to make
X * a separate pass after we've collected all the components. (We could save
X * some I/O by doing CQ prescan during the last scan, but the extra logic
X * doesn't seem worth the trouble.)
X */
X
X single_scan = (cinfo->comps_in_scan == cinfo->num_components);
X
X /* Account for passes needed (color quantizer adds its passes separately).
X * If multiscan file, we guess that each component has its own scan,
X * and increment completed_passes by the number of components in the scan.
X */
X
X if (single_scan)
X cinfo->total_passes++; /* the single scan */
X else {
X cinfo->total_passes += cinfo->num_components; /* guessed # of scans */
X if (cinfo->two_pass_quantize)
X cinfo->total_passes++; /* account for separate CQ prescan pass */
X }
X if (! cinfo->two_pass_quantize)
X cinfo->total_passes++; /* count output pass unless quantizer does it */
X
X /* Loop over scans in file */
X
X do {
X
X /* Prepare for this scan */
X if (cinfo->comps_in_scan == 1) {
X noninterleaved_scan_setup(cinfo);
X /* Need to read Vk MCU rows to obtain Vk block rows */
X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
X } else {
X interleaved_scan_setup(cinfo);
X /* in an interleaved scan, one MCU row provides Vk block rows */
X mcu_rows_per_loop = 1;
X }
X
X /* Allocate scan-local working memory */
X /* coeff_data holds a single MCU row of coefficient blocks */
X coeff_data = alloc_MCU_row(cinfo);
X /* if doing cross-block smoothing, need extra space for its input */
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X if (cinfo->do_block_smoothing) {
X bsmooth[0] = alloc_MCU_row(cinfo);
X bsmooth[1] = alloc_MCU_row(cinfo);
X bsmooth[2] = alloc_MCU_row(cinfo);
X }
X#endif
X /* subsampled_data is sample data before unsubsampling */
X alloc_sampling_buffer(cinfo, subsampled_data);
X
X /* line up the big buffers for components in this scan */
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
X (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
X (long) 0, TRUE);
X }
X
X /* Initialize to read scan data */
X
X (*cinfo->methods->entropy_decoder_init) (cinfo);
X (*cinfo->methods->unsubsample_init) (cinfo);
X (*cinfo->methods->disassemble_init) (cinfo);
X
X /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
X
X pixel_rows_output = 0;
X whichss = 1; /* arrange to start with subsampled_data[0] */
X
X for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
X cur_mcu_row += mcu_rows_per_loop) {
X (*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
X cinfo->MCU_rows_in_scan);
X
X whichss ^= 1; /* switch to other subsample buffer */
X
X /* Obtain v_samp_factor block rows of each component in the scan. */
X /* This is a single MCU row if interleaved, multiple MCU rows if not. */
X /* In the noninterleaved case there might be fewer than v_samp_factor */
X /* block rows remaining; if so, pad with copies of the last pixel row */
X /* so that unsubsampling doesn't have to treat it as a special case. */
X
X for (ri = 0; ri < mcu_rows_per_loop; ri++) {
X if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
X /* OK to actually read an MCU row. */
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X if (cinfo->do_block_smoothing)
X get_smoothed_row(cinfo, coeff_data,
X bsmooth, &whichb, cur_mcu_row + ri);
X else
X#endif
X (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
X
X (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
X subsampled_data[whichss],
X ri * DCTSIZE);
X } else {
X /* Need to pad out with copies of the last subsampled row. */
X /* This can only happen if there is just one component. */
X duplicate_row(subsampled_data[whichss][0],
X cinfo->cur_comp_info[0]->subsampled_width,
X ri * DCTSIZE - 1, DCTSIZE);
X }
X }
X
X /* Unsubsample the data */
X /* First time through is a special case */
X
X if (cur_mcu_row) {
X /* Expand last row group of previous set */
X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
X (short) (DCTSIZE-1));
X /* If single scan, can do color quantization prescan on-the-fly */
X if (single_scan)
X (*cinfo->methods->color_quant_prescan) (cinfo, rows_in_mem,
X fullsize_ptrs,
X output_workspace[0]);
X /* Realign the big buffers */
X pixel_rows_output += rows_in_mem;
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
X (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
X pixel_rows_output, TRUE);
X }
X /* Expand first row group of this set */
X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
X (short) (DCTSIZE+1), (short) 0, (short) 1,
X (short) 0);
X } else {
X /* Expand first row group with dummy above-context */
X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
X (short) (-1), (short) 0, (short) 1,
X (short) 0);
X }
X /* Expand second through next-to-last row groups of this set */
X for (i = 1; i <= DCTSIZE-2; i++) {
X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
X (short) (i-1), (short) i, (short) (i+1),
X (short) i);
X }
X } /* end of loop over scan's data */
X
X /* Expand the last row group with dummy below-context */
X /* Note whichss points to last buffer side used */
X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
X (short) (DCTSIZE-1));
X /* If single scan, finish on-the-fly color quantization prescan */
X if (single_scan)
X (*cinfo->methods->color_quant_prescan) (cinfo,
X (int) (cinfo->image_height - pixel_rows_output),
X fullsize_ptrs, output_workspace[0]);
X
X /* Clean up after the scan */
X (*cinfo->methods->disassemble_term) (cinfo);
X (*cinfo->methods->unsubsample_term) (cinfo);
X (*cinfo->methods->entropy_decoder_term) (cinfo);
X (*cinfo->methods->read_scan_trailer) (cinfo);
X if (single_scan)
X cinfo->completed_passes++;
X else
X cinfo->completed_passes += cinfo->comps_in_scan;
X
X /* Release scan-local working memory */
X free_MCU_row(cinfo, coeff_data);
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X if (cinfo->do_block_smoothing) {
X free_MCU_row(cinfo, bsmooth[0]);
X free_MCU_row(cinfo, bsmooth[1]);
X free_MCU_row(cinfo, bsmooth[2]);
X }
X#endif
X free_sampling_buffer(cinfo, subsampled_data);
X
X /* Repeat if there is another scan */
X } while ((!single_scan) && (*cinfo->methods->read_scan_header) (cinfo));
X
X if (single_scan) {
X /* If we expected just one scan, make SURE there's just one */
X if ((*cinfo->methods->read_scan_header) (cinfo))
X ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
X /* We did the CQ prescan on-the-fly, so we are all set. */
X } else {
X /* For multiple-scan file, do the CQ prescan as a separate pass. */
X /* The main reason why prescan is passed the output_workspace is */
X /* so that we can use scan_big_image to call it... */
X if (cinfo->two_pass_quantize)
X scan_big_image(cinfo, cinfo->methods->color_quant_prescan);
X }
X
X /* Now that we've collected the data, do color processing and output */
X if (cinfo->two_pass_quantize)
X (*cinfo->methods->color_quant_doit) (cinfo, scan_big_image);
X else
X scan_big_image(cinfo, emit_1pass);
X
X /* Release working memory */
X /* (no work -- we let free_all release what's needful) */
X}
X
X#endif /* NEED_COMPLEX_CONTROLLER */
X
X
X/*
X * The method selection routine for decompression pipeline controllers.
X * Note that at this point we've already read the JPEG header and first SOS,
X * so we can tell whether the input is one scan or not.
X */
X
XGLOBAL void
Xjseldpipeline (decompress_info_ptr cinfo)
X{
X /* simplify subsequent tests on color quantization */
X if (! cinfo->quantize_colors)
X cinfo->two_pass_quantize = FALSE;
X
X if (cinfo->comps_in_scan == cinfo->num_components) {
X /* It's a single-scan file */
X if (cinfo->two_pass_quantize) {
X#ifdef NEED_COMPLEX_CONTROLLER
X cinfo->methods->d_pipeline_controller = complex_dcontroller;
X#else
X ERREXIT(cinfo->emethods, "2-pass quantization support was not compiled");
X#endif
X } else
X cinfo->methods->d_pipeline_controller = simple_dcontroller;
X } else {
X /* It's a multiple-scan file */
X#ifdef NEED_COMPLEX_CONTROLLER
X cinfo->methods->d_pipeline_controller = complex_dcontroller;
X#else
X ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
X#endif
X }
X}
END_OF_FILE
if test 36733 -ne `wc -c <'jdpipe.c'`; then
echo shar: \"'jdpipe.c'\" unpacked with wrong size!
fi
# end of 'jdpipe.c'
fi
echo shar: End of archive 3 \(of 18\).
cp /dev/null ark3isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jpegdata.h jwrgif.c makcjpeg.lnk
# Wrapped by kent@sparky on Mon Mar 23 16:02:42 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 4 (of 18)."'
if test -f 'jpegdata.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jpegdata.h'\"
else
echo shar: Extracting \"'jpegdata.h'\" \(37381 characters\)
sed "s/^X//" >'jpegdata.h' <<'END_OF_FILE'
X/*
X * jpegdata.h
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file defines shared data structures for the various JPEG modules.
X */
X
X
X/*
X * You might need to change some of the following declarations if you are
X * using the JPEG software within a surrounding application program
X * or porting it to an unusual system.
X */
X
X
X/* If the source or destination of image data is not to be stdio streams,
X * these types may need work. You can replace them with some kind of
X * pointer or indicator that is useful to you, or just ignore 'em.
X * Note that the user interface and the various jrdxxx/jwrxxx modules
X * will also need work for non-stdio input/output.
X */
X
Xtypedef FILE * JFILEREF; /* source or dest of JPEG-compressed data */
X
Xtypedef FILE * IFILEREF; /* source or dest of non-JPEG image data */
X
X
X/* These defines are used in all function definitions and extern declarations.
X * You could modify them if you need to change function linkage conventions,
X * as is shown below for use with C++. Another application would be to make
X * all functions global for use with code profilers that require it.
X * NOTE: the C++ test does the right thing if you are reading this include
X * file in a C++ application to link to JPEG code that's been compiled with a
X * regular C compiler. I'm not sure it works if you try to compile the JPEG
X * code with C++.
X */
X
X#define METHODDEF static /* a function called through method pointers */
X#define LOCAL static /* a function used only in its module */
X#define GLOBAL /* a function referenced thru EXTERNs */
X#ifdef __cplusplus
X#define EXTERN extern "C" /* a reference to a GLOBAL function */
X#else
X#define EXTERN extern /* a reference to a GLOBAL function */
X#endif
X
X
X/* Here is the pseudo-keyword for declaring pointers that must be "far"
X * on 80x86 machines. Most of the specialized coding for 80x86 is handled
X * by just saying "FAR *" where such a pointer is needed. In a few places
X * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
X */
X
X#ifdef NEED_FAR_POINTERS
X#define FAR far
X#else
X#define FAR
X#endif
X
X
X
X/* The remaining declarations are not system-dependent, we hope. */
X
X
X/*
X * NOTE: if you have an ancient, strict-K&R C compiler, it may choke on the
X * similarly-named fields in compress_info_struct and decompress_info_struct.
X * If this happens, you can get around it by rearranging the two structs so
X * that the similarly-named fields appear first and in the same order in
X * each struct. Since such compilers are now pretty rare, we haven't done
X * this in the portable code, preferring to maintain a logical ordering.
X */
X
X
X
X/* This macro is used to declare a "method", that is, a function pointer. */
X/* We want to supply prototype parameters if the compiler can cope. */
X/* Note that the arglist parameter must be parenthesized! */
X
X#ifdef PROTO
X#define METHOD(type,methodname,arglist) type (*methodname) arglist
X#else
X#define METHOD(type,methodname,arglist) type (*methodname) ()
X#endif
X
X/* Forward references to lists of method pointers */
Xtypedef struct external_methods_struct * external_methods_ptr;
Xtypedef struct compress_methods_struct * compress_methods_ptr;
Xtypedef struct decompress_methods_struct * decompress_methods_ptr;
X
X
X/* Data structures for images containing either samples or coefficients. */
X/* Note that the topmost (leftmost) index is always color component. */
X/* On 80x86 machines, the image arrays are too big for near pointers, */
X/* but the pointer arrays can fit in near memory. */
X
Xtypedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */
Xtypedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
Xtypedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
X
X
X#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
X#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
X
Xtypedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
Xtypedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */
Xtypedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
Xtypedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
X
Xtypedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */
X
X
X/* The input and output data of the DCT transform subroutines are of
X * the following type, which need not be the same as JCOEF.
X * For example, on a machine with fast floating point, it might make sense
X * to recode the DCT routines to use floating point; then DCTELEM would be
X * 'float' or 'double'.
X */
X
Xtypedef JCOEF DCTELEM;
Xtypedef DCTELEM DCTBLOCK[DCTSIZE2];
X
X
X/* Types for JPEG compression parameters and working tables. */
X
X
Xtypedef enum { /* defines known color spaces */
X CS_UNKNOWN, /* error/unspecified */
X CS_GRAYSCALE, /* monochrome (only 1 component) */
X CS_RGB, /* red/green/blue */
X CS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
X CS_YIQ, /* Y/I/Q */
X CS_CMYK /* C/M/Y/K */
X} COLOR_SPACE;
X
X
Xtypedef struct { /* Basic info about one component */
X /* These values are fixed over the whole image */
X /* For compression, they must be supplied by the user interface; */
X /* for decompression, they are read from the SOF marker. */
X short component_id; /* identifier for this component (0..255) */
X short component_index; /* its index in SOF or cinfo->comp_info[] */
X short h_samp_factor; /* horizontal sampling factor (1..4) */
X short v_samp_factor; /* vertical sampling factor (1..4) */
X short quant_tbl_no; /* quantization table selector (0..3) */
X /* These values may vary between scans */
X /* For compression, they must be supplied by the user interface; */
X /* for decompression, they are read from the SOS marker. */
X short dc_tbl_no; /* DC entropy table selector (0..3) */
X short ac_tbl_no; /* AC entropy table selector (0..3) */
X /* These values are computed during compression or decompression startup */
X long true_comp_width; /* component's image width in samples */
X long true_comp_height; /* component's image height in samples */
X /* the above are the logical dimensions of the subsampled image */
X /* These values are computed before starting a scan of the component */
X short MCU_width; /* number of blocks per MCU, horizontally */
X short MCU_height; /* number of blocks per MCU, vertically */
X short MCU_blocks; /* MCU_width * MCU_height */
X long subsampled_width; /* image width in samples, after expansion */
X long subsampled_height; /* image height in samples, after expansion */
X /* the above are the true_comp_xxx values rounded up to multiples of */
X /* the MCU dimensions; these are the working dimensions of the array */
X /* as it is passed through the DCT or IDCT step. NOTE: these values */
X /* differ depending on whether the component is interleaved or not!! */
X} jpeg_component_info;
X
X
X/* DCT coefficient quantization tables.
X * For 8-bit precision, 'INT16' should be good enough for quantization values;
X * for more precision, we go for the full 16 bits. 'INT16' provides a useful
X * speedup on many machines (multiplication & division of JCOEFs by
X * quantization values is a significant chunk of the runtime).
X * Note: the values in a QUANT_TBL are always given in zigzag order.
X */
X#ifdef EIGHT_BIT_SAMPLES
Xtypedef INT16 QUANT_VAL; /* element of a quantization table */
X#else
Xtypedef UINT16 QUANT_VAL; /* element of a quantization table */
X#endif
Xtypedef QUANT_VAL QUANT_TBL[DCTSIZE2]; /* A quantization table */
Xtypedef QUANT_VAL * QUANT_TBL_PTR; /* pointer to same */
X
X
Xtypedef struct { /* A Huffman coding table */
X /* These two fields directly represent the contents of a JPEG DHT marker */
X UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
X /* length k bits; bits[0] is unused */
X UINT8 huffval[256]; /* The symbols, in order of incr code length */
X /* This field is used only during compression. It's initialized FALSE when
X * the table is created, and set TRUE when it's been output to the file.
X */
X boolean sent_table; /* TRUE when table has been output */
X /* The remaining fields are computed from the above to allow more efficient
X * coding and decoding. These fields should be considered private to the
X * Huffman compression & decompression modules.
X */
X /* encoding tables: */
X UINT16 ehufco[256]; /* code for each symbol */
X char ehufsi[256]; /* length of code for each symbol */
X /* decoding tables: (element [0] of each array is unused) */
X UINT16 mincode[17]; /* smallest code of length k */
X INT32 maxcode[18]; /* largest code of length k (-1 if none) */
X /* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
X short valptr[17]; /* huffval[] index of 1st symbol of length k */
X} HUFF_TBL;
X
X
X#define NUM_QUANT_TBLS 4 /* quantization tables are numbered 0..3 */
X#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
X#define NUM_ARITH_TBLS 16 /* arith-coding tables are numbered 0..15 */
X#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
X#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
X#define MAX_BLOCKS_IN_MCU 10 /* JPEG limit on # of blocks in an MCU */
X
X
X/* Working data for compression */
X
Xstruct compress_info_struct {
X/*
X * All of these fields shall be established by the user interface before
X * calling jpeg_compress, or by the input_init or c_ui_method_selection
X * methods.
X * Most parameters can be set to reasonable defaults by j_c_defaults.
X * Note that the UI must supply the storage for the main methods struct,
X * though it sets only a few of the methods there.
X */
X compress_methods_ptr methods; /* Points to list of methods to use */
X
X external_methods_ptr emethods; /* Points to list of methods to use */
X
X IFILEREF input_file; /* tells input routines where to read image */
X JFILEREF output_file; /* tells output routines where to write JPEG */
X
X long image_width; /* input image width */
X long image_height; /* input image height */
X short input_components; /* # of color components in input image */
X
X short data_precision; /* bits of precision in image data */
X
X COLOR_SPACE in_color_space; /* colorspace of input file */
X COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file */
X
X double input_gamma; /* image gamma of input file */
X
X boolean write_JFIF_header; /* should a JFIF marker be written? */
X /* These three values are not used by the JPEG code, only copied */
X /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
X /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
X /* ratio is defined by X_density/Y_density even when density_unit=0. */
X UINT8 density_unit; /* JFIF code for pixel size units */
X UINT16 X_density; /* Horizontal pixel density */
X UINT16 Y_density; /* Vertical pixel density */
X
X short num_components; /* # of color components in JPEG image */
X jpeg_component_info * comp_info;
X /* comp_info[i] describes component that appears i'th in SOF */
X
X QUANT_TBL_PTR quant_tbl_ptrs[NUM_QUANT_TBLS];
X /* ptrs to coefficient quantization tables, or NULL if not defined */
X
X HUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
X HUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
X /* ptrs to Huffman coding tables, or NULL if not defined */
X
X UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arithmetic-coding tables */
X UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arithmetic-coding tables */
X UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arithmetic-coding tables */
X
X boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
X boolean interleave; /* TRUE=interleaved output, FALSE=not */
X boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
X boolean CCIR601_sampling; /* TRUE=first samples are cosited */
X
X UINT16 restart_interval;/* MDUs per restart interval, or 0 for no restart */
X
X/*
X * These fields are computed during jpeg_compress startup
X */
X short max_h_samp_factor; /* largest h_samp_factor */
X short max_v_samp_factor; /* largest v_samp_factor */
X
X/*
X * These fields may be useful for progress monitoring
X */
X
X int total_passes; /* number of passes expected */
X int completed_passes; /* number of passes completed so far */
X
X/*
X * These fields are valid during any one scan
X */
X short comps_in_scan; /* # of JPEG components output this time */
X jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
X /* *cur_comp_info[i] describes component that appears i'th in SOS */
X
X long MCUs_per_row; /* # of MCUs across the image */
X long MCU_rows_in_scan; /* # of MCU rows in the image */
X
X short blocks_in_MCU; /* # of DCT blocks per MCU */
X short MCU_membership[MAX_BLOCKS_IN_MCU];
X /* MCU_membership[i] is index in cur_comp_info of component owning */
X /* i'th block in an MCU */
X
X /* these fields are private data for the entropy encoder */
X JCOEF last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each comp */
X JCOEF last_dc_diff[MAX_COMPS_IN_SCAN]; /* last DC diff for each comp */
X UINT16 restarts_to_go; /* MDUs left in this restart interval */
X short next_restart_num; /* # of next RSTn marker (0..7) */
X};
X
Xtypedef struct compress_info_struct * compress_info_ptr;
X
X
X/* Working data for decompression */
X
Xstruct decompress_info_struct {
X/*
X * These fields shall be established by the user interface before
X * calling jpeg_decompress.
X * Most parameters can be set to reasonable defaults by j_d_defaults.
X * Note that the UI must supply the storage for the main methods struct,
X * though it sets only a few of the methods there.
X */
X decompress_methods_ptr methods; /* Points to list of methods to use */
X
X external_methods_ptr emethods; /* Points to list of methods to use */
X
X JFILEREF input_file; /* tells input routines where to read JPEG */
X IFILEREF output_file; /* tells output routines where to write image */
X
X /* these can be set at d_ui_method_selection time: */
X
X COLOR_SPACE out_color_space; /* colorspace of output */
X
X double output_gamma; /* image gamma wanted in output */
X
X boolean quantize_colors; /* T if output is a colormapped format */
X /* the following are ignored if not quantize_colors: */
X boolean two_pass_quantize; /* use two-pass color quantization? */
X boolean use_dithering; /* want color dithering? */
X int desired_number_of_colors; /* max number of colors to use */
X
X boolean do_block_smoothing; /* T = apply cross-block smoothing */
X boolean do_pixel_smoothing; /* T = apply post-subsampling smoothing */
X
X/*
X * These fields are used for efficient buffering of data between read_jpeg_data
X * and the entropy decoding object. By using a shared buffer, we avoid copying
X * data and eliminate the need for an "unget" operation at the end of a scan.
X * The actual source of the data is known only to read_jpeg_data; see the
X * JGETC macro, below.
X * Note: the user interface is expected to allocate the input_buffer and
X * initialize bytes_in_buffer to 0. Also, for JFIF/raw-JPEG input, the UI
X * actually supplies the read_jpeg_data method. This is all handled by
X * j_d_defaults in a typical implementation.
X */
X char * input_buffer; /* start of buffer (private to input code) */
X char * next_input_byte; /* => next byte to read from buffer */
X int bytes_in_buffer; /* # of bytes remaining in buffer */
X
X/*
X * These fields are set by read_file_header or read_scan_header
X */
X long image_width; /* overall image width */
X long image_height; /* overall image height */
X
X short data_precision; /* bits of precision in image data */
X
X COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file */
X
X /* These three values are not used by the JPEG code, merely copied */
X /* from the JFIF APP0 marker (if any). */
X UINT8 density_unit; /* JFIF code for pixel size units */
X UINT16 X_density; /* Horizontal pixel density */
X UINT16 Y_density; /* Vertical pixel density */
X
X short num_components; /* # of color components in JPEG image */
X jpeg_component_info * comp_info;
X /* comp_info[i] describes component that appears i'th in SOF */
X
X QUANT_TBL_PTR quant_tbl_ptrs[NUM_QUANT_TBLS];
X /* ptrs to coefficient quantization tables, or NULL if not defined */
X
X HUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
X HUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
X /* ptrs to Huffman coding tables, or NULL if not defined */
X
X UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
X UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
X UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
X
X boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
X boolean CCIR601_sampling; /* TRUE=first samples are cosited */
X
X UINT16 restart_interval;/* MDUs per restart interval, or 0 for no restart */
X
X/*
X * These fields are computed during jpeg_decompress startup
X */
X short max_h_samp_factor; /* largest h_samp_factor */
X short max_v_samp_factor; /* largest v_samp_factor */
X
X short color_out_comps; /* # of color components output by color_convert */
X /* (need not match num_components) */
X short final_out_comps; /* # of color components sent to put_pixel_rows */
X /* (1 when quantizing colors, else same as color_out_comps) */
X
X/*
X * When quantizing colors, the color quantizer leaves a pointer to the output
X * colormap in these fields. The colormap is valid from the time put_color_map
X * is called (must be before any put_pixel_rows calls) until shutdown (more
X * specifically, until free_all is called to release memory).
X */
X int actual_number_of_colors; /* actual number of entries */
X JSAMPARRAY colormap; /* NULL if not valid */
X /* map has color_out_comps rows * actual_number_of_colors columns */
X
X/*
X * These fields may be useful for progress monitoring
X */
X
X int total_passes; /* number of passes expected */
X int completed_passes; /* number of passes completed so far */
X
X/*
X * These fields are valid during any one scan
X */
X short comps_in_scan; /* # of JPEG components input this time */
X jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
X /* *cur_comp_info[i] describes component that appears i'th in SOS */
X
X long MCUs_per_row; /* # of MCUs across the image */
X long MCU_rows_in_scan; /* # of MCU rows in the image */
X
X short blocks_in_MCU; /* # of DCT blocks per MCU */
X short MCU_membership[MAX_BLOCKS_IN_MCU];
X /* MCU_membership[i] is index in cur_comp_info of component owning */
X /* i'th block in an MCU */
X
X /* these fields are private data for the entropy encoder */
X JCOEF last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each comp */
X JCOEF last_dc_diff[MAX_COMPS_IN_SCAN]; /* last DC diff for each comp */
X UINT16 restarts_to_go; /* MDUs left in this restart interval */
X short next_restart_num; /* # of next RSTn marker (0..7) */
X};
X
Xtypedef struct decompress_info_struct * decompress_info_ptr;
X
X
X/* Macros for reading data from the decompression input buffer */
X
X#ifdef CHAR_IS_UNSIGNED
X#define JGETC(cinfo) ( --(cinfo)->bytes_in_buffer < 0 ? \
X (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
X (int) (*(cinfo)->next_input_byte++) )
X#else
X#define JGETC(cinfo) ( --(cinfo)->bytes_in_buffer < 0 ? \
X (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
X (int) (*(cinfo)->next_input_byte++) & 0xFF )
X#endif
X
X#define JUNGETC(ch,cinfo) ((cinfo)->bytes_in_buffer++, \
X *(--((cinfo)->next_input_byte)) = (ch))
X
X#define MIN_UNGET 4 /* may always do at least 4 JUNGETCs */
X
X
X/* A virtual image has a control block whose contents are private to the
X * memory manager module (and may differ between managers). The rest of the
X * code only refers to virtual images by these pointer types, and never
X * dereferences the pointer.
X */
X
Xtypedef struct big_sarray_control * big_sarray_ptr;
Xtypedef struct big_barray_control * big_barray_ptr;
X
X/* Although a real ANSI C compiler can deal perfectly well with pointers to
X * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
X * and pseudo-ANSI compilers get confused. To keep one of these bozos happy,
X * add -DINCOMPLETE_TYPES_BROKEN to CFLAGS in your Makefile. Then we will
X * pseudo-define the structs as containing a single "dummy" field.
X * The memory managers #define AM_MEMORY_MANAGER before including this file,
X * so that they can make their own definitions of the structs.
X */
X
X#ifdef INCOMPLETE_TYPES_BROKEN
X#ifndef AM_MEMORY_MANAGER
Xstruct big_sarray_control { long dummy; };
Xstruct big_barray_control { long dummy; };
X#endif
X#endif
X
X
X/* Method types that need typedefs */
X
Xtypedef METHOD(void, MCU_output_method_ptr, (compress_info_ptr cinfo,
X JBLOCK *MCU_data));
Xtypedef METHOD(void, MCU_output_caller_ptr, (compress_info_ptr cinfo,
X MCU_output_method_ptr output_method));
Xtypedef METHOD(void, subsample_ptr, (compress_info_ptr cinfo,
X int which_component,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPARRAY above,
X JSAMPARRAY input_data,
X JSAMPARRAY below,
X JSAMPARRAY output_data));
Xtypedef METHOD(void, unsubsample_ptr, (decompress_info_ptr cinfo,
X int which_component,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPARRAY above,
X JSAMPARRAY input_data,
X JSAMPARRAY below,
X JSAMPARRAY output_data));
Xtypedef METHOD(void, quantize_method_ptr, (decompress_info_ptr cinfo,
X int num_rows,
X JSAMPIMAGE input_data,
X JSAMPARRAY output_workspace));
Xtypedef METHOD(void, quantize_caller_ptr, (decompress_info_ptr cinfo,
X quantize_method_ptr quantize_method));
X
X
X/* These structs contain function pointers for the various JPEG methods. */
X
X/* Routines to be provided by the surrounding application, rather than the
X * portable JPEG code proper. These are the same for compression and
X * decompression.
X */
X
Xstruct external_methods_struct {
X /* User interface: error exit and trace message routines */
X /* NOTE: the string msgtext parameters will eventually be replaced */
X /* by an enumerated-type code so that non-English error messages */
X /* can be substituted easily. This will not be done until all the */
X /* code is in place, so that we know what messages are needed. */
X METHOD(void, error_exit, (const char *msgtext));
X METHOD(void, trace_message, (const char *msgtext));
X
X /* Working data for error/trace facility */
X /* See macros below for the usage of these variables */
X int trace_level; /* level of detail of tracing messages */
X /* Use level 0 for unsuppressable messages (nonfatal errors) */
X /* Use levels 1, 2, 3 for successively more detailed trace options */
X
X int message_parm[8]; /* store numeric parms for messages here */
X
X /* Memory management */
X /* NB: alloc routines never return NULL. They exit to */
X /* error_exit if not successful. */
X METHOD(void *, alloc_small, (size_t sizeofobject));
X METHOD(void, free_small, (void *ptr));
X METHOD(void FAR *, alloc_medium, (size_t sizeofobject));
X METHOD(void, free_medium, (void FAR *ptr));
X METHOD(JSAMPARRAY, alloc_small_sarray, (long samplesperrow,
X long numrows));
X METHOD(void, free_small_sarray, (JSAMPARRAY ptr));
X METHOD(JBLOCKARRAY, alloc_small_barray, (long blocksperrow,
X long numrows));
X METHOD(void, free_small_barray, (JBLOCKARRAY ptr));
X METHOD(big_sarray_ptr, request_big_sarray, (long samplesperrow,
X long numrows,
X long unitheight));
X METHOD(big_barray_ptr, request_big_barray, (long blocksperrow,
X long numrows,
X long unitheight));
X METHOD(void, alloc_big_arrays, (long extra_small_samples,
X long extra_small_blocks,
X long extra_medium_space));
X METHOD(JSAMPARRAY, access_big_sarray, (big_sarray_ptr ptr,
X long start_row,
X boolean writable));
X METHOD(JBLOCKARRAY, access_big_barray, (big_barray_ptr ptr,
X long start_row,
X boolean writable));
X METHOD(void, free_big_sarray, (big_sarray_ptr ptr));
X METHOD(void, free_big_barray, (big_barray_ptr ptr));
X METHOD(void, free_all, (void));
X
X long max_memory_to_use; /* maximum amount of memory to use */
X};
X
X/* Macros to simplify using the error and trace message stuff */
X/* The first parameter is generally cinfo->emethods */
X
X#define ERREXIT(emeth,msg) ((*(emeth)->error_exit) (msg))
X#define ERREXIT1(emeth,msg,p1) ((emeth)->message_parm[0] = (p1), \
X (*(emeth)->error_exit) (msg))
X#define ERREXIT2(emeth,msg,p1,p2) ((emeth)->message_parm[0] = (p1), \
X (emeth)->message_parm[1] = (p2), \
X (*(emeth)->error_exit) (msg))
X#define ERREXIT3(emeth,msg,p1,p2,p3) ((emeth)->message_parm[0] = (p1), \
X (emeth)->message_parm[1] = (p2), \
X (emeth)->message_parm[2] = (p3), \
X (*(emeth)->error_exit) (msg))
X#define ERREXIT4(emeth,msg,p1,p2,p3,p4) ((emeth)->message_parm[0] = (p1), \
X (emeth)->message_parm[1] = (p2), \
X (emeth)->message_parm[2] = (p3), \
X (emeth)->message_parm[3] = (p4), \
X (*(emeth)->error_exit) (msg))
X
X#define MAKESTMT(stuff) do { stuff } while (0)
X
X#define TRACEMS(emeth,lvl,msg) \
X MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
X (*(emeth)->trace_message) (msg); } )
X#define TRACEMS1(emeth,lvl,msg,p1) \
X MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
X (emeth)->message_parm[0] = (p1); \
X (*(emeth)->trace_message) (msg); } )
X#define TRACEMS2(emeth,lvl,msg,p1,p2) \
X MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
X (emeth)->message_parm[0] = (p1); \
X (emeth)->message_parm[1] = (p2); \
X (*(emeth)->trace_message) (msg); } )
X#define TRACEMS3(emeth,lvl,msg,p1,p2,p3) \
X MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
X int * _mp = (emeth)->message_parm; \
X *_mp++ = (p1); *_mp++ = (p2); *_mp = (p3); \
X (*(emeth)->trace_message) (msg); } )
X#define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4) \
X MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
X int * _mp = (emeth)->message_parm; \
X *_mp++ = (p1); *_mp++ = (p2); *_mp++ = (p3); *_mp = (p4); \
X (*(emeth)->trace_message) (msg); } )
X#define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8) \
X MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
X int * _mp = (emeth)->message_parm; \
X *_mp++ = (p1); *_mp++ = (p2); *_mp++ = (p3); *_mp++ = (p4); \
X *_mp++ = (p5); *_mp++ = (p6); *_mp++ = (p7); *_mp = (p8); \
X (*(emeth)->trace_message) (msg); } )
X
X
X/* Methods used during JPEG compression. */
X
Xstruct compress_methods_struct {
X /* Hook for user interface to get control after input_init */
X METHOD(void, c_ui_method_selection, (compress_info_ptr cinfo));
X /* Hook for user interface to do progress monitoring */
X METHOD(void, progress_monitor, (compress_info_ptr cinfo,
X long loopcounter, long looplimit));
X /* Input image reading & conversion to standard form */
X METHOD(void, input_init, (compress_info_ptr cinfo));
X METHOD(void, get_input_row, (compress_info_ptr cinfo,
X JSAMPARRAY pixel_row));
X METHOD(void, input_term, (compress_info_ptr cinfo));
X /* Color space and gamma conversion */
X METHOD(void, colorin_init, (compress_info_ptr cinfo));
X METHOD(void, get_sample_rows, (compress_info_ptr cinfo,
X int rows_to_read,
X JSAMPIMAGE image_data));
X METHOD(void, colorin_term, (compress_info_ptr cinfo));
X /* Expand picture data at edges */
X METHOD(void, edge_expand, (compress_info_ptr cinfo,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPIMAGE image_data));
X /* Subsample pixel values of a single component */
X /* There can be a different subsample method for each component */
X METHOD(void, subsample_init, (compress_info_ptr cinfo));
X subsample_ptr subsample[MAX_COMPS_IN_SCAN];
X METHOD(void, subsample_term, (compress_info_ptr cinfo));
X /* Extract samples in MCU order, process & hand off to output_method */
X /* The input is always exactly N MCU rows worth of data */
X METHOD(void, extract_init, (compress_info_ptr cinfo));
X METHOD(void, extract_MCUs, (compress_info_ptr cinfo,
X JSAMPIMAGE image_data,
X int num_mcu_rows,
X MCU_output_method_ptr output_method));
X METHOD(void, extract_term, (compress_info_ptr cinfo));
X /* Entropy encoding parameter optimization */
X METHOD(void, entropy_optimize, (compress_info_ptr cinfo,
X MCU_output_caller_ptr source_method));
X /* Entropy encoding */
X METHOD(void, entropy_encoder_init, (compress_info_ptr cinfo));
X METHOD(void, entropy_encode, (compress_info_ptr cinfo,
X JBLOCK *MCU_data));
X METHOD(void, entropy_encoder_term, (compress_info_ptr cinfo));
X /* JPEG file header construction */
X METHOD(void, write_file_header, (compress_info_ptr cinfo));
X METHOD(void, write_scan_header, (compress_info_ptr cinfo));
X METHOD(void, write_jpeg_data, (compress_info_ptr cinfo,
X char *dataptr,
X int datacount));
X METHOD(void, write_scan_trailer, (compress_info_ptr cinfo));
X METHOD(void, write_file_trailer, (compress_info_ptr cinfo));
X /* Pipeline control */
X METHOD(void, c_pipeline_controller, (compress_info_ptr cinfo));
X METHOD(void, entropy_output, (compress_info_ptr cinfo,
X char *dataptr,
X int datacount));
X /* Overall control */
X METHOD(void, c_per_scan_method_selection, (compress_info_ptr cinfo));
X};
X
X/* Methods used during JPEG decompression. */
X
Xstruct decompress_methods_struct {
X /* Hook for user interface to get control after reading file header */
X METHOD(void, d_ui_method_selection, (decompress_info_ptr cinfo));
X /* Hook for user interface to do progress monitoring */
X METHOD(void, progress_monitor, (decompress_info_ptr cinfo,
X long loopcounter, long looplimit));
X /* JPEG file scanning */
X METHOD(void, read_file_header, (decompress_info_ptr cinfo));
X METHOD(boolean, read_scan_header, (decompress_info_ptr cinfo));
X METHOD(int, read_jpeg_data, (decompress_info_ptr cinfo));
X METHOD(void, read_scan_trailer, (decompress_info_ptr cinfo));
X METHOD(void, read_file_trailer, (decompress_info_ptr cinfo));
X /* Entropy decoding */
X METHOD(void, entropy_decoder_init, (decompress_info_ptr cinfo));
X METHOD(void, entropy_decode, (decompress_info_ptr cinfo,
X JBLOCK *MCU_data));
X METHOD(void, entropy_decoder_term, (decompress_info_ptr cinfo));
X /* MCU disassembly: fetch MCUs from entropy_decode, build coef array */
X /* The reverse_DCT step is in the same module for symmetry reasons */
X METHOD(void, disassemble_init, (decompress_info_ptr cinfo));
X METHOD(void, disassemble_MCU, (decompress_info_ptr cinfo,
X JBLOCKIMAGE image_data));
X METHOD(void, reverse_DCT, (decompress_info_ptr cinfo,
X JBLOCKIMAGE coeff_data,
X JSAMPIMAGE output_data, int start_row));
X METHOD(void, disassemble_term, (decompress_info_ptr cinfo));
X /* Cross-block smoothing */
X METHOD(void, smooth_coefficients, (decompress_info_ptr cinfo,
X jpeg_component_info *compptr,
X JBLOCKROW above,
X JBLOCKROW currow,
X JBLOCKROW below,
X JBLOCKROW output));
X /* Un-subsample pixel values of a single component */
X /* There can be a different unsubsample method for each component */
X METHOD(void, unsubsample_init, (decompress_info_ptr cinfo));
X unsubsample_ptr unsubsample[MAX_COMPS_IN_SCAN];
X METHOD(void, unsubsample_term, (decompress_info_ptr cinfo));
X /* Color space and gamma conversion */
X METHOD(void, colorout_init, (decompress_info_ptr cinfo));
X METHOD(void, color_convert, (decompress_info_ptr cinfo,
X int num_rows, long num_cols,
X JSAMPIMAGE input_data,
X JSAMPIMAGE output_data));
X METHOD(void, colorout_term, (decompress_info_ptr cinfo));
X /* Color quantization */
X METHOD(void, color_quant_init, (decompress_info_ptr cinfo));
X METHOD(void, color_quantize, (decompress_info_ptr cinfo,
X int num_rows,
X JSAMPIMAGE input_data,
X JSAMPARRAY output_data));
X METHOD(void, color_quant_prescan, (decompress_info_ptr cinfo,
X int num_rows,
X JSAMPIMAGE image_data,
X JSAMPARRAY workspace));
X METHOD(void, color_quant_doit, (decompress_info_ptr cinfo,
X quantize_caller_ptr source_method));
X METHOD(void, color_quant_term, (decompress_info_ptr cinfo));
X /* Output image writing */
X METHOD(void, output_init, (decompress_info_ptr cinfo));
X METHOD(void, put_color_map, (decompress_info_ptr cinfo,
X int num_colors, JSAMPARRAY colormap));
X METHOD(void, put_pixel_rows, (decompress_info_ptr cinfo,
X int num_rows,
X JSAMPIMAGE pixel_data));
X METHOD(void, output_term, (decompress_info_ptr cinfo));
X /* Pipeline control */
X METHOD(void, d_pipeline_controller, (decompress_info_ptr cinfo));
X /* Overall control */
X METHOD(void, d_per_scan_method_selection, (decompress_info_ptr cinfo));
X};
X
X
X/* External declarations for routines that aren't called via method ptrs. */
X/* Note: use "j" as first char of names to minimize namespace pollution. */
X/* The PP macro hides prototype parameters from compilers that can't cope. */
X
X#ifdef PROTO
X#define PP(arglist) arglist
X#else
X#define PP(arglist) ()
X#endif
X
X
X/* main entry for compression */
XEXTERN void jpeg_compress PP((compress_info_ptr cinfo));
X
X/* default parameter setup for compression */
XEXTERN void j_c_defaults PP((compress_info_ptr cinfo, int quality,
X boolean force_baseline));
XEXTERN void j_monochrome_default PP((compress_info_ptr cinfo));
XEXTERN void j_set_quality PP((compress_info_ptr cinfo, int quality,
X boolean force_baseline));
X
X/* main entry for decompression */
XEXTERN void jpeg_decompress PP((decompress_info_ptr cinfo));
X
X/* default parameter setup for decompression */
XEXTERN void j_d_defaults PP((decompress_info_ptr cinfo,
X boolean standard_buffering));
X
X/* forward DCT */
XEXTERN void j_fwd_dct PP((DCTBLOCK data));
X/* inverse DCT */
XEXTERN void j_rev_dct PP((DCTBLOCK data));
X
X/* utility routines in jutils.c */
XEXTERN long jround_up PP((long a, long b));
XEXTERN void jcopy_sample_rows PP((JSAMPARRAY input_array, int source_row,
X JSAMPARRAY output_array, int dest_row,
X int num_rows, long num_cols));
XEXTERN void jcopy_block_row PP((JBLOCKROW input_row, JBLOCKROW output_row,
X long num_blocks));
XEXTERN void jzero_far PP((void FAR * target, size_t bytestozero));
X
X/* method selection routines for compression modules */
XEXTERN void jselcpipeline PP((compress_info_ptr cinfo)); /* jcpipe.c */
XEXTERN void jselchuffman PP((compress_info_ptr cinfo)); /* jchuff.c */
XEXTERN void jselcarithmetic PP((compress_info_ptr cinfo)); /* jcarith.c */
XEXTERN void jselexpand PP((compress_info_ptr cinfo)); /* jcexpand.c */
XEXTERN void jselsubsample PP((compress_info_ptr cinfo)); /* jcsample.c */
XEXTERN void jselcmcu PP((compress_info_ptr cinfo)); /* jcmcu.c */
XEXTERN void jselccolor PP((compress_info_ptr cinfo)); /* jccolor.c */
X/* The user interface should call one of these to select input format: */
XEXTERN void jselrgif PP((compress_info_ptr cinfo)); /* jrdgif.c */
XEXTERN void jselrppm PP((compress_info_ptr cinfo)); /* jrdppm.c */
XEXTERN void jselrrle PP((compress_info_ptr cinfo)); /* jrdrle.c */
XEXTERN void jselrtarga PP((compress_info_ptr cinfo)); /* jrdtarga.c */
X/* and one of these to select output header format: */
XEXTERN void jselwjfif PP((compress_info_ptr cinfo)); /* jwrjfif.c */
X
X/* method selection routines for decompression modules */
XEXTERN void jseldpipeline PP((decompress_info_ptr cinfo)); /* jdpipe.c */
XEXTERN void jseldhuffman PP((decompress_info_ptr cinfo)); /* jdhuff.c */
XEXTERN void jseldarithmetic PP((decompress_info_ptr cinfo)); /* jdarith.c */
XEXTERN void jseldmcu PP((decompress_info_ptr cinfo)); /* jdmcu.c */
XEXTERN void jselbsmooth PP((decompress_info_ptr cinfo)); /* jbsmooth.c */
XEXTERN void jselunsubsample PP((decompress_info_ptr cinfo)); /* jdsample.c */
XEXTERN void jseldcolor PP((decompress_info_ptr cinfo)); /* jdcolor.c */
XEXTERN void jsel1quantize PP((decompress_info_ptr cinfo)); /* jquant1.c */
XEXTERN void jsel2quantize PP((decompress_info_ptr cinfo)); /* jquant2.c */
X/* The user interface should call one of these to select input format: */
XEXTERN void jselrjfif PP((decompress_info_ptr cinfo)); /* jrdjfif.c */
X/* and one of these to select output image format: */
XEXTERN void jselwgif PP((decompress_info_ptr cinfo)); /* jwrgif.c */
XEXTERN void jselwppm PP((decompress_info_ptr cinfo)); /* jwrppm.c */
XEXTERN void jselwrle PP((decompress_info_ptr cinfo)); /* jwrrle.c */
XEXTERN void jselwtarga PP((decompress_info_ptr cinfo)); /* jwrtarga.c */
X
X/* method selection routines for system-dependent modules */
XEXTERN void jselerror PP((external_methods_ptr emethods)); /* jerror.c */
XEXTERN void jselmemmgr PP((external_methods_ptr emethods)); /* jmemmgr.c */
X
X
X/* We assume that right shift corresponds to signed division by 2 with
X * rounding towards minus infinity. This is correct for typical "arithmetic
X * shift" instructions that shift in copies of the sign bit. But some
X * C compilers implement >> with an unsigned shift. For these machines you
X * must define RIGHT_SHIFT_IS_UNSIGNED.
X * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
X * It is only applied with constant shift counts. SHIFT_TEMPS must be
X * included in the variables of any routine using RIGHT_SHIFT.
X */
X
X#ifdef RIGHT_SHIFT_IS_UNSIGNED
X#define SHIFT_TEMPS INT32 shift_temp;
X#define RIGHT_SHIFT(x,shft) \
X ((shift_temp = (x)) < 0 ? \
X (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
X (shift_temp >> (shft)))
X#else
X#define SHIFT_TEMPS
X#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
X#endif
X
X
X/* Miscellaneous useful macros */
X
X#undef MAX
X#define MAX(a,b) ((a) > (b) ? (a) : (b))
X#undef MIN
X#define MIN(a,b) ((a) < (b) ? (a) : (b))
X
X
X#define RST0 0xD0 /* RST0 marker code */
END_OF_FILE
if test 37381 -ne `wc -c <'jpegdata.h'`; then
echo shar: \"'jpegdata.h'\" unpacked with wrong size!
fi
# end of 'jpegdata.h'
fi
if test -f 'jwrgif.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jwrgif.c'\"
else
echo shar: Extracting \"'jwrgif.c'\" \(13893 characters\)
sed "s/^X//" >'jwrgif.c' <<'END_OF_FILE'
X/*
X * jwrgif.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to write output images in GIF format.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume output to
X * an ordinary stdio stream.
X *
X * These routines are invoked via the methods put_pixel_rows, put_color_map,
X * and output_init/term.
X */
X
X/*
X * This code is loosely based on ppmtogif from the PBMPLUS distribution
X * of Feb. 1991. That file contains the following copyright notice:
X * Based on GIFENCODE by David Rowley <mga...@watdscu.waterloo.edu>.
X * Lempel-Ziv compression based on "compress" by Spencer W. Thomas et al.
X * Copyright (C) 1989 by Jef Poskanzer.
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted, provided
X * that the above copyright notice appear in all copies and that both that
X * copyright notice and this permission notice appear in supporting
X * documentation. This software is provided "as is" without express or
X * implied warranty.
X *
X * We are also required to state that
X * "The Graphics Interchange Format(c) is the Copyright property of
X * CompuServe Incorporated. GIF(sm) is a Service Mark property of
X * CompuServe Incorporated."
X */
X
X#include "jinclude.h"
X
X#ifdef GIF_SUPPORTED
X
X
Xstatic decompress_info_ptr dcinfo; /* to avoid passing to all functions */
X
X#define MAX_LZW_BITS 12 /* maximum LZW code size (4096 symbols) */
X
Xtypedef INT16 code_int; /* must hold -1 .. 2**MAX_LZW_BITS */
X
X#define LZW_TABLE_SIZE ((code_int) 1 << MAX_LZW_BITS)
X
X#define HSIZE 5003 /* hash table size for 80% occupancy */
X
Xtypedef int hash_int; /* must hold -2*HSIZE..2*HSIZE */
X
Xstatic int n_bits; /* current number of bits/code */
Xstatic code_int maxcode; /* maximum code, given n_bits */
X#define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
X
Xstatic int init_bits; /* initial n_bits ... restored after clear */
X
Xstatic code_int ClearCode; /* clear code (doesn't change) */
Xstatic code_int EOFCode; /* EOF code (ditto) */
X
Xstatic code_int free_code; /* first not-yet-used symbol code */
X
X/*
X * The LZW hash table consists of three parallel arrays:
X * hash_code[i] code of symbol in slot i, or 0 if empty slot
X * hash_prefix[i] symbol's prefix code; undefined if empty slot
X * hash_suffix[i] symbol's suffix character; undefined if empty slot
X * where slot values (i) range from 0 to HSIZE-1.
X *
X * Algorithm: use open addressing double hashing (no chaining) on the
X * prefix code / suffix character combination. We do a variant of Knuth's
X * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
X * secondary probe.
X *
X * The hash tables are allocated from FAR heap space since they would use up
X * rather a lot of the near data space in a PC.
X */
X
Xstatic code_int FAR *hash_code; /* => hash table of symbol codes */
Xstatic code_int FAR *hash_prefix; /* => hash table of prefix symbols */
Xstatic UINT8 FAR *hash_suffix; /* => hash table of suffix bytes */
X
X
X/*
X * Routines to package compressed data bytes into GIF data blocks.
X * A data block consists of a count byte (1..255) and that many data bytes.
X */
X
Xstatic int bytesinpkt; /* # of bytes in current packet */
Xstatic char packetbuf[256]; /* workspace for accumulating packet */
X
X
XLOCAL void
Xflush_packet (void)
X/* flush any accumulated data */
X{
X if (bytesinpkt > 0) { /* never write zero-length packet */
X packetbuf[0] = (char) bytesinpkt++;
X if (JFWRITE(dcinfo->output_file, packetbuf, bytesinpkt)
X != (size_t) bytesinpkt)
X ERREXIT(dcinfo->emethods, "Output file write error");
X bytesinpkt = 0;
X }
X}
X
X
X/* Add a character to current packet; flush to disk if necessary */
X#define CHAR_OUT(c) \
X { packetbuf[++bytesinpkt] = (char) (c); \
X if (bytesinpkt >= 255) \
X flush_packet(); \
X }
X
X
X/* Routine to convert variable-width codes into a byte stream */
X
Xstatic INT32 cur_accum; /* holds bits not yet output */
Xstatic int cur_bits; /* # of bits in cur_accum */
X
X
XLOCAL void
Xoutput (code_int code)
X/* Emit a code of n_bits bits */
X/* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
X{
X cur_accum |= ((INT32) code) << cur_bits;
X cur_bits += n_bits;
X
X while (cur_bits >= 8) {
X CHAR_OUT(cur_accum & 0xFF);
X cur_accum >>= 8;
X cur_bits -= 8;
X }
X
X /*
X * If the next entry is going to be too big for the code size,
X * then increase it, if possible. We do this here to ensure
X * that it's done in sync with the decoder's codesize increases.
X */
X if (free_code > maxcode) {
X n_bits++;
X if (n_bits == MAX_LZW_BITS)
X maxcode = LZW_TABLE_SIZE; /* free_code will never exceed this */
X else
X maxcode = MAXCODE(n_bits);
X }
X}
X
X
X/* The LZW algorithm proper */
X
Xstatic code_int waiting_code; /* symbol not yet output; may be extendable */
Xstatic boolean first_byte; /* if TRUE, waiting_code is not valid */
X
X
XLOCAL void
Xclear_hash (void)
X/* Fill the hash table with empty entries */
X{
X /* It's sufficient to zero hash_code[] */
X jzero_far((void FAR *) hash_code, HSIZE * SIZEOF(code_int));
X}
X
X
XLOCAL void
Xclear_block (void)
X/* Reset compressor and issue a Clear code */
X{
X clear_hash(); /* delete all the symbols */
X free_code = ClearCode + 2;
X output(ClearCode); /* inform decoder */
X n_bits = init_bits; /* reset code size */
X maxcode = MAXCODE(n_bits);
X}
X
X
XLOCAL void
Xcompress_init (int i_bits)
X/* Initialize LZW compressor */
X{
X /* init all the static variables */
X n_bits = init_bits = i_bits;
X maxcode = MAXCODE(n_bits);
X ClearCode = ((code_int) 1 << (init_bits - 1));
X EOFCode = ClearCode + 1;
X free_code = ClearCode + 2;
X first_byte = TRUE; /* no waiting symbol yet */
X /* init output buffering vars */
X bytesinpkt = 0;
X cur_accum = 0;
X cur_bits = 0;
X /* clear hash table */
X clear_hash();
X /* GIF specifies an initial Clear code */
X output(ClearCode);
X}
X
X
XLOCAL void
Xcompress_byte (int c)
X/* Accept and compress one 8-bit byte */
X{
X register hash_int i;
X register hash_int disp;
X
X if (first_byte) { /* need to initialize waiting_code */
X waiting_code = c;
X first_byte = FALSE;
X return;
X }
X
X /* Probe hash table to see if a symbol exists for
X * waiting_code followed by c.
X * If so, replace waiting_code by that symbol and return.
X */
X i = ((hash_int) c << (MAX_LZW_BITS-8)) + waiting_code;
X /* i is less than twice 2**MAX_LZW_BITS, therefore less than twice HSIZE */
X if (i >= HSIZE)
X i -= HSIZE;
X
X if (hash_code[i] != 0) { /* is first probed slot empty? */
X if (hash_prefix[i] == waiting_code && hash_suffix[i] == (UINT8) c) {
X waiting_code = hash_code[i];
X return;
X }
X if (i == 0) /* secondary hash (after G. Knott) */
X disp = 1;
X else
X disp = HSIZE - i;
X while (1) {
X i -= disp;
X if (i < 0)
X i += HSIZE;
X if (hash_code[i] == 0)
X break; /* hit empty slot */
X if (hash_prefix[i] == waiting_code && hash_suffix[i] == (UINT8) c) {
X waiting_code = hash_code[i];
X return;
X }
X }
X }
X
X /* here when hashtable[i] is an empty slot; desired symbol not in table */
X output(waiting_code);
X if (free_code < LZW_TABLE_SIZE) {
X hash_code[i] = free_code++; /* add symbol to hashtable */
X hash_prefix[i] = waiting_code;
X hash_suffix[i] = (UINT8) c;
X } else
X clear_block();
X waiting_code = c;
X}
X
X
XLOCAL void
Xcompress_term (void)
X/* Clean up at end */
X{
X /* Flush out the buffered code */
X if (! first_byte)
X output(waiting_code);
X /* Send an EOF code */
X output(EOFCode);
X /* Flush the bit-packing buffer */
X if (cur_bits > 0) {
X CHAR_OUT(cur_accum & 0xFF);
X }
X /* Flush the packet buffer */
X flush_packet();
X}
X
X
X/* GIF header construction */
X
X
XLOCAL void
Xput_word (UINT16 w)
X/* Emit a 16-bit word, LSB first */
X{
X putc(w & 0xFF, dcinfo->output_file);
X putc((w >> 8) & 0xFF, dcinfo->output_file);
X}
X
X
XLOCAL void
Xput_3bytes (int val)
X/* Emit 3 copies of same byte value --- handy subr for colormap construction */
X{
X putc(val, dcinfo->output_file);
X putc(val, dcinfo->output_file);
X putc(val, dcinfo->output_file);
X}
X
X
XLOCAL void
Xemit_header (int num_colors, JSAMPARRAY colormap)
X/* Output the GIF file header, including color map */
X/* If colormap==NULL, synthesize a gray-scale colormap */
X{
X int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte;
X int cshift = dcinfo->data_precision - 8;
X int i;
X
X if (num_colors > 256)
X ERREXIT(dcinfo->emethods, "GIF can only handle 256 colors");
X /* Compute bits/pixel and related values */
X BitsPerPixel = 1;
X while (num_colors > (1 << BitsPerPixel))
X BitsPerPixel++;
X ColorMapSize = 1 << BitsPerPixel;
X if (BitsPerPixel <= 1)
X InitCodeSize = 2;
X else
X InitCodeSize = BitsPerPixel;
X /*
X * Write the GIF header.
X * Note that we generate a plain GIF87 header for maximum compatibility.
X */
X (void) JFWRITE(dcinfo->output_file, "GIF87a", 6);
X /* Write the Logical Screen Descriptor */
X put_word((UINT16) dcinfo->image_width);
X put_word((UINT16) dcinfo->image_height);
X FlagByte = 0x80; /* Yes, there is a global color table */
X FlagByte |= (BitsPerPixel-1) << 4; /* color resolution */
X FlagByte |= (BitsPerPixel-1); /* size of global color table */
X putc(FlagByte, dcinfo->output_file);
X putc(0, dcinfo->output_file); /* Background color index */
X putc(0, dcinfo->output_file); /* Reserved in GIF87 (aspect ratio in GIF89) */
X /* Write the Global Color Map */
X /* If the color map is more than 8 bits precision, */
X /* we reduce it to 8 bits by shifting */
X for (i=0; i < ColorMapSize; i++) {
X if (i < num_colors) {
X if (colormap != NULL) {
X if (dcinfo->out_color_space == CS_RGB) {
X /* Normal case: RGB color map */
X putc(GETJSAMPLE(colormap[0][i]) >> cshift, dcinfo->output_file);
X putc(GETJSAMPLE(colormap[1][i]) >> cshift, dcinfo->output_file);
X putc(GETJSAMPLE(colormap[2][i]) >> cshift, dcinfo->output_file);
X } else {
X /* Grayscale "color map": possible if quantizing grayscale image */
X put_3bytes(GETJSAMPLE(colormap[0][i]) >> cshift);
X }
X } else {
X /* Create a gray-scale map of num_colors values, range 0..255 */
X put_3bytes((i * 255 + (num_colors-1)/2) / (num_colors-1));
X }
X } else {
X /* fill out the map to a power of 2 */
X put_3bytes(0);
X }
X }
X /* Write image separator and Image Descriptor */
X putc(',', dcinfo->output_file); /* separator */
X put_word((UINT16) 0); /* left/top offset */
X put_word((UINT16) 0);
X put_word((UINT16) dcinfo->image_width); /* image size */
X put_word((UINT16) dcinfo->image_height);
X /* flag byte: not interlaced, no local color map */
X putc(0x00, dcinfo->output_file);
X /* Write Initial Code Size byte */
X putc(InitCodeSize, dcinfo->output_file);
X
X /* Initialize for LZW compression of image data */
X compress_init(InitCodeSize+1);
X}
X
X
X
X/*
X * Initialize for GIF output.
X */
X
XMETHODDEF void
Xoutput_init (decompress_info_ptr cinfo)
X{
X dcinfo = cinfo; /* save for use by local routines */
X if (cinfo->final_out_comps != 1) /* safety check */
X ERREXIT(cinfo->emethods, "GIF output got confused");
X /* Allocate space for hash table */
X hash_code = (code_int FAR *) (*cinfo->emethods->alloc_medium)
X (HSIZE * SIZEOF(code_int));
X hash_prefix = (code_int FAR *) (*cinfo->emethods->alloc_medium)
X (HSIZE * SIZEOF(code_int));
X hash_suffix = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
X (HSIZE * SIZEOF(UINT8));
X /*
X * If we aren't quantizing, put_color_map won't be called,
X * so emit the header now. This only happens with gray scale output.
X * (If we are quantizing, wait for the color map to be provided.)
X */
X if (! cinfo->quantize_colors)
X emit_header(256, (JSAMPARRAY) NULL);
X}
X
X
X/*
X * Write the color map.
X */
X
XMETHODDEF void
Xput_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
X{
X emit_header(num_colors, colormap);
X}
X
X
X/*
X * Write some pixel data.
X */
X
XMETHODDEF void
Xput_pixel_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X register JSAMPROW ptr;
X register long col;
X register long width = cinfo->image_width;
X register int row;
X
X for (row = 0; row < num_rows; row++) {
X ptr = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X compress_byte(GETJSAMPLE(*ptr));
X ptr++;
X }
X }
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xoutput_term (decompress_info_ptr cinfo)
X{
X /* Flush LZW mechanism */
X compress_term();
X /* Write a zero-length data block to end the series */
X putc(0, cinfo->output_file);
X /* Write the GIF terminator mark */
X putc(';', cinfo->output_file);
X /* Make sure we wrote the output file OK */
X fflush(cinfo->output_file);
X if (ferror(cinfo->output_file))
X ERREXIT(cinfo->emethods, "Output file write error");
X /* Free space */
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for GIF format output.
X * This should be called from d_ui_method_selection if GIF output is wanted.
X */
X
XGLOBAL void
Xjselwgif (decompress_info_ptr cinfo)
X{
X cinfo->methods->output_init = output_init;
X cinfo->methods->put_color_map = put_color_map;
X cinfo->methods->put_pixel_rows = put_pixel_rows;
X cinfo->methods->output_term = output_term;
X
X if (cinfo->out_color_space != CS_GRAYSCALE &&
X cinfo->out_color_space != CS_RGB)
X ERREXIT(cinfo->emethods, "GIF output must be grayscale or RGB");
X
X /* Force quantization if color or if > 8 bits input */
X if (cinfo->out_color_space == CS_RGB || cinfo->data_precision > 8) {
X /* Force quantization to at most 256 colors */
X cinfo->quantize_colors = TRUE;
X if (cinfo->desired_number_of_colors > 256)
X cinfo->desired_number_of_colors = 256;
X }
X}
X
X#endif /* GIF_SUPPORTED */
END_OF_FILE
if test 13893 -ne `wc -c <'jwrgif.c'`; then
echo shar: \"'jwrgif.c'\" unpacked with wrong size!
fi
# end of 'jwrgif.c'
fi
if test -f 'makcjpeg.lnk' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makcjpeg.lnk'\"
else
echo shar: Extracting \"'makcjpeg.lnk'\" \(320 characters\)
sed "s/^X//" >'makcjpeg.lnk' <<'END_OF_FILE'
Xjcmain.obj +
Xjcmaster.obj +
Xjcdeflts.obj +
Xjcarith.obj +
Xjccolor.obj +
Xjcexpand.obj +
Xjchuff.obj +
Xjcmcu.obj +
Xjcpipe.obj +
Xjcsample.obj +
Xjfwddct.obj +
Xjwrjfif.obj +
Xjrdgif.obj +
Xjrdppm.obj +
Xjrdrle.obj +
Xjrdtarga.obj +
Xjutils.obj +
Xjerror.obj +
Xjmemmgr.obj +
Xjmemsys.obj +
Xjmemdosa.obj
Xcjpeg.exe /NOI
Xnul.map
X
Xnul.def
END_OF_FILE
if test 320 -ne `wc -c <'makcjpeg.lnk'`; then
echo shar: \"'makcjpeg.lnk'\" unpacked with wrong size!
fi
# end of 'makcjpeg.lnk'
fi
echo shar: End of archive 4 \(of 18\).
cp /dev/null ark4isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jcarith.c jmemmgr.c jrdtarga.c makvms.opt
# Wrapped by kent@sparky on Mon Mar 23 16:02:42 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 5 (of 18)."'
if test -f 'jcarith.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcarith.c'\"
else
echo shar: Extracting \"'jcarith.c'\" \(1161 characters\)
sed "s/^X//" >'jcarith.c' <<'END_OF_FILE'
X/*
X * jcarith.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains arithmetic entropy encoding routines.
X * These routines are invoked via the methods entropy_encode,
X * entropy_encoder_init/term, and entropy_optimize.
X */
X
X#include "jinclude.h"
X
X#ifdef ARITH_CODING_SUPPORTED
X
X
X/*
X * The arithmetic coding option of the JPEG standard specifies Q-coding,
X * which is covered by patents held by IBM (and possibly AT&T and Mitsubishi).
X * At this time it does not appear to be legal for the Independent JPEG
X * Group to distribute software that implements arithmetic coding.
X * We have therefore removed arithmetic coding support from the
X * distributed source code.
X *
X * We're not happy about it either.
X */
X
X
X/*
X * The method selection routine for arithmetic entropy encoding.
X */
X
XGLOBAL void
Xjselcarithmetic (compress_info_ptr cinfo)
X{
X if (cinfo->arith_code) {
X ERREXIT(cinfo->emethods, "Sorry, there are legal restrictions on arithmetic coding");
X }
X}
X
X#endif /* ARITH_CODING_SUPPORTED */
END_OF_FILE
if test 1161 -ne `wc -c <'jcarith.c'`; then
echo shar: \"'jcarith.c'\" unpacked with wrong size!
fi
# end of 'jcarith.c'
fi
if test -f 'jmemmgr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemmgr.c'\"
else
echo shar: Extracting \"'jmemmgr.c'\" \(35862 characters\)
sed "s/^X//" >'jmemmgr.c' <<'END_OF_FILE'
X/*
X * jmemmgr.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file provides the standard system-independent memory management
X * routines. This code is usable across a wide variety of machines; most
X * of the system dependencies have been isolated in a separate file.
X * The major functions provided here are:
X * * bookkeeping to allow all allocated memory to be freed upon exit;
X * * policy decisions about how to divide available memory among the
X * various large arrays;
X * * control logic for swapping virtual arrays between main memory and
X * backing storage.
X * The separate system-dependent file provides the actual backing-storage
X * access code, and it contains the policy decision about how much total
X * main memory to use.
X * This file is system-dependent in the sense that some of its functions
X * are unnecessary in some systems. For example, if there is enough virtual
X * memory so that backing storage will never be used, much of the big-array
X * control logic could be removed. (Of course, if you have that much memory
X * then you shouldn't care about a little bit of unused code...)
X *
X * These routines are invoked via the methods alloc_small, free_small,
X * alloc_medium, free_medium, alloc_small_sarray, free_small_sarray,
X * alloc_small_barray, free_small_barray, request_big_sarray,
X * request_big_barray, alloc_big_arrays, access_big_sarray, access_big_barray,
X * free_big_sarray, free_big_barray, and free_all.
X */
X
X#define AM_MEMORY_MANAGER /* we define big_Xarray_control structs */
X
X#include "jinclude.h"
X#include "jmemsys.h" /* import the system-dependent declarations */
X
X
X/*
X * On many systems it is not necessary to distinguish alloc_small from
X * alloc_medium; the main case where they must be distinguished is when
X * FAR pointers are distinct from regular pointers. However, you might
X * want to keep them separate if you have different system-dependent logic
X * for small and large memory requests (i.e., jget_small and jget_large
X * do different things).
X */
X
X#ifdef NEED_FAR_POINTERS
X#define NEED_ALLOC_MEDIUM /* flags alloc_medium really exists */
X#endif
X
X
X/*
X * Some important notes:
X * The allocation routines provided here must never return NULL.
X * They should exit to error_exit if unsuccessful.
X *
X * It's not a good idea to try to merge the sarray and barray routines,
X * even though they are textually almost the same, because samples are
X * usually stored as bytes while coefficients are shorts. Thus, in machines
X * where byte pointers have a different representation from word pointers,
X * the resulting machine code could not be the same.
X */
X
X
Xstatic external_methods_ptr methods; /* saved for access to error_exit */
X
X
X#ifdef MEM_STATS /* optional extra stuff for statistics */
X
X/* These macros are the assumed overhead per block for malloc().
X * They don't have to be accurate, but the printed statistics will be
X * off a little bit if they are not.
X */
X#define MALLOC_OVERHEAD (SIZEOF(void *)) /* overhead for jget_small() */
X#define MALLOC_FAR_OVERHEAD (SIZEOF(void FAR *)) /* for jget_large() */
X
Xstatic long total_num_small = 0; /* total # of small objects alloced */
Xstatic long total_bytes_small = 0; /* total bytes requested */
Xstatic long cur_num_small = 0; /* # currently alloced */
Xstatic long max_num_small = 0; /* max simultaneously alloced */
X
X#ifdef NEED_ALLOC_MEDIUM
Xstatic long total_num_medium = 0; /* total # of medium objects alloced */
Xstatic long total_bytes_medium = 0; /* total bytes requested */
Xstatic long cur_num_medium = 0; /* # currently alloced */
Xstatic long max_num_medium = 0; /* max simultaneously alloced */
X#endif
X
Xstatic long total_num_sarray = 0; /* total # of sarray objects alloced */
Xstatic long total_bytes_sarray = 0; /* total bytes requested */
Xstatic long cur_num_sarray = 0; /* # currently alloced */
Xstatic long max_num_sarray = 0; /* max simultaneously alloced */
X
Xstatic long total_num_barray = 0; /* total # of barray objects alloced */
Xstatic long total_bytes_barray = 0; /* total bytes requested */
Xstatic long cur_num_barray = 0; /* # currently alloced */
Xstatic long max_num_barray = 0; /* max simultaneously alloced */
X
X
XLOCAL void
Xprint_mem_stats (void)
X{
X /* since this is only a debugging stub, we can cheat a little on the
X * trace message mechanism... helpful 'cuz trace_message can't handle longs.
X */
X fprintf(stderr, "total_num_small = %ld\n", total_num_small);
X fprintf(stderr, "total_bytes_small = %ld\n", total_bytes_small);
X if (cur_num_small)
X fprintf(stderr, "cur_num_small = %ld\n", cur_num_small);
X fprintf(stderr, "max_num_small = %ld\n", max_num_small);
X
X#ifdef NEED_ALLOC_MEDIUM
X fprintf(stderr, "total_num_medium = %ld\n", total_num_medium);
X fprintf(stderr, "total_bytes_medium = %ld\n", total_bytes_medium);
X if (cur_num_medium)
X fprintf(stderr, "cur_num_medium = %ld\n", cur_num_medium);
X fprintf(stderr, "max_num_medium = %ld\n", max_num_medium);
X#endif
X
X fprintf(stderr, "total_num_sarray = %ld\n", total_num_sarray);
X fprintf(stderr, "total_bytes_sarray = %ld\n", total_bytes_sarray);
X if (cur_num_sarray)
X fprintf(stderr, "cur_num_sarray = %ld\n", cur_num_sarray);
X fprintf(stderr, "max_num_sarray = %ld\n", max_num_sarray);
X
X fprintf(stderr, "total_num_barray = %ld\n", total_num_barray);
X fprintf(stderr, "total_bytes_barray = %ld\n", total_bytes_barray);
X if (cur_num_barray)
X fprintf(stderr, "cur_num_barray = %ld\n", cur_num_barray);
X fprintf(stderr, "max_num_barray = %ld\n", max_num_barray);
X}
X
X#endif /* MEM_STATS */
X
X
XLOCAL void
Xout_of_memory (int which)
X/* Report an out-of-memory error and stop execution */
X/* If we compiled MEM_STATS support, report alloc requests before dying */
X{
X#ifdef MEM_STATS
X if (methods->trace_level <= 0) /* don't do it if free_all() will */
X print_mem_stats(); /* print optional memory usage statistics */
X#endif
X ERREXIT1(methods, "Insufficient memory (case %d)", which);
X}
X
X
X/*
X * Management of "small" objects.
X * These are all-in-memory, and are in near-heap space on an 80x86.
X */
X
Xtypedef struct small_struct * small_ptr;
X
Xtypedef struct small_struct {
X small_ptr next; /* next in list of allocated objects */
X } small_hdr;
X
Xstatic small_ptr small_list; /* head of list */
X
X
XMETHODDEF void *
Xalloc_small (size_t sizeofobject)
X/* Allocate a "small" object */
X{
X small_ptr result;
X
X sizeofobject += SIZEOF(small_hdr); /* add space for header */
X
X#ifdef MEM_STATS
X total_num_small++;
X total_bytes_small += sizeofobject + MALLOC_OVERHEAD;
X cur_num_small++;
X if (cur_num_small > max_num_small) max_num_small = cur_num_small;
X#endif
X
X result = (small_ptr) jget_small(sizeofobject);
X if (result == NULL)
X out_of_memory(1);
X
X result->next = small_list;
X small_list = result;
X result++; /* advance past header */
X
X return (void *) result;
X}
X
X
XMETHODDEF void
Xfree_small (void *ptr)
X/* Free a "small" object */
X{
X small_ptr hdr;
X small_ptr * llink;
X
X hdr = (small_ptr) ptr;
X hdr--; /* point back to header */
X
X /* Remove item from list -- linear search is fast enough */
X llink = &small_list;
X while (*llink != hdr) {
X if (*llink == NULL)
X ERREXIT(methods, "Bogus free_small request");
X llink = &( (*llink)->next );
X }
X *llink = hdr->next;
X
X jfree_small((void *) hdr);
X
X#ifdef MEM_STATS
X cur_num_small--;
X#endif
X}
X
X
X/*
X * Management of "medium-size" objects.
X * These are just like small objects except they are in the FAR heap.
X */
X
X#ifdef NEED_ALLOC_MEDIUM
X
Xtypedef struct medium_struct FAR * medium_ptr;
X
Xtypedef struct medium_struct {
X medium_ptr next; /* next in list of allocated objects */
X } medium_hdr;
X
Xstatic medium_ptr medium_list; /* head of list */
X
X
XMETHODDEF void FAR *
Xalloc_medium (size_t sizeofobject)
X/* Allocate a "medium-size" object */
X{
X medium_ptr result;
X
X sizeofobject += SIZEOF(medium_hdr); /* add space for header */
X
X#ifdef MEM_STATS
X total_num_medium++;
X total_bytes_medium += sizeofobject + MALLOC_FAR_OVERHEAD;
X cur_num_medium++;
X if (cur_num_medium > max_num_medium) max_num_medium = cur_num_medium;
X#endif
X
X result = (medium_ptr) jget_large(sizeofobject);
X if (result == NULL)
X out_of_memory(2);
X
X result->next = medium_list;
X medium_list = result;
X result++; /* advance past header */
X
X return (void FAR *) result;
X}
X
X
XMETHODDEF void
Xfree_medium (void FAR *ptr)
X/* Free a "medium-size" object */
X{
X medium_ptr hdr;
X medium_ptr FAR * llink;
X
X hdr = (medium_ptr) ptr;
X hdr--; /* point back to header */
X
X /* Remove item from list -- linear search is fast enough */
X llink = &medium_list;
X while (*llink != hdr) {
X if (*llink == NULL)
X ERREXIT(methods, "Bogus free_medium request");
X llink = &( (*llink)->next );
X }
X *llink = hdr->next;
X
X jfree_large((void FAR *) hdr);
X
X#ifdef MEM_STATS
X cur_num_medium--;
X#endif
X}
X
X#endif /* NEED_ALLOC_MEDIUM */
X
X
X/*
X * Management of "small" (all-in-memory) 2-D sample arrays.
X * The pointers are in near heap, the samples themselves in FAR heap.
X * The header structure is adjacent to the row pointers.
X * To minimize allocation overhead and to allow I/O of large contiguous
X * blocks, we allocate the sample rows in groups of as many rows as possible
X * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
X * Note that the big-array control routines, later in this file, know about
X * this chunking of rows ... and also how to get the rowsperchunk value!
X */
X
Xtypedef struct small_sarray_struct * small_sarray_ptr;
X
Xtypedef struct small_sarray_struct {
X small_sarray_ptr next; /* next in list of allocated sarrays */
X long numrows; /* # of rows in this array */
X long rowsperchunk; /* max # of rows per allocation chunk */
X } small_sarray_hdr;
X
Xstatic small_sarray_ptr small_sarray_list; /* head of list */
X
X
XMETHODDEF JSAMPARRAY
Xalloc_small_sarray (long samplesperrow, long numrows)
X/* Allocate a "small" (all-in-memory) 2-D sample array */
X{
X small_sarray_ptr hdr;
X JSAMPARRAY result;
X JSAMPROW workspace;
X long rowsperchunk, currow, i;
X
X#ifdef MEM_STATS
X total_num_sarray++;
X cur_num_sarray++;
X if (cur_num_sarray > max_num_sarray) max_num_sarray = cur_num_sarray;
X#endif
X
X /* Calculate max # of rows allowed in one allocation chunk */
X rowsperchunk = MAX_ALLOC_CHUNK / (samplesperrow * SIZEOF(JSAMPLE));
X if (rowsperchunk <= 0)
X ERREXIT(methods, "Image too wide for this implementation");
X
X /* Get space for header and row pointers; this is always "near" on 80x86 */
X hdr = (small_sarray_ptr) alloc_small((size_t) (numrows * SIZEOF(JSAMPROW)
X + SIZEOF(small_sarray_hdr)));
X
X result = (JSAMPARRAY) (hdr+1); /* advance past header */
X
X /* Insert into list now so free_all does right thing if I fail */
X /* after allocating only some of the rows... */
X hdr->next = small_sarray_list;
X hdr->numrows = 0;
X hdr->rowsperchunk = rowsperchunk;
X small_sarray_list = hdr;
X
X /* Get the rows themselves; on 80x86 these are "far" */
X currow = 0;
X while (currow < numrows) {
X rowsperchunk = MIN(rowsperchunk, numrows - currow);
X#ifdef MEM_STATS
X total_bytes_sarray += rowsperchunk * samplesperrow * SIZEOF(JSAMPLE)
X + MALLOC_FAR_OVERHEAD;
X#endif
X workspace = (JSAMPROW) jget_large((size_t) (rowsperchunk * samplesperrow
X * SIZEOF(JSAMPLE)));
X if (workspace == NULL)
X out_of_memory(3);
X for (i = rowsperchunk; i > 0; i--) {
X result[currow++] = workspace;
X workspace += samplesperrow;
X }
X hdr->numrows = currow;
X }
X
X return result;
X}
X
X
XMETHODDEF void
Xfree_small_sarray (JSAMPARRAY ptr)
X/* Free a "small" (all-in-memory) 2-D sample array */
X{
X small_sarray_ptr hdr;
X small_sarray_ptr * llink;
X long i;
X
X hdr = (small_sarray_ptr) ptr;
X hdr--; /* point back to header */
X
X /* Remove item from list -- linear search is fast enough */
X llink = &small_sarray_list;
X while (*llink != hdr) {
X if (*llink == NULL)
X ERREXIT(methods, "Bogus free_small_sarray request");
X llink = &( (*llink)->next );
X }
X *llink = hdr->next;
X
X /* Free the rows themselves; on 80x86 these are "far" */
X /* Note we only free the row-group headers! */
X for (i = 0; i < hdr->numrows; i += hdr->rowsperchunk) {
X jfree_large((void FAR *) ptr[i]);
X }
X
X /* Free header and row pointers */
X free_small((void *) hdr);
X
X#ifdef MEM_STATS
X cur_num_sarray--;
X#endif
X}
X
X
X/*
X * Management of "small" (all-in-memory) 2-D coefficient-block arrays.
X * This is essentially the same as the code for sample arrays, above.
X */
X
Xtypedef struct small_barray_struct * small_barray_ptr;
X
Xtypedef struct small_barray_struct {
X small_barray_ptr next; /* next in list of allocated barrays */
X long numrows; /* # of rows in this array */
X long rowsperchunk; /* max # of rows per allocation chunk */
X } small_barray_hdr;
X
Xstatic small_barray_ptr small_barray_list; /* head of list */
X
X
XMETHODDEF JBLOCKARRAY
Xalloc_small_barray (long blocksperrow, long numrows)
X/* Allocate a "small" (all-in-memory) 2-D coefficient-block array */
X{
X small_barray_ptr hdr;
X JBLOCKARRAY result;
X JBLOCKROW workspace;
X long rowsperchunk, currow, i;
X
X#ifdef MEM_STATS
X total_num_barray++;
X cur_num_barray++;
X if (cur_num_barray > max_num_barray) max_num_barray = cur_num_barray;
X#endif
X
X /* Calculate max # of rows allowed in one allocation chunk */
X rowsperchunk = MAX_ALLOC_CHUNK / (blocksperrow * SIZEOF(JBLOCK));
X if (rowsperchunk <= 0)
X ERREXIT(methods, "Image too wide for this implementation");
X
X /* Get space for header and row pointers; this is always "near" on 80x86 */
X hdr = (small_barray_ptr) alloc_small((size_t) (numrows * SIZEOF(JBLOCKROW)
X + SIZEOF(small_barray_hdr)));
X
X result = (JBLOCKARRAY) (hdr+1); /* advance past header */
X
X /* Insert into list now so free_all does right thing if I fail */
X /* after allocating only some of the rows... */
X hdr->next = small_barray_list;
X hdr->numrows = 0;
X hdr->rowsperchunk = rowsperchunk;
X small_barray_list = hdr;
X
X /* Get the rows themselves; on 80x86 these are "far" */
X currow = 0;
X while (currow < numrows) {
X rowsperchunk = MIN(rowsperchunk, numrows - currow);
X#ifdef MEM_STATS
X total_bytes_barray += rowsperchunk * blocksperrow * SIZEOF(JBLOCK)
X + MALLOC_FAR_OVERHEAD;
X#endif
X workspace = (JBLOCKROW) jget_large((size_t) (rowsperchunk * blocksperrow
X * SIZEOF(JBLOCK)));
X if (workspace == NULL)
X out_of_memory(4);
X for (i = rowsperchunk; i > 0; i--) {
X result[currow++] = workspace;
X workspace += blocksperrow;
X }
X hdr->numrows = currow;
X }
X
X return result;
X}
X
X
XMETHODDEF void
Xfree_small_barray (JBLOCKARRAY ptr)
X/* Free a "small" (all-in-memory) 2-D coefficient-block array */
X{
X small_barray_ptr hdr;
X small_barray_ptr * llink;
X long i;
X
X hdr = (small_barray_ptr) ptr;
X hdr--; /* point back to header */
X
X /* Remove item from list -- linear search is fast enough */
X llink = &small_barray_list;
X while (*llink != hdr) {
X if (*llink == NULL)
X ERREXIT(methods, "Bogus free_small_barray request");
X llink = &( (*llink)->next );
X }
X *llink = hdr->next;
X
X /* Free the rows themselves; on 80x86 these are "far" */
X /* Note we only free the row-group headers! */
X for (i = 0; i < hdr->numrows; i += hdr->rowsperchunk) {
X jfree_large((void FAR *) ptr[i]);
X }
X
X /* Free header and row pointers */
X free_small((void *) hdr);
X
X#ifdef MEM_STATS
X cur_num_barray--;
X#endif
X}
X
X
X
X/*
X * About "big" array management:
X *
X * To allow machines with limited memory to handle large images,
X * all processing in the JPEG system is done a few pixel or block rows
X * at a time. The above "small" array routines are only used to allocate
X * strip buffers (as wide as the image, but just a few rows high).
X * In some cases multiple passes must be made over the data. In these
X * cases the "big" array routines are used. The array is still accessed
X * a strip at a time, but the memory manager must save the whole array
X * for repeated accesses. The intended implementation is that there is
X * a strip buffer in memory (as high as is possible given the desired memory
X * limit), plus a backing file that holds the rest of the array.
X *
X * The request_big_array routines are told the total size of the image (in case
X * it is useful to know the total file size that will be needed). They are
X * also given the unit height, which is the number of rows that will be
X * accessed at once; the in-memory buffer should be made a multiple of
X * this height for best efficiency.
X *
X * The request routines create control blocks (and may open backing files),
X * but they don't create the in-memory buffers. This is postponed until
X * alloc_big_arrays is called. At that time the total amount of space needed
X * is known (approximately, anyway), so free memory can be divided up fairly.
X *
X * The access_big_array routines are responsible for making a specific strip
X * area accessible (after reading or writing the backing file, if necessary).
X * Note that the access routines are told whether the caller intends to modify
X * the accessed strip; during a read-only pass this saves having to rewrite
X * data to disk.
X *
X * The typical access pattern is one top-to-bottom pass to write the data,
X * followed by one or more read-only top-to-bottom passes. However, other
X * access patterns may occur while reading. For example, translation of image
X * formats that use bottom-to-top scan order will require bottom-to-top read
X * passes. The memory manager need not support multiple write passes nor
X * funny write orders (meaning that rearranging rows must be handled while
X * reading data out of the big array, not while putting it in).
X *
X * In current usage, the access requests are always for nonoverlapping strips;
X * that is, successive access start_row numbers always differ by exactly the
X * unitheight. This allows fairly simple buffer dump/reload logic if the
X * in-memory buffer is made a multiple of the unitheight. It would be
X * possible to keep subsampled rather than fullsize data in the "big" arrays,
X * thus reducing temp file size, if we supported overlapping strip access
X * (access requests differing by less than the unitheight). At the moment
X * I don't believe this is worth the extra complexity.
X */
X
X
X
X/* The control blocks for virtual arrays.
X * System-dependent info for the associated backing store is hidden inside
X * the backing_store_info struct.
X */
X
Xstruct big_sarray_control {
X long rows_in_array; /* total virtual array height */
X long samplesperrow; /* width of array (and of memory buffer) */
X long unitheight; /* # of rows accessed by access_big_sarray() */
X JSAMPARRAY mem_buffer; /* the in-memory buffer */
X long rows_in_mem; /* height of memory buffer */
X long rowsperchunk; /* allocation chunk size in mem_buffer */
X long cur_start_row; /* first logical row # in the buffer */
X boolean dirty; /* do current buffer contents need written? */
X boolean b_s_open; /* is backing-store data valid? */
X big_sarray_ptr next; /* link to next big sarray control block */
X backing_store_info b_s_info; /* System-dependent control info */
X};
X
Xstatic big_sarray_ptr big_sarray_list; /* head of list */
X
Xstruct big_barray_control {
X long rows_in_array; /* total virtual array height */
X long blocksperrow; /* width of array (and of memory buffer) */
X long unitheight; /* # of rows accessed by access_big_barray() */
X JBLOCKARRAY mem_buffer; /* the in-memory buffer */
X long rows_in_mem; /* height of memory buffer */
X long rowsperchunk; /* allocation chunk size in mem_buffer */
X long cur_start_row; /* first logical row # in the buffer */
X boolean dirty; /* do current buffer contents need written? */
X boolean b_s_open; /* is backing-store data valid? */
X big_barray_ptr next; /* link to next big barray control block */
X backing_store_info b_s_info; /* System-dependent control info */
X};
X
Xstatic big_barray_ptr big_barray_list; /* head of list */
X
X
XMETHODDEF big_sarray_ptr
Xrequest_big_sarray (long samplesperrow, long numrows, long unitheight)
X/* Request a "big" (virtual-memory) 2-D sample array */
X{
X big_sarray_ptr result;
X
X /* get control block */
X result = (big_sarray_ptr) alloc_small(SIZEOF(struct big_sarray_control));
X
X result->rows_in_array = numrows;
X result->samplesperrow = samplesperrow;
X result->unitheight = unitheight;
X result->mem_buffer = NULL; /* marks array not yet realized */
X result->b_s_open = FALSE; /* no associated backing-store object */
X result->next = big_sarray_list; /* add to list of big arrays */
X big_sarray_list = result;
X
X return result;
X}
X
X
XMETHODDEF big_barray_ptr
Xrequest_big_barray (long blocksperrow, long numrows, long unitheight)
X/* Request a "big" (virtual-memory) 2-D coefficient-block array */
X{
X big_barray_ptr result;
X
X /* get control block */
X result = (big_barray_ptr) alloc_small(SIZEOF(struct big_barray_control));
X
X result->rows_in_array = numrows;
X result->blocksperrow = blocksperrow;
X result->unitheight = unitheight;
X result->mem_buffer = NULL; /* marks array not yet realized */
X result->b_s_open = FALSE; /* no associated backing-store object */
X result->next = big_barray_list; /* add to list of big arrays */
X big_barray_list = result;
X
X return result;
X}
X
X
XMETHODDEF void
Xalloc_big_arrays (long extra_small_samples, long extra_small_blocks,
X long extra_medium_space)
X/* Allocate the in-memory buffers for any unrealized "big" arrays */
X/* 'extra' values are upper bounds for total future small-array requests */
X/* and far-heap requests */
X{
X long total_extra_space = extra_small_samples * SIZEOF(JSAMPLE)
X + extra_small_blocks * SIZEOF(JBLOCK)
X + extra_medium_space;
X long space_per_unitheight, maximum_space, avail_mem;
X long unitheights, max_unitheights;
X big_sarray_ptr sptr;
X big_barray_ptr bptr;
X
X /* Compute the minimum space needed (unitheight rows in each buffer)
X * and the maximum space needed (full image height in each buffer).
X * These may be of use to the system-dependent jmem_available routine.
X */
X space_per_unitheight = 0;
X maximum_space = total_extra_space;
X for (sptr = big_sarray_list; sptr != NULL; sptr = sptr->next) {
X if (sptr->mem_buffer == NULL) { /* if not realized yet */
X space_per_unitheight += sptr->unitheight *
X sptr->samplesperrow * SIZEOF(JSAMPLE);
X maximum_space += sptr->rows_in_array *
X sptr->samplesperrow * SIZEOF(JSAMPLE);
X }
X }
X for (bptr = big_barray_list; bptr != NULL; bptr = bptr->next) {
X if (bptr->mem_buffer == NULL) { /* if not realized yet */
X space_per_unitheight += bptr->unitheight *
X bptr->blocksperrow * SIZEOF(JBLOCK);
X maximum_space += bptr->rows_in_array *
X bptr->blocksperrow * SIZEOF(JBLOCK);
X }
X }
X
X if (space_per_unitheight <= 0)
X return; /* no unrealized arrays, no work */
X
X /* Determine amount of memory to actually use; this is system-dependent. */
X avail_mem = jmem_available(space_per_unitheight + total_extra_space,
X maximum_space);
X
X /* If the maximum space needed is available, make all the buffers full
X * height; otherwise parcel it out with the same number of unitheights
X * in each buffer.
X */
X if (avail_mem >= maximum_space)
X max_unitheights = 1000000000L;
X else {
X max_unitheights = (avail_mem - total_extra_space) / space_per_unitheight;
X /* If there doesn't seem to be enough space, try to get the minimum
X * anyway. This allows a "stub" implementation of jmem_available().
X */
X if (max_unitheights <= 0)
X max_unitheights = 1;
X }
X
X /* Allocate the in-memory buffers and initialize backing store as needed. */
X
X for (sptr = big_sarray_list; sptr != NULL; sptr = sptr->next) {
X if (sptr->mem_buffer == NULL) { /* if not realized yet */
X unitheights = (sptr->rows_in_array + sptr->unitheight - 1L)
X / sptr->unitheight;
X if (unitheights <= max_unitheights) {
X /* This buffer fits in memory */
X sptr->rows_in_mem = sptr->rows_in_array;
X } else {
X /* It doesn't fit in memory, create backing store. */
X sptr->rows_in_mem = max_unitheights * sptr->unitheight;
X jopen_backing_store(& sptr->b_s_info,
X sptr->rows_in_array
X * sptr->samplesperrow * SIZEOF(JSAMPLE));
X sptr->b_s_open = TRUE;
X }
X sptr->mem_buffer = alloc_small_sarray(sptr->samplesperrow,
X sptr->rows_in_mem);
X /* Reach into the small_sarray header and get the rowsperchunk field.
X * Yes, I know, this is horrible coding practice.
X */
X sptr->rowsperchunk =
X ((small_sarray_ptr) sptr->mem_buffer)[-1].rowsperchunk;
X sptr->cur_start_row = 0;
X sptr->dirty = FALSE;
X }
X }
X
X for (bptr = big_barray_list; bptr != NULL; bptr = bptr->next) {
X if (bptr->mem_buffer == NULL) { /* if not realized yet */
X unitheights = (bptr->rows_in_array + bptr->unitheight - 1L)
X / bptr->unitheight;
X if (unitheights <= max_unitheights) {
X /* This buffer fits in memory */
X bptr->rows_in_mem = bptr->rows_in_array;
X } else {
X /* It doesn't fit in memory, create backing store. */
X bptr->rows_in_mem = max_unitheights * bptr->unitheight;
X jopen_backing_store(& bptr->b_s_info,
X bptr->rows_in_array
X * bptr->blocksperrow * SIZEOF(JBLOCK));
X bptr->b_s_open = TRUE;
X }
X bptr->mem_buffer = alloc_small_barray(bptr->blocksperrow,
X bptr->rows_in_mem);
X /* Reach into the small_barray header and get the rowsperchunk field. */
X bptr->rowsperchunk =
X ((small_barray_ptr) bptr->mem_buffer)[-1].rowsperchunk;
X bptr->cur_start_row = 0;
X bptr->dirty = FALSE;
X }
X }
X}
X
X
XLOCAL void
Xdo_sarray_io (big_sarray_ptr ptr, boolean writing)
X/* Do backing store read or write of a "big" sample array */
X{
X long bytesperrow, file_offset, byte_count, rows, i;
X
X bytesperrow = ptr->samplesperrow * SIZEOF(JSAMPLE);
X file_offset = ptr->cur_start_row * bytesperrow;
X /* Loop to read or write each allocation chunk in mem_buffer */
X for (i = 0; i < ptr->rows_in_mem; i += ptr->rowsperchunk) {
X /* One chunk, but check for short chunk at end of buffer */
X rows = MIN(ptr->rowsperchunk, ptr->rows_in_mem - i);
X /* Transfer no more than fits in file */
X rows = MIN(rows, ptr->rows_in_array - (ptr->cur_start_row + i));
X if (rows <= 0) /* this chunk might be past end of file! */
X break;
X byte_count = rows * bytesperrow;
X if (writing)
X (*ptr->b_s_info.write_backing_store) (& ptr->b_s_info,
X (void FAR *) ptr->mem_buffer[i],
X file_offset, byte_count);
X else
X (*ptr->b_s_info.read_backing_store) (& ptr->b_s_info,
X (void FAR *) ptr->mem_buffer[i],
X file_offset, byte_count);
X file_offset += byte_count;
X }
X}
X
X
XLOCAL void
Xdo_barray_io (big_barray_ptr ptr, boolean writing)
X/* Do backing store read or write of a "big" coefficient-block array */
X{
X long bytesperrow, file_offset, byte_count, rows, i;
X
X bytesperrow = ptr->blocksperrow * SIZEOF(JBLOCK);
X file_offset = ptr->cur_start_row * bytesperrow;
X /* Loop to read or write each allocation chunk in mem_buffer */
X for (i = 0; i < ptr->rows_in_mem; i += ptr->rowsperchunk) {
X /* One chunk, but check for short chunk at end of buffer */
X rows = MIN(ptr->rowsperchunk, ptr->rows_in_mem - i);
X /* Transfer no more than fits in file */
X rows = MIN(rows, ptr->rows_in_array - (ptr->cur_start_row + i));
X if (rows <= 0) /* this chunk might be past end of file! */
X break;
X byte_count = rows * bytesperrow;
X if (writing)
X (*ptr->b_s_info.write_backing_store) (& ptr->b_s_info,
X (void FAR *) ptr->mem_buffer[i],
X file_offset, byte_count);
X else
X (*ptr->b_s_info.read_backing_store) (& ptr->b_s_info,
X (void FAR *) ptr->mem_buffer[i],
X file_offset, byte_count);
X file_offset += byte_count;
X }
X}
X
X
XMETHODDEF JSAMPARRAY
Xaccess_big_sarray (big_sarray_ptr ptr, long start_row, boolean writable)
X/* Access the part of a "big" sample array starting at start_row */
X/* and extending for ptr->unitheight rows. writable is true if */
X/* caller intends to modify the accessed area. */
X{
X /* debugging check */
X if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_array ||
X ptr->mem_buffer == NULL)
X ERREXIT(methods, "Bogus access_big_sarray request");
X
X /* Make the desired part of the virtual array accessible */
X if (start_row < ptr->cur_start_row ||
X start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
X if (! ptr->b_s_open)
X ERREXIT(methods, "Virtual array controller messed up");
X /* Flush old buffer contents if necessary */
X if (ptr->dirty) {
X do_sarray_io(ptr, TRUE);
X ptr->dirty = FALSE;
X }
X /* Decide what part of virtual array to access.
X * Algorithm: if target address > current window, assume forward scan,
X * load starting at target address. If target address < current window,
X * assume backward scan, load so that target address is top of window.
X * Note that when switching from forward write to forward read, will have
X * start_row = 0, so the limiting case applies and we load from 0 anyway.
X */
X if (start_row > ptr->cur_start_row) {
X ptr->cur_start_row = start_row;
X } else {
X ptr->cur_start_row = start_row + ptr->unitheight - ptr->rows_in_mem;
X if (ptr->cur_start_row < 0)
X ptr->cur_start_row = 0; /* don't fall off front end of file */
X }
X /* If reading, read in the selected part of the array.
X * If we are writing, we need not pre-read the selected portion,
X * since the access sequence constraints ensure it would be garbage.
X */
X if (! writable) {
X do_sarray_io(ptr, FALSE);
X }
X }
X /* Flag the buffer dirty if caller will write in it */
X if (writable)
X ptr->dirty = TRUE;
X /* Return address of proper part of the buffer */
X return ptr->mem_buffer + (start_row - ptr->cur_start_row);
X}
X
X
XMETHODDEF JBLOCKARRAY
Xaccess_big_barray (big_barray_ptr ptr, long start_row, boolean writable)
X/* Access the part of a "big" coefficient-block array starting at start_row */
X/* and extending for ptr->unitheight rows. writable is true if */
X/* caller intends to modify the accessed area. */
X{
X /* debugging check */
X if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_array ||
X ptr->mem_buffer == NULL)
X ERREXIT(methods, "Bogus access_big_barray request");
X
X /* Make the desired part of the virtual array accessible */
X if (start_row < ptr->cur_start_row ||
X start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
X if (! ptr->b_s_open)
X ERREXIT(methods, "Virtual array controller messed up");
X /* Flush old buffer contents if necessary */
X if (ptr->dirty) {
X do_barray_io(ptr, TRUE);
X ptr->dirty = FALSE;
X }
X /* Decide what part of virtual array to access.
X * Algorithm: if target address > current window, assume forward scan,
X * load starting at target address. If target address < current window,
X * assume backward scan, load so that target address is top of window.
X * Note that when switching from forward write to forward read, will have
X * start_row = 0, so the limiting case applies and we load from 0 anyway.
X */
X if (start_row > ptr->cur_start_row) {
X ptr->cur_start_row = start_row;
X } else {
X ptr->cur_start_row = start_row + ptr->unitheight - ptr->rows_in_mem;
X if (ptr->cur_start_row < 0)
X ptr->cur_start_row = 0; /* don't fall off front end of file */
X }
X /* If reading, read in the selected part of the array.
X * If we are writing, we need not pre-read the selected portion,
X * since the access sequence constraints ensure it would be garbage.
X */
X if (! writable) {
X do_barray_io(ptr, FALSE);
X }
X }
X /* Flag the buffer dirty if caller will write in it */
X if (writable)
X ptr->dirty = TRUE;
X /* Return address of proper part of the buffer */
X return ptr->mem_buffer + (start_row - ptr->cur_start_row);
X}
X
X
XMETHODDEF void
Xfree_big_sarray (big_sarray_ptr ptr)
X/* Free a "big" (virtual-memory) 2-D sample array */
X{
X big_sarray_ptr * llink;
X
X /* Remove item from list -- linear search is fast enough */
X llink = &big_sarray_list;
X while (*llink != ptr) {
X if (*llink == NULL)
X ERREXIT(methods, "Bogus free_big_sarray request");
X llink = &( (*llink)->next );
X }
X *llink = ptr->next;
X
X if (ptr->b_s_open) /* there may be no backing store */
X (*ptr->b_s_info.close_backing_store) (& ptr->b_s_info);
X
X if (ptr->mem_buffer != NULL) /* just in case never realized */
X free_small_sarray(ptr->mem_buffer);
X
X free_small((void *) ptr); /* free the control block too */
X}
X
X
XMETHODDEF void
Xfree_big_barray (big_barray_ptr ptr)
X/* Free a "big" (virtual-memory) 2-D coefficient-block array */
X{
X big_barray_ptr * llink;
X
X /* Remove item from list -- linear search is fast enough */
X llink = &big_barray_list;
X while (*llink != ptr) {
X if (*llink == NULL)
X ERREXIT(methods, "Bogus free_big_barray request");
X llink = &( (*llink)->next );
X }
X *llink = ptr->next;
X
X if (ptr->b_s_open) /* there may be no backing store */
X (*ptr->b_s_info.close_backing_store) (& ptr->b_s_info);
X
X if (ptr->mem_buffer != NULL) /* just in case never realized */
X free_small_barray(ptr->mem_buffer);
X
X free_small((void *) ptr); /* free the control block too */
X}
X
X
X/*
X * Cleanup: free anything that's been allocated since jselmemmgr().
X */
X
XMETHODDEF void
Xfree_all (void)
X{
X /* First free any open "big" arrays -- these may release small arrays */
X while (big_sarray_list != NULL)
X free_big_sarray(big_sarray_list);
X while (big_barray_list != NULL)
X free_big_barray(big_barray_list);
X /* Free any open small arrays -- these may release small objects */
X /* +1's are because we must pass a pointer to the data, not the header */
X while (small_sarray_list != NULL)
X free_small_sarray((JSAMPARRAY) (small_sarray_list + 1));
X while (small_barray_list != NULL)
X free_small_barray((JBLOCKARRAY) (small_barray_list + 1));
X /* Free any remaining small objects */
X while (small_list != NULL)
X free_small((void *) (small_list + 1));
X#ifdef NEED_ALLOC_MEDIUM
X while (medium_list != NULL)
X free_medium((void FAR *) (medium_list + 1));
X#endif
X
X jmem_term(); /* system-dependent cleanup */
X
X#ifdef MEM_STATS
X if (methods->trace_level > 0)
X print_mem_stats(); /* print optional memory usage statistics */
X#endif
X}
X
X
X/*
X * The method selection routine for virtual memory systems.
X * The system-dependent setup routine should call this routine
X * to install the necessary method pointers in the supplied struct.
X */
X
XGLOBAL void
Xjselmemmgr (external_methods_ptr emethods)
X{
X methods = emethods; /* save struct addr for error exit access */
X
X emethods->alloc_small = alloc_small;
X emethods->free_small = free_small;
X#ifdef NEED_ALLOC_MEDIUM
X emethods->alloc_medium = alloc_medium;
X emethods->free_medium = free_medium;
X#else
X emethods->alloc_medium = alloc_small;
X emethods->free_medium = free_small;
X#endif
X emethods->alloc_small_sarray = alloc_small_sarray;
X emethods->free_small_sarray = free_small_sarray;
X emethods->alloc_small_barray = alloc_small_barray;
X emethods->free_small_barray = free_small_barray;
X emethods->request_big_sarray = request_big_sarray;
X emethods->request_big_barray = request_big_barray;
X emethods->alloc_big_arrays = alloc_big_arrays;
X emethods->access_big_sarray = access_big_sarray;
X emethods->access_big_barray = access_big_barray;
X emethods->free_big_sarray = free_big_sarray;
X emethods->free_big_barray = free_big_barray;
X emethods->free_all = free_all;
X
X /* Initialize list headers to empty */
X small_list = NULL;
X#ifdef NEED_ALLOC_MEDIUM
X medium_list = NULL;
X#endif
X small_sarray_list = NULL;
X small_barray_list = NULL;
X big_sarray_list = NULL;
X big_barray_list = NULL;
X
X jmem_init(emethods); /* system-dependent initialization */
X}
END_OF_FILE
if test 35862 -ne `wc -c <'jmemmgr.c'`; then
echo shar: \"'jmemmgr.c'\" unpacked with wrong size!
fi
# end of 'jmemmgr.c'
fi
if test -f 'jrdtarga.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jrdtarga.c'\"
else
echo shar: Extracting \"'jrdtarga.c'\" \(13177 characters\)
sed "s/^X//" >'jrdtarga.c' <<'END_OF_FILE'
X/*
X * jrdtarga.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to read input images in Targa format.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume input from
X * an ordinary stdio stream. They further assume that reading begins
X * at the start of the file; input_init may need work if the
X * user interface has already read some data (e.g., to determine that
X * the file is indeed Targa format).
X *
X * These routines are invoked via the methods get_input_row
X * and input_init/term.
X *
X * Based on code contributed by Lee Daniel Crocker.
X */
X
X#include "jinclude.h"
X
X#ifdef TARGA_SUPPORTED
X
X
X/* Macros to deal with unsigned chars as efficiently as compiler allows */
X
X#ifdef HAVE_UNSIGNED_CHAR
Xtypedef unsigned char U_CHAR;
X#define UCH(x) ((int) (x))
X#else /* !HAVE_UNSIGNED_CHAR */
X#ifdef CHAR_IS_UNSIGNED
Xtypedef char U_CHAR;
X#define UCH(x) ((int) (x))
X#else
Xtypedef char U_CHAR;
X#define UCH(x) ((int) (x) & 0xFF)
X#endif
X#endif /* HAVE_UNSIGNED_CHAR */
X
X
X#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
X
X
Xstatic JSAMPARRAY colormap; /* Targa colormap (converted to my format) */
X
Xstatic big_sarray_ptr whole_image; /* Needed if funny input row order */
Xstatic long current_row; /* Current logical row number to read */
X
X/* Pointer to routine to extract next Targa pixel from input file */
Xstatic void (*read_pixel) PP((compress_info_ptr cinfo));
X
X/* Result of read_pixel is delivered here: */
Xstatic U_CHAR tga_pixel[4];
X
Xstatic int pixel_size; /* Bytes per Targa pixel (1 to 4) */
X
X/* State info for reading RLE-coded pixels; both counts must be init to 0 */
Xstatic int block_count; /* # of pixels remaining in RLE block */
Xstatic int dup_pixel_count; /* # of times to duplicate previous pixel */
X
X/* This saves the correct pixel-row-expansion method for preload_image */
Xstatic void (*get_pixel_row) PP((compress_info_ptr cinfo,
X JSAMPARRAY pixel_row));
X
X
X/* For expanding 5-bit pixel values to 8-bit with best rounding */
X
Xstatic const UINT8 c5to8bits[32] = {
X 0, 8, 16, 24, 32, 41, 49, 57,
X 65, 74, 82, 90, 98, 106, 115, 123,
X 131, 139, 148, 156, 164, 172, 180, 189,
X 197, 205, 213, 222, 230, 238, 246, 255
X};
X
X
X
XLOCAL int
Xread_byte (compress_info_ptr cinfo)
X/* Read next byte from Targa file */
X{
X register FILE *infile = cinfo->input_file;
X register int c;
X
X if ((c = getc(infile)) == EOF)
X ERREXIT(cinfo->emethods, "Premature EOF in Targa file");
X return c;
X}
X
X
XLOCAL void
Xread_colormap (compress_info_ptr cinfo, int cmaplen, int mapentrysize)
X/* Read the colormap from a Targa file */
X{
X int i;
X
X /* Presently only handles 24-bit BGR format */
X if (mapentrysize != 24)
X ERREXIT(cinfo->emethods, "Unsupported Targa colormap format");
X
X for (i = 0; i < cmaplen; i++) {
X colormap[2][i] = (JSAMPLE) read_byte(cinfo);
X colormap[1][i] = (JSAMPLE) read_byte(cinfo);
X colormap[0][i] = (JSAMPLE) read_byte(cinfo);
X }
X}
X
X
X/*
X * read_pixel methods: get a single pixel from Targa file into tga_pixel[]
X */
X
XLOCAL void
Xread_non_rle_pixel (compress_info_ptr cinfo)
X/* Read one Targa pixel from the input file; no RLE expansion */
X{
X register FILE * infile = cinfo->input_file;
X register int i;
X
X for (i = 0; i < pixel_size; i++) {
X tga_pixel[i] = (U_CHAR) getc(infile);
X }
X}
X
X
XLOCAL void
Xread_rle_pixel (compress_info_ptr cinfo)
X/* Read one Targa pixel from the input file, expanding RLE data as needed */
X{
X register FILE * infile = cinfo->input_file;
X register int i;
X
X /* Duplicate previously read pixel? */
X if (dup_pixel_count > 0) {
X dup_pixel_count--;
X return;
X }
X
X /* Time to read RLE block header? */
X if (--block_count < 0) { /* decrement pixels remaining in block */
X i = read_byte(cinfo);
X if (i & 0x80) { /* Start of duplicate-pixel block? */
X dup_pixel_count = i & 0x7F; /* number of duplications after this one */
X block_count = 0; /* then read new block header */
X } else {
X block_count = i & 0x7F; /* number of pixels after this one */
X }
X }
X
X /* Read next pixel */
X for (i = 0; i < pixel_size; i++) {
X tga_pixel[i] = (U_CHAR) getc(infile);
X }
X}
X
X
X/*
X * Read one row of pixels.
X *
X * We provide several different versions depending on input file format.
X */
X
X
XMETHODDEF void
Xget_8bit_gray_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading 8-bit grayscale pixels */
X{
X register JSAMPROW ptr0;
X register long col;
X
X ptr0 = pixel_row[0];
X for (col = cinfo->image_width; col > 0; col--) {
X (*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
X *ptr0++ = (JSAMPLE) UCH(tga_pixel[0]);
X }
X}
X
XMETHODDEF void
Xget_8bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading 8-bit colormap indexes */
X{
X register int t;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X (*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
X t = UCH(tga_pixel[0]);
X *ptr0++ = colormap[0][t];
X *ptr1++ = colormap[1][t];
X *ptr2++ = colormap[2][t];
X }
X}
X
XMETHODDEF void
Xget_16bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading 16-bit pixels */
X{
X register int t;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X (*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
X t = UCH(tga_pixel[0]);
X t += UCH(tga_pixel[1]) << 8;
X /* We expand 5 bit data to 8 bit sample width.
X * The format of the 16-bit (LSB first) input word is
X * xRRRRRGGGGGBBBBB
X */
X *ptr2++ = (JSAMPLE) c5to8bits[t & 0x1F];
X t >>= 5;
X *ptr1++ = (JSAMPLE) c5to8bits[t & 0x1F];
X t >>= 5;
X *ptr0++ = (JSAMPLE) c5to8bits[t & 0x1F];
X }
X}
X
XMETHODDEF void
Xget_24bit_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This version is for reading 24-bit pixels */
X{
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X (*read_pixel) (cinfo); /* Load next pixel into tga_pixel */
X *ptr0++ = (JSAMPLE) UCH(tga_pixel[2]); /* convert BGR to RGB order */
X *ptr1++ = (JSAMPLE) UCH(tga_pixel[1]);
X *ptr2++ = (JSAMPLE) UCH(tga_pixel[0]);
X }
X}
X
X/*
X * Targa also defines a 32-bit pixel format with order B,G,R,A.
X * We presently ignore the attribute byte, so the code for reading
X * these pixels is identical to the 24-bit routine above.
X * This works because the actual pixel length is only known to read_pixel.
X */
X
X#define get_32bit_row get_24bit_row
X
X
X/*
X * This method is for re-reading the input data in standard top-down
X * row order. The entire image has already been read into whole_image
X * with proper conversion of pixel format, but it's in a funny row order.
X */
X
XMETHODDEF void
Xget_memory_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X JSAMPARRAY image_ptr;
X long source_row;
X
X /* Compute row of source that maps to current_row of normal order */
X /* For now, assume image is bottom-up and not interlaced. */
X /* NEEDS WORK to support interlaced images! */
X source_row = cinfo->image_height - current_row - 1;
X
X /* Fetch that row from virtual array */
X image_ptr = (*cinfo->emethods->access_big_sarray)
X (whole_image, source_row * cinfo->input_components, FALSE);
X
X jcopy_sample_rows(image_ptr, 0, pixel_row, 0,
X cinfo->input_components, cinfo->image_width);
X
X current_row++;
X}
X
X
X/*
X * This method loads the image into whole_image during the first call on
X * get_input_row. The get_input_row pointer is then adjusted to call
X * get_memory_row on subsequent calls.
X */
X
XMETHODDEF void
Xpreload_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X JSAMPARRAY image_ptr;
X long row;
X
X /* Read the data into a virtual array in input-file row order */
X for (row = 0; row < cinfo->image_height; row++) {
X (*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
X image_ptr = (*cinfo->emethods->access_big_sarray)
X (whole_image, row * cinfo->input_components, TRUE);
X (*get_pixel_row) (cinfo, image_ptr);
X }
X cinfo->completed_passes++;
X
X /* Set up to read from the virtual array in unscrambled order */
X cinfo->methods->get_input_row = get_memory_row;
X current_row = 0;
X /* And read the first row */
X get_memory_row(cinfo, pixel_row);
X}
X
X
X/*
X * Read the file header; return image size and component count.
X */
X
XMETHODDEF void
Xinput_init (compress_info_ptr cinfo)
X{
X U_CHAR targaheader[18];
X int idlen, cmaptype, subtype, flags, interlace_type, components;
X UINT16 width, height, maplen;
X boolean is_bottom_up;
X
X#define GET_2B(offset) ((unsigned int) UCH(targaheader[offset]) + \
X (((unsigned int) UCH(targaheader[offset+1])) << 8))
X
X if (! ReadOK(cinfo->input_file, targaheader, 18))
X ERREXIT(cinfo->emethods, "Unexpected end of file");
X
X /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */
X if (targaheader[16] == 15)
X targaheader[16] = 16;
X
X idlen = UCH(targaheader[0]);
X cmaptype = UCH(targaheader[1]);
X subtype = UCH(targaheader[2]);
X maplen = GET_2B(5);
X width = GET_2B(12);
X height = GET_2B(14);
X pixel_size = UCH(targaheader[16]) >> 3;
X flags = UCH(targaheader[17]); /* Image Descriptor byte */
X
X is_bottom_up = ((flags & 0x20) == 0); /* bit 5 set => top-down */
X interlace_type = flags >> 6; /* bits 6/7 are interlace code */
X
X if (cmaptype > 1 || /* cmaptype must be 0 or 1 */
X pixel_size < 1 || pixel_size > 4 ||
X (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */
X interlace_type != 0) /* currently don't allow interlaced image */
X ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
X
X if (subtype > 8) {
X /* It's an RLE-coded file */
X read_pixel = read_rle_pixel;
X block_count = dup_pixel_count = 0;
X subtype -= 8;
X } else {
X /* Non-RLE file */
X read_pixel = read_non_rle_pixel;
X }
X
X /* Now should have subtype 1, 2, or 3 */
X components = 3; /* until proven different */
X cinfo->in_color_space = CS_RGB;
X
X switch (subtype) {
X case 1: /* colormapped image */
X if (pixel_size == 1 && cmaptype == 1)
X get_pixel_row = get_8bit_row;
X else
X ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
X break;
X case 2: /* RGB image */
X switch (pixel_size) {
X case 2:
X get_pixel_row = get_16bit_row;
X break;
X case 3:
X get_pixel_row = get_24bit_row;
X break;
X case 4:
X get_pixel_row = get_32bit_row;
X break;
X default:
X ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
X break;
X }
X break;
X case 3: /* Grayscale image */
X components = 1;
X cinfo->in_color_space = CS_GRAYSCALE;
X if (pixel_size == 1)
X get_pixel_row = get_8bit_gray_row;
X else
X ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
X break;
X default:
X ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
X break;
X }
X
X if (is_bottom_up) {
X whole_image = (*cinfo->emethods->request_big_sarray)
X ((long) width, (long) height * components,
X (long) components);
X cinfo->methods->get_input_row = preload_image;
X cinfo->total_passes++; /* count file reading as separate pass */
X } else {
X whole_image = NULL;
X cinfo->methods->get_input_row = get_pixel_row;
X }
X
X while (idlen--) /* Throw away ID field */
X (void) read_byte(cinfo);
X
X if (maplen > 0) {
X if (maplen > 256 || GET_2B(3) != 0)
X ERREXIT(cinfo->emethods, "Colormap too large");
X /* Allocate space to store the colormap */
X colormap = (*cinfo->emethods->alloc_small_sarray)
X ((long) maplen, 3L);
X /* and read it from the file */
X read_colormap(cinfo, (int) maplen, UCH(targaheader[7]));
X } else {
X if (cmaptype) /* but you promised a cmap! */
X ERREXIT(cinfo->emethods, "Invalid or unsupported Targa file");
X colormap = NULL;
X }
X
X cinfo->input_components = components;
X cinfo->image_width = width;
X cinfo->image_height = height;
X cinfo->data_precision = 8; /* always, even if 12-bit JSAMPLEs */
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xinput_term (compress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for Targa format input.
X * Note that this must be called by the user interface before calling
X * jpeg_compress. If multiple input formats are supported, the
X * user interface is responsible for discovering the file format and
X * calling the appropriate method selection routine.
X */
X
XGLOBAL void
Xjselrtarga (compress_info_ptr cinfo)
X{
X cinfo->methods->input_init = input_init;
X /* cinfo->methods->get_input_row is set by input_init */
X cinfo->methods->input_term = input_term;
X}
X
X#endif /* TARGA_SUPPORTED */
END_OF_FILE
if test 13177 -ne `wc -c <'jrdtarga.c'`; then
echo shar: \"'jrdtarga.c'\" unpacked with wrong size!
fi
# end of 'jrdtarga.c'
fi
if test -f 'makvms.opt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makvms.opt'\"
else
echo shar: Extracting \"'makvms.opt'\" \(142 characters\)
sed "s/^X//" >'makvms.opt' <<'END_OF_FILE'
X! a pointer to the VAX/VMS C Run-Time Shareable Library
X! This file is needed by makefile.mms and makefile.vms
XSys$Library:VAXCRTL.EXE /Share
END_OF_FILE
if test 142 -ne `wc -c <'makvms.opt'`; then
echo shar: \"'makvms.opt'\" unpacked with wrong size!
fi
# end of 'makvms.opt'
fi
echo shar: End of archive 5 \(of 18\).
cp /dev/null ark5isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: arch.b ckconfig.c jerror.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:43 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 6 (of 18)."'
if test -f 'arch.b' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'arch.b'\"
else
echo shar: Extracting \"'arch.b'\" \(36460 characters\)
sed "s/^X//" >'arch.b' <<'END_OF_FILE'
X2. Gamma and color space conversion. This provides three methods:
X colorin_init: initialization.
X get_sample_rows: read, convert, and return a specified number of pixel
X rows (not more than remain in the picture).
X colorin_term: finish up at the end.
X The most efficient approach seems to be for this object to call
X get_input_row directly, rather than being passed the input data; that way,
X any intermediate storage required can be local to this object.
X (get_sample_rows might tell get_input_row to read directly into its own
X output area and then convert in place; or it may do something different.
X For example, conversion in place wouldn't work if it is changing the number
X of color components.) The output of this step is in the standardized
X sample array format shown previously.
X (Hides all knowledge of color space semantics and conversion. Remaining
X modules only need to know the number of JPEG components.)
X
X3. Edge expansion: needs only a single method.
X edge_expand: Given an NxM sample array, expand to a desired size (a
X multiple of the MCU dimensions) by duplicating the last
X row or column. Repeat for each component.
X Expansion will occur in place, so the caller must have pre-allocated enough
X storage. (I'm assuming that it is easier and faster to do this expansion
X than it is to worry about boundary conditions in the next two steps.
X Notice that vertical expansion will occur only once, at the bottom of the
X picture, so only horizontal expansion by a few pixels is speed-critical.)
X (This doesn't really hide any information, so maybe it could be a simple
X subroutine instead of a method. Depends on whether we want to be able to
X use alternative, optimized methods.)
X
X4. Subsampling: this will be applied to one component at a time.
X subsample_init: initialize (precalculate convolution factors, for
X example). This will be called once per scan.
X subsample: Given a sample array, reduce it to a smaller number of
X samples using specified sampling factors.
X subsample_term: clean up at the end of a scan.
X If the current component has vertical sampling factor Vk and the largest
X sampling factor is Vmax, then the input is always Vmax sample rows (whose
X width is a multiple of Hmax) and the output is always Vk sample rows.
X Vmax additional rows above and below the nominal input rows are also passed
X for use by partial-pixel-averaging sampling methods. (Is this necessary?)
X At the top and bottom of the image, these extra rows are copies of the
X first or last actual input row.
X (This hides whether and how cross-pixel averaging occurs.)
X
X5. MCU extraction (creation of a single sequence of 8x8 sample blocks).
X extract_init: initialize as needed. This will be called once per scan.
X extract_MCUs: convert a sample array to a sequence of MCUs.
X extract_term: clean up at the end of a scan.
X Given one or more MCU rows worth of image data, extract sample blocks in the
X appropriate order; pass these off to subsequent steps one MCU at a time.
X The input must be a multiple of the MCU dimensions. It will probably be
X most convenient for the DCT transform, frequency quantization, and zigzag
X reordering of each block to be done as simple subroutines of this step.
X Once a transformed MCU has been completed, it'll be passed off to a
X method call, which will be passed as a parameter to extract_MCUs.
X That routine might either encode and output the MCU immediately, or buffer
X it up for later output if we want to do global optimization of the entropy
X encoding coefficients. Note: when outputting a noninterleaved file this
X object will be called separately for each component. Direct output could
X be done for the first component, but the others would have to be buffered.
X (Again, an object mainly on the grounds that multiple instantiations might
X be useful.)
X
X6. DCT transformation of each 8x8 block. This probably doesn't have to be a
X full-fledged method, but just a plain subroutine that will be called by MCU
X extraction. One 8x8 block will be processed per call.
X
X7. Quantization scaling and zigzag reordering of the elements in each 8x8
X block. (This can probably be a plain subroutine called once per block by
X MCU extraction; hard to see a need for multiple instantiations here.)
X
X8. Entropy encoding (Huffman or arithmetic).
X entropy_encoder_init: prepare for one scan.
X entropy_encode: accepts an MCU's worth of quantized coefficients,
X encodes and outputs them.
X entropy_encoder_term: finish up at end of a scan (dump any buffered
X bytes, for example).
X The data output by this module will be sent to the entropy_output method
X provided by the pipeline controller. (It will probably be worth using
X buffering to pass multiple bytes per call of the output method.) The
X output method could be just write_jpeg_data, but might also be a dummy
X routine that counts output bytes (for use during cut-and-try coefficient
X optimization).
X (This hides which entropy encoding method is in use.)
X
X9. JPEG file header construction. This will provide these methods:
X write_file_header: output the initial header.
X write_scan_header: output scan header (called once per component
X if noninterleaved mode).
X write_jpeg_data: the actual data output method for the preceding step.
X write_scan_trailer: finish up after one scan.
X write_file_trailer: finish up at end of file.
X Note that compressed data is passed to the write_jpeg_data method, in case
X a simple fwrite isn't appropriate for some reason.
X (This hides which variant JPEG file format is being written. Also, the
X actual mechanism for writing the file is private to this object and the
X user interface.)
X
X10. Pipeline control. This object will provide the "main loop" that invokes
X all the pipeline objects. Note that we will need several different main
X loops depending on the situation (interleaved output or not, global
X optimization of encoding parameters or not, etc). This object will do
X most of the memory allocation, since it will provide the working buffers
X that are the inputs and outputs of the pipeline steps.
X (An object mostly to support multiple instantiations; however, overall
X memory management and sequencing of operations are known only here.)
X
X11. Overall control. This module will provide at least two routines:
X jpeg_compress: the main entry point to the compressor.
X per_scan_method_selection: called by pipeline controllers for
X secondary method selection passes.
X jpeg_compress is invoked from the user interface after the UI has selected
X the input and output files and obtained values for all compression
X parameters that aren't dynamically determined. jpeg_compress performs
X basic initialization (e.g., calculating the size of MCUs), does the
X "global" method selection pass, and finally calls the selected pipeline
X control object. (Per-scan method selections will be invoked by the
X pipeline controller.)
X Note that jpeg_compress can't be a method since it is invoked prior to
X method selection.
X
X12. User interface; this is the architecture's term for "the rest of the
X application program", i.e., that which invokes the JPEG compressor. In a
X standalone JPEG compression program the UI need be little more than a C
X main() routine and argument parsing code; but we can expect that the JPEG
X compressor may be incorporated into complex graphics applications, wherein
X the UI is much more complex. Much of the UI will need to be written
X afresh for each non-Unix-like platform the compressor is ported to.
X The UI is expected to supply input and output files and values for all
X non-automatically-chosen compression parameters. (Hence defaults are
X determined by the UI; we should provide helpful routines to fill in
X the recommended defaults.) The UI must also supply error handling
X routines and some mechanism for trace messages.
X (This module hides the user interface provided --- command line,
X interactive, etc. Except for error/message handling, the UI calls the
X portable JPEG code, not the other way around.)
X
X13. (Optional) Compression parameter selection control.
X entropy_optimize: given an array of MCUs ready to be fed to entropy
X encoding, find optimal encoding parameters.
X The actual optimization algorithm ought to be separated out as an object,
X even though a special pipeline control method will be needed. (The
X pipeline controller only has to understand that the output of extract_MCUs
X must be built up as a virtual array rather than fed directly to entropy
X encoding and output. This pipeline behavior may also be useful for future
X implementation of hierarchical modes, etc.)
X To minimize the amount of control logic in the optimization module, the
X pipeline control doesn't actually hand over big-array pointers, but rather
X an "iterator": a function which knows how to scan the stored image.
X (This hides the details of the parameter optimization algorithm.)
X
X The present design doesn't allow for multiple passes at earlier points
X in the pipeline, but allowing that would only require providing some
X new pipeline control methods; nothing else need change.
X
X14. A memory management object. This will provide methods to allocate "small"
X things and "big" things. Small things have to fit in memory and you get
X back direct pointers (this could be handled by direct calls to malloc, but
X it's cleaner not to assume malloc is the right routine). "Big" things
X mean buffered images for multiple passes, noninterleaved output, etc.
X In this case the memory management object will give you room for a few MCU
X rows and you have to ask for access to the next few; dumping and reloading
X in a temporary file will go on behind the scenes. (All big objects are
X image arrays containing either samples or coefficients, and will be
X scanned top-to-bottom some number of times, so we can apply this access
X model easily.) On a platform with virtual memory, the memory manager can
X treat small and big things alike: just malloc up enough virtual memory for
X the whole image, and let the operating system worry about swapping the
X image to disk.
X
X Most of the actual calls on the memory manager will be made from pipeline
X control objects; changing any data item from "small" to "big" status would
X require a new pipeline control object, since it will contain the logic to
X ask for a new chunk of a big thing. Thus, one way in which pipeline
X controllers will vary is in which structures they treat as big.
X
X The memory manager will need to be told roughly how much space is going to
X be requested overall, so that it can figure out how big a buffer is safe
X to allocate for a "big" object. (If it happens that you are dealing with
X a small image, you'd like to decide to keep it all in memory!) The most
X flexible way of doing this is to divide allocation of "big" objects into
X two steps. First, there will be one or more "request" calls that indicate
X the desired object sizes; then an "instantiate" call causes the memory
X manager to actually construct the objects. The instantiation must occur
X before the contents of any big object can be accessed.
X
X For 80x86 CPUs, we would like the code to be compilable under small or
X medium model, meaning that pointers are 16 bits unless explicitly declared
X FAR. Hence space allocated by the "small" allocator must fit into the
X 64Kb default data segment, along with stack space and global/static data.
X For normal JPEG operations we seem to need only about 32Kb of such space,
X so we are within the target (and have a reasonable slop for the needs of
X a surrounding application program). However, some color quantization
X algorithms need 64Kb or more of all-in-memory space in order to create
X color histograms. For this purpose, we will also support "medium" size
X things. These are semantically the same as "small" things but are
X referenced through FAR pointers.
X
X The following methods will be needed:
X alloc_small: allocate an object of given size; use for any random
X data that's not an image array.
X free_small: release same.
X alloc_medium: like alloc_small, but returns a FAR pointer. Use for
X any object bigger than a couple kilobytes.
X free_medium: release same.
X alloc_small_sarray: construct an all-in-memory image sample array.
X free_small_sarray: release same.
X alloc_small_barray,
X free_small_barray: ditto for block (coefficient) arrays.
X request_big_sarray: request a virtual image sample array. The size
X of the in-memory buffer will be determined by the
X memory manager, but it will always be a multiple
X of the passed-in MCU height.
X request_big_barray: ditto for block (coefficient) arrays.
X alloc_big_arrays: instantiate all the big arrays previously requested.
X This call will also pass some info about future
X memory demands, so that the memory manager can
X figure out how much space to leave unallocated.
X access_big_sarray: obtain access to a specified portion of a virtual
X image sample array.
X free_big_sarray: release a virtual sample array.
X access_big_barray,
X free_big_barray: ditto for block (coefficient) arrays.
X free_all: release any remaining storage. This is called
X before normal or error termination; the main reason
X why it must exist is to ensure that any temporary
X files will be deleted upon error termination.
X
X alloc_big_arrays will be called by the pipeline controller, which does
X most of the memory allocation anyway. The only reason for having separate
X request calls is to allow some of the other modules to get big arrays.
X The pipeline controller is required to give an upper bound on total future
X small-array requests, so that this space can be discounted. (A fairly
X conservative estimate will be adequate.) Future small-object requests
X aren't counted; the memory manager has to use a slop factor for those.
X 10K or so seems to be sufficient. (In an 80x86, small objects aren't an
X issue anyway, since they don't compete for far-heap space. "Medium"-size
X objects will have to be counted separately.)
X
X The distinction between sample and coefficient array routines is annoying,
X but it has to be maintained for machines in which "char *" is represented
X differently from "int *". On byte-addressable machines some of these
X methods could perhaps point to the same code.
X
X The array routines will operate on only 2-D arrays (one component at a
X time), since different components may require different-size arrays.
X
X (This object hides the knowledge of whether virtual memory is available,
X as well as the actual interface to OS and library support routines.)
X
XNote that any given implementation will presumably contain only one
Xinstantiation of input file header reading, overall control, user interface,
Xand memory management. Thus these could be called as simple subroutines,
Xwithout bothering with an object indirection. This is essential for overall
Xcontrol (which has to initialize the object structure); for consistency we
Xwill impose objectness on the other three.
X
X
X*** Decompression object structure ***
X
XI propose the following set of objects for decompression. The general
Xcomments at the top of the compression object section also apply here.
X
X1. JPEG file scanning. This will provide these methods:
X read_file_header: read the file header, determine which variant
X JPEG format is in use, read everything through SOF.
X read_scan_header: read scan header (up through SOS). This is called
X after read_file_header and again after each scan;
X it returns TRUE if it finds SOS, FALSE if EOI.
X read_jpeg_data: fetch data for entropy decoder.
X read_scan_trailer: finish up after one scan, prepare for another call
X of read_scan_header (may be a no-op).
X read_file_trailer: finish up at end of file (probably a no-op).
X The entropy decoder must deal with restart markers, but all other JPEG
X marker types will be handled in this object; useful data from the markers
X will be extracted into data structures available to subsequent routines.
X Note that on exit from read_file_header, only the SOF-marker data should be
X assumed valid (image size, component IDs, sampling factors); other data
X such as Huffman tables may not appear until after the SOF. The overall
X image size and colorspace can be determined after read_file_header, but not
X whether or how the data is interleaved. (This hides which variant JPEG
X file format is being read. In particular, for JPEG-in-TIFF the read_header
X routines might not be scanning standard JPEG markers at all; they could
X extract the data from TIFF tags. The user interface will already have
X opened the input file and possibly read part of the header before
X read_file_header is called.)
X
X NOTE: for JFIF/raw-JPEG file format, the read_jpeg_data routine is actually
X supplied by the user interface; the jrdjfif module uses read_jpeg_data
X internally to scan the input stream. This makes it possible for the user
X interface module to single-handedly implement special applications like
X reading from a non-stdio source. For JPEG-in-TIFF format, the need for
X random access will make it impossible for this to work; hence the TIFF
X header module will override the UI-supplied read_jpeg_data routine.
X Non-stdio input from a TIFF file will require extensive surgery to the TIFF
X header module, if indeed it is practical at all.
X
X2. Entropy (Huffman or arithmetic) decoding of the coefficient sequence.
X entropy_decoder_init: prepare for one scan.
X entropy_decode: decodes and returns an MCU's worth of quantized
X coefficients per call.
X entropy_decoder_term: finish up after a scan (may be a no-op).
X This will read raw data by calling the read_jpeg_data method (I don't see
X any reason to provide a further level of indirection).
X (This hides which entropy encoding method is in use.)
X
X3. Quantization descaling and zigzag reordering of the elements in each 8x8
X block. (This can probably be a plain subroutine called once per block;
X hard to see a need for multiple instantiations here.)
X
X4. MCU disassembly (conversion of a possibly interleaved sequence of 8x8
X blocks back to separate components in pixel map order).
X disassemble_init: initialize. This will be called once per scan.
X disassemble_MCU: Given an MCU's worth of dequantized blocks,
X distribute them into the proper locations in a
X coefficient image array.
X disassemble_term: clean up at the end of a scan.
X Probably this should be called once per MCU row and should call the
X preceding two objects repeatedly to obtain the row's data. The output is
X always a multiple of an MCU's dimensions.
X (An object on the grounds that multiple instantiations might be useful.)
X
X5. Cross-block smoothing per JPEG section K.8 or a similar algorithm.
X smooth_coefficients: Given three block rows' worth of a single
X component, emit a smoothed equivalent of the
X middle row. The "above" and "below" pointers
X may be NULL if at top/bottom of image.
X The pipeline controller will do the necessary buffering to provide the
X above/below context. Smoothing will be optional since a good deal of
X extra memory is needed to buffer the additional block rows.
X (This object hides the details of the smoothing algorithm.)
X
X6. Inverse DCT transformation of each 8x8 block.
X reverse_DCT: given an MCU row's worth of blocks, perform inverse
X DCT on each block and output the results into an array
X of samples.
X We put this method into the jdmcu module for symmetry with the division of
X labor in compression. Note that the actual IDCT code is a separate source
X file.
X
X7. De-subsampling and smoothing: this will be applied to one component at a
X time. Note that cross-pixel smoothing, which was a separate step in the
X prototype code, will now be performed simultaneously with expansion.
X unsubsample_init: initialize (precalculate convolution factors, for
X example). This will be called once per scan.
X unsubsample: Given a sample array, enlarge it by specified sampling
X factors.
X unsubsample_term: clean up at the end of a scan.
X If the current component has vertical sampling factor Vk and the largest
X sampling factor is Vmax, then the input is always Vk sample rows (whose
X width is a multiple of Hk) and the output is always Vmax sample rows.
X Vk additional rows above and below the nominal input rows are also passed
X for use in cross-pixel smoothing. At the top and bottom of the image,
X these extra rows are copies of the first or last actual input row.
X (This hides whether and how cross-pixel smoothing occurs.)
X
X8. Cropping to the original pixel dimensions (throwing away duplicated
X pixels at the edges). This won't be a separate object, just an
X adjustment of the nominal image size in the pipeline controller.
X
X9. Color space reconversion and gamma adjustment.
X colorout_init: initialization. This will be passed the component
X data from read_file_header, and will determine the
X number of output components.
X color_convert: convert a specified number of pixel rows. Input and
X output are image arrays of same size but possibly
X different numbers of components.
X colorout_term: cleanup (probably a no-op except for memory dealloc).
X In practice will usually be given an MCU row's worth of pixel rows, except
X at the bottom where a smaller number of rows may be left over. Note that
X this object works on all the components at once.
X When quantizing colors, color_convert may be applied to the colormap
X instead of actual pixel data. color_convert is called by the color
X quantizer in this case; the pipeline controller calls color_convert
X directly only when not quantizing.
X (Hides all knowledge of color space semantics and conversion. Remaining
X modules only need to know the number of JPEG and output components.)
X
X10. Color quantization (used only if a colormapped output format is requested).
X We use two different strategies depending on whether one-pass (on-the-fly)
X or two-pass quantization is requested. Note that the two-pass interface
X is actually designed to let the quantizer make any number of passes.
X color_quant_init: initialization, allocate working memory. In 1-pass
X quantization, should call put_color_map.
X color_quantize: convert a specified number of pixel rows. Input
X and output are image arrays of same size, but input
X is N coefficients and output is only one. (Used only
X in 1-pass quantization.)
X color_quant_prescan: prescan a specified number of pixel rows in
X 2-pass quantization.
X color_quant_doit: perform multi-pass color quantization. Input is a
X "big" sample image, output is via put_color_map and
X put_pixel_rows. (Used only in 2-pass quantization.)
X color_quant_term: cleanup (probably a no-op except for memory dealloc).
X The input to the color quantizer is always in the unconverted colorspace;
X its output colormap must be in the converted colorspace. The quantizer
X has the choice of which space to work in internally. It must call
X color_convert either on its input data or on the colormap it sends to the
X output module.
X For one-pass quantization the image is simply processed by color_quantize,
X a few rows at a time. For two-pass quantization, the pipeline controller
X accumulates the output of steps 1-8 into a "big" sample image. The
X color_quant_prescan method is invoked during this process so that the
X quantizer can accumulate statistics. (If the input file has multiple
X scans, the prescan may be done during the final scan or as a separate
X pass.) At the end of the image, color_quant_doit is called; it must
X create and output a colormap, then rescan the "big" image and pass mapped
X data to the output module. Additional scans of the image could be made
X before the output pass is done (in fact, prescan could be a no-op).
X As with entropy parameter optimization, the pipeline controller actually
X passes an iterator function rather than direct access to the big image.
X (Hides color quantization algorithm.)
X
X11. Writing of the desired image format.
X output_init: produce the file header given data from read_file_header.
X put_color_map: output colormap, if any (called by color quantizer).
X If used, must be called before any pixel data is output.
X put_pixel_rows: output image data in desired format.
X output_term: finish up at the end.
X The actual timing of I/O may differ from that suggested by the routine
X names; for instance, writing of the file header may be delayed until
X put_color_map time if the actual number of colors is needed in the header.
X Also, the colormap is available to put_pixel_rows and output_term as well
X as put_color_map.
X Note that whether colormapping is needed will be determined by the user
X interface object prior to method selection. In implementations that
X support multiple output formats, the actual output format will also be
X determined by the user interface.
X (Hides format of output image and mechanism used to write it. Note that
X several other objects know the color model used by the output format.
X The actual mechanism for writing the file is private to this object and
X the user interface.)
X
X12. Pipeline control. This object will provide the "main loop" that invokes
X all the pipeline objects. Note that we will need several different main
X loops depending on the situation (interleaved input or not, whether to
X apply cross-block smoothing or not, etc). We may want to divvy up the
X pipeline controllers into two levels, one that retains control over the
X whole file and one that is invoked per scan.
X This object will do most of the memory allocation, since it will provide
X the working buffers that are the inputs and outputs of the pipeline steps.
X (An object mostly to support multiple instantiations; however, overall
X memory management and sequencing of operations are known only here.)
X
X13. Overall control. This module will provide at least two routines:
X jpeg_decompress: the main entry point to the decompressor.
X per_scan_method_selection: called by pipeline controllers for
X secondary method selection passes.
X jpeg_decompress is invoked from the user interface after the UI has
X selected the input and output files and obtained values for all
X user-specified options (e.g., output file format, whether to do block
X smoothing). jpeg_decompress calls read_file_header, performs basic
X initialization (e.g., calculating the size of MCUs), does the "global"
X method selection pass, and finally calls the selected pipeline control
X object. (Per-scan method selections will be invoked by the pipeline
X controller.)
X Note that jpeg_decompress can't be a method since it is invoked prior to
X method selection.
X
X14. User interface; this is the architecture's term for "the rest of the
X application program", i.e., that which invokes the JPEG decompressor.
X The UI is expected to supply input and output files and values for all
X operational parameters. The UI must also supply error handling routines.
X (This module hides the user interface provided --- command line,
X interactive, etc. Except for error handling, the UI calls the portable
X JPEG code, not the other way around.)
X
X15. A memory management object. This will be identical to the memory
X management for compression (and will be the same code, in combined
X programs). See above for details.
X
X
X*** Initial method selection ***
X
XThe main ugliness in this design is the portion of startup that will select
Xwhich of several instantiations should be used for each of the objects. (For
Xexample, Huffman or arithmetic for entropy encoding; one of several pipeline
Xcontrollers depending on interleaving, the size of the image, etc.) It's not
Xreally desirable to have a single chunk of code that knows the names of all
Xthe possible instantiations and the conditions under which to select each one.
X
XThe best approach seems to be to provide a selector function for each object
X(group of related method calls). This function knows about each possible
Xinstantiation of its object and how to choose the right one; but it doesn't
Xknow about any other objects.
X
XNote that there will be several rounds of method selection: at initial startup,
Xafter overall compression parameters are determined (after the file header is
Xread, if decompressing), and one in preparation for each scan (this occurs
Xmore than once if the file is noninterleaved). Each object method will need
Xto be clearly identified as to which round sets it up.
X
X
X*** Implications of DNL marker ***
X
XSome JPEG files may use a DNL marker to postpone definition of the image
Xheight (this would be useful for a fax-like scanner's output, for instance).
XIn these files the SOF marker claims the image height is 0, and you only
Xfind out the true image height at the end of the first scan.
X
XWe could handle these files as follows:
X1. Upon seeing zero image height, replace it by 65535 (the maximum allowed).
X2. When the DNL is found, update the image height in the global image
X descriptor.
XThis implies that pipeline control objects must avoid making copies of the
Ximage height, and must re-test for termination after each MCU row. This is
Xno big deal.
X
XIn situations where image-size data structures are allocated, this approach
Xwill result in very inefficient use of virtual memory or
Xmuch-larger-than-necessary temporary files. This seems acceptable for
Xsomething that probably won't be a mainstream usage. People might have to
Xforgo use of memory-hogging options (such as two-pass color quantization or
Xnoninterleaved JPEG files) if they want efficient conversion of such files.
X(One could improve efficiency by demanding a user-supplied upper bound for the
Xheight, less than 65536; in most cases it could be much less.)
X
XAlternately, we could insist that DNL-using files be preprocessed by a
Xseparate program that reads ahead to the DNL, then goes back and fixes the SOF
Xmarker. This is a much simpler solution and is probably far more efficient.
XEven if one wants piped input, buffering the first scan of the JPEG file
Xneeds a lot smaller temp file than is implied by the maximum-height method.
XFor this approach we'd simply treat DNL as a no-op in the decompressor (at
Xmost, check that it matches the SOF image height).
X
XWe will not worry about making the compressor capable of outputting DNL.
XSomething similar to the first scheme above could be applied if anyone ever
Xwants to make that work.
X
X
X*** Memory manager internal structure ***
X
XThe memory manager contains the most potential for system dependencies.
XTo isolate system dependencies as much as possible, we have broken the
Xmemory manager into two parts. There is a reasonably system-independent
X"front end" (jmemmgr.c) and a "back end" that contains only the code
Xlikely to change across systems. All of the memory management methods
Xoutlined above are implemented by the front end. The back end provides
Xthe following routines for use by the front end (none of these routines
Xare known to the rest of the JPEG code):
X
Xjmem_init, jmem_term system-dependent initialization/shutdown
X
Xjget_small, jfree_small interface to malloc and free library routines
X
Xjget_large, jfree_large interface to FAR malloc/free in MS-DOS machines;
X otherwise same as jget_small/jfree_small
X
Xjmem_available estimate available memory
X
Xjopen_backing_store create a backing-store object
X
Xread_backing_store, manipulate a backing store object
Xwrite_backing_store,
Xclose_backing_store
X
XOn some systems there will be more than one type of backing-store object
X(specifically, in MS-DOS a backing store file might be an area of extended
Xmemory as well as a disk file). jopen_backing_store is responsible for
Xchoosing how to implement a given object. The read/write/close routines
Xare method pointers in the structure that describes a given object; this
Xlets them be different for different object types.
X
XIt may be necessary to ensure that backing store objects are explicitly
Xreleased upon abnormal program termination. (For example, MS-DOS won't free
Xextended memory by itself.) To support this, we will expect the main program
Xor surrounding application to arrange to call the free_all method upon
Xabnormal termination; this may require a SIGINT signal handler, for instance.
X(We don't want to have the system-dependent module install its own signal
Xhandler, because that would pre-empt the surrounding application's ability
Xto control signal handling.)
X
X
X*** Notes for MS-DOS implementors ***
X
XThe standalone cjpeg and djpeg applications can be compiled in "small" memory
Xmodel, at least at the moment; as the code grows we may be forced to switch to
X"medium" model. (Small = both code and data pointers are near by default;
Xmedium = far code pointers, near data pointers.) Medium model will slow down
Xcalls through method pointers, but I don't think this will amount to any
Xsignificant speed penalty.
X
XWhen integrating the JPEG code into a larger application, it's a good idea to
Xstay with a small-data-space model if possible. An 8K stack is much more than
Xsufficient for the JPEG code, and its static data requirements are less than
X1K. When executed, it will typically malloc about 10K-20K worth of near heap
Xspace (and lots of far heap, but that doesn't count in this calculation).
XThis figure will vary depending on image size and other factors, but figuring
X30K should be more than sufficient. Thus you have about 25K available for
Xother modules' static data and near heap requirements before you need to go to
Xa larger memory model. The C library's static data will account for several K
Xof this, but that still leaves a good deal for your needs. (If you are tight
Xon space, you could reduce JPEG_BUF_SIZE from 4K to 1K to save 3K of near heap
Xspace.)
X
XAs the code is improved, we will endeavor to hold the near data requirements
Xto the range given above. This does imply that certain data structures will
Xbe allocated as FAR although they would fit in near space if we assumed the
XJPEG code is stand-alone. (The LZW tables in jrdgif/jwrgif are examples.)
XTo make an optimal implementation, you might want to move these structures
Xback to near heap if you know there is sufficient space.
X
XFAR data space may also be a tight resource when you are dealing with large
Ximages. The most memory-intensive case is decompression with two-pass color
Xquantization. This requires a 128Kb color histogram plus strip buffers
Xamounting to about 150 bytes per column for typical sampling ratios (eg, about
X96000 bytes for a 640-pixel-wide image). You may not be able to process wide
Ximages if you have large data structures of your own.
X
X
X*** Potential optimizations ***
X
XFor colormapped input formats it might be worthwhile to merge the input file
Xreading and the colorspace conversion steps; in other words, do the colorspace
Xconversion by hacking up the colormap before inputting the image body, rather
Xthan doing the conversion on each pixel independently. Not clear if this is
Xworth the uglification involved. In the above design for the compressor, only
Xthe colorspace conversion step ever sees the output of get_input_row, so this
Xsort of thing could be done via private agreement between those two modules.
X
XLevel shift from 0..255 to -128..127 may be done either during colorspace
Xconversion, or at the moment of converting an 8x8 sample block into the format
Xused by the DCT step (which will be signed short or long int). This could be
Xselectable by a compile-time flag, so that the intermediate steps can work on
Xeither signed or unsigned chars as samples, whichever is most easily handled
Xby the platform. However, making sure that rounding is done right will be a
Xlot easier if we can assume positive values. At the moment I think that
Xbenefit is worth the overhead of "& 0xFF" when reading out sample values on
Xsigned-char-only machines.
END_OF_FILE
if test 36460 -ne `wc -c <'arch.b'`; then
echo shar: \"'arch.b'\" unpacked with wrong size!
elif [ -f arch.a ]; then
echo shar: Combining \"'arch.a'\" and \"'arch.b'\" into \"'architecture'\"
cat arch.a arch.b > architecture
echo shar: Removing \"'arch.a'\" and \"'arch.b'\"
rm arch.a arch.b
# end of 'arch.b'
fi
fi
if test -f 'ckconfig.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ckconfig.c'\"
else
echo shar: Extracting \"'ckconfig.c'\" \(12938 characters\)
sed "s/^X//" >'ckconfig.c' <<'END_OF_FILE'
X/*
X * ckconfig.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X */
X
X/*
X * This program is intended to help you determine how to configure the JPEG
X * software for installation on a particular system. The idea is to try to
X * compile and execute this program. If your compiler fails to compile the
X * program, make changes as indicated in the comments below. Once you can
X * compile the program, run it, and it will tell you how to set the various
X * switches in jconfig.h and in your Makefile.
X *
X * This could all be done automatically if we could assume we were on a Unix
X * system, but we don't want to assume that, so you'll have to edit and
X * recompile this program until it works.
X *
X * As a general rule, each time you try to compile this program,
X * pay attention only to the *first* error message you get from the compiler.
X * Many C compilers will issue lots of spurious error messages once they
X * have gotten confused. Go to the line indicated in the first error message,
X * and read the comments preceding that line to see what to change.
X *
X * Almost all of the edits you may need to make to this program consist of
X * changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL",
X * or vice versa. This is called defining or undefining that symbol.
X */
X
X
X/* First we must see if your system has the include files we need.
X * We start out with the assumption that your system follows the ANSI
X * conventions for include files. If you get any error in the next dozen
X * lines, undefine INCLUDES_ARE_ANSI.
X */
X
X#define INCLUDES_ARE_ANSI /* replace 'define' by 'undef' if error here */
X
X#ifdef INCLUDES_ARE_ANSI /* this will be skipped if you undef... */
X#include <stdio.h> /* If you ain't got this, you ain't got C. */
X#ifdef __SASC /* Amiga SAS C provides size_t in stddef.h. */
X#include <stddef.h> /* (They are wrong...) */
X#endif
X#include <string.h> /* size_t might be here too. */
Xtypedef size_t my_size_t; /* The payoff: do we have size_t now? */
X#include <stdlib.h> /* Check other ANSI includes we use. */
X#endif
X
X
X/* If your system doesn't follow the ANSI conventions, we have to figure out
X * what it does follow. If you didn't get an error before this line, you can
X * ignore everything down to "#define HAVE_ANSI_DEFINITIONS".
X */
X
X#ifndef INCLUDES_ARE_ANSI /* skip these tests if INCLUDES_ARE_ANSI */
X
X#include <stdio.h> /* If you ain't got this, you ain't got C. */
X
X/* jinclude.h will try to include <sys/types.h> if you don't set
X * INCLUDES_ARE_ANSI. We need to test whether that include file is provided.
X * If you get an error here, undefine HAVE_TYPES_H.
X */
X
X#define HAVE_TYPES_H
X
X#ifdef HAVE_TYPES_H
X#include <sys/types.h>
X#endif
X
X/* We have to see if your string functions are defined by
X * strings.h (BSD convention) or string.h (everybody else).
X * We try the non-BSD convention first; define BSD if the compiler
X * says it can't find string.h.
X */
X
X#undef BSD
X
X#ifdef BSD
X#include <strings.h>
X#else
X#include <string.h>
X#endif
X
X/* Usually size_t is defined in stdio.h, sys/types.h, and/or string.h.
X * If not, you'll get an error on the "typedef size_t my_size_t;" line below.
X * In that case, you'll have to search through your system library to
X * figure out which include file defines "size_t". Look for a line that
X * says "typedef something-or-other size_t;" (stddef.h and stdlib.h are
X * good places to look first). Then, change the line below that says
X * "#include <someincludefile.h>" to instead include the file
X * you found size_t in, and define NEED_SPECIAL_INCLUDE.
X */
X
X#undef NEED_SPECIAL_INCLUDE /* assume we DON'T need it, for starters */
X
X#ifdef NEED_SPECIAL_INCLUDE
X#include <someincludefile.h>
X#endif
X
Xtypedef size_t my_size_t; /* The payoff: do we have size_t now? */
X
X
X#endif /* INCLUDES_ARE_ANSI */
X
X
X
X/* The next question is whether your compiler supports ANSI-style function
X * definitions. You need to know this in order to choose between using
X * makefile.ansi and using makefile.unix.
X * The #define line below is set to assume you have ANSI function definitions.
X * If you get an error in this group of lines, undefine HAVE_ANSI_DEFINITIONS.
X */
X
X#define HAVE_ANSI_DEFINITIONS
X
X#ifdef HAVE_ANSI_DEFINITIONS
Xint testfunction (int arg1, int * arg2); /* check prototypes */
X
Xstruct methods_struct { /* check method-pointer declarations */
X int (*error_exit) (char *msgtext);
X int (*trace_message) (char *msgtext);
X int (*another_method) (void);
X};
X
Xint testfunction (int arg1, int * arg2) /* check definitions */
X{
X return arg2[arg1];
X}
X
Xint testfunction1 (void) /* check void arg list */
X{
X return 0;
X}
X#endif
X
X
X/* Now we want to find out if your compiler knows what "unsigned char" means.
X * If you get an error on the "unsigned char un_char;" line,
X * then undefine HAVE_UNSIGNED_CHAR.
X */
X
X#define HAVE_UNSIGNED_CHAR
X
X#ifdef HAVE_UNSIGNED_CHAR
Xunsigned char un_char;
X#endif
X
X
X/* Now we want to find out if your compiler knows what "unsigned short" means.
X * If you get an error on the "unsigned short un_short;" line,
X * then undefine HAVE_UNSIGNED_SHORT.
X */
X
X#define HAVE_UNSIGNED_SHORT
X
X#ifdef HAVE_UNSIGNED_SHORT
Xunsigned short un_short;
X#endif
X
X
X/* Now we want to find out if your compiler understands type "void".
X * If you get an error anywhere in here, undefine HAVE_VOID.
X */
X
X#define HAVE_VOID
X
X#ifdef HAVE_VOID
Xtypedef void * void_ptr; /* check void * */
Xtypedef void (*void_func) (); /* check ptr to function returning void */
X
Xvoid testfunction2 (arg1, arg2) /* check void function result */
X void_ptr arg1;
X void_func arg2;
X{
X char * locptr = (char *) arg1; /* check casting to and from void * */
X arg1 = (void *) locptr;
X (*arg2) (1, 2); /* check call of fcn returning void */
X}
X#endif
X
X
X/* Now we want to find out if your compiler knows what "const" means.
X * If you get an error here, undefine HAVE_CONST.
X */
X
X#define HAVE_CONST
X
X#ifdef HAVE_CONST
Xstatic const int carray[3] = {1, 2, 3};
X
Xint testfunction3 (arg1)
X const int arg1;
X{
X return carray[arg1];
X}
X#endif
X
X
X
X/************************************************************************
X * OK, that's it. You should not have to change anything beyond this
X * point in order to compile and execute this program. (You might get
X * some warnings, but you can ignore them.)
X * When you run the program, it will make a couple more tests that it
X * can do automatically, and then it will print out a summary of the changes
X * that you need to make to the makefile and jconfig.h.
X ************************************************************************
X */
X
X
Xstatic int any_changes = 0;
X
Xint new_change ()
X{
X if (! any_changes) {
X printf("\nMost of the changes recommended by this program can be made either\n");
X printf("by editing jconfig.h, or by adding -Dsymbol switches to the CFLAGS\n");
X printf("line in your Makefile. (Some PC compilers expect /Dsymbol instead.)\n");
X printf("The CFLAGS method is simpler, but if your system doesn't use makefiles,\n");
X printf("or if your compiler doesn't support -D, then you must change jconfig.h.\n");
X any_changes = 1;
X }
X printf("\n"); /* blank line before each problem report */
X return 0;
X}
X
X
Xint test_char_sign (arg)
X int arg;
X{
X if (arg == 189) { /* expected result for unsigned char */
X new_change();
X printf("You should add -DCHAR_IS_UNSIGNED to CFLAGS,\n");
X printf("or else remove the /* */ comment marks from the line\n");
X printf("/* #define CHAR_IS_UNSIGNED */ in jconfig.h.\n");
X printf("(Be sure to delete the space before the # character too.)\n");
X }
X else if (arg != -67) { /* expected result for signed char */
X new_change();
X printf("Hmm, it seems 'char' is less than eight bits wide on your machine.\n");
X printf("I fear the JPEG software will not work at all.\n");
X }
X return 0;
X}
X
X
Xint test_shifting (arg)
X long arg;
X/* See whether right-shift on a long is signed or not. */
X{
X long res = arg >> 4;
X
X if (res == 0x80817F4L) { /* expected result for unsigned */
X new_change();
X printf("You must add -DRIGHT_SHIFT_IS_UNSIGNED to CFLAGS,\n");
X printf("or else remove the /* */ comment marks from the line\n");
X printf("/* #define RIGHT_SHIFT_IS_UNSIGNED */ in jconfig.h.\n");
X }
X else if (res != -0x7F7E80CL) { /* expected result for signed */
X new_change();
X printf("Right shift isn't acting as I expect it to.\n");
X printf("I fear the JPEG software will not work at all.\n");
X }
X return 0;
X}
X
X
Xint main (argc, argv)
X int argc;
X char ** argv;
X{
X char signed_char_check = (char) (-67);
X
X printf("Results of configuration check for Independent JPEG Group's software:\n");
X printf("\nIf there's not a specific makefile provided for your compiler,\n");
X#ifdef HAVE_ANSI_DEFINITIONS
X printf("you should use makefile.ansi as the starting point for your Makefile.\n");
X#else
X printf("you should use makefile.unix as the starting point for your Makefile.\n");
X#endif
X
X /* Check whether we have all the ANSI features, */
X /* and whether this agrees with __STDC__ being predefined. */
X#ifdef __STDC__
X#define HAVE_STDC /* ANSI compilers won't allow redefining __STDC__ */
X#endif
X
X#ifdef HAVE_ANSI_DEFINITIONS
X#ifdef HAVE_UNSIGNED_CHAR
X#ifdef HAVE_UNSIGNED_SHORT
X#ifdef HAVE_CONST
X#define HAVE_ALL_ANSI_FEATURES
X#endif
X#endif
X#endif
X#endif
X
X#ifdef HAVE_ALL_ANSI_FEATURES
X#ifndef HAVE_STDC
X new_change();
X printf("Your compiler doesn't claim to be ANSI-compliant, but it is close enough\n");
X printf("for me. Either add -DHAVE_STDC to CFLAGS, or add #define HAVE_STDC at the\n");
X printf("beginning of jconfig.h.\n");
X#define HAVE_STDC
X#endif
X#else /* !HAVE_ALL_ANSI_FEATURES */
X#ifdef HAVE_STDC
X new_change();
X printf("Your compiler claims to be ANSI-compliant, but it is lying!\n");
X printf("Delete the line #define HAVE_STDC near the beginning of jconfig.h.\n");
X#undef HAVE_STDC
X#endif
X#endif /* HAVE_ALL_ANSI_FEATURES */
X
X#ifndef HAVE_STDC
X
X#ifdef HAVE_ANSI_DEFINITIONS
X new_change();
X printf("You should add -DPROTO to CFLAGS, or else take out the several\n");
X printf("#ifdef/#else/#endif lines surrounding #define PROTO in jconfig.h.\n");
X printf("(Leave only one #define PROTO line.)\n");
X#endif
X
X#ifdef HAVE_UNSIGNED_CHAR
X#ifdef HAVE_UNSIGNED_SHORT
X new_change();
X printf("You should add -DHAVE_UNSIGNED_CHAR and -DHAVE_UNSIGNED_SHORT\n");
X printf("to CFLAGS, or else take out the #ifdef HAVE_STDC/#endif lines\n");
X printf("surrounding #define HAVE_UNSIGNED_CHAR and #define HAVE_UNSIGNED_SHORT\n");
X printf("in jconfig.h.\n");
X#else /* only unsigned char */
X new_change();
X printf("You should add -DHAVE_UNSIGNED_CHAR to CFLAGS,\n");
X printf("or else move #define HAVE_UNSIGNED_CHAR outside the\n");
X printf("#ifdef HAVE_STDC/#endif lines surrounding it in jconfig.h.\n");
X#endif
X#else /* !HAVE_UNSIGNED_CHAR */
X#ifdef HAVE_UNSIGNED_SHORT
X new_change();
X printf("You should add -DHAVE_UNSIGNED_SHORT to CFLAGS,\n");
X printf("or else move #define HAVE_UNSIGNED_SHORT outside the\n");
X printf("#ifdef HAVE_STDC/#endif lines surrounding it in jconfig.h.\n");
X#endif
X#endif /* HAVE_UNSIGNED_CHAR */
X
X#ifdef HAVE_CONST
X new_change();
X printf("You should delete the #define const line from jconfig.h.\n");
X#endif
X
X#endif /* HAVE_STDC */
X
X test_char_sign((int) signed_char_check);
X
X test_shifting(-0x7F7E80B1L);
X
X#ifndef HAVE_VOID
X new_change();
X printf("You should add -Dvoid=char to CFLAGS,\n");
X printf("or else remove the /* */ comment marks from the line\n");
X printf("/* #define void char */ in jconfig.h.\n");
X printf("(Be sure to delete the space before the # character too.)\n");
X#endif
X
X#ifdef INCLUDES_ARE_ANSI
X#ifndef __STDC__
X new_change();
X printf("You should add -DINCLUDES_ARE_ANSI to CFLAGS, or else add\n");
X printf("#define INCLUDES_ARE_ANSI at the beginning of jinclude.h (NOT jconfig.h).\n");
X#endif
X#else /* !INCLUDES_ARE_ANSI */
X#ifdef __STDC__
X new_change();
X printf("You should add -DNONANSI_INCLUDES to CFLAGS, or else add\n");
X printf("#define NONANSI_INCLUDES at the beginning of jinclude.h (NOT jconfig.h).\n");
X#endif
X#ifdef NEED_SPECIAL_INCLUDE
X new_change();
X printf("In jinclude.h, change the line reading #include <sys/types.h>\n");
X printf("to instead include the file you found size_t in.\n");
X#else /* !NEED_SPECIAL_INCLUDE */
X#ifndef HAVE_TYPES_H
X new_change();
X printf("In jinclude.h, delete the line reading #include <sys/types.h>.\n");
X#endif
X#endif /* NEED_SPECIAL_INCLUDE */
X#ifdef BSD
X new_change();
X printf("You should add -DBSD to CFLAGS, or else add\n");
X printf("#define BSD at the beginning of jinclude.h (NOT jconfig.h).\n");
X#endif
X#endif /* INCLUDES_ARE_ANSI */
X
X if (any_changes) {
X printf("\nI think that's everything...\n");
X } else {
X printf("\nI think jconfig.h is OK as distributed.\n");
X }
X
X return any_changes;
X}
END_OF_FILE
if test 12938 -ne `wc -c <'ckconfig.c'`; then
echo shar: \"'ckconfig.c'\" unpacked with wrong size!
fi
# end of 'ckconfig.c'
fi
if test -f 'jerror.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jerror.c'\"
else
echo shar: Extracting \"'jerror.c'\" \(2205 characters\)
sed "s/^X//" >'jerror.c' <<'END_OF_FILE'
X/*
X * jerror.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains simple error-reporting and trace-message routines.
X * These are suitable for Unix-like systems and others where writing to
X * stderr is the right thing to do. If the JPEG software is integrated
X * into a larger application, you may well need to replace these.
X *
X * The error_exit() routine should not return to its caller. Within a
X * larger application, you might want to have it do a longjmp() to return
X * control to the outer user interface routine. This should work since
X * the portable JPEG code doesn't use setjmp/longjmp. You should make sure
X * that free_all is called either within error_exit or after the return to
X * the outer-level routine.
X *
X * These routines are used by both the compression and decompression code.
X */
X
X#include "jinclude.h"
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare exit() */
X#endif
X
X#ifndef EXIT_FAILURE /* define exit() codes if not provided */
X#define EXIT_FAILURE 1
X#endif
X
X
Xstatic external_methods_ptr methods; /* saved for access to message_parm, free_all */
X
X
XMETHODDEF void
Xtrace_message (const char *msgtext)
X{
X fprintf(stderr, msgtext,
X methods->message_parm[0], methods->message_parm[1],
X methods->message_parm[2], methods->message_parm[3],
X methods->message_parm[4], methods->message_parm[5],
X methods->message_parm[6], methods->message_parm[7]);
X fprintf(stderr, "\n");
X}
X
X
XMETHODDEF void
Xerror_exit (const char *msgtext)
X{
X trace_message(msgtext);
X (*methods->free_all) (); /* clean up memory allocation */
X exit(EXIT_FAILURE);
X}
X
X
X/*
X * The method selection routine for simple error handling.
X * The system-dependent setup routine should call this routine
X * to install the necessary method pointers in the supplied struct.
X */
X
XGLOBAL void
Xjselerror (external_methods_ptr emethods)
X{
X methods = emethods; /* save struct addr for later access */
X
X emethods->error_exit = error_exit;
X emethods->trace_message = trace_message;
X
X emethods->trace_level = 0; /* default = no tracing */
X}
END_OF_FILE
if test 2205 -ne `wc -c <'jerror.c'`; then
echo shar: \"'jerror.c'\" unpacked with wrong size!
fi
# end of 'jerror.c'
fi
echo shar: End of archive 6 \(of 18\).
cp /dev/null ark6isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jrdjfif.c makdjpeg.lnk timg.ppm.u.a
# Wrapped by kent@sparky on Mon Mar 23 16:02:44 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 7 (of 18)."'
if test -f 'jrdjfif.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jrdjfif.c'\"
else
echo shar: Extracting \"'jrdjfif.c'\" \(18541 characters\)
sed "s/^X//" >'jrdjfif.c' <<'END_OF_FILE'
X/*
X * jrdjfif.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to decode standard JPEG file headers/markers.
X * This code will handle "raw JPEG" and JFIF-convention JPEG files.
X *
X * You can also use this module to decode a raw-JPEG or JFIF-standard data
X * stream that is embedded within a larger file. To do that, you must
X * position the file to the JPEG SOI marker (0xFF/0xD8) that begins the
X * data sequence to be decoded. If nothing better is possible, you can scan
X * the file until you see the SOI marker, then use JUNGETC to push it back.
X *
X * This module relies on the JGETC macro and the read_jpeg_data method (which
X * is provided by the user interface) to read from the JPEG data stream.
X * Therefore, this module is not dependent on any particular assumption about
X * the data source; it need not be a stdio stream at all. (This fact does
X * NOT carry over to more complex JPEG file formats such as JPEG-in-TIFF;
X * those format control modules may well need to assume stdio input.)
X *
X * These routines are invoked via the methods read_file_header,
X * read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer.
X */
X
X#include "jinclude.h"
X
X#ifdef JFIF_SUPPORTED
X
X
Xtypedef enum { /* JPEG marker codes */
X M_SOF0 = 0xc0,
X M_SOF1 = 0xc1,
X M_SOF2 = 0xc2,
X M_SOF3 = 0xc3,
X
X M_SOF5 = 0xc5,
X M_SOF6 = 0xc6,
X M_SOF7 = 0xc7,
X
X M_JPG = 0xc8,
X M_SOF9 = 0xc9,
X M_SOF10 = 0xca,
X M_SOF11 = 0xcb,
X
X M_SOF13 = 0xcd,
X M_SOF14 = 0xce,
X M_SOF15 = 0xcf,
X
X M_DHT = 0xc4,
X
X M_DAC = 0xcc,
X
X M_RST0 = 0xd0,
X M_RST1 = 0xd1,
X M_RST2 = 0xd2,
X M_RST3 = 0xd3,
X M_RST4 = 0xd4,
X M_RST5 = 0xd5,
X M_RST6 = 0xd6,
X M_RST7 = 0xd7,
X
X M_SOI = 0xd8,
X M_EOI = 0xd9,
X M_SOS = 0xda,
X M_DQT = 0xdb,
X M_DNL = 0xdc,
X M_DRI = 0xdd,
X M_DHP = 0xde,
X M_EXP = 0xdf,
X
X M_APP0 = 0xe0,
X M_APP15 = 0xef,
X
X M_JPG0 = 0xf0,
X M_JPG13 = 0xfd,
X M_COM = 0xfe,
X
X M_TEM = 0x01,
X
X M_ERROR = 0x100
X} JPEG_MARKER;
X
X
X/*
X * Reload the input buffer after it's been emptied, and return the next byte.
X * This is exported for direct use by the entropy decoder.
X * See the JGETC macro for calling conditions.
X *
X * For this header control module, read_jpeg_data is supplied by the
X * user interface. However, header formats that require random access
X * to the input file would need to supply their own code. This code is
X * left here to indicate what is required.
X */
X
X#if 0 /* not needed in this module */
X
XMETHODDEF int
Xread_jpeg_data (decompress_info_ptr cinfo)
X{
X cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
X
X cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
X cinfo->next_input_byte,
X JPEG_BUF_SIZE);
X
X if (cinfo->bytes_in_buffer <= 0)
X ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
X
X return JGETC(cinfo);
X}
X
X#endif
X
X
X/*
X * Routines to parse JPEG markers & save away the useful info.
X */
X
X
XLOCAL INT32
Xget_2bytes (decompress_info_ptr cinfo)
X/* Get a 2-byte unsigned integer (e.g., a marker parameter length field) */
X{
X INT32 a;
X
X a = JGETC(cinfo);
X return (a << 8) + JGETC(cinfo);
X}
X
X
XLOCAL void
Xskip_variable (decompress_info_ptr cinfo, int code)
X/* Skip over an unknown or uninteresting variable-length marker */
X{
X INT32 length;
X
X length = get_2bytes(cinfo);
X
X TRACEMS2(cinfo->emethods, 1,
X "Skipping marker 0x%02x, length %u", code, (int) length);
X
X for (length -= 2; length > 0; length--)
X (void) JGETC(cinfo);
X}
X
X
XLOCAL void
Xget_dht (decompress_info_ptr cinfo)
X/* Process a DHT marker */
X{
X INT32 length;
X UINT8 bits[17];
X UINT8 huffval[256];
X int i, index, count;
X HUFF_TBL **htblptr;
X
X length = get_2bytes(cinfo)-2;
X
X while (length > 0) {
X index = JGETC(cinfo);
X
X TRACEMS1(cinfo->emethods, 1, "Define Huffman Table 0x%02x", index);
X
X bits[0] = 0;
X count = 0;
X for (i = 1; i <= 16; i++) {
X bits[i] = (UINT8) JGETC(cinfo);
X count += bits[i];
X }
X
X TRACEMS8(cinfo->emethods, 2, " %3d %3d %3d %3d %3d %3d %3d %3d",
X bits[1], bits[2], bits[3], bits[4],
X bits[5], bits[6], bits[7], bits[8]);
X TRACEMS8(cinfo->emethods, 2, " %3d %3d %3d %3d %3d %3d %3d %3d",
X bits[9], bits[10], bits[11], bits[12],
X bits[13], bits[14], bits[15], bits[16]);
X
X if (count > 256)
X ERREXIT(cinfo->emethods, "Bogus DHT counts");
X
X for (i = 0; i < count; i++)
X huffval[i] = (UINT8) JGETC(cinfo);
X
X length -= 1 + 16 + count;
X
X if (index & 0x10) { /* AC table definition */
X index -= 0x10;
X htblptr = &cinfo->ac_huff_tbl_ptrs[index];
X } else { /* DC table definition */
X htblptr = &cinfo->dc_huff_tbl_ptrs[index];
X }
X
X if (index < 0 || index >= NUM_HUFF_TBLS)
X ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index);
X
X if (*htblptr == NULL)
X *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
X
X memcpy((void *) (*htblptr)->bits, (void *) bits,
X SIZEOF((*htblptr)->bits));
X memcpy((void *) (*htblptr)->huffval, (void *) huffval,
X SIZEOF((*htblptr)->huffval));
X }
X}
X
X
XLOCAL void
Xget_dac (decompress_info_ptr cinfo)
X/* Process a DAC marker */
X{
X INT32 length;
X int index, val;
X
X length = get_2bytes(cinfo)-2;
X
X while (length > 0) {
X index = JGETC(cinfo);
X val = JGETC(cinfo);
X
X TRACEMS2(cinfo->emethods, 1,
X "Define Arithmetic Table 0x%02x: 0x%02x", index, val);
X
X if (index < 0 || index >= (2*NUM_ARITH_TBLS))
X ERREXIT1(cinfo->emethods, "Bogus DAC index %d", index);
X
X if (index >= NUM_ARITH_TBLS) { /* define AC table */
X cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
X } else { /* define DC table */
X cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
X cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
X if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
X ERREXIT1(cinfo->emethods, "Bogus DAC value 0x%x", val);
X }
X
X length -= 2;
X }
X}
X
X
XLOCAL void
Xget_dqt (decompress_info_ptr cinfo)
X/* Process a DQT marker */
X{
X INT32 length;
X int n, i, prec;
X UINT16 tmp;
X QUANT_TBL_PTR quant_ptr;
X
X length = get_2bytes(cinfo) - 2;
X
X while (length > 0) {
X n = JGETC(cinfo);
X prec = n >> 4;
X n &= 0x0F;
X
X TRACEMS2(cinfo->emethods, 1,
X "Define Quantization Table %d precision %d", n, prec);
X
X if (n >= NUM_QUANT_TBLS)
X ERREXIT1(cinfo->emethods, "Bogus table number %d", n);
X
X if (cinfo->quant_tbl_ptrs[n] == NULL)
X cinfo->quant_tbl_ptrs[n] = (QUANT_TBL_PTR)
X (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
X quant_ptr = cinfo->quant_tbl_ptrs[n];
X
X for (i = 0; i < DCTSIZE2; i++) {
X tmp = JGETC(cinfo);
X if (prec)
X tmp = (tmp<<8) + JGETC(cinfo);
X quant_ptr[i] = tmp;
X }
X
X for (i = 0; i < DCTSIZE2; i += 8) {
X TRACEMS8(cinfo->emethods, 2, " %4d %4d %4d %4d %4d %4d %4d %4d",
X quant_ptr[i ], quant_ptr[i+1], quant_ptr[i+2], quant_ptr[i+3],
X quant_ptr[i+4], quant_ptr[i+5], quant_ptr[i+6], quant_ptr[i+7]);
X }
X
X length -= DCTSIZE2+1;
X if (prec) length -= DCTSIZE2;
X }
X}
X
X
XLOCAL void
Xget_dri (decompress_info_ptr cinfo)
X/* Process a DRI marker */
X{
X if (get_2bytes(cinfo) != 4)
X ERREXIT(cinfo->emethods, "Bogus length in DRI");
X
X cinfo->restart_interval = (UINT16) get_2bytes(cinfo);
X
X TRACEMS1(cinfo->emethods, 1,
X "Define Restart Interval %d", cinfo->restart_interval);
X}
X
X
XLOCAL void
Xget_app0 (decompress_info_ptr cinfo)
X/* Process an APP0 marker */
X{
X#define JFIF_LEN 14
X INT32 length;
X UINT8 b[JFIF_LEN];
X int buffp;
X
X length = get_2bytes(cinfo) - 2;
X
X /* See if a JFIF APP0 marker is present */
X
X if (length >= JFIF_LEN) {
X for (buffp = 0; buffp < JFIF_LEN; buffp++)
X b[buffp] = (UINT8) JGETC(cinfo);
X length -= JFIF_LEN;
X
X if (b[0]=='J' && b[1]=='F' && b[2]=='I' && b[3]=='F' && b[4]==0) {
X /* Found JFIF APP0 marker: check version */
X /* Major version must be 1 */
X if (b[5] != 1)
X ERREXIT2(cinfo->emethods, "Unsupported JFIF revision number %d.%02d",
X b[5], b[6]);
X /* Minor version should be 0 or 1, but try to process anyway if newer */
X if (b[6] != 0 && b[6] != 1)
X TRACEMS2(cinfo->emethods, 0, "Warning: unknown JFIF revision number %d.%02d",
X b[5], b[6]);
X /* Save info */
X cinfo->density_unit = b[7];
X cinfo->X_density = (b[8] << 8) + b[9];
X cinfo->Y_density = (b[10] << 8) + b[11];
X /* Assume colorspace is YCbCr, unless UI has overridden me */
X if (cinfo->jpeg_color_space == CS_UNKNOWN)
X cinfo->jpeg_color_space = CS_YCbCr;
X TRACEMS3(cinfo->emethods, 1, "JFIF APP0 marker, density %dx%d %d",
X cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
X } else {
X TRACEMS(cinfo->emethods, 1, "Unknown APP0 marker (not JFIF)");
X }
X } else {
X TRACEMS1(cinfo->emethods, 1,
X "Short APP0 marker, length %d", (int) length);
X }
X
X while (length-- > 0) /* skip any remaining data */
X (void) JGETC(cinfo);
X}
X
X
XLOCAL void
Xget_sof (decompress_info_ptr cinfo, int code)
X/* Process a SOFn marker */
X{
X INT32 length;
X short ci;
X int c;
X jpeg_component_info * compptr;
X
X length = get_2bytes(cinfo);
X
X cinfo->data_precision = JGETC(cinfo);
X cinfo->image_height = get_2bytes(cinfo);
X cinfo->image_width = get_2bytes(cinfo);
X cinfo->num_components = JGETC(cinfo);
X
X TRACEMS4(cinfo->emethods, 1,
X "Start Of Frame 0x%02x: width=%u, height=%u, components=%d",
X code, (int) cinfo->image_width, (int) cinfo->image_height,
X cinfo->num_components);
X
X /* We don't support files in which the image height is initially specified */
X /* as 0 and is later redefined by DNL. As long as we have to check that, */
X /* might as well have a general sanity check. */
X if (cinfo->image_height <= 0 || cinfo->image_width <= 0
X || cinfo->num_components <= 0)
X ERREXIT(cinfo->emethods, "Empty JPEG image (DNL not supported)");
X
X#ifdef EIGHT_BIT_SAMPLES
X if (cinfo->data_precision != 8)
X ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
X#endif
X#ifdef TWELVE_BIT_SAMPLES
X if (cinfo->data_precision != 12) /* this needs more thought?? */
X ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
X#endif
X#ifdef SIXTEEN_BIT_SAMPLES
X if (cinfo->data_precision != 16) /* this needs more thought?? */
X ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
X#endif
X
X if (length != (cinfo->num_components * 3 + 8))
X ERREXIT(cinfo->emethods, "Bogus SOF length");
X
X cinfo->comp_info = (jpeg_component_info *) (*cinfo->emethods->alloc_small)
X (cinfo->num_components * SIZEOF(jpeg_component_info));
X
X for (ci = 0; ci < cinfo->num_components; ci++) {
X compptr = &cinfo->comp_info[ci];
X compptr->component_index = ci;
X compptr->component_id = JGETC(cinfo);
X c = JGETC(cinfo);
X compptr->h_samp_factor = (c >> 4) & 15;
X compptr->v_samp_factor = (c ) & 15;
X compptr->quant_tbl_no = JGETC(cinfo);
X
X TRACEMS4(cinfo->emethods, 1, " Component %d: %dhx%dv q=%d",
X compptr->component_id, compptr->h_samp_factor,
X compptr->v_samp_factor, compptr->quant_tbl_no);
X }
X}
X
X
XLOCAL void
Xget_sos (decompress_info_ptr cinfo)
X/* Process a SOS marker */
X{
X INT32 length;
X int i, ci, n, c, cc;
X jpeg_component_info * compptr;
X
X length = get_2bytes(cinfo);
X
X n = JGETC(cinfo); /* Number of components */
X cinfo->comps_in_scan = n;
X length -= 3;
X
X if (length != (n * 2 + 3) || n < 1 || n > MAX_COMPS_IN_SCAN)
X ERREXIT(cinfo->emethods, "Bogus SOS length");
X
X TRACEMS1(cinfo->emethods, 1, "Start Of Scan: %d components", n);
X
X for (i = 0; i < n; i++) {
X cc = JGETC(cinfo);
X c = JGETC(cinfo);
X length -= 2;
X
X for (ci = 0; ci < cinfo->num_components; ci++)
X if (cc == cinfo->comp_info[ci].component_id)
X break;
X
X if (ci >= cinfo->num_components)
X ERREXIT(cinfo->emethods, "Invalid component number in SOS");
X
X compptr = &cinfo->comp_info[ci];
X cinfo->cur_comp_info[i] = compptr;
X compptr->dc_tbl_no = (c >> 4) & 15;
X compptr->ac_tbl_no = (c ) & 15;
X
X TRACEMS3(cinfo->emethods, 1, " c%d: [dc=%d ac=%d]", cc,
X compptr->dc_tbl_no, compptr->ac_tbl_no);
X }
X
X while (length > 0) {
X (void) JGETC(cinfo);
X length--;
X }
X}
X
X
XLOCAL void
Xget_soi (decompress_info_ptr cinfo)
X/* Process an SOI marker */
X{
X int i;
X
X TRACEMS(cinfo->emethods, 1, "Start of Image");
X
X /* Reset all parameters that are defined to be reset by SOI */
X
X for (i = 0; i < NUM_ARITH_TBLS; i++) {
X cinfo->arith_dc_L[i] = 0;
X cinfo->arith_dc_U[i] = 1;
X cinfo->arith_ac_K[i] = 5;
X }
X cinfo->restart_interval = 0;
X
X cinfo->density_unit = 0; /* set default JFIF APP0 values */
X cinfo->X_density = 1;
X cinfo->Y_density = 1;
X
X cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling */
X}
X
X
XLOCAL int
Xnext_marker (decompress_info_ptr cinfo)
X/* Find the next JPEG marker */
X/* Note that the output might not be a valid marker code, */
X/* but it will never be 0 or FF */
X{
X int c, nbytes;
X
X nbytes = 0;
X do {
X do { /* skip any non-FF bytes */
X nbytes++;
X c = JGETC(cinfo);
X } while (c != 0xFF);
X do { /* skip any duplicate FFs */
X nbytes++;
X c = JGETC(cinfo);
X } while (c == 0xFF);
X } while (c == 0); /* repeat if it was a stuffed FF/00 */
X
X if (nbytes != 2)
X TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before marker 0x%02x",
X nbytes-2, c);
X
X return c;
X}
X
X
XLOCAL JPEG_MARKER
Xprocess_tables (decompress_info_ptr cinfo)
X/* Scan and process JPEG markers that can appear in any order */
X/* Return when an SOI, EOI, SOFn, or SOS is found */
X{
X int c;
X
X while (TRUE) {
X c = next_marker(cinfo);
X
X switch (c) {
X case M_SOF0:
X case M_SOF1:
X case M_SOF2:
X case M_SOF3:
X case M_SOF5:
X case M_SOF6:
X case M_SOF7:
X case M_JPG:
X case M_SOF9:
X case M_SOF10:
X case M_SOF11:
X case M_SOF13:
X case M_SOF14:
X case M_SOF15:
X case M_SOI:
X case M_EOI:
X case M_SOS:
X return ((JPEG_MARKER) c);
X
X case M_DHT:
X get_dht(cinfo);
X break;
X
X case M_DAC:
X get_dac(cinfo);
X break;
X
X case M_DQT:
X get_dqt(cinfo);
X break;
X
X case M_DRI:
X get_dri(cinfo);
X break;
X
X case M_APP0:
X get_app0(cinfo);
X break;
X
X case M_RST0: /* these are all parameterless */
X case M_RST1:
X case M_RST2:
X case M_RST3:
X case M_RST4:
X case M_RST5:
X case M_RST6:
X case M_RST7:
X case M_TEM:
X TRACEMS1(cinfo->emethods, 1, "Unexpected marker 0x%02x", c);
X break;
X
X default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn */
X skip_variable(cinfo, c);
X break;
X }
X }
X}
X
X
X
X/*
X * Initialize and read the file header (everything through the SOF marker).
X */
X
XMETHODDEF void
Xread_file_header (decompress_info_ptr cinfo)
X{
X int c;
X
X /* Demand an SOI marker at the start of the file --- otherwise it's
X * probably not a JPEG file at all. If the user interface wants to support
X * nonstandard headers in front of the SOI, it must skip over them itself
X * before calling jpeg_decompress().
X */
X if (JGETC(cinfo) != 0xFF || JGETC(cinfo) != M_SOI)
X ERREXIT(cinfo->emethods, "Not a JPEG file");
X
X get_soi(cinfo); /* OK, process SOI */
X
X /* Process markers until SOF */
X c = process_tables(cinfo);
X
X switch (c) {
X case M_SOF0:
X case M_SOF1:
X get_sof(cinfo, c);
X cinfo->arith_code = FALSE;
X break;
X
X case M_SOF9:
X get_sof(cinfo, c);
X cinfo->arith_code = TRUE;
X break;
X
X default:
X ERREXIT1(cinfo->emethods, "Unsupported SOF marker type 0x%02x", c);
X break;
X }
X
X /* Figure out what colorspace we have */
X /* (too bad the JPEG committee didn't provide a real way to specify this) */
X
X switch (cinfo->num_components) {
X case 1:
X cinfo->jpeg_color_space = CS_GRAYSCALE;
X break;
X
X case 3:
X /* if we saw a JFIF marker, leave it set to YCbCr; */
X /* also leave it alone if UI has provided a value */
X if (cinfo->jpeg_color_space == CS_UNKNOWN) {
X short cid0 = cinfo->comp_info[0].component_id;
X short cid1 = cinfo->comp_info[1].component_id;
X short cid2 = cinfo->comp_info[2].component_id;
X
X if (cid0 == 1 && cid1 == 2 && cid2 == 3)
X cinfo->jpeg_color_space = CS_YCbCr; /* assume it's JFIF w/out marker */
X else if (cid0 == 1 && cid1 == 4 && cid2 == 5)
X cinfo->jpeg_color_space = CS_YIQ; /* prototype's YIQ matrix */
X else {
X TRACEMS3(cinfo->emethods, 0,
X "Unrecognized component IDs %d %d %d, assuming YCbCr",
X cid0, cid1, cid2);
X cinfo->jpeg_color_space = CS_YCbCr;
X }
X }
X break;
X
X case 4:
X cinfo->jpeg_color_space = CS_CMYK;
X break;
X
X default:
X cinfo->jpeg_color_space = CS_UNKNOWN;
X break;
X }
X}
X
X
X/*
X * Read the start of a scan (everything through the SOS marker).
X * Return TRUE if find SOS, FALSE if find EOI.
X */
X
XMETHODDEF boolean
Xread_scan_header (decompress_info_ptr cinfo)
X{
X int c;
X
X /* Process markers until SOS or EOI */
X c = process_tables(cinfo);
X
X switch (c) {
X case M_SOS:
X get_sos(cinfo);
X return TRUE;
X
X case M_EOI:
X TRACEMS(cinfo->emethods, 1, "End Of Image");
X return FALSE;
X
X default:
X ERREXIT1(cinfo->emethods, "Unexpected marker 0x%02x", c);
X break;
X }
X return FALSE; /* keeps lint happy */
X}
X
X
X/*
X * Finish up after a compressed scan (series of read_jpeg_data calls);
X * prepare for another read_scan_header call.
X */
X
XMETHODDEF void
Xread_scan_trailer (decompress_info_ptr cinfo)
X{
X /* no work needed */
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xread_file_trailer (decompress_info_ptr cinfo)
X{
X /* no work needed */
X}
X
X
X/*
X * The method selection routine for standard JPEG header reading.
X * Note that this must be called by the user interface before calling
X * jpeg_decompress. When a non-JFIF file is to be decompressed (TIFF,
X * perhaps), the user interface must discover the file type and call
X * the appropriate method selection routine.
X */
X
XGLOBAL void
Xjselrjfif (decompress_info_ptr cinfo)
X{
X cinfo->methods->read_file_header = read_file_header;
X cinfo->methods->read_scan_header = read_scan_header;
X /* For JFIF/raw-JPEG format, the user interface supplies read_jpeg_data. */
X#if 0
X cinfo->methods->read_jpeg_data = read_jpeg_data;
X#endif
X cinfo->methods->read_scan_trailer = read_scan_trailer;
X cinfo->methods->read_file_trailer = read_file_trailer;
X}
X
X#endif /* JFIF_SUPPORTED */
END_OF_FILE
if test 18541 -ne `wc -c <'jrdjfif.c'`; then
echo shar: \"'jrdjfif.c'\" unpacked with wrong size!
fi
# end of 'jrdjfif.c'
fi
if test -f 'makdjpeg.lnk' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makdjpeg.lnk'\"
else
echo shar: Extracting \"'makdjpeg.lnk'\" \(348 characters\)
sed "s/^X//" >'makdjpeg.lnk' <<'END_OF_FILE'
Xjdmain.obj +
Xjdmaster.obj +
Xjddeflts.obj +
Xjbsmooth.obj +
Xjdarith.obj +
Xjdcolor.obj +
Xjdhuff.obj +
Xjdmcu.obj +
Xjdpipe.obj +
Xjdsample.obj +
Xjquant1.obj +
Xjquant2.obj +
Xjrevdct.obj +
Xjrdjfif.obj +
Xjwrgif.obj +
Xjwrppm.obj +
Xjwrrle.obj +
Xjwrtarga.obj +
Xjutils.obj +
Xjerror.obj +
Xjmemmgr.obj +
Xjmemsys.obj +
Xjmemdosa.obj
Xdjpeg.exe /NOI
Xnul.map
X
Xnul.def
END_OF_FILE
if test 348 -ne `wc -c <'makdjpeg.lnk'`; then
echo shar: \"'makdjpeg.lnk'\" unpacked with wrong size!
fi
# end of 'makdjpeg.lnk'
fi
if test -f 'timg.ppm.u.a' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'timg.ppm.u.a'\"
else
echo shar: Extracting \"'timg.ppm.u.a'\" \(32510 characters\)
sed "s/^X//" >'timg.ppm.u.a' <<'END_OF_FILE'
Xbegin 666 testimg.ppm
XM4#8*,3(U(#$R-0HR-34*JD=*R&5HW'E\UG-VRVAKS&ELSVQOSFMNUG-VQF-F
XMLU!3NE=:T&UPU'%TT6YQV'5XVWZ U7AZS7)RS'%QSW5PTWETTWQTTGMSS7=Q
XMWHB"Y8^+T7MWQ7!OV82#YI"2UX&#VXF$V(:!V8B%X(^,X).0WI&.VI*/W)21
XMW9*0W)&/W9.-V8^)T81[UXJ!Y)2*XY.)U(Y^UY&!W)>+U9"$RH1]T8N$VY>5
XMVI:4UY22TY".W)N6WIV8VIV1V)N/TYB)W:*3X::-Y:J1XZ26UYB*UI&2VY:7
XMXIJAXIJAU8^8V9.<WIV:X:"=T9F)PXM[Q9)VTZ"$[+>HYK&BW*F<UZ27UJ67
XMW*N=X;2FY[JL\<:W[\2UZ,&SY;ZPW[JNWKFMW+>KW+>KT+NQT+NQU+JRU;NS
XMW+RVW[^YY;^[Y\&]W[FUY;^[YL*]X[^ZX\"[Z,7 Y<? XL2]\<J^W+6IQY.,
XMNX> UXZ.YYZ>XY"3RG=ZQ'9SW8^,VIV3Z*NA\,VVR69IU'%TV79YT&UPR&5H
XMRVAKSVQOT&UPQF-FQ&%DOEM>Q&%DU'%TUG-VT6YQUG-VT'-UTG5WT79VSW1T
XMS7-NS')MS79NSWAPW8>!T7MUT7MWTGQXS'=VTWY]X8N-YI"2WXV(V8>"U82!
XMV8B%WY*/XI62V9&.T8F&TXB&SH.!U(J$W)*,V(N"V(N"X)"&W8V#W):&S(9V
XMRH5YU9"$UY&*V)*+U9&/S8F'V9:4UY22W9R7WYZ9V9R0TY:*S)&"T9:'TYA_
XMT99]UYB*WI^1X)N<V925V9&8W96<U(Z7THR5SXZ+T(^,RY.#SI:&V*6)Y+&5
XMW*>8W*>8VJ>:W:J=X*^AZ+>I[+^Q\,.UZK^PZ;ZOY+VOXKNMWKFMWKFMWKFM
XMWKFMT+NQT;RRU;NSV+ZVWKZXX,"ZYL"\YL"\Y+ZZY+ZZY,"[YL*]Y,&\Y,&\
XMY<? ZLS%[\B\R*&5NH9_S9F2[:2DWY:6SGM^P6YQUHB%W(Z+X:2:]+>M\,VV
XMW7I]V'5XTF]RS6IMRVAKRVAKRF=JR69IME-6Q6)ES&ELSVQOV79YV79YTW!S
XMTW!SRFUOS7!RSW)SSG%RRF]MRF]MSW=RU'QWUX%]QW%MRW1TV8*"V(*&U7^#
XMU8&'U("&U(&"UX2%U(6'TH.%UHJ-W)"3U8R/RH&$UHV0T(>*VX^2YIJ=XY:5
XMW9"/V8N(SH!]S8!WPW9MT(1]Y9F2X96.VHZ'X):0ZJ":SH: T8F#UH^,WI>4
XMWYB5VY21V961VY>3V9F0TY.*TY&,U9..V).4UY*3UI&3U9"2TY"0R8:&O8%Z
XMQ(B!U:"1YK&BX[.>V:F4TZ*4UZ:8W:R>Y;2FY[NKZ[^O[,&R[<*SW[BJWK>I
XMW+BIW+BIW+FLW;JMW[ROW[ROW+>NWKFPX+NRX[ZUX\&WY,*XXL.XXL.XXL6Y
XMW\*VWL.WX<:ZX<B[X,>ZXLN]Z-'#WZBER9*/R8J)V9J9WY>4RH)_RGUZV8R)
XMV)"+SX>"Y:FB_\6^V*^FTF]RS&ELS&ELT6YQT6YQRF=JP5YAO5I=MU17RVAK
XMTW!STW!SVG=ZW'E\U7)UT6YQS&]QR&MMQ&=HQ6AIRW!NTWAVV(![VX-^Q6]K
XMR')NTWQ\VH.#VH2(X(J.W(B.S'A^S7I[W8J+X9*4UXB*SX.&T86(S(.&PWI]
XMS82'SH6(U8F,U8F,U8B'VXZ-VHR)QWEVV8R#U8A_X)2-Z)R5V8V&SX-\UXV'
XMX):0V9&+W96/UH^,VI.0V)&.T8J'U)",T(R(T9&(UI:-U)*-RXF$SHF*V).4
XMU9"2RH6'R8:&T8Z.TI:/UYN4WJF:Z+.DWJZ9T*"+WZZ@XK&CY[:HZ[JLZ+RL
XMY;FIX+6FW;*CV;*DVK.EV;6FVK:GV[BKW;JMW[ROW[ROWKFPX+NRX[ZUYL&X
XMYL2ZYL2ZX\2YXL.XXL6YX\:ZX,6YW\2XX\J]Z=##Y,V_V\2VOH>$S)62UI>6
XMS8Z-RH)_RH)_U8B%VHV*QW]ZRX-^ZJZG_\_(G'-JQ&%EQ6)FRVALT6YRSFMO
XMPV!DO%E=NE=;QV1HU'%UTW!TSVQPV'5YVWA\TW!TSVQPSFYQQ65HO6!AQ&=H
XMTW9WW'^ V7Y^TG=WQ&UMS'5UV(*&W(:*U8&*VX>0WHF7U8".S'F$V8:1VXJ7
XMU(.0S8*0SX22QWV-N&Y^L6IYMW!_M6QYI%MHIUQHRX",WY*;T(.,XY.;V8F1
XMUXB,UXB,UH>'W8Z.W9&,T86 VXZ+XI62TX>+V(R0VHR9U(:3WY.FUXN>RH.0
XMS8:3T8N4THR5T8R.SXJ,R(9_QH1]Q8I_WZ29[;BKY*^BT:*5SZ"3UJN>W;*E
XMZ+RLZ+RLY[RLYKNKX+BHV[.CU*V=T:J:U[.DV+2EV;:GVK>HV[JLW+NMV[VN
XMV[VNZKBR[+JTZKZV[<&YY\6ZYL2YW\:XWL6WV<6UX<V]X<J[VL.TY<R^\]K,
XMYLF\R*N>SG^+VXR8V8V1S("$R(![S(1_NWANHV!6M'9NTI2,];R^_\O-:#-
XMQ&%ERF=KS6INR&5IP%UAO%E=P%UAQ6)FU7)VV'5YT&UQRVALU'%UU7)VS6IN
XMRVALQV=JQ&1GPF5FS&]PUWI[V'M\S7)RP69FRG-SRG-SVH2(YY&5U(")OVMT
XMNV9TNV9TN69QMV1OLV)ON&=TQ'F'T(63Q7N+LFAXMW!_O'6$LVIWE4Q9D492
XMNW!\W9"9V(N4VXN3VHJ2VXR0UH>+T8*"VHN+WI*-U8F$TH6"X).0S8&%UHJ.
XMUXF6S7^,V8V@R'R/WYBET8J7SHB1TXV6RH6'NW9XPX%ZW)J3Y*F>YJN@WZJ=
XMV*.6TZ27VJN>X[BKY[ROZ+RLY[NKY+FIX;:FW;6EV[.CV+&AU["@VK:GV[>H
XMV[BIW;JKW;RNW;RNV[VNW+ZO[+JT[;NUZ[^W[<&YYL2YYL2YW\:XWL6WV,2T
XMXLZ^X\R]W<:WY\[ [];(VKVPMIF,XI.?UH>3QWM_O7%UK&1?GE91F%5+G%E/
XMPH1\[K"H_\O-WZ:H210AQF-GSFMOS&EMO5I>M5)6O%E=R69JT&UQUG-WU7)V
XMS6INS&EMTF]SRVALPV!DR&5IQ&)FRVEMT7%TTW-VSW)TRVYPR&QNR&QNSG9]
XMSG9]UG^+U7Z*O&AYK%AIJU9LJ%-IJEAOHE!GFTIBH$]GJ5UXLF:!K&2!IEY[
XMR8.?S8>CRH2?M&Z)H%ERJF-\OG:-OW>.S82ASX:CVY.JV9&HQ7Z-NW2#P7N"
XMPGR#RH2-W9>@RH*7THJ?QW^>JV."K&*,BT%KQGJ8S8&?SX>;QW^3O7I[P7Y_
XMTYB+Z:ZAZ[>AV:6/R)N'TJ61X;BKZ\*UY[^YX;FSXKNKX+FIW+BGVK:EVK:E
XMVK:EVK>HV[BIVKFKV[JLW;RNW[ZPWK^SW\"TWK^SWK^SZKZTZKZTY<*UY<*U
XMX,:VW\6UW,BVV\>UX,BWX,BWZ<:Y[<J]]<B^Z[ZTVJ*<PXN%X("3QV=ZL%EA
XMJ%%9BT,^?C8QDE=,P89[W*6A^\3 _\?1EEUG1PDIP5YBS&EMR69JN%59LD]3
XMP5YBT&UQU7)VTF]ST6YRS6INSVQPTF]SQ&%EO%E=Q6)FQ6-GTG!TVWM^TW-V
XMPV9HOV)DS'!RWH*$UGZ%V8&(RG-_J%%=ED)3LEYORW:,Q&^%N6=^LV%XJUIR
XMH$]GD$1?B3U8C45BF%!MQ'Z:R...@V9.NUI"KMW")H%ERGE9MH%AOIUY[G51Q
XMKF9]RH*9T(F8RH.2R(*)R(*)GEAAO'9_M&R!R8&6Q7V<J6& IER&@#9@<B9$
XMKV.!SX>;P'B,OGM\WYR=[;*EX::9SIJ$T9V'V:R8Z[ZJ[<2WY;ROX;FSYKZX
XMY+VMXKNKWKJIV[>FVK:EVK:EVK>HV[BIV[JLW+NMW[ZPX<"RX<*VX<*VX<*V
XMX<*VZ[^UZ[^UY,&TY,&TWL2TW\6UV\>UW,BVY<V\W,2SY\2W]=+%]LF_VJVC
XMRY.-QX^)OEYQHT-6C#4]D3I"C45 E$Q'K'%FU)F.\;JV_<;"]+O%6!\I1PDI
XMSVMROEIAL4U4ME)9Q6%HT&QSUG)YV'1[T&QST6UTS6EPQF)IP%QCP%QCQ6%H
XMQV-JR65LSVMRR&9LV'9\Q65JS6URR&MTV'N$T7B%R7!]NF1VN&)TOFN$Q7*+
XMP&R,M6&!I5%RN&2%H$]QGDUOC4)IA#E@<2E2E$QUR(2NU)"ZSHJRRH:NL&V2
XMLF^4J62)J62)I&>9DU:(E%B#>CYIBDUPG%^"L'21K7&.EUMXC%!M@4-I9"9,
XM<S1B;2Y<@4%UBTM_4 8F@SE9N7.&THR?Z*NIZ*NIQ9%]QI)^SJ*(V*R2V[2>
XMWK>AX+FMY+VQW[FUV;.OWKRJW[VKW[VKWKRJV[BIVK>HV[JLW+NMVKFKW;RN
XMX;^TY<.XX\2XX,&UW\"TX,&UWL:UVL*QW,6TX,FXW\>VY<V\Z<R]V[ZO[L6Z
XM[L6Z_<&\^KZY]*6GU8:(O61IK%-8FC9'E3%"G$1,HTM3CTA%IE]<SY>1[+2N
XM^L;)_,C+@TA=3A,H7!9#NE9=LT]6M%!7P%QCSFIQT6UTSFIQRV=NSVMRSFIQ
XMR65LQ&!GP5UDPU]FR&1KRF9MS6EPSFIQPV%GT&YTR&AMU75ZS7!YU7B!VH&.
XMOV9SK%9HN6-URG>0QW2-L%Q\FT=GKEI[HDYOA316A#-5?#%8<"5,;25.D$AQ
XMOGJDOWNEU9&YNG:>Q8*GHV"%J&.(E5!UD52&ATI\?T-N<C9ADE5X@41G;3%.
XM:BY+:R],<#11<C1:7!Y$8R1241) 5A9*6!A,4PDI<2='SHB;]*[!SI&/Q(>%
XMS)B$U*",X[>=Z+RBYK^IY+VGX[RPY;ZRX;NWW+:RWKRJW[VKW[VKW;NIV[BI
XMVK>HV[JLW+NMX<"RW[ZPW;NPWKRQW\"TX<*VXL.WX\2XWL:UX,BWY<Z]X,FX
XMUKZMV\.RZLV^ZLV^]\[#YKVRW:&<R(R'OF]QIE=9G41)ECU"GCI+F#1%DSM#
XMFT-+I%U:R8)_WZ>AYZ^I_]+5L7V 7R0Y20XC50\\K4E0KTM2NE9=RF9MU'!W
XMTFYURF9MQF)IS&AOR&1KQ&!GPEYEQ&!GQV-JRV=NS6EPT&IQSFAOP5UFRV=P
XMS6MSW7N#T72 S&][MUUNLUEJO&5_SG>1R'25L%Q]GDMRGDMRH4UWCSMED$!J
XMG4UWFU!_@39EA#]OGUJ*H%^0LG&BJ6B9NGFJE52%F%>(=31C<"]>93%J1Q-,
XM=D!UFV6:@DQ_2A1'8BM;>D-S2A1!5B!-5Q]+1 PX41E%4!A$3A9"0PLW<"L_
XMKFE]X*&KTI.=P8N$T)J3U*>3YKFEZL"IZ\&JY;^KX+JFW[BJX+FKX+BPWK:N
XMW;JKWKNLWKNLW;JKV[BIVK>HW+FLWKNNXL"UX+ZSWKNPWKNPX+ZTX\&WX\&W
XMX+ZTV\>WU\.SX<BZYLV_[LF_\<S"\\&[XK"JUI.3P7Y^L5UCH$Q2H#U(F39!
XMG#- GC5"ES]$ECY#F4I,M&5GSHN,X9Z?[[6Z_\_4[;;%;C=&6!HX5A@V6 \]
XMM%!7N%1;Q&!GSVMRU'!WT6UTS6EPS6EPQF)IPEYEP%QCQ6%HRF9MRV=NRV=N
XMS&AORV5LS&9MQV-LS&AQT6]WVGB RVYZOF%MGT56M%IKR'&+RW2.LEY_GDIK
XMIU1[O&F0KUN%I5%[O&R6NVN5J5Z-?3)A?SIJAT)RA$-TC$M\GEV.DE&"C4Q]
XM<S)C;BU<9213625>B%2-A$Z#7RE>=T%T<#IM<#EI9B]?6")/3QE&2! \1@XZ
XM3!1 2A(^9"Q8BU-_O7B,W)>KU)6?LW1^RY6.\;NTY[JF\<2PYKREY;NDX+JF
XMW;>CW+6GW;:HW;6MW;6MW+FJW;JKWKNLW+FJV[BIVK>HW+FLWKNNV[FNX+ZS
XMX\"UXK^TXL"VX;^UW[VSV[FOU\.SU\.SY<R^Z]+$Z<2ZV;2JQ9.-I')LEE-3
XMC$E)CCI CSM!GCM&H#U(I3Q)ICU*FD)'L%A=N6ILT(&#[:JK]K.TY*JOYZVR
XMC59E1Q ?6APZ5!8T4 <UOUMDPU]HS&AQU'!YTV]XS6ERRF9OS6ERP5UFO5EB
XMP%QERF9OSVMTS6ERR65NR65NQ5UES&1LTVQVTVQVTW![S&ETOV%PM%9EN6!U
XMP6A]O&:$KEAVI5)YK%F MF.0NVB5IU2!G$EVHU2"CC]M@#9H9QU/;BM@:B=<
XM;"QB?3USEUF1D5.+C4^%>#IP@$-VA$=ZD%N+=D%Q>$%T=3YQ82EA41E1?$)]
XM:C!K8B9;415*1@PU4!8_3!,O3!,OA4I?VI^TW:.AL7=UO8:"U)V9TZ29YK>L
XMZ,"OY+RKX;NIX+JHX+JHX;NIX;FIX+BHX;:IXK>JV[BIW+FJW;JKW+FJVK>J
XMVK>JW;BLW[JNVK6KX[ZTY\*YY+^VXKVTY+^VYL&XY<"WZ,2[[\O"_,S'X[.N
XMP'Y_H%Y?FDI0C3U#FCU'E3A"E39!G#U(I$50ID=2ID=2ITA3IV!3S89YU9&+
XMV96/];.X\[&VL7&#=#1&4!$M41(N6Q@\6!4Y7!0]PEYGQV-LT&QUUW-\TV]X
XMR65NPEYGPU]HP%QEO5EBPEYGS6ERT&QURF9OQ6%JQV-LR&!HS&1LV7)\U&UW
XMSVQWNE=BMEAGM5=FP6A]R&^$P&J(L%IXJ59]L%V$IU2!ET1QC#EF@2Y;<R12
XM9!5#:B!2;2-5;2I?:"5:<C)HCT^%DU6-JFRD@4-YB$J @$-VF5R/9S)BFV:6
XMB%&$72998BIB6"!8>T%\@4>"10D^5AI/1@PU0@@Q7B5!G62 O8*7RY"EJ6]M
XML'9TUI^;Z[2PY;:KX[2IU*R;VK*AX;NIW[FGW[FGXKRJX;FIW+2DW+&DW;*E
XMVK>HV[BIW+FJV[BIVK>JVK>JW;BLW[JNW;BNY+^UY+^VWKFPWKFPY\*YZ\:]
XMZL6\\,S#Y<&XV:FDL8%\CTU.?CP]CCY$CS]%F3Q&E3A"EC="GC]*J$E4L5)=
XMO%UHQ69QS89YW)6(\:VG_\"Z]+*WM7-X;2T_3 P>4Q0P8R1 4@\S7AL_<2E2
XMR&1MR65NSFISTFYWSFISQ&!IOEICOEICPU]HP%QEQ6%JSFISS6ERQ&!IPEYG
XMR&1MU6UUS65MUW!ZSF=QR&5QK$E5M5=HP6-TNF%XPFF O6:(K59XF4=QD3]I
XMBSAIA3)CCCMHBSAE;A]/:1I*:1]3:B!471E1;2EACU&+C4^)H62>@$-]?T)\
XM72!:?$!WBT^&F%^%@DEO<C=F?T1S=SEQ5!9.>SIW;BUJ/@ Q5A1)4! S:"A+
XMGU]NY*2ST9.5K6]QG6A9VJ66\+^QVJF;X;:IYKNNRJ.3UJ^?W;FJV;6FVK.C
XMW;:FW[2DV:Z>V:V;W+">VK>HVK>HW+FLV[BKV[:JV[:JW;BNW[JPX;FPY+RS
XMX[NSW[>OXKJRZ,"XX[FRUJRET9F;P8F+N7-ZI5]FG492G492JT97I4!1H3=*
XMHSE,IT55M%)BN&-OQ&][SX*+VXZ7W:2,V:"(]+FN_\6ZPX.+:BHR4 TH9B,^
XM610Z7QI 4 @Q7!0]:"%&T&QUS&AQRF9ORF9OQF)KP5UFP%QEPEYGQV-LPU]H
XMQF)KS&AQR65NP%QEP5UFRF9OX7F!SV=OTVQVQE]IPE]KI4).MUEJS6^ RW*)
XMN6!WGD=IB3)4=R5/=2--@S!ADC]P@"U:AS1A9QA(:1I*7A1(7Q5)7AI2EE**
XMFUV7EUF3@D5_<C5O411.5AE3:2UDBT^&8RI0B5!V@49U;C-B9BA@2PU%=C5R
XM;RYK5A1)1 (W5Q<ZN7F<W)RKQ864GF!BMGAZYK&BW*>8Z;BJW:R>QYR/UJN>
XMV;*BU*V=W+BIU[.DV+&AW+6EW[2DVJ^?W+">X;6CV;:GVK>HV[BKV[BKVK6I
XMV[:JW;BNW[JPWK:MXKJQXKJRXKJRZ,"XYKZVT*:?M(J#B%!2E5U?L6MRL6MR
XMJ5)>H$E5IT)3GSI+LDA;O%)ERFAXVWF)VH61VX:2VXZ7XI6>XJF1Z*^7Z["E
XMP89[=C8^4A(:5Q0O618Q6Q8\81Q":R-,:"!)8AM S&=HSVIKSVENR&)GP%AB
XMO%1>PU=HREYOQEQMQUUNQ6)NQF-OP&!EO%QAPV=IT'1VTFYUUG)YQ6-QSFQZ
XMP&:!DSE4Q'":OFJ4FTY_B3QM="U>7QA);"=7DDU]CDEW<"M93Q,];3%;515
XM7AY)9")/40\\A#UNK6:7F5*%IE^2<RUB8!I/5!)'7!I/C4V!A$1X6S->>E)]
XM>$=U4R)0104X2 @[FE%_@#=E5 <HACE:PWJ%V9";P8%XL7%HR(UV[K.<Z+FL
XMY;:IX+&DVZR?UZJ<UZJ<VZZ@W;"BW;"BW;"BWK&CWK&CX+&DWJ^BVZR?V*F<
XMV;6CV[>EW;6DV[.BV[.BW[>FW[RMXK^PX\:ZUKFMZ</'TZVQYJ["S)2H?S=6
XMCT=FDE=LE%ENNW>'N'2$OW!RK%U?QW!FRW1JUWYIWH5PXX]TYY-XX9AWXIEX
XMWYM[X)Q\Y:*K^;:_R(24;RL[3@DA6A4M81H]7A<Z81E"9AY'9AY)8QM&81E$
XMU7!QS6AIPEQAN%)7MT]9O%1>QUMLSF)SR%YOS&)SQ&%MO%EEN5E>OEYCO6%C
XMN5U?RF9MS6EPT&Y\W7N)T':1HDACL%R&H$QV?S)C;B%2;B=8@#EJAD%Q>#-C
XM8!M)611"6Q])8"1.41$\7!Q'61=$92-0G5:'EU"!F%&$@CMN6A1)50]$<C!E
XME5.(E%2(;R]C:T-N<DIU8"]=0 \]41%$6AI-C$-Q>"]=BSY?PW:7VI&<NW)]
XMJ6E@RHJ!ZJ^8\+6>XK.FX+&DW*V@V:J=UJF;UZJ<VZZ@W;"BV*N=V*N=V:R>
XMVJV?W:ZAWJ^BWJ^BW:ZAU+">V[>EX[NJX;FHWK:EW+2CUK.DT["ARJVAXL6Y
XMY\'%L8N/@DI>=S]3A3U<@CI9D%5JD59KIV-SOWN+T(&#UXB*X(E_WXA^ZY)]
XMYXYYY)!UZ)1YWI5TVY)QWYM[[JJ*_\K3RXB1>#1$30D94@TE7!<O7!4X7Q@[
XM8AI#9AY'9Q]*8QM&81E$T7!RQ&-EMU-:L4U4N%%>P5IGR%YQRV%TQEQOS&)U
XMPU]PMU-DNEEDR&=RPV5NLU5>J4=7I$)2N%EPR&F P6N+HTUMD$!L?R];:B!2
XM=2M==C%C>#-E=3-B9")14Q$^4A ]:RM66!A#3@PX7!I&5Q) ?#=EJV25=2Y?
XM@#EN719+6A=,:B=<B$A^HF*8CE"&?#YT>TV"21M03AM-6"575QM(5AI'C$EM
XMFE=[SHF=Q8"4MW5XM7-VPXI_X:B=[[FF[[FFVZZBV:R@UJF=U:B<TZB;UJN>
XMVJVAW*^CUJF=UJF=U*F<U*F<UJF=V:R@W*^CW;"DV+2EW+BIX;:GWK.DX+&D
XMYK>JZ[RQZKNP]<;#Q)62AU5?>4=18",[<C5-NW25ED]PD%1OEEIUFUEKP'Z0
XMT(.$YYJ;X8R XXZ"YY)\ZI5_Z9>"YI1_X)B%ZJ*/^+.E_\&ST(R>@3U/3 <=
XM40PB7A@V6Q4S7!4Z8QQ!8QM$9Q](9Q]*8QM&81E"P6!BO%M=NE9=O5E@Q5YK
XMR&%NQEQOPEAKP5=JQEQOP5UNOUMLQV9QTW)]SW%ZPF1MO%IJHD!0L%%HL5)I
XMIE!PG$9F>BI6<"!,=BQ>B3]Q>C5G;"=98R%06AA'8R%.;RU:;"Q7515 30LW
XM7QU)9R)0AD%OF%&"7!5&:B-84PQ!9B-8C$E^C4V#A45[ATE_D%*(83-H/A!%
XM<#UO<T!R20TZ:BY;NG>;QH.GR828IF%UI6-FU)*5\+>L[+.HY:^<\+JGV:R@
XMUZJ>U:B<U*>;U*F<UJN>V*N?V:R@UZJ>UJF=TZB;T*68T:28TZ::V*N?W*^C
XMV[>HW+BIWK.DV["AX[2GZ[ROZ+FNW["EJ'EV8S0Q1Q4?AE1>A4A@<#-+LFN,
XML6J+DU=RG6%\HV%SMW6'R'M\UXJ+VH5YXHV!Y(]YZ)-]Y9-^Y9-^\ZN8_\"M
XM^K6GW)>)<2T_4@X@4@TC9!\U8APZ7QDW8QQ!7A<\9!Q%:"!):"!+8QM&81E"
XML5%6ME9;OEUGQ61NR61SQF%PP5EMO%1HOU9LOU9LP5QSR61[S6J S&E_R6M]
XMR&I\K5%MC#!,D3E:C356A3-<DT%J=BM;>B]?@3QN?#=I:"=8<S)C:BE84A%
XM;2U9BDIV8!Q(615!4 HW9B!-A3MMASUO=BQ@60]#91U49!Q38AY6AD)Z@#]Z
XM=31OC$^)=3AR.PI+>TJ+FF2;6R5<1@TSH&>-TI:GN7V.E%M=KW9XT9N2Y[&H
XMZ+>JY+.FX;6EY+BHVJZDV*RBU:F?U*B>UJJ@UJJ@UJF?U:B>TZ:<U*>=T:6;
XMSZ.9SZ.9T:6;UZNAW+"FV+"GV[.JX;*IX[2K\;BPZ[*JTY".LF]M?S<\7!09
XM9A\PG59GFU5Q?#92CTQPMW28F5Z!G6*%I61YHF%VR'^!S(.%W(U]Y)6%ZIJ&
XMY)2 XI:(\Z>9_K>X[::GL&MY>31"8AHY4 @G5 PM7Q<X7!,Y81@^9QU'6Q$[
XM91M':1]+:!Y(9!I$81<_L5%6MU=<P%]IQ&-MQ6!OP5QKP5EMP5EMP%=MP%=M
XMPUYUS&=^QV1ZO%EOMEAJNEQNESM7?R,_?R=(@"A)<R%*BSEB>"U=A#EI>#-E
XM=C%C7!M,7QY/61A'8B%0C$QXA45Q3PLW6!1 4PTZ:B11DTE[@3=I71-'81=+
XM6Q-*=R]F:"1<;2EA7QY9<"]JDU:04A5/0 ]0J'>XB%*)10]&<3A>KW:<I&AY
XMH&1UKW9XU9R>[[FP[KBOXK&DY+.FXK:FW;&AW+"FV*RBU:F?U:F?UZNAUZNA
XMU*>=T:2:S)^5SZ*8T*2:T:6;T:6;U*B>VZ^EX+2JV[.JV[.JW:ZEW*VDZK&I
XMYZZFS(F'IV1BC45*@SM @#E*>#%"B4-?G%9RCDMOGUR IVR/HF>*GUYSD$]D
XMR'^!S(.%VXQ\WH]_Y96!ZIJ&_;&C_[ZPWYB9ED]081PJ51 >9!P[5 PK5P\P
XM8QL\7Q8\6A$W81=!:R%+91M':1]+:!Y(8QE#8!8^N%ICO%YGPV%OQ6-QQ&!Q
XMPU]PPUUTQ%YUNU9QPEUXQF)_QF)_OEY[MU=TK4]NJ4MJJ%-]FD5OD#UJD3YK
XM<B56?S)C=2]D?3=L9"-6;2Q?4Q-&2 @[1P@X>#EIJVN7;2U93PDV6A1!7A5$
XM;B54C$%S>S!B60]#9!I.715,;B9=;"A@7QM33@U&<C%JB4R&20Q&9"YUHVVT
XM=CYV>4%YFV.!D%AV@4Q/J71WX*^BXK&DXK2CYKBGXKJJW[>GV;*FU*VAV*^F
XMU:RCU*B@U:FAV:NDV*JCU:6?T*":R9F3SIZ8TZ6>UJBAU:FAUZNCVK&HWK6L
XMW;.LW+*KVZFAU:.;Z*>B\K&L[IN<U8*#D#$^F#E&H41=DS9/BSU>F4ML@D%H
XM@4!GJFR6KW&;GUUXDU%LNG5WQX*$SX9WWI6&XYB*[Z26]:JJVH^/DTQC6!$H
XM2P8L7QI 4PDS6A Z8AA":B!*:!Y(7!(\7A1 <BA49!I$:!Y(9QU%81<_7A0\
XMOV%JPF1MR&9TRFAVS&AYRV=XR&)YQ5]VMU)MQ6![R66"PEY[OEY[P&!]MEAW
XMI4=FD3QFD#MEA3)?CSQI<215@#-DA3]TD4N 71Q/5!-&1@8Y6QM.7!U-@$%Q
XMJ&B47Q]+6!(_71=$:!].<"=6?C-E=BM=71-'81=+="QC50U$7!A06Q=/6AE2
XM@4!Y>SYX2@U'<SV$EF"GD%B0O86]H&B&?D9DGVIMQ9"3WZZAZ;BKZ+JIW[&@
XMV;&AW[>GV[2HT:J>U:RCTJF@T:6=U*B@V*JCV*JCU:6?SY^9RYN5TJ*<UZFB
XMV:NDUZNCUJJBUZZEV[*ITJBAVK"IX*ZFW*JB[ZZI][:Q]Z2EX(V.RFMXFSQ)
XMBRY'HD5>GE!QFTUNE%-ZD5!WF5N%MGBBI&)]HV%\L&MMR82&THEZ]:R=_[:H
XM]:J<QGM[@C<W6!$H7!4L71@^5A$W6 XX:1])8AA"6Q$[:1]):R%+81=#8QE%
XM9!I$:!Y(9AQ$81<_71,[P6)MR&ETS6MYQ&)PO%AKN55HNU9MO5AOPU]\PEY[
XMLU)TKDUON%V N%V FD%H@RI1="-5@S)DA3AK@#-F@SQOD$E\AT1Y<B]D82%5
XM6QM/6QM.1 0W8R)3C4Q]F%:%7!I)5A ^:")0?S9E7A5$9AM-8A=):R!2;B-5
XMB#YR?C1HB4-XB4-X:BE<D5"#?#]R:"M>@DB,CE28C5:'LWRMF&1YGFI_Q)2.
XMT:&;W;&=VZ^;V:^8W;.<W;:FW+6ETJVDS:B?SJ6<U:RCV:NDTJ2=T:&;U:6?
XMV*2?TIZ9T9V8UZ.>VZNEW:VGV:NDUZFBU*NBU:RCXK*OXK*OY[6M[+JR^KJR
XM]K:N^J6C\)N9UVY[N$]<H3=2F2]*DS]BKUM^G5V&=C9?@4%LIF:1N':3M7.0
XMK6=PP'J#ZJ*=XYN6U(R)F%!-:!\L7A4B5Q S5@\R6!-%6Q9(7! _815$9QM*
XM:AY-:1U(9QM&:!Q':1U(:A]'9QQ$818]7A,Z71(YPV1OPF-NOEQJM5-ALT]B
XMN55HP%MRPUYUPU]\P%QYPV*$Q62&L%5XE3I=@"=.>!]&>BE;?"M=>BU@?C%D
XMA#UPBD-V@#UR<S!E7!Q05Q=+6QM.41%$;"M<>3AI@#YM9B139B!.:2-1>3!?
XM91Q+:R!28!5'9!E+7Q1&71-'>"YB:R5:6!)'82!3A$-V8217:"M>ADR0@4>+
XMA$U^H&F:HFZ#M("5SIZ8TJ*<U:F5U:F5UJR5V*Z7UJ^?U*V=S*>>R*.:S*.:
XMSJ6<T**;S9^8SY^9TJ*<U:&<T9V8V*2?U:&<T*":T:&;U:>@VZVFW+.JWK6L
XMY+2QX[.PYK2LZ;>O][>O]K:N_ZJH^*.A[821QEUJJ#Y9FS%,A#!3CSM>C4UV
XMA45N>CIE@D)ML6^,KVV*M6]XP7N$THJ%QW]ZKV=D?C8S7!,@7A4B718Y718Y
XM7!=)7!=)8!1#9!A':!Q+:AY-:1U(9QM&:!Q':1U(:A]'9AM#818]71(Y7!$X
XMQ%]LPEUJNU9EMU)AO%=HQ6!QRF9ZR65YO%QXHT-?JU!RQ6J,L5Z%E4)IA#1@
XM>RM7>"M@;2!5:!Y2="I>?3AJ@#MM=C5H;RYA9"-67AU07AU06QI-=3)F9B-7
XM<2M@A#YS@D!O92-26Q9&40P\5PT_5 H\8QA(8!5%60X]9!E(5PX\40@V7AA#
XM="Y9:B90BT=Q<CEM:3!D@TQRD%E_IG.#NXB8QY>1R)B2T*22TZ>5U:N8U:N8
XMTZB;SZ27R:"7QYZ5T:6;S:&7SI^6T:*9V**;UJ"9V)Z9V9^:VZ&<U9N6SYF2
XMTYV6VZRCY;:MY;FOY+BN[+.QZK&OY;.IY[6K[KFH\+NJ_;*H^J^E_Y>=U&QR
XMN$EAJ#E1@"5(=1H]=#-:B4AOA4!F;2A.IV%_LFR*O'6&QX"1Q'J$N&YXGU1@
XM<R@T5P\F6Q,J7!0[6A(Y61)#5Q!!91E&:!Q):1U(:AY):1Y%:!U$:1Y#:A]$
XM:1Y#91H_8!4Z71(W7!$XM5!=NU9CPEULQF%PS&=XT&M\S&A\Q6%UR6F%H$!<
XMGD-ELUAZFTAOBSA?A#1@=B92;B%691A-71-'9!I.<2Q>>S9H=#-F:BE<=#-F
XM;RYA8B%461A+=S1H8!U1<"I?H%J/D$Y]:2=651! 7QI*9QU/7Q5':!U-7A-#
XM9QQ+6 T\711"711"4PTX>3->F%1^E5%[<CEM=CUQJW2:JG.9P(V=R9:FS)R6
XMU:6?TZ>5V*R:V[&>UZV:T*68RI^2Q9R3QIV4SJ*8S*"6T:*9V*F@V:.<T)J3
XMTYF4VZ&<U)J5U)J5UJ"9X*JCY[BO[+VTYKJPX;6K[;2R[+.QYK2JZ+:L[KFH
XM[[JI_K.I_+&G_Y>=W75[PU1LL$%9A2I-;A,V8!]&<S)9CTIP<BU3C4=EM6^-
XMMW"!QX"1RH"*O7-]H59B=RPX6Q,J61$H50TT50TT6!%"61)#9QM(:!Q):1U(
XM:AY):A]&:A]&:R!%;"%&9QQ!8Q@]7Q0Y7!$V7!$XL$12O5%?RF%NT6AUTFMX
XMT&EVQF)UOUMNLE=OECM3C3M:B3=6:1Y&:R!(>S5B=2]<819(8QA*7!)$6 Y
XM92!0?#=G>3AI:BE:?#EK?CMM:B1950]$=R]F9!Q3;B-;F4Z&G6"0>CUM3@T^
XM5!-$611"51 ^9!I&7A1 7A,Z6@\V71(W60XS:!X^F4]OKF:#@CI7CUEZE%Y_
XMPHVFO(>@TI^LTZ"MT)^?W:RLVZRCW["GX+&DVJN>T9^5RIB.R):,RIB.R)N/
XMS)^3V*6;VZB>UYN4RHZ'T8^*W9N6V9>2X)Z9YJJC\+2M[[RR[[RRZ+NOY;BL
XM\[*Q\[*QZ+JKZ;NLY\"FYK^E]+:B\;.?]YB5X8)_QUINK4!4C3%1>AX^7!D^
XM71H_ACY=@SM:<2A%N&^,L66"P762TH6@P'..E$=B<B5 71 Q7 \P5PXT6A$W
XM81E"8QM$:1M#:1M#:AU":QY#;B%";R)#<"1"<"1"9ADZ8Q8W8!,V7A$T7Q$Y
XMNT]=Q5EGRV)OS&-PRF-PR6)OPU]ROUMNJ$UEBS!(;QT\9!(Q71(Z=2I2?CAE
XM;2=46@]!91I,81=)5PT_7QI*>31D>SIK;RY?=3)D?CMM;2=<5A!%>#!G91U4
XM819.="EAH&.3G6"09"-47QY/7AE'5A$_7!(^5@PX6 TT5 DP2P E;B-(K6.#
XMGE1TD4EFD$AEMH"AK7>8LWZ7N(.<U:*OUZ2QT)^?VZJJW["GX+&HWJ^BU::9
XMS)J0Q9.)Q9.)QY6+RYZ2T:28W*F?V::<U)B1RX^(TY&,W9N6XZ&<ZJBC[;&J
XM\;6NZK>MZK>MZKVQ[L&U\[*Q];2S[+ZO[;^PZL.IY\"F]+:B\K2@_9Z;[(V*
XMRUYRJ#M/D#14@B9&7!D^5!$V;R=&BD)A:2 ]L6B%N6V*PG:3V(NFOW*-@C50
XM:QXY8!,T8Q8W710Z7!,Y7Q= 7!0]:!I"9QE!:1Q!;!]$<"-$<21%<25#;R-!
XM9!<X8A4V7Q(U7Q(U8!(ZS5YMSE]NR5QJQ%=EP%=DPUIGO5EJN%1ENV)WDSI/
XM81,Q6@PJ:R9,?CE?9R=3104Q60X^8A='81M)6A1"71A&;"=5=3-@=3-@<2Q<
XM>#-C<"E<8!E,?S-K:Q]77Q%,8Q50?$%RL'6FBDM[B4IZA4-P;2M86 XX1@ F
XM6 LN6 LN:QT\J%IYU(>@ETICGE-IQWR2T9VRPX^DIG.!P8Z<WJRVWZVWV:BJ
XMX[*TXJ^MX*VKVZ>@TIZ7RY6,QY&(R9*'RY2)U*68V*F<W::;U)V2TY.+UI:.
XMX)J4Y)Z8[:>A\:NE\K*J\[.KZ[2I[+6J[+VP\<*U][.Q^;6S[<&O[\.QY\FJ
XMYLBI\\"D\\"D_JB@\9N3TFEWK412ECA7@B1#610Y5Q(W814PA#A3>"I(FDQJ
XMQWF:RWV>VXRPP'&5>"E-9A<[8A4Z9QH_8!4Z7!$V714V61$R:!L^:!L^:1P]
XM;!] <25"<25";R,^;" [8A8S8!0Q7Q(S8!,T8A0]SV!OREMJP%-ANDU;N$]<
XMNU)?LDY?J$15GD5:ARY#8!(P8Q4S>31:@3QB925141$]60X^71)"7AA&7AA&
XM7!=%7AE':BA5=S5B<2Q<<2Q<<2I=:"%4A#AP;R-;91=2:!I5:S!AK7*C<C-C
XM71Y.6AA%51- 50LU50LU1P =;!]"KF!_RGR;M6B!F$MDV(VCY9JPPX^DOHJ?
XMEF-QPH^=UJ2NT)ZHSIV?W:RNXJ^MWJNIV*2=SIJ3RI2+R)*)RY2)S9:+UZB;
XMUJ>:U)V2QY"%S8V%V9F1Y)Z8XIR6ZZ6?\*JD\K*J];6M[[BM[[BMZ[RO[+VP
XM^;6S^[>U[L*P\,2RZ,JKZ<NL^,6I^L>K_ZJB]J"8W'.!NU)@G3]>?1\^4@TR
XM6A4Z6@XI=2E$@C12>BQ*RGR=SX&BV8JNOW"4;R!$8!$U7A$V8Q8[7A,X8!4Z
XM91T^91T^:1P_:1P_:AT^;2!!<25"<"1!;" [:!PW814R8!0Q7Q(S810U8Q4^
XMU%AGS5%@MDQ?KT58?RI#F$-<@S9;<"-(?B]@@3)C;!M/7@U!C4)T?3)D611"
XM3@DW7!0]714^9AY'9Q](6!,[6A4]9B!+:2-.=3!>9!]-8A]1:B=9@3YS;"E>
XM:B9>7AI292Q>H6B:>41S2!-".@8N4!Q$2PPO/P C7A,KGU1LTX20N&EUGE=4
XMUH^,\;6FS)"!RHJ2W)RDIG!UPHR1OI62O921QZF@U+:MSZVBRJB=S:"6S)^5
XMU):0TI2.W9*.XI>3\I2+Y(9]VX!VXXA^YI*)YY.*Z)R5\J:?ZZB@[ZRD[[2I
XM\K>L[[JM[[JM[;RN[KVOY[^LZ,"M[<*R[\2T]L.W^,6Y_\.R_\2S_K6F\JF:
XMX(F)OF=GID%<CBE$?@]";P S7!%#7A-%?C1><RE3I5U\U(RKV9*IR8*9<BQ
XM8APP:2(]91XY7Q8\:!]%9AQ(:B!,9!L_91Q :B%%;R9*<2E*;B9':B)#91T^
XM714T7A8U81DX9!P[:" ]VEYMRT]>J3]2H3=*?RI#DCU6>RY3;!]$<R15;!U.
XM:!=+:1A,F4Z <"575 \]6Q9$:2%*:"!):B)+9AY'6Q8^7AE!9!Y)8AQ'8QY,
XM;BE7:"577!E+@#URAD-XAD)Z9R-;3Q9(?41V>41S1 \^2A8^0 PT1@<J5A<Z
XMG%%IOG.+O6YZL6)NRX2!Y)V:V9V.V)R-SHZ6VIJBI&YSP8N0R)^<RJ&>S*ZE
XMTK2KU[6JS*J?S)^5S)^5VIR6V9N5X)61WY20YXF WH!WW(%WYXR"ZI:-[)B/
XM[:&:]JJC[:JB\*VE[[2I\;:K[[JM[[JM[KVO\+^QZ,"MZ<&N[<*R\,6U]\2X
XM^,6Y_\2S_\2S_[NL^*^@YY"0Q6YNK4ACE"]*@A-&<P0W5 D[6@]!;"),=BQ6
XMC45DTXNJTHNBPGN2>S5)9R$U:B,^9!TX8!<]:!]%91M'9QU)9QY":!]#:B%%
XM;B5)<"A);B9'9Q] 8AH[6Q,R714T7Q<V8QLZ9AX[V69\TV!VM%-KL$]GCD!?
XMACA7;2--8AA";2!36 L^81%%:!A,F$U_7A-%30@V7QI(;B91;R=2:R-.8QM&
XM7AA%8AQ)8AQ)7!9#6Q9&;RI:8!U15A-'AT1YE%&&EU.+>#1L7R-:>3UTH&66
XM5QQ-5!D\-0 =6Q8ND$MCS7V-QG:&M69JQ79ZYJ2=Y:.<S9B)VZ:7RY>=UJ*H
XMJWM^OHZ1S**?SZ6BUJZHW+2NXK:NTJ:>S):-S9>.VIB1V9>0UXV'T8>!W()Y
XMVH!WW8A]Z).(ZYJ0[)N1[:.9]JRB[ZRB\J^E\;2J\K6K[[BL\;JN\+VP\\"S
XMZ[^M[<&O[L.S\,6U],6X]L>Z_,BT_,BT_\*O^;FFZYN5R7ESLT]CF#1(AQ=!
XM> @R4P@Z6@]!7A0^?#)<=R].U(RKTXRCP7J1B$)6;"8Z:2(]8QPW81@^:B%'
XM91M'91M';"1%:B)#:B)#;25&<"A);25&91Q 7A4Y7!,W7A4Y8!<[8QH^91Q
XMR%5KRE=MKDUEJ$=?@C13:AP[8QE#:!Y(:1Q/50@[70U!60D]CD-U9AM-7AE'
XM8AU+91U(;"1/:"!+7Q="7QE&8QU*8!I'7AA%:"-3:"-33PQ 71I.CTR!@3YS
XMB45]@#QT;C)I>CYUO(&R:S!A0 4H/P0GAD%9P'N3PG*"K5UMQWA\Z9J>WIR5
XMWIR5X:R=W*>8T)RBW:FONHJ-NHJ-Q)J7R)Z;UZ^IY+RVX+2LT:6=RY6,RI2+
XMU)*+T8^(SH1^R'YXWX5\XHA_Y9"%[)>,ZIF/Z9B.ZJ"6\ZF?\:ZD\["F\;2J
XM\K6K[[BL\+FM\;ZQ],&T[,"N[<&O[L.S\<:V]<:Y]L>Z_,BT_,BT_\.P_+RI
XM\:&;T(!ZN55IG#A,B1E#>0DS5@L]5PP^6Q$[>2]9;R=&R("?VI.JPWR3D4M?
XM;2<[91XY8!DT81@^:R)(91M'91M';25&:B)#:2%";"1%;R=(;25&9!L_7!,W
XM7Q8Z81@\9!L_9AU!9AU!MU5WJ4=I@R]2?"A+92!&6A4[>#9C@T%N60]#6 Y"
XM7A%$3@$T@SII@3AG>#9B7QU)81A&;"-19QY,7Q9$81I+7QA)7!5&9A]0<2M@
XM:2-82@<\7QQ1A4)W9R19>#1L<BYF6QE281]8J6F5?#QH/P 6=C--MVATR'F%
XMLEU<O&=FWX^)[IZ8TI>*W:*5X;FHU:V<T*RMTJZOLXR,I7Y^Q9:7T:*CY:ZM
XM[;:UX:.?V9N7U9&+U)"*V(Z(U(J$T85^T85^WXZ$XY*(YI:,Z)B.Y)>,Y)>,
XMYZ"5\:J?\;"C\K&D\K6I\K6I\+BJ\;FK]+VQ]K^S\+ZN\;^O[\.S\L:V\,JX
XM\<NY\\RT\\RT^\BL]\2H\:N;THQ\P%]JH4!+D1]!@0\Q60Y 408X71,]:B!*
XM<BI)KV>&WI>NQX"7E$YB;"8Z81HU7A<R81@^:R)(9AQ(9QU);"1%:B)#:2%"
XM:R-$;B5);"-'91Q"7A4[8!8^8QE!91M%91M%8QE%M%)TEC16<1U <Q]"9B%'
XM8AU#C4MX?CQI5 H^8AA,9!=*4@4X<"=6@3AG<S%=4A \;B53<RI89AU+8!=%
XM91Y/6Q1%6A-$<2I;:2-8<2M@5Q1)6QA-;"E>7!E.?3EQ7!A02 8_3 I#?S]K
XMCDYZ:29 KFN%PW2 KE]KO&=FY9"/Y)2.U(1^V9Z1Z*V@UZ^>V[.BVK:WS*BI
XMK8:&F7)RS)V>X+&RZ+&PX*FHSY&-S(Z*T(R&T8V'U8N%THB"U8F"VHZ'XI&'
XMY92*YI:,YY>-Y)>,YYJ/ZZ29\ZRA\*^B\K&D\K6I\[:J\+BJ\+BJ\KNO]+VQ
XM[[VM\;^O[\.S\<6U[\FW\<NY\\RT\\RT_<JN^\BL^;.CW):&RFETJTI5FRE+
XMBQD[7Q1&4@<Y8AA"81=!?#13F5%PWI>NTXRCEE!D;"8Z8!DT7A<R8AD_:R)(
XM9AQ(:1]+:R-$:R-$:R-$;"1%:R)&:!]#9!M!7Q8\8!8^8AA 9!I$8AA"7A1
XMBS9F<AU-91Q*;B5351E&2P\\@41V7!]16A1)91]48QA*7A-%5Q$^9R%.8B%*
XM82!)@#=E>"]=7A5$6Q)!9R!36A-&6A-(?C=L7!9,<"I@8A]47QQ171I.7!E-
XMD$V!6A=+3 0[4PM"8QM"G%1[IEQLPGB(N&9CN6=DVX5W\9N-W8Y^SG]OTYZ/
XMX:R=SZZ>U[:FTK:RR*RHO).3HGEYV:&CYJZPZZ.FW968U(*%TH"#UX* VH6#
XMV8>"V(:!VHJ$WX^)X9.-Y):0YIF0YIF0Y)N.Z)^2ZZ:8[ZJ<[ZV>\:^@]+6G
XM];:H\K>J\K>J\[BM]+FN\[NK]+RL[\&R\L2U[<FW[LJX[LVS[LVS]\NM]\NM
XM^KFDX)^*TG)WLU-8HS)+DR([819(6 T_8!9 8!9 @#A7BT-BUH^FX)FPFE1H
XM;RD]8QPW81HU9!M!:R)(9AQ(:B!,;"1#;B9%;R=(;25&:!]#8QH^8!8^7Q4]
XM81=#8QE%9!E(819%6Q!"?"=7;QI*="M9=BU;2P\\0@8SD%.%;S)D8AQ19!Y3
XM71)$:1Y030<T61- 9R9/CTYWB4!N=BU;4PHY4PHY9A]26A-&7!5*AT!U5Q%'
XM9R%78R!5:29;71I.71I.GEN/:"591P V5 Q#2@(ICT=NO'*"KF1TI5-0VHB%
XM[YF+V()TUXAXX)&!Q9"!TYZ/VKFITK&AR:VISK*NU:RLLHF)V:&CV:&CWI:9
XMUX^2VXF,UX6(VH6#W8B&WHR'W(J%W(R&X)"*XY6/YYF3Z)N2Z)N2YIV0Z:"3
XMZ:26Z:26[JR=\:^@\[2F]K>I\K>J\;:I\K>L\K>L\KJJ\[NK[\&R\<.T[,BV
XM[LJX[<RR[LVS]<FK]LJL^[JEXJ&,U'1YM55:IC5.EB4^7!%#60Y 5@PV71,]
XM>C)1@#A7R(&8Y)VTG5=K<BQ 9A\Z9!TX91Q":R)(91M':R%-;25$<"A'<BI+
XM;R=(9AU!8!<[7A0\7A0\9!I&9AQ(9QQ+8A=&7!%#7Q1,<RA@D5&%8"!4.0(S
XM4AM,?T9X=CUO92)640Y"8QE+7A1&;"A4=C)>BTUU>CQD>#!;715 50P[8AE(
XM8AM.5Q!#9Q]6A3UT40M!9!Y4FUB-7!E.6A=)>#5G:BA551- 5P<S7P\[=RY*
XMJV)^G558CT=*T85WZ9V/X)!\XI)^V9%^THIWQI2$U:.3UK.FV+6HPYN5Y;VW
XMU)^>SIF8YJ&CVI67X8N1VX6+XX**YH6-ZHJ-Z(B+XH>'XXB(Y(V,Z9*1YY:4
XMZIF7[IZ8[IZ8Z)N0Y9B-Y)Z.ZJ24ZJ65[JF9\;"A]+.D\K:G\K:G\;2J\K6K
XM\[FG]+JH\KVP]+^R\,6V\\BY]<NV]LRW^,>M^,>M_[JI[*:5VWM^MU=:IS=.
XMG"Q#7Q1&5PP^6Q$[5PTW<2E(?354O7:-X9JQL&I^;2<[>C-.81HU;"-)="M1
XM:R%-:R%-:2% ;R=&<BI+;25&91Q 8!<[8QE!:1]'81=#:1]+8A=&6 T\7!%#
XM:A]7;"%9C$R 515)3QA)1Q!!CE6'?D5W5!%%30H^81=)8AA*=3%=>#1@@4-K
XM=#9>:"!+715 6 \^7!-"719)6Q1'8QM2;R=>30<]8AQ2A4)W7QQ17AM-?SQN
XM92-07QU*8A(^8! \NW*.O'./A3U PWM^]ZN=TX=YY96!ZIJ&X9F&U(QYPY&!
XMTZ&1U+&DUK.FX[NUW;6OTYZ=Z[:U[JFKL6QNL5MAQ6]USVYVU71\WW^"Z(B+
XMZ8Z.Z8Z.Y8Z-Y(V,YI63ZIF7[9V7[IZ8[)^4[:"5ZJ24ZJ24Z:24[:B8\*^@
XM\[*C\;6F\+2E\+.I\+.I[[6C\[FG\[ZQ]<"S[L.T[\2U\LBS]<NV^\JP_,NQ
XM_\*Q^+*AY(2'M558ER<^@1$H7A-%50H\60\Y60\Y;R=&>#!/M6Z%Y)VTN'*&
XM=S%%=2Y)9!TX;B5+<"=-:R%-:1]+;25$<2E(<BI+;25&9!L_7A4Y81<_91M#
XM8QE%:B!,8QA'7A-"9AM-=2YK>S1Q?3]W2@Q$4AQ/4AQ/G&.5=SYP4 T_4@]!
XM7A5$7Q9%;2M79B107R9,7B5+61$X7A8]7A5#6A$_6Q1'91Y1:2%891U44PU#
XM;RE?AD-U7!E+;"I6>#9B7AU$4A$X;A<PH4ICR7Z*I%EEI61?YJ6@Y*:3S8]\
XMX)R(YJ*.W9N*S(IYQ(V"V:*7X+2LX;6M[ZVH\:^JY)F9SH.#KEA<BC0XFSI"
XMJ4A0P%ECPEMER&%KTFMUW'B!YH*+ZXJ2[HV5[Y:;])N@])N<[Y:7[)B1\9V6
XM[:&2YYN,ZJ*/[J:3[ZV<\[&@\;*D\+&C[;"F[;"F\;6B]+BE];JM]+FL\;BP
XM\KFQ^+VR_,&V_+>I][*D^:B>[)N1V7:!L4Y9DB,]?@\I7A-%4@<Y5PTW6Q$[
XM;"1#<2E(IV!WYI^VPGR0AT%5;29!9R [<BE/:R)(;2-/:!Y*<2E*<RM,<BI+
XM:R-$8AD]710X7Q8\8AD_81<_91M#7A0^7Q4_;2-/?SAUF%&.9REA20M#1Q%$
XM=3]RH6B:92Q>4Q!"6A=)7!-"7!-"9B106QE%4!<]721*5P\V7Q<^8AE'711"
XM7A=*:2)5<RMB=2UD61-)>#)HBD=Y5A-%=3-?7QU)5A4\20@OD3I3T7J3FU!<
XMFD];X)^:XJ&<TY6"X**/[:F5ZZ>3V):%Q8-RQ8Z#WZB=Y;FQXK:N[ZVH\K"K
XMW)&1J5Y>DCQ HTU1NUIBJTI2M4Y8KD=1I3Y(HCM%J45.NU=@SVYVW7R$ZI&6
XM]9RA]YZ?[Y:7Z)2-[IJ3Z)R-XY>(YY^,ZZ.0[:N:\:^>[["B[J^AZZZDZZZD
XM\;6B\+2A\+6H\;:I\[JR]KVU^\"U_,&V_\.U\JV?X(^%R7ANN59AFC="AQ@R
XM>PPF7A-%4@<Y5@PV7!(\:" _;"1#F%%HZ*&XRH28EE!D:"$\:2(]<RI0:B%'
XM;R51:B!,<BI+<BI+;B9':"!!81@\7A4Y7Q8\8AD_9!I"8AA 6A Z7Q4_="I6
XMAC]\D$F&4A1,3 Y&6B-4A$U^H&64:B]>30@X6!-#6Q)!9QY-;"Q792506"-*
XM;SIA91Y!81H]7A8_7A8_6Q5#7QE'<"E>@SQQ:")7>C1I;2M89B11:2A-2PHO
XM3P\N<3%0T'1XO&!DGE91SH:!V:27SIF,WK"AVJR=[[ROWZR?S9&(P85\T96.
XMZJZG[K:RY*RH_Y^=W'MYRF=HS&EJU7)UWGM^V')YRF1KP5ECMDY8HSI(DBDW
XMBB QD2<XH#9)K4-6RF-PWWB%\(Z4]9.9\I:2])B4[IN,ZI>(Y9J&ZZ",[JB7
XM\ZV<\*^B[ZZAZJRDZ:NCZ["9[+&:\;&F][>L_[JW_[>T^ZBI\9Z?W86$Q6UL
XMM%)6JDA,H#M,CRH[A!@X@14U819(50H\5PTW7!(\91T\:R-"BD-:YI^VS(::
XMH5MO:2(]:"$\<2A.;R9,;R51;B10<BI+;B9':B)#9!P]81DZ8!@Y8AD]8QH^
XM;"-'9AU!710X9AU!?S9:AT!]:B-@3A!(61M3?TAY;C=HCE."A4IY200T4@T]
XM711#=BU<;2U89B916"-*;3A?>S1791Y!6! Y61$Z5 X\40LY81I/>3)GA#YS
XMBD1Y4 X[@D!M4Q(W2@DN61DXIV>&V'R J4U1T8F$[*2?QI&$UJ&4W[&BX;.D
XMYK.FT)V0Q(A_RHZ%XJ:?\K:OZ;&MVZ.?U71RO5Q:Q6)CUW1UXG^"W'E\TVUT
XMYH"'WW>!UFYXQ5QJLDE7H#9'DRDZC"(UBB SE2X[K493S&IPYX6+\)20\961
XMZ9:'Z)6&XI>#Z)V)[*:5\JR;\*^B[ZZAZJRDZJRD[;*;[;*;\+"E\+"E[:6B
XMV9&.Q7)SL5Y?G$1#D3DXES4YJ$9*L4Q=J415HC96H35591I,7!%#6A Z6Q$[
XM81DX;B9%?SA/X9JQRX69IV%U<BM&9!TX:B%'>"]5:R%-<BA4<2E*;"1%91T^
XM81DZ81DZ8AH[9!L_91Q :B%%91Q 7Q8Z;"-'B4!D?C=R71917Q]5>3EOA4U]
XM5AY.;#!=F5V*5Q) 51 ^8!=%?#-A7B!*5AA"3!@_7BI1C49G;RA)5@XU5 PS
XM50\\4PTZ6!%$8QQ/>S9HC4AZ5A4^=C5>2@HK514VA49@MG>1P6-:T7-JZJ.6
XMX)F,R9V-VJZ>S*F<XK^RTZJAOI6,P8F%UIZ:[["OZ*FHSXZ-O'MZQE%0SEE8
XMW&MLU&-DSV1ER%U>NU-9X7E_YX"*VW1^RV%RP5=HO$YBLT59IS9/G"M$EB@X
XMGC! M$Q4UFYVY82"YX:$X8M]Y8^!X9. Z)J'ZZ62\JR9\*^B\*^B[*ZFZZVE
XM[[:<[+.9ZJ>;VYB,SWQ_M6)EJ4=/G#I"NE):L$A0M4I5Q5IEQEUUMTYFICUB
XMHCE>:1Y09!E+7A0^60\Y7Q<V="Q+>3))VY2KRH28K&9Z?C=28!DT8AD_@3A>
XM9!I&<BA4<RI.:R)&8QH^7A4Y8!@Y8QL\9!P]9!P]8QLZ81DX81DX=BY-E4UJ
XM<BMF;29A<C)HE56+;C9F3Q='31$^F5V*9B%/6A5#8!=%?#-A4A0^3Q$[3AI!
XM82U4F%%R=S!161$X4PLR6Q5"7AA%61)%50Y!3 <Y>#-E:"=020@Q2@HK7Q]
XMMWB2IVB"O%Y5]YF0X)F,WI>*UZN;UJJ:XK^RX+VPV*^FQ)N2SI:2Y:VI[["O
XMSY"/HF%@B$=&P4Q+N41#O$M,OTY/R5Y?L49'B" FJ4%'TVQVOUABK$)3J#Y/
XMMDA<P%)FODUFMT9?O$Y>KT%1KT=/RF)JVGEWWGU[W(9XY(Z WY%^YYF&ZZ62
XM\JR9\;"C\;"C[:^G[:^GZK&7YJV3WIN/QH-WN69IJ599L$Y6LU%9M4U5I3U%
XMHSA#K4)-JD%9G#-+D2A-DRI/:R!2:1Y08!9 5PTW7A8U>#!/=S!'V)&HRH28
XMKVE]AT!;7A<R7!,YASYD7A1 <2=3=2Q0;"-'8AD]710X7Q<X8QL\8QL\8AH[
XM81DX8QLZ:2% @CI9HUMX6B):>D)Z92E@FU^6:2E<0P,V5Q9%=C5DB41T3@DY
XM6AA'A$)Q5!-$3PX_41%$6QM.?#9KEE"%8!U1208Z6AM+4Q1$5!9 5QE#41$T
XM6AH]7!0Q6A(O6PHAJUIQRW6'IU%CV9.#WIB(WYV,XZ&0Y:V;\;FGZKZLY+BF
XMU:B<S)^3Z:ZO[K.TR76&ED)3F#%/G394BS-2H$AG?B%$=QH]A"=-?B%'70DL
XM@2U0B#I;:1L\:QDY:1<WDS%1N5=WNTIMPU)URE1=R5-<O5I=PV!CU&IMWW5X
XM\79_]'F"X7]]])*0VZ:5X*N:[L&M[<"L\:R>]*^A_JFHZY:5WHN8RWB%M6.
XML%Y[<2! B3A8<R$^:QDV;!<P=2 Y@"-&@"-&@"!,@B).=BM09QQ!7!$Y4 4M
XM7Q0\>S!8=RY+V(^LUX^CGU=KDDI>:B(V9!HZ>"Y.:Q],=2E6="-';!L_8A<^
XM818]7AA%7AA%71M'81]+81Q"51 V:1TXEDIEOFUZ7R=??D9^<35LH&2;:2E<
XM104X6!=&=S9E;BE97!='6QE(DE!_3 L\511%3 P_3@Y!9!Y3G%:+AT1X8A]3
XM41)"3 T]5QE#5AA"5!0W2@HM6! M10 :A31+P7"'M%YPO6=Y\:N;ZJ24X)Z-
XMX)Z-XJJ8[K:DZKZLY[NIVJVAW*^CX*6FN7Y_DCY/@2T^D2I(B2) ?"1#;Q<V
XM;Q(U?B%$:@TS<A4[9Q,V8 PO9QDZ60LL8A P91,S<Q$Q@B! L#]BY'.6U%YG
XMT5MDPE]BQF-FTVELW7-V[W1]\79_Y8.!\8^-W:B7YK&@Z+NGY;BD];"B_KFK
XM_*>F]Z*AKUQIDC],?"I'<R$^=21$8A$Q9!(O9!(O;ADR=2 Y>AU =QH]>QM'
XM@2%-;B-(8Q@]7A,[4P@P8!4]>2Y6<BE&THFFW)2HI5UQE$Q@<"@\9QT]>C!0
XM;"!-="A5<B%%:QH^818]818]7AA%7AA%7!I&8!Y*71@^4PXT;" [G%!KQ'.
XM:C)J@4F!?D1[GF2;92A:1@D[61A'=C5D6A5#<BU;7QU*GER)3 L\7QY/4Q)#
XM3 L\40PZ>C5CD4]^EE2#=31E3@T^3PX]6!=&61@_2PHQ40HE8!DTP'*#OG"!
XMMF9NYI:>Z)V1XI>+T9^-W*J8W+VDX,&HX;FHW;6D^;*OZJ.@U':%G3].=!@L
XM=QLO>",[:10L9 XN;!8V80LK:Q4U81 P:!<W6A<R;"E$B4QD>SY6:",Y6A4K
XM6 860 9D"5 MDMFVV-MV&!JRF-ES&5GTV=KVFYR['!Y[G)[ZH6&[8B)X*F;
XM[;:HYKFEY[JF_[FN_[RQZYF?JEA>CCQ/;QTP9Q8V9A4U8A0U<R5&>"A$;Q\[
XM:18O:A<P<A<Y=!D[=QE$>AQ'9!D^7Q0Y8!4]6 TU8A<_=RQ4;"- RX*?WY>K
XMJF)VD4E==BY":B! >S%1:Q],<252;!U!9A<[7Q0[818]7AA#71="71E%81U)
XM610Y51 U=2I"J%UURWN%>D)Z@DJ"ATV$E%J17B%32PY 6!=&;RY=5 \]=C%?
XM6QE&F5>$7!M,7QY/6QI+4 ] 3PHX6!-!>#9EEE2#A$-T9R977AU,511#2PHQ
XM20@O10 9EU!KRGR-F$I;SW^']*2LWY2(W)&%TZ&/X[&?X<*IX,&HW[>FW+2C
XM^+&NQG]\H4-2BBP[?" T<Q<K:10L9Q(J:Q4U>B1$:1,S:!(R7PXN:ADY:"5
XMD4YIS9"HS9"HGUIP=C%'9@TF7P8?B!TX@A<RU%QFU%QFR6)DS&5GTV=KV&QP
XMZ&QUZFYWYH&"ZH6&X:J<\+FK[+^K]\JV_\&V[ZB=KEQB8A 6=R4X8Q$D;1P\
XM?RY.@C15I%9WM66!DD)>;!DR7@LD;!$S>!T_>!I%<1,^8!4Z7A,X8A<_6Q X
XM8QA =2I2:2 ]R'^<WI:JK&1XBT-7>S-';")"?#)2:Q],;2%.:!D]8Q0X7Q0[
XM8A<^7QE$7AA#7!A$7QM'6!,X71@]@SA0M&F!T("*BE.-?TB"BE"'A4N"51A*
XM4!-%5Q9%9"-240PZ8QY,5A$_BD5S?#IG6QE&6QI)3@T\5A,X6Q@]:"1071E%
XM6!5'>#5G>S5J4@Q!4PTX5 XY9B$YP'N3KF9MJF)I\:FDYIZ9YZ6=Y**:TZ^=
XMV;6CU,&IUL.KZ+NMZ[ZPX7^'L$Y6FATVF1PUBB$Y=PXF6A,D:B,TC#13=1T\
XM<B ]?BQ)3PDD9B [<S]2<S]2T*6RZ+W*U9ZJK'6!C3E(<1TLFC!%GC1)RDM5
XMS4Y8Q5E=S&!DU&1IV6ENZ&=TZFEVY'I][H2'XZN=\+BJ]<2T_]7%_;.KP7=O
XM;!PL:QLK9!0N5P<A8A,W>2I.MF>+IE=[WI&LLF6 ?RY&8A$I9Q$Q<1L[<AE
XM:Q(Y818[7Q0Y8QA 7!$Y9!E!=2I2:B$^R'^<WI:JKV=[A3U1@CI.<"9&@#96
XM;B)/;2%.91@]810Y7A4[8AD_8QM$8!A!7!<_7AE!718W;29'EDMAO7*(SW^'
XMEE^9?$5_D5>.?$)Y3Q)$51A*5Q9%7!M*5A$_4PX\6!-!>S9DF5>$8!Y+61A'
XM3@T\6Q@]5A,X8!Q(3PLW10(T8A]191]44 H_81M&81M&FU9NMW**FU-:Y9VD
XM^K*MTXN&VYF1XZ&9V;6CX+RJV\BPV\BPX[:HV*N=KTU5I4-+I2A!FATVA!LS
XM= LC718G="T^FT-BD3E8?"I'A#)/;RE$>#)-9C)%:35(W;*_Y[S)[[C$X*FU
XMOVMZBC9%HCA-O5-HP$%+Q490P%18R%Q@T6%FUF9KYF5RZFEVXWE\](J-Y:V?
XM\;FK^\JZ_\Z^WI2,F$Y&>2DY<R,S?"Q&<2$[;1Y">"E-DD-GH5)VWY*MP72/
XMF$=?<B$Y90\O9Q$Q;!,Z;!,Z8Q@]7Q0Y8QA 71(Z9AM#=RQ4:B$^QGV:XIJN
XMM6V!@SM/BT-7=BQ,A3M;<B93;B)/9!<\8A4Z8!<]91Q"91U&81E"6Q8^6Q8^
XM81H[?C=8J%USP7:,RGJ"EV.<>$1]G66;?$1Z3A-$6!U.5A5$6!=&81U)4P\[
XM6Q=!:"1.FU>#:R=361=#61=#6QDX2@@G7QM#81U%5Q!!40H[2@ T6A!$6Q$[
XM=2M5HUYRDTYBI&-BXZ*ATI2!QHAUOI>+SZB<V[BIY,&R[\2WZ+VPVY.0MV]L
XMK4)-ND]:O4-9L#9,FS!'A1HQ;1<K?2<[HS]=OEIXD351A2E%A3U4A3U4:SA&
XMH&U[],K1Y+K!]K[#[[>\W8:0JU1>J#9&P$Y>PT%,R$91PE)7QU=<SUMAUF)H
XMYV1R[6IXYWN!^X^5[+"G^[^V_]'$[KVPPWATD49"J5IN>BL_DT-ADD)@B#9=
XMB#9=<B%%Q'.7W(NEQG6/GTYE=R8]9A N9 XL:1(X:A,Y818[71(W818^7A,[
XM:1Y&>B]7:!\\P'>4Y9VQNG*&@3E-D4E=>2]/ACQ<<252:Q],8Q@_818]81@^
XM9QY$9Q]&81E 7!4Z6Q0Y9!PYC$1AMVM^P76(PG1YEV.<>$1]J'"F@4E_3Q1%
XM6A]05A5$5Q9%:B925Q,_5A(\4P\YAD)N:R=351,_8B!,5Q4T5!(Q9B)*6!0\
XM4@L\6A-$4PD]7Q5)71,]GE1^HEUQE5!DUY:5S8R+Q8=TXJ21VK.GX[RPX;ZO
XMW+FJX[BKV:ZAP'AUCT=$Q%EDR5YIS5-IT%9LPE=NG#%(;QDM=R$UJD9DMU-Q
XMH45AD3519AXU>S-*FF=UVJ>UZ\'(XKB__\?,ZK*WW(6/OVARM$)2Q5-CRDA3
XMS$I5PU-8Q55:S%A>TU]EYV1R[VQZZ7V#_I*8\+2K_\G _]C+X*^BMVQHGU10
XMN&E]JUQP@C)0D4%?B3=>B#9=I%-WYI6YXY*LQ72.ET9=<2 W9Q$O:A0R:A,Y
XM90XT7Q0Y6Q U8!4]7Q0\;"%)?#%99ATZNW*/Y9VQO'2(?C9*DDI>>"Y.A#I:
XM;2%.9AI'9!E 8A<^8QI :!]%:"!'8AI!7!4Z6A,X9!PYDTMHOG*%P'2'O6]T
XM@4^'<D!XFF29B%*'6A]0829771U)20DU8Q])6Q=!6!,[7AE!8AU%81Q$81U'
XM9B),6Q@Z30HL71@^9B%'5@PX5 HV8Q5 7 XYASI;Q'>8CTQ7Q(&,W*.9R9"&
XMUJ*+VZ>0U,&QT+VMYK"I[[FR]IJ>NEYBKD%+T61NOEICQ&!IR&ETS&UXS65W
XMO%1FKCM3GRQ$MD=AOD]IQ5]VP5MRM%MPS'.(XI^J]+&\]+S!\+B]];&UXY^C
XMVGF#S6QVUUYLRU)@XUYHUE%;Q%)8S%I@TUUDTUUDX%UKZ69TYWR#_)&8\[JR
XM_]#(_]3)UJ><JF%AB#\_L6%SN6E[N&6 H4YIFD9GOFJ+Z9&P\9FXYY&EP&I^
XME3]1<!HL;A<Q<1HT9@XP=!P^8Q@]7!$V9AM#9!E!=BM3="E1:R(_K&. V9&E
XMU...@CI.A3U1BD!@?#)2;B)/9AI'6A$W8AD_7A4[6Q(X9!U"9A]$7Q<X714V
XM;R<^H%AOOW2 NF][NFUNFVFA41]7QY'&EV&6>3YO3A-$<#!<71U)6A9 5! Z
XM5 \W6A4]7QI"7QI"7QM%8Q])618X71H\9R)(5A$W40<S50LW5PDT;1]*OG&2
XMG$]PJVAS\*VXUIV3PXJ WZN4XZ^8V,6UT\"P\KRUU)Z7LU=;L559T61NPE5?
XMPU]HQV-LRFMVSW![U&Q^RV-UQ5)JNTA@L$%;N4IDQF!WSFA_QVZ#UWZ3VI>B
XMVI>BYJZSXZNP[:FMY:&EY82.VGF#WF5SRU)@WUIDUE%;QU5;SEQBTUUDTEQC
XMWUQJZ69TZ'V$_9*9\KFQ_\O#_L_$W:ZCPWIZL&=GI55GM65WQ7*-PF^*PV^0
XMVH:GZ)"OV8&@OVE]HDQ@AS%#<QTO>B,]?B=!;14W=!P^8Q@]71(W9QQ$9AM#
XM=RQ4<RA0:2 ]J%]\VI*FUX^CBT-7A#Q0CD1D>2]/;R-091E&7A4[81@^710Z
XM7A4[9A]$91Y#8AH[:"!!@CI1K&1[PWB$NF][NVYOJGJS:#AQO(B_?TN"=CYN
XM?$1T<3%=5!1 5Q,[5! X51 V610Z71@^7!<]7!<]7AD_6AA$8R%-9Q](4 @Q
XM50@M5 <L6PLGF4EEOW.$D$15TI"1\:^PRY:)U)^2YKNDX;:?XL"U[,J_Z):9
XMJUE<MS='S$Q<W%MIV5AFR6ELS&QOPW1TR'EYUG-^U'%\Y&-XWUYSQE=FO4Y=
XMNTU=NTU=MU)CQ6!QQF][P&EUM&IRN&YVS7V#W(R2[8F2\8V6]X"-Y&UZUU5>
XMU%);RUE?T5]ETEYDSUMAW5QJYV9TXGJ"^9&9\;FS_\O%^\_'XK:NU9"1SHF*
XMSG>!SG>!T':)QVV PF5^R&N$P6%VI$19GCQ*CBPZAB<T@B,PCS!'D3))>!<[
XM>!<[8A<\71(W:!U%:!U%>"U5<B=/91PYI%MXVI*FV)"DFE)F...@CI.D4=G="I*
XM;B)/8A9#8AI!7Q<^6Q,Z8QM":B%%8AD]91PY>"],FE!DMVV!PGB N6]WO7!O
XMF&BAE&2=H6VD<CYUC56%FV.35Q=#2PLW7!A 6Q<_6Q8\71@^71@^6Q8\6A4[
XM6A4[7QU)7QU)50TV5P\X6 LP3P(G?BY*P'",G%!AK&!QX9^@TY&2V*.6WJF<
XMW+&:ZK^HX\&VRJB=K5M>D3]"RTM;U55ETU)@YF5STG)UTG)UQWAXR7IZV'6
XMUW1_Z6A]YF5Z['V,UF=VQ%9FNTU=LDU>OEEJPFMWOF=SJV%IKV5MQ75[TH*(
XMXW^(YH*+['6"VF-PU%);UE1=T5]EU6-ITU]ESEI@W%MIY61RVW-[]HZ6\;FS
XM_\W'_]3,YKJRVI66TXZ/TGN%QW!ZOF1WLUELL%-LMUISM%1IG#Q1D"X\C"HX
XMD#$^D3(_F#E0DS1+=A4Y=Q8Z7Q0Y6Q U:1Y&:1Y&>2Y6<B=/9!LXH5AUV9&E
XMV)"DJ&!T@#A,D$9F;R5%:Q],8!1!8QM"714\7!0[:2%(;21(710X9!LX@CE6
XMJ%YRN6^#O7-[MVUUP'-R>$J"CF"8I'*HE&*8LGJJ<#AH4! [7AY)6Q<_71E!
XM8!D^7Q@]7Q@]7A<\718[7!4Z6A=,7AM02@$O6 \]504C7P\MLV)OQ'. I%=6
XMS8!_UY>.T)"'Y;2GT:"3U["@\<JZ[)J?HU%6GC,^N$U8SDU;UU9DY&5OX&%K
XMVW1TVW1TTGIWU'QYVWI\VGE[WG!XW&YVW7I[T6YOTFMOT6INSF9NTVMSTW)\
XMSVYXS'A_S7F UX.*V86,V7N$V7N$W75]SV=OU%);VEAAU65JUF9KT5]ES5MA
XMVEIHXF)PVG9]\(R3Y[.N_LK%_]?/Z<&YW)J=TI"3U'=VS7!OS&MSR6APQ6!M
XMR&-PR%UHM4I5I#@^I3D_JT-+IS]'I#Q0F#!$>Q,U@1D[7!$V60XS:!U%:1Y&
XM>B]7<B=/8QHWGU9SUX^CVI*FLFI^?S=+B3]?;")"9AI'8!1!8!M#610\714\
XM;"1+;25&61$R9!@SBS]:LF9WNV^ N6UQN&QPPG=S<D1\A%:.D%Z4I7.IB%"
XM:3%A:"A39B9151$Y614]7A<\7!4Z6Q0Y7A<\8!D^7Q@]4@]$8A]440@V3P8T
XM504CA#12SGV*JEEFMFEHX).2VIJ1W)R3V*>:XK&D_-7%UJ^?JEA=DT%&HSA#
XMND]:U51BV%=EWV!JYF=QW'5UW79VUGY[V8%^X8""X8""YGB Y'9^UW1UT&UN
XMUW!TW'5YUFYVUFYVV'>!UW: U("'U8&(W8F0WHJ1WH")XH2-[(2,XWN#V5=@
XMWUUFV&AMUV=LTF!FSEQBVEIHWU]MX'R#[XN2X*RG]L*]_=7-[L:^YJ2GW9N>
XMZ8R+X(."W7R$UG5]RV9SQV)OR5YIOE->MTM1MTM1NE):L4E1JD)6FS-'@!@Z
XMAQ]!71(W60XS:!U%:1Y&>2Y6<"5-81@UG%-PU(R@WI:JN'"$@CI.?C14;B1$
XM815"8Q=$71A 610\7A8]:R-*:2%"5@XO:!PWE$ACN6U^O'"!N&QPNFYRQGMW
XM@5.+?E"(<#YTBEB.<CIJA4U]9RE361M%51 X6Q8^7A<\6A,X6A$U7Q8Z8AL^
XM81H]6!-271A77!%!3@,S=",[L6!XP&YQHE!3R7YRZZ"4X:*2Z*F9U*68]<:Y
XM[\O"DV]FGB TP$)6OD53O412U%]HTUYGRUI=Y'-VZ'1VZ'1VYGEYZGU]YX6#
XMZ8>%X(B%WX>$Z).(WHE^Y82"YX:$XGM_XGM_ZX>0[XN4ZY.:Y8V4XY&7X8^5
XMVX>-VX>-W8&'S7%WWEYFXV-KV6QPUFEMTF)GSU]DV%MHVUYKW7N![8N1W*RF
XM\L*\^];-[\K!Z*JLX:.EZXR!WX!UW7AWV'-RTF9MT65LV&AMUF9KR5A9Q%-4
XMQ55:NTM0M4=;ISE-AQL\B1T^818[71(W:1Y&:1Y&=RQ4;2)*7A4RF$]LTXN?
END_OF_FILE
if test 32510 -ne `wc -c <'timg.ppm.u.a'`; then
echo shar: \"'timg.ppm.u.a'\" unpacked with wrong size!
elif [ -f timg.ppm.u.b ]; then
echo shar: Combining \"'timg.ppm.u.a'\" and \"'timg.ppm.u.b'\"
cat timg.ppm.u.a timg.ppm.u.b > testimg.ppm.u
echo shar: Removing \"'timg.ppm.u.a'\" and \"'timg.ppm.u.b'\"
rm timg.ppm.u.a timg.ppm.u.b
echo shar: Uudecoding \"'testimg.ppm.u'\"
cat testimg.ppm.u | uudecode
if [ -f testimg.ppm ]; then
echo shar: Removing \"'testimg.ppm.u'\"
rm testimg.ppm.u
fi
fi
# end of 'timg.ppm.u.a'
fi
echo shar: End of archive 7 \(of 18\).
cp /dev/null ark7isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: SETUP jdarith.c timg.ppm.u.b
# Wrapped by kent@sparky on Mon Mar 23 16:02:44 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 8 (of 18)."'
if test -f 'SETUP' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'SETUP'\"
else
echo shar: Extracting \"'SETUP'\" \(18117 characters\)
sed "s/^X//" >'SETUP' <<'END_OF_FILE'
XSETUP instructions for the Independent JPEG Group's JPEG software
X=================================================================
X
XThis file explains how to configure and compile the JPEG software. We have
Xtried to make this software extremely portable and flexible, so that it can be
Xadapted to almost any environment. The downside of this decision is that the
Xinstallation process is not very automatic; you will need at least a little
Xfamiliarity with C programming and program build procedures for your system.
X
XThis file contains general instructions, then sections of specific hints for
Xcertain systems. You may save yourself considerable time if you scan the
Xwhole file before starting to do anything.
X
XBefore installing the software you must unpack the distributed source code.
XSince you are reading this file, you have probably already succeeded in this
Xtask. However, there is one potential trap if you are on a non-Unix system:
Xyou may need to convert these files to the local standard text file format
X(for example, if you are on MS-DOS you probably have to convert LF end-of-line
Xto CR/LF). If so, apply the conversion to all the files EXCEPT those whose
Xnames begin with "test". The test files contain binary data; if you change
Xthem in any way then the self-test will give bad results.
X
X
XSTEP 1: PREPARE A MAKEFILE
X==========================
X
XFirst, select a makefile and copy it to "Makefile" (or whatever your version
Xof make uses as the default makefile name; for example, "makefile.mak" for
Xold versions of Borland C). We include several standard makefiles in the
Xdistribution:
X
X makefile.ansi: for Unix systems with ANSI-compatible C compilers.
X makefile.unix: for Unix systems with non-ANSI C compilers.
X makefile.mc5: for Microsoft C 5.x under MS-DOS.
X makefile.mc6: for Microsoft C 6.x under MS-DOS.
X makefile.bcc: for Borland C (Turbo C) under MS-DOS.
X makefile.pwc: for Mix Software's Power C under MS-DOS.
X makefile.manx: for Manx Aztec C on Amigas.
X makefile.sas: for SAS C on Amigas.
X makefile.mms: for VAX/VMS systems with MMS.
X makefile.vms: for VAX/VMS systems without MMS.
X
XIf you don't see a makefile for your system, we recommend starting from either
Xmakefile.ansi or makefile.unix, depending on whether your compiler accepts
XANSI C or not. Actually you should start with makefile.ansi whenever your
Xcompiler supports ANSI-style function definitions; you don't need full ANSI
Xcompatibility. The difference between the two makefiles is that makefile.unix
Xpreprocesses the source code to convert function definitions to old-style C.
X(Our thanks to Peter Deutsch of Aladdin Enterprises for the ansi2knr program.)
X
XIf you don't know whether your compiler supports ANSI-style function
Xdefinitions, then take a look at ckconfig.c. It is a test program that will
Xhelp you figure out this fact, as well as some other facts you'll need in
Xlater steps. You must compile and execute ckconfig.c by hand; the makefiles
Xdon't provide any support for this. ckconfig.c may not compile the first try
X(in fact, the whole idea is for it to fail if anything is going to). If you
Xget compile errors, fix them by editing ckconfig.c according to the directions
Xgiven in ckconfig.c. Once you get it to run, select a makefile according to
Xthe advice it prints out, and make any other changes it recommends.
X
XLook over the selected Makefile and adjust options as needed. In particular
Xyou may want to change the CC and CFLAGS definitions. For instance, if you
Xare using GCC, set CC=gcc. If you had to use any compiler switches to get
Xckconfig.c to work, make sure the same switches are in CFLAGS.
X
XIf you are on a system that doesn't use makefiles, you'll need to set up
Xproject files (or whatever you do use) to compile all the source files and
Xlink them into executable files cjpeg and djpeg. See the file lists in any of
Xthe makefiles to find out which files go into each program. As a last resort,
Xyou can make a batch script that just compiles everything and links it all
Xtogether; makefile.vms is an example of this (it's for VMS systems that have
Xno make-like utility).
X
X
XSTEP 2: EDIT JCONFIG.H
X======================
X
XLook over jconfig.h and adjust #defines to reflect the properties of your
Xsystem and C compiler. (If you prefer, you can usually leave jconfig.h
Xunmodified and add -Dsymbol switches to the Makefile's CFLAGS definition.)
X
XIf you have an ANSI-compliant C compiler, no changes should be necessary
Xexcept perhaps for RIGHT_SHIFT_IS_UNSIGNED and TWO_FILE_COMMANDLINE. For
Xolder compilers other changes may be needed, depending on what ANSI features
Xare supported.
X
XIf you don't know enough about C programming to understand the questions in
Xjconfig.h, then use ckconfig.c to figure out what to change. (See description
Xof ckconfig.c in step 1.)
X
XA note about TWO_FILE_COMMANDLINE: defining this selects the command line
Xsyntax in which the input and output files are both named on the command line.
XIf it's not defined, the output image goes to standard output, and the input
Xcan optionally come from standard input. You MUST use two-file style on any
Xsystem that doesn't cope well with binary data fed through stdin/stdout; this
Xis true for most MS-DOS compilers, for example. If you're not on a Unix
Xsystem, it's probably safest to assume you need two-file style.
X
X
XSTEP 3: SELECT SYSTEM-DEPENDENT FILES
X=====================================
X
XThe only system-dependent file in the current version is jmemsys.c. This file
Xcontrols use of temporary files for big images that won't fit in main memory.
XYou'll notice there is no file by that name in the distribution; you must
Xselect one of the provided versions and copy, rename, or link it to jmemsys.c.
XHere are the provided versions:
X
X jmemansi.c This is a reasonably portable version that should
X work on most ANSI and near-ANSI C compilers. It uses
X the ANSI-standard library routine tmpfile(), which not
X all pre-ANSI systems have. On some systems tmpfile()
X may put the temporary file in a non-optimal location;
X if you don't like what it does, use jmemname.c.
X
X jmemname.c This version constructs the temp file name by itself.
X For anything except a Unix machine, you'll need to
X configure the select_file_name() routine appropriately;
X see the comments near the head of jmemname.c.
X If you use this version, define NEED_SIGNAL_CATCHER
X in jconfig.h or in the Makefile to make sure the temp
X files are removed if the program is aborted.
X
X jmemnobs.c (That stands for No Backing Store :-). This will
X compile on almost any system, but it assumes you
X have enough main memory or virtual memory to hold
X the biggest images you need to work with.
X
X jmemdos.c This should be used in most MS-DOS installations; see
X the system-specific notes about MS-DOS for more info.
X IMPORTANT: if you use this, also copy jmemdos.h to
X jmemsys.h, replacing the standard version. ALSO,
X include the assembly file jmemdosa.asm in the programs.
X (This last is already done if you used one of the
X supplied MS-DOS-specific makefiles.)
X
XIf you have plenty of (real or virtual) main memory, just use jmemnobs.c.
X"Plenty" means at least ten bytes for every pixel in the largest images
Xyou plan to process, so a lot of systems don't meet this criterion.
XIf yours doesn't, try jmemansi.c first. If that doesn't compile, you'll have
Xto use jmemname.c; be sure to adjust select_file_name() for local conditions.
XYou may also need to change unlink() to remove() in close_backing_store().
X
XExcept with jmemnobs.c, you need to adjust the #define DEFAULT_MAX_MEM to a
Xreasonable value for your system (either by editing jmemsys.c, or by adding
Xa -D switch to the Makefile). This value limits the amount of data space the
Xprogram will attempt to allocate. Code and static data space isn't counted,
Xso the actual memory needs for cjpeg or djpeg are typically 100 to 150Kb more
Xthan the max-memory setting. Larger max-memory settings reduce the amount of
XI/O needed to process a large image, but too large a value can result in
X"insufficient memory" failures. On most Unix machines (and other systems with
Xvirtual memory), just set DEFAULT_MAX_MEM to several million and forget it.
XAt the other end of the spectrum, for MS-DOS machines you probably can't go
Xmuch above 300K to 400K.
X
X
XSTEP 4: MAKE
X============
X
XNow you should be able to "make" the software.
X
XIf you have trouble with missing system include files or inclusion of the
Xwrong ones, look at jinclude.h (or use ckconfig.c, if you are not a C expert).
X
XIf your compiler complains about big_sarray_control and big_barray_control
Xbeing undefined structures, you should be able to shut it up by adding
X-DINCOMPLETE_TYPES_BROKEN to CFLAGS (or add #define INCOMPLETE_TYPES_BROKEN
Xto jconfig.h).
X
XThere are a fair number of routines that do not use all of their parameters;
Xsome compilers will issue warnings about this, which you can ignore. Any
Xother warning deserves investigation.
X
X
XSTEP 5: TEST
X============
X
XAs a quick test of functionality we've included a small sample image in
Xseveral forms:
X testorig.jpg A reduced section of the well-known Lenna picture.
X testimg.ppm The output of djpeg testorig.jpg
X testimg.gif The output of djpeg -G testorig.jpg
X testimg.jpg The output of cjpeg testimg.ppm
X(The two .jpg files aren't identical since JPEG is lossy.) If you can
Xgenerate duplicates of the testimg.* files then you probably have working
Xprograms.
X
XWith most of the makefiles, "make test" will perform the necessary
Xcomparisons. If you're using a makefile that doesn't provide this option, run
Xdjpeg and cjpeg to generate testout.ppm, testout.gif, and testout.jpg, then
Xcompare these to testimg.* with whatever binary file comparison tool you have.
XThe files should be bit-for-bit identical.
X
XIf your choice of jmemsys.c was anything other than jmemnobs.c, you should
Xalso test that temporary-file usage works. Try "djpeg -G -m 0 testorig.jpg"
Xand make sure its output matches testimg.gif. If you have any really large
Ximages handy, try compressing them with -o and/or decompressing with -G
Xto make sure your DEFAULT_MAX_MEM setting is not too large.
X
XNOTE: this is far from an exhaustive test of the JPEG software; some modules,
Xsuch as fast color quantization, are not exercised at all. It's just a quick
Xtest to give you some confidence that you haven't missed something major.
X
XIf the test passes, you can copy the executable files cjpeg and djpeg to
Xwherever you normally install programs. Read the file USAGE to learn more
Xabout using the programs.
X
X
XOPTIONAL STUFF
X==============
X
XWe distribute the software with support for RLE image files (Utah Raster
XToolkit format) disabled, because the RLE support won't compile without the
XUtah library. If you have URT version 3.0, you can enable RLE support as
Xfollows:
X 1. #define RLE_SUPPORTED in jconfig.h or in the Makefile.
X 2. Add a -I option to CFLAGS in the Makefile for the directory
X containing the URT .h files (typically the "include"
X subdirectory of the URT distribution).
X 3. Add -L... -lrle to LDLIBS in the Makefile, where ... specifies
X the directory containing the URT "librle.a" file (typically the
X "lib" subdirectory of the URT distribution).
X
XIf you want to incorporate the JPEG code as subroutines in a larger program,
Xwe recommend that you make libjpeg.a. (See file README for more info.)
X
XCAUTION: When you use the JPEG code as subroutines, we recommend that you make
Xany required configuration changes by modifying jconfig.h, not by adding -D
Xswitches to the Makefile. Otherwise you must be sure to provide the same -D
Xswitches when compiling any program that includes the JPEG .h files.
X
XIf you need to make a smaller version of the JPEG software, some optional
Xfunctions can be removed at compile time. See the xxx_SUPPORTED #defines in
Xjconfig.h. If at all possible, we recommend that you leave in decoder support
Xfor all valid JPEG files, to ensure that you can read anyone's output.
XRestricting your encoder, or removing optional functions like block smoothing,
Xwon't hurt compatibility. Taking out support for image file formats that you
Xdon't use is the most painless way to make the programs smaller.
X
X
XNOTES FOR SPECIFIC SYSTEMS
X==========================
X
XWe welcome reports on changes needed for systems not mentioned here.
XSubmit 'em to jpeg...@uunet.uu.net. Also, ckconfig.c is fairly new and not
Xyet thoroughly tested; if it's wrong about how to configure the JPEG software
Xfor your system, please let us know.
X
X
XAmiga:
X
XMakefiles are provided for Manx Aztec C and SAS C. I have also heard from
Xpeople who have compiled with the free DICE compiler, using makefile.ansi as a
Xstarting point (set "CC= dcc" and "CFLAGS= -c -DAMIGA -DTWO_FILE_COMMANDLINE
X-DNEED_SIGNAL_CATCHER" in the makefile). For all compilers, we recommend you
Xuse jmemname.c as the system-dependent memory manager. Assuming you have
X-DAMIGA in the makefile, jmemname.c will put temporary files in JPEGTMP:.
XChange jmemname.c if you don't like this.
X
X
XCray:
X
XShould you be so fortunate as to be running JPEG on a Cray YMP, there is a
Xcompiler bug in Cray's Standard C versions prior to 3.1. You'll need to
Xinsert a line reading "#pragma novector" just before the loop
X for (i = 1; i <= (int) htbl->bits[l]; i++)
X huffsize[p++] = (char) l;
Xin fix_huff_tbl (in V2, line 42 of jchuff.c and line 38 of jdhuff.c). The
Xusual symptom of not adding this line is a core-dump. See Cray's SPR 48222.
X
X
XHP/Apollo DOMAIN:
X
XAt least in version 10.3.5, the C compiler is ANSI but the system include
Xfiles are not. Use makefile.ansi and add -DNONANSI_INCLUDES to CFLAGS.
X
X
XHP-UX:
X
XIf you have HP-UX 7.05 or later with the "software development" C compiler,
Xthen you can use makefile.ansi. Add "-Aa" to the CFLAGS line in the makefile
Xto make the compiler work in ANSI mode. If you have a pre-7.05 system, or if
Xyou are using the non-ANSI C compiler delivered with a minimum HP-UX 8.0
Xsystem, then you must use makefile.unix (and do NOT add -Aa). Also, adding
X"-lmalloc" to LDLIBS is recommended if you have libmalloc.a (it seems not to
Xbe present in minimum 8.0).
X
XOn HP 9000 series 800 machines, the HP C compiler is buggy in revisions prior
Xto A.08.07. If you get complaints about "not a typedef name", you'll have to
Xconvert the code to K&R style (i.e., use makefile.unix).
X
X
XMacintosh Think C:
X
XYou'll have to prepare project files for cjpeg and djpeg; we don't include
Xthose in the distribution since they are not text files. The COBJECTS and
XDOBJECTS lists in makefile.unix show which files should be included in each
Xproject. Also add the ANSI and Unix C libraries in a separate segment. You
Xmay need to divide the JPEG files into more than one segment; you can do this
Xpretty much as you please.
X
XIf you have Think C version 5.0 you need not modify jconfig.h; instead you
Xshould turn on both the ANSI Settings and Language Extensions option buttons
X(so that both __STDC__ and THINK_C are predefined). With version 4.0 you must
Xedit jconfig.h. (You can #define HAVE_STDC to do the right thing for all
Xoptions except const; you must also #define const.)
X
Xjcmain and jdmain are set up to provide the usual command-line interface
Xby means of Think's ccommand() library routine. Anybody want to write a
Xmore Mac-like interface for us?
X
X
XMS-DOS, generic comments:
X
XThe JPEG code is designed to be compiled with 80x86 "small" or "medium" memory
Xmodels (i.e., data pointers are 16 bits unless explicitly declared "far"; code
Xpointers can be either size). You should be able to use small model to
Xcompile cjpeg or djpeg by itself, but you will probably have to go to medium
Xmodel if you include the JPEG code in a larger application. This shouldn't
Xhurt performance much. You *will* take a noticeable performance hit if you
Xcompile in a large-data memory model, and you should avoid "huge" model if at
Xall possible. Be sure that NEED_FAR_POINTERS is defined by jconfig.h or by
Xthe Makefile if you use a small-data model; be sure it is NOT defined if you
Xuse a large-data memory model. (As distributed, jconfig.h defines
XNEED_FAR_POINTERS if MSDOS is defined.)
X
XThe DOS-specific memory manager, jmemdos.c, should be used if possible.
X(Be sure to install jmemdos.h and jmemdosa.asm along with it.) If you
Xcan't use jmemdos.c for some reason --- for example, because you don't have
Xa Microsoft-compatible assembler to assemble jmemdosa.asm --- you'll have
Xto fall back to jmemansi.c or jmemname.c. IMPORTANT: if you use either of
Xthose files, you will have to compile in a large-data memory model in order
Xto get the right stdio library. Too bad.
X
XNone of the above advice applies if you are using a 386 flat-memory-space
Xenvironment, such as DJGPP or Watcom C. For these compilers, do NOT define
XNEED_FAR_POINTERS, and do NOT use jmemdos.c. Use jmemnobs.c if the
Xenvironment supplies adequate virtual memory, otherwise use jmemansi.c or
Xjmemname.c.
X
X
XMS-DOS, DJGPP:
X
XThe file egetopt.c conflicts with some library routines in DJGPP 1.05.
XRemove #include "egetopt.c" from jcmain.c and jdmain.c, and in each of
Xthose files change the egetopt(...) call to getopt(...). This will be
Xfixed more cleanly in some future version. Use makefile.ansi, and put
X"-DTWO_FILE_COMMANDLINE" (but *not* -DMSDOS) in CFLAGS.
X
X
XMS-DOS, Microsoft C:
X
XSome versions of MS C fail with an "out of macro expansion space" error
Xbecause they can't cope with the macro TRACEMS8 (defined in jpegdata.h).
XIf this happens to you, the easiest solution is to change TRACEMS8 to
Xexpand to nothing. You'll lose the ability to dump out JPEG coefficient
Xtables with djpeg -d -d, but at least you can compile.
X
Xmakefile.mc6 (MS C 6.x makefile) has not been tested since jmemdosa.asm
Xwas added; we'd appreciate hearing whether it works or not.
X
X
XSun:
X
XDon't forget to add -DBSD to CFLAGS. If you are using GCC on SunOS 4.0.1 or
Xearlier, you will need to add -DNONANSI_INCLUDES to CFLAGS (your compiler may
Xbe ANSI, but your system include files aren't). I've gotten conflicting
Xreports on whether this is still necessary on SunOS 4.1 or later.
END_OF_FILE
if test 18117 -ne `wc -c <'SETUP'`; then
echo shar: \"'SETUP'\" unpacked with wrong size!
fi
# end of 'SETUP'
fi
if test -f 'jdarith.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdarith.c'\"
else
echo shar: Extracting \"'jdarith.c'\" \(1144 characters\)
sed "s/^X//" >'jdarith.c' <<'END_OF_FILE'
X/*
X * jdarith.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains arithmetic entropy decoding routines.
X * These routines are invoked via the methods entropy_decode
X * and entropy_decoder_init/term.
X */
X
X#include "jinclude.h"
X
X#ifdef ARITH_CODING_SUPPORTED
X
X
X/*
X * The arithmetic coding option of the JPEG standard specifies Q-coding,
X * which is covered by patents held by IBM (and possibly AT&T and Mitsubishi).
X * At this time it does not appear to be legal for the Independent JPEG
X * Group to distribute software that implements arithmetic coding.
X * We have therefore removed arithmetic coding support from the
X * distributed source code.
X *
X * We're not happy about it either.
X */
X
X
X/*
X * The method selection routine for arithmetic entropy decoding.
X */
X
XGLOBAL void
Xjseldarithmetic (decompress_info_ptr cinfo)
X{
X if (cinfo->arith_code) {
X ERREXIT(cinfo->emethods, "Sorry, there are legal restrictions on arithmetic coding");
X }
X}
X
X#endif /* ARITH_CODING_SUPPORTED */
END_OF_FILE
if test 1144 -ne `wc -c <'jdarith.c'`; then
echo shar: \"'jdarith.c'\" unpacked with wrong size!
fi
# end of 'jdarith.c'
fi
if test -f 'timg.ppm.u.b' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'timg.ppm.u.b'\"
else
echo shar: Extracting \"'timg.ppm.u.b'\" \(32122 characters\)
sed "s/^X//" >'timg.ppm.u.b' <<'END_OF_FILE'
XMXYNONW.'AS]3=2M+<BA(7A(_:!Q)6A4]6A4]7A8]91U$8AH[5P\P<25 HE9Q
XMOG!_OG!_N6UPO7%TS()\C%Z69CAP=T5[=$)XLWNK?$1T1@@R5QE#6A4]8!M#
XM8AM 6Q0Y61 T7A4Y8AL^81H]9B%@4 M*7A-#50HZFDEAS'N3HE!3K5M>YYR0
XM[:*6VYR,_+VM\,&TZKNNIH)Y8#PSK"Y"LC1(R5!>TEEGQ5!9T5QEX&]RV6AK
XMZW=YZW=YZ'M[ZWY^Z(:$ZHB&XXN(XHJ'YI&&WHE^ZXJ(\9".[H>+[8:*\8V6
XM\X^8ZY.:Y(R3X8^5Y)*8XHZ4XHZ4WX.)RFYTXF)JYF9NVFUQU6ALTF)GT6%F
XMV5QIV5QIUG1ZZXF/WZ^I]\?!_MG0[LG YJBJWJ"B[H^$Y(5ZZ(."Z82#X75\
XMUVMRU65JRUM@SUY?QU97Q%19O4U2NTUAK3]3AQL\@Q<X91H_8!4Z:R!(:1Y&
XM=2I2:R!(6A$NE4QITXN?YY^SO'2(BT-7;R5%=BQ,71$^;2%.610\6Q8^7A8]
XM81E 714V6! Q>2U(K&![O&Y]O&Y]N6UPP'1WT(: C%^/?$]_G&B/KWNBH62$
XM<#-36!$T;29):1]+71,_7Q5'9AQ.5Q8_3PXW5!H[72-$51Y12Q1'8!$U;1Y"
XMT7-\OF!IFTM!W8V#T)Z,X[&?U[*HW[JP]KS!SI29<R(PA#-!L#8\OT5+RE-8
XMSE=<SE=<TUQAVF1IWVENX7%TY'1WXWQ\Z8*"Z8J'ZXR)YXV(YHR'YY62Z9>4
XMYI62XI&.WI*-XI:1XI:1X)2/X)*.XY61[)23ZY.2[(N-XH&#W79ZUF]SS71U
XMRG%RV61MUF%JXUEGX5=EVUEDVEACT&YRX'Z"XZ6A_L"\_='*]LK#X;BUU*NH
XMYYF3X9.-X(2(V'R W6Y[V6IWX6%OWEYLW5UCVEI@RU19R%%6OE)@J3U+AR0\
XM?QPT8Q0Z8!$W;R!(<"%)=B=/:QQ$7A(OC$!=U(J<YYVOSH>8?SA)>S)/81@U
XM6Q$];2-/7!9#5Q$^:AA!;AQ%:0\L<!8SED%/NF5SPWAVO'%OMW1HQ(%UTHU]
XM@52$FVZ>M("GB55\=#=7BTYNEU!SC49I?3-?8QE%60]!8AA*6QI#5Q8_4QDZ
XM4!8W51Y14QQ/7 TQGD]SR6MTNUUFK%Q2[)R2VJB6X:^=WKFOX;RRXZFN;3,X
XM=",Q?RX\M#I P4=-RU19SE=<SE=<TUQAVF1IWVENX7%TY'1WXGM[Z(&!YXB%
XMZXR)Z8^*Z(Z)ZIB5[)J7ZIF6YI62XI:1YIJ5YIJ5XY>2XY61Y9>3[964[)23
XM[(N-Y(.%WWA\VG-WSW9WS'-TVV9OUV)KXUEGXEAFVUEDVEACSFQPWGR XJ2@
XM_+ZZ_='*]\O$X;BUTZJGY9>1X)*,X(2(V7V!WW!]VFMXX6%OWEYLW%QBVUMA
XMS59;RE-8P%1BJCY,B"4]?QPT918\8Q0Z<"%)<R1,>"E1:AM#7! MASM8THB:
XMY)JLSH>8CTA9=RY+81@U6A \:1]+6Q5"61- :AA!:AA!9PTJ=QTZH$M9P&MY
XMPG=UO'%ONG=KQH-WTHU]E5Z/:S1E61Y#3Q0Y>3A1N'>0M&V&A3Y7?C-88A<\
XM50PZ7A5#6QE%61=#51H_4A<\515 5Q=";AXZPW./O65JJ5%6PWQQ[::;VZZ@
XMZ[ZPXKRXX;NWF5IF20H6<18NE#E1ND!&Q4M1SU5;T%9<T%9<U5MAVF1IWVEN
XMX7%TXW-VXWIZZ']_YH6#ZXJ(ZX^+[9&-[9B4\)N7[9N6ZIB3YYF3ZIR6Z)R5
XMY9F2ZIJ4ZIJ4[I:3ZY.0[(F*Y8*#Y'I]X'9YU'=XTG5VWFERVF5NY%IHXEAF
XMW%IEW%IES6IMWGM^XJ&<_;RW_M++^<W&X[JWTJFFY96/X9&+X86)VW^#X7)_
XMVVQYWV)OVUYKW%QBW%QBSUE@S%9=P%9GJ#Y/A"1 ?!PX9A<[9Q@\<"%)=B=/
XM>RQ4:1I"6@XK?S-0T(:8X):HRX25I5YO;R9#8!<T60\Y8QE#6A1!71=$:QE
XM9!(Y9 HE@2="KEEEQW)^P'5QOG-OOGMOR(5YTHU]A4Y_0PP].P E6!U"AT9?
XML7")L6J#G%5N>2Y39!D^711"8AE'5Q5!4A \51H_6A]$30TX4A(]GDYJP7&-
XMN&!EJU-8YI^4Z:*7VJV?\<2VYL"\HGQX4A,?8"$M<Q@PH49>P$9,R4]5T5==
XMT%9<T%9<UEQBVF1IWFAMX7%TXG)UXGEYYGU]XX* Z8B&[)",[Y./ZY:2[IF5
XM[9N6ZYF4YYF3ZIR6Z)R5Y)B1[)R6ZIJ4[962Z9&.ZH>(Y(&"Y'I]XGA[UGEZ
XMU7AYX6QUW&=PY5MIXEAFW%IEW5MFS&ELW7I]X)^:^[JU_M++_='*YKVZTJFF
XMXY.-WX^)XH:*W8&%Y'6"W6Y[X&-PVUYKVUMAW5UCT5MBSEA?P%9GISU.@R,_
XM>QLW9!4Y:!D];1Y&>2I2?S!8:!E!6P\L>"Q)SH26W)*DQ7Z/N'&"9QX[7!,P
XM60\Y7Q4_6Q5"81M(:QE 7@PS9 HEC#)-N61PR72 OG-OP79RPX!TRXA\TXY^
XM=C-E619(8!DZ9A] @CM*K69UMFMYK&%OB3Y6;B,[7A8]81E 51- 4 X[4A,_
XM4Q1 4PHF;B5!R'F&N&EVIEE6RWY[\+>LWZ:;VK2NXKRVS*"H2Q\G4P@@:A\W
XMD"A*GS=9PTE/S%)8T5==T5==T5==UUUCVV1IW69KX&]RXG%TXG=XY7I[Y']^
XMZ82#[(V*\9*/ZY2,\)F1\)R3[IJ1ZYN1[9V3ZYN1YY>-[)N1Z9B.[9&+Z(R&
XMZ(. XWY[XWAWXG=VV79YV79YXVUTWFAOX5QFWEECVUMCW5UESVALWWA\X9J7
XM^[2Q_]#*_]/-Z,*\TJRFX9&+WX^)XX:(WX*$Y7>!WW%[X61PW%]KVEQAW5]D
XMSUUERUEANU5IH3M/?2$_=1DW8A,W:!D]:!E!>2I2@C-99Q@^7! M<B9#S8.5
XMVI"BOWB'PWR+9QX[6 \L6 XX71,]8!I%8QU(:AD]7 LO:A$JF#]8P&QSQG)Y
XMO7-MQ7MURHAYSXU^TXY^>C=I619(308G4PPMAC].M6Y]MFMYLVAVFD]G;B,[
XM3@8M40DP4A ]51- 41(^20HV6A$MD4ADQWB%LF-PHE52]*>DZ[*GY*N@Y+ZX
XMU:^I>4U50!0<8!4M9ALSEBY0F3%3Q$I0S%)8T5==T5==TEA>V%YDVF-HVV1I
XMW6QOX7!SX79WY'EZX7Q[Y8!_Z8J'[H^,ZY2,\)F1\9V4\)R3[IZ4[Y^5[)R2
XMZ)B.Z9B.YY:,ZHZ(Y8F#Y8!]X'MXX79UWW1SUG-VUW1WXFQSW6=NX%MEW%=A
XMVUMCW5UESVALWG=[W9:3]J^L_L[(_]7/Z\6_TZVGX9&+WHZ(XH6'WH&#Y7>!
XMWW%[XV9RWF%MVUUBWF!ESUUER5=?MU%EFS5)>!PZ<A8T81(V:1H^8Q0\>"E1
XM@S1:9!4[6P\L;" ]RH"2V8^AOG>&RH.2="M(5PXK6 XX7!(\9B!+9!Y):!<[
XM8 \S=QXWI4QEQ7%XPV]VO')LRH!ZT8^ TY&"THU]=RA69!5#7 PJ:QLYETI3
XMIUICJ5M@T8.(O'"!A3E*6! Q40DJ4 PX5! \41(^2@LW>"4RN&5RM&=HJEU>
XMO'IR]K2LW[&JYKBQV[>\GGI_0@\E72I :!0W<1U DR!*IS1>PDA.RE!6T5==
XMTEA>U5E@VEYEVV%GVV%GWFAMXVURY'1WYG9YXWIZY7Q\YX6#[(J(ZI&&\)>,
XM\IN0\IN0\)V0\9Z1[)N.YY:)Z92(Z).'ZHR#YHA_YW]YXGITXG-PWW!MUVUP
XMV6]RX&IQVV5LW%ICV%9?VEIBW5UETF5IWW)VW8^,]:>D_<G$_]3/ZLC T*ZF
XMXY&,X(Z)X82&W8""Y7=_WW%YXVAQWV1MV5]CVV%EREQDPU5=KDYCDC)';Q@\
XM:A,W8A0U;!X_8!$W=RA.@C-98!$W60TH91DTQ7N+VI"@P'F(T(F8B4!<6A$M
XM6 XV6A X:B5-8AU%910V9Q8XABY LUMMRG=ZPF]RO7-ISH1ZUY6$UI2#THU]
XM8Q1"9QA&8! N9!0RE4A1H51=CD!%J5M@YIJKL&1U?#158QL\3@HV2@8R30XZ
XM4!$]DC],R7:#K6!AHE56[*JB[*JBZ+JS\L2]S*BM32DN1Q0J4!TS<!P_:Q<Z
XMD!U'J39@P4=-R4]5T%9<TUE?UEIAVEYEVV%GV5]EW&9KXFQQY'1WYG9YXGEY
XMXWIZY(* ZHB&YHV"[).([I>,[YB-[9J-[IN.Z)>*XY*%Z).'YY*&ZHR#Y8=^
XMYW]YX7ESX7)OWF]LU6MNUVUPWVEPVF1KVUEBUU5>V5EAW5UET&-GW7!TVHR)
XM\**?^<7 _]+-ZLC T*ZFXY&,X(Z)X82&W8""Y'9^WW%YY&ERX&5NVF!DVV%E
XMR5MCP%):JDI?CBY#;!4Y9Q T91<X;B!!7@\U=RA.@3)87 TS5@HE8!0OPGB(
XMVI"@Q'V,U8Z=FE%M7A4Q60\W60\W;"=/8!M#9!,U;1P^D#A*O&1VSGM^PW!S
XMO7-IT(9\VIB'V):%THU];AE!:10\>28_=R0]HE):NVMSN6MP?S$VHE9ISX.6
XMQ7V<7!0S6!4Z6!4Z/0 A8R)'QG!RL%I<IUU7NW%K\;FQ[;6MXKFY],O+9#I-
XM1APO3A P71\_@"-);1 VG2A.I3!6N3]%P4=-S%!7TU=>UUMBV5UDW6%HWV-J
XMWF=LX6IOXG%TYG5XY7AZZ'M]ZH&![(.#YXF [(Z%\)6+\I>-[)6*Z9*'YY*&
XMZ).'Z9"%Z9"%ZXJ"Y81\Z7UYY7EUWVQJU&%?VFANU6-IUV!EV&%FV5M@TE19
XMU%9;VEQAV&1JW&ANW(.$]9R=];^X_]'*[L_$T;*GWXN$WXN$XH*$VWM]X')Y
XMW6]VX&ENW69KV61FTUY@R5YGQ5ICH$5??2(\8Q$[8Q$[:!H[;R%":!D_?S!6
XMAC=;7Q T50DD9AHULFEVV(^<NG. P7J'M&N%91PV4PDQ7Q4]92!%92!%7@XL
XM:QLYJ%!?R'!_Q7-PQ')OQGUMSH5UTI!^U9.!U(^!C#=?:A4]>RA!AC-,JEIB
XMTX.+V8N0CT%&;2$TM6E\SH:E:B)!3@LP3 DN3@TR@#]DM%Y@P&ILIEQ6V(Z(
XM\[NS_,2\Z\+"JH&!5"H]/1,F2PTM7B! @R9,;1 VF21*H2Q2NT%'PTE/S5%8
XMU%A?UEIAV%QCVU]FW6%HW69KX&ENX7!SY71WY7AZYWI\Z8" ZX*"YXF ZHR#
XM[)&'[I.)ZI.(Z9*'YY*&YY*&Z(^$Z9"%ZXJ"Y81\Z'QXY'ATX&UKUF-AV6=M
XMU6-IUV!EV&%FV5M@TE19TU5:V%I?V&1JW&ANW82%])N<\[VV_]#)\M/(VKNP
XMWXN$W8F"X(""VWM]X')YW&YUWVAMW&5JV&-ETUY@R5YGP59?FC]9>1XX8A Z
XM8Q$[:!H[<2-$:AM!?S!6AC=;7Q T5 @C9!@SJ6!MV(^<PWR)QG^,M&N%9ATW
XM40<O8!8^8AU"8!M 81$O=R=%L5EHRW."Q')OPW%NR8!PSX9VT8]]TY%_TXZ
XM?"E&80XKAS5*HE!EMF=TZ)FF]*BYH55F7! KBS]:K66&:"!!2@<B1@,>7QTR
XMF5=LP&YINFACK6IB[*FA\[^[_\W)N(N721PH2A0T/0<G40<O:1]'C2Q0<Q(V
XMDR4_G"Y(O4-)Q$I0SE)9U%A?UUA@V5IBV5UDVU]FWF1JXFANY&YSYW%VYG5X
XMZ7A[Z7Q^['^!Z(=_Z(=_Z(B ZHJ"ZH^%[)&'ZI&&Z9"%Z8N"ZXV$[HB"YH!Z
XMYWAUXW1QX6MJVF1CVV%GV5]EUV!CUV!CU5M?SU59TE19U%9;UV!EW69KWW^!
XM])26[K2O_\O&]MG-Y,>[X(R%W(B!WWZ VWI\X'-WW&]SWF=JVV1GU6%CTU]A
XMPU]HM5%:C#94<!HX6Q! 7A-#9A@W<R5$;1Y"@#%5A39:8!$U4P@@8!4MG51A
XMUHV:S8:3RH.0M&N%:B$[40@N8!<]7AH\614W914QAS=3O69PS'5_PW%JQ')K
XMS85PT8ETT(]XT9!YT(M]<1X[@2Y+IU5JJUENK%UJW8Z;[J*SM&AY:!PW:1TX
XM?C976Q,T2 4@10(==#)'MG2)N&9AFTE$T(V%^[BP\[^[Y[.O;D%-1!<C1 XN
XM/PDI50LS;B1,ES9:>1@\DR4_GS%+NT%'PTE/S5%8TU=>UUA@V5IBV5UDW&!G
XMW6-IX6=MXFQQYG!UY71WYW9YYWI\ZGU_YH5]XX)ZX8%YY(1\YXR"ZH^%Z9"%
XMYXZ#YXF ZHR#[(: Y'YXY'5RX'%NWVEHV6-BUEQBUUUCUV!CUE]BU5M?T%9:
XMT5-8T%)7U%UBVF-HVWM][HZ0YJRG_\;!^-O/[=#$X8V&VX> W7Q^W'M]XG5Y
XMW&]SWF=JW&5HU6%CU6%CP5UFK$A1@BQ*:Q4S7!%!819&9!8U=2=&<2)&@#%5
XMA#598!$U4P@@7!$IE$M8THF6T8J7R8*/MFV'=2Q&5@TS7A4[6Q<Y5! R:AHV
XMED9BQ&UWRW1^Q')KQG1MTHIUTXMVSXYWSHUVSHE[AC9*LV-WLF-WB#E-?#!%
XMI5ENK&. DTIG7!(Z6A X:R)&40@L2P8:6!,GDU%4QH2'K&!;L65@^+JT^KRV
XMWJJNDU]C.P<=5B(X4 PV3@HT7PLV=B)-GCY:?1TYC"HRFCA NCY%P45,RT]6
XMTE9=UUA@V5IBW5YFX&%IW6%HX&1KXFMPY6YSY7%UYW-WZ'=ZZWI]Y8%[XGYX
XMWWUWXH!ZY8=_Z8N#Z8N#Z(J"YX> Z(B![()^Y7MWY7)QX&ULW61EUEU>U%5=
XMV%EAV5]CV5]CTUY>SUI:T%57S5)4UUMBW&!GWG=[[XB,YJBB_\2^^=_1\MC*
XMY(Z&VX5]W'M[W7Q\XW9ZW&]SW&=IVV9HTF-ATF-AO%EDH3Y)=2-#91,S6Q1'
XM8!E,8A0S>"I)="5)?S!4@3-481,T5 DA6Q HC$-.RX*-T8N5Q7^)N7&(AS]6
XM710Z7!,Y5Q,U4@XP="4\HE-JQ6]UR')XQW9JRGEMU(QUU(QUSHUVS(MTS(=Y
XMFDI>RWN/N6I^BSQ0>R]$CT-8>C%.:B$^5@PT6Q$Y710X20 D9R(VB418I6-F
XMG5M>JU]:UHJ%Y:>AWZ&;PX^36B8J.04;/0D?4P\Y4P\Y7PLV=2%,HT-?@2$]
XMB2<OF#8^N3U$P$1+RT]6TE9=UUA@VEMCWE]GX&%IW&!GWV-JX6IOY&URXV]S
XMYG)VYG5XZ7A[X7UWX7UWWWUWX7]YXX5]Y8=_YXF!YXF!YH9_Y85^Z'YZXGAT
XMY'%PWVQKV%]@S515TE-;V5IBW&)FW&)FUF%AU%]?U%E;SU16V5UDW6%HWG=[
XM[XB,YJBB_\; ^^'3\]G+Y8^'V8-[V7AXW'M[Y'=[W&]SVV9HVF5GT&%?T&%?
XMM5)=E#$\:QDY8Q$Q719)8!E,81,R>BQ+=B=+?2Y2?C!181,T5PPD6Q H?S9!
XMPWJ%THR6PWV'OW>.F%!G9!M!61 V4P\Q51$S@C-*KV!WQG!VQW%WRWINSGUQ
XMU8UVU(QUS8QURXISS(=YCD-1L69TM6M]KV5WCD5?C$-=;B1,7Q4]6A% 5@T\
XM4PDQ8!8^I%]MO'>%MW5ME%)*H%I4PWUWO']]S(^-I')Z62<O6!L[20PL6@X]
XM6P\^9 <T?!],JDM@AR@]A2HHDS@VNCY%P45,RT]6TE9=UUA@V%EAW5UEWU]G
XMW5YFX&%IXFANY&IPXVURY6]TY71WYW9YWWEVX7MXXWY[Y']\XH)]XX-^Y(6
XMY8:!YH2 Y()^Y'EXX'5TY7!RX&MMU%A=Q$A-TU%:W5MDWV5IX&9JW&=GVV9F
XMVV!BU%E;VUMCW5UEW7-X[H2)Y:>A_\2^]MW/[-/%Y(Z&UH!XUG5UVGEYXW9X
XMV6QNV&-CV&-CSE]=RUQ:K$M6B"<R8!(S7A Q7!9,7AA.7Q$P>RU,=RE*>BQ-
XM>RU.8A0U60XF71(J;R8QNG%\UI":QX&+QGZ5I5UT:!]%5PXT30DI6A8VDD-:
XMO6Z%R7-WR7-WT']RSWYQU(UTTXQSS(MRRXIQS8AZ:1XL=BLYCT57I5MM;20^
XM8!<Q4PDQ3@0L4@DX3 ,R6Q$YC$)JUY*@T8R:S8N#R8=_O'9PP7MUV)N9XZ:D
XM@E!831LC0@4E5!<W6@X]71% 90@U?R)/L5)GC2Y#ARPJE#DWO$!'PT=.S%!7
XMTE9=UE=?UUA@VUMCW5UEW5YFX&%IX6=MY&IPXFQQY&YSY'-VYG5XW7=TXGQY
XMY8!]Y8!]X8%\X8%\XH-^Y8:!YH2 XX%]XG=VWW1SYG%SX&MMT55:OD)'U%);
XMWUUFXFALY&INX&MKX&MKWV1FV%U?V%A@V5EAV&YSZH"%XJ2>_\&[\=C*Y<R^
XMXXV%U'YVTW)RV7AXX71VUVILUF%AUF%AS%U;R%E7ID50@2 K6PTN70\P7!9,
XM7!9,7Q$P?"Y-=RE*>2M,>2M,8A0U6Q H7A,K8ADDM&MVVI2>RX6/RH*9JV-Z
XM:2!&5PXT204E71DYGD]FQG>.S'9ZRW5YTX)USWYQU(UTTXQSS(MRRXIQS8AZ
XM60TX60TXA5!W@TYU>#EG519$6 O8@0Y9A4Y5P8J*P$&NY&6P)F)R:*2X):$
XMZ9^-VYNLZ:FZV)2FFU=I9!\S4PXB4! O3P\N6!D_30XT7!$V<29+J$EBCB](
XME20QI#- O3M$QD1-TT]6VU=>W5E=W5E=VUI;W%M<WE]?XF-CXFEIY6QLX6UO
XMXV]QXW)UYG5XZG5WZG5WYWAXZ'EYXWUZY7]\XX%]Y8-_YX)_YH%^YGMZXG=V
XMY'!RW6EKU%A=QDI/R5A;V6AKXV=NU5E@UTQ8X59B[%QLZUMKT$E6VE-@U65L
XMX7%XZ9>4_[6R_[^X\[&JUWUXUGQWX7MUW7=QW6IHWVQJW&EUSEMGP%Y\L4]M
XM?"E68 TZ6Q5#6Q5#5Q,_9"!,;!E(<!U,AS)*=B$Y@RQ%:Q0M7PPY8@\\6!,Y
XMJ&.)RX^6RX^6NW=]KFIP>29)70HM7@TD8Q(IIE=CR7J&QWAZRWQ^R'QNU8E[
XMU8IVU(EUTXATT89RSX9V:1U(IEJ%KWJA5R)).P J3Q ^>!I/:@Q!4 C3P B
XM7S4ZS:.HOYB(V;*B\JB6\*:4[*R]R8F:EU-E:"0V3PH>3 <;4! O6!@W6QQ"
XM4!$W71(W<29+JDMDD3)+FBDVJ3A%O3M$Q4-,T4U4UU-:V559VE9:V5A9VUI;
XMWE]?X6)BX6AHY&MKX6UOXV]QY'-VYG5XZ71VZ71VYG=WZ'EYXWUZY7]\XX%]
XMY()^YH%^YH%^YWQ[XWAWY7%SWVMMUUM@RT]4U&-FT6!CPD9-H"0KG1(>K"$M
XMP3%!QS='UD]<VE-@SEYEUV=NWHR)^JBE\:^HXJ"9VX%\U'IUW7=QW'9PWVQJ
XMWFMIV69RRUADOEQZHD!>;QQ)70HW6!) 6Q5#6A9"81U);AM*<R!/A"]'=2 X
XM@"E";!4N8Q ]9A- 51 VG5A^RX^6SI*9N75[M'!V@S!37@LN:!<N=20[LV1P
XMRWR(Q79XRGM]RGYPU8E[U8IVU(EUTXATT89RSX9V;2Q3KVZ5L6R4:"-+5Q(X
XM51 V7QP^1P0F2P8<5A$GE$M6UXZ9V)J6[[&MV*J9X;.B[JW&IF5^81PT2@4=
XM4 LC51 H5!$S6!4W7AU$4A$X7A,X="E.KD]HEC=0G2X[K3Y+P#Y'QD1-STU4
XMU%)9V%18V559VEE:W%M<W%U=X&%AX69GY&EJXFUOY&]QY'-VYG5XZ'-UZ'-U
XMYG=WYWAXY7QZYWY\XX%]Y()^XX%]Y8-_Y7]\X7MXY'5UX'%QV61FSEE;VV%G
XMVF!FSD]7MC<_L2PVNC4_P3]*P#Y)OT1-PD=0MU%5PUUAU()_\9^<Z*2>V96/
XMX82#U'=VVG%MW71PWFUNVFEJTF-RQUAGM5=XBRU.81,^70\Z5Q) 6Q9$71Q%
XM7AU&<!U*>293@BU#=B$W?28_;!4N9Q1!:19#3@DOB41JQHJ1T)2;LV]UMW-Y
XMBSE97 HJ<R(RCCU-Q'1\SW^'PG1QR'IWS8%SU8E[U8EXTX=VT8=UT(9TSH5V
XMFEF FEF :B5-4 LS<"M18!M!;"E+9R1&;"<]A4!6G%->MFUXS8^+SY&-Q9>&
XMYKBGMW:/?#M43@DA4 LC9R(Z;"<_7!D[4@\Q7!M"41 W8!4Z=RQ1M%5NG#U6
XMH#$^K3Y+Q4-,RTE2T4]6U5-:V%18VE9:W%M<WUY?VUQ<WV!@X&5FXVAIX6QN
XMXVYPXW)UYG5XYG%SYW)TY79VYWAXY7QZYGU[XH!\XX%]XX%]Y8-_YH!]XWUZ
XMYG=WY'5UX&MMUV)DR$Y4TEA>VEMCUUA@VU9@WUIDUU5@RTE4N3Y'PD=0P5M?
XMT6MOW8N(\9^<Y:&;V)2.Y(>&U'=VV7!LW71PVVIKUF5FT6)QREMJI4=H>1L\
XM70\Z9AA#6A5#6Q9$8B%*82!)<1Y+@2Y;@BU#?"<]?28_;A<P:19#9Q1!3@DO
XM>#-9PX>.U)B?L6USO'A^DT%A7PTM=20TH$]?S7V%SW^'PW5RR'IWT85WU(AZ
XMU(AWTX=VT8=UT(9TSH5VDU1ZBDMQ7@PS30 B=S1.?3I4AU]FB&!GGF-HK'%V
XMN%-BME%@L5UFP&QUS+2KOZ>>:"5)5A,W3@8G6! Q;R5%>"Y.:2)'6A,X6Q=!
XM40TW8!4Z>S!5MUISGD%:GS(^J3Q(QD9.RTM3TE!7U5-:UE58UU99W%M<WUY?
XMVUQ<WE]?WV1EXF=HX&MMXFUOY'!TYG)VY6YQYF]RY71UZ'=XY7QZYGU[XH!\
XMXH!\X8%\Y(1_Y()^X7][X7MXX7MXWW1SV&ULV%EAW%UEUUUCTUE?T5UAUV-G
XMT65IREYBP%]?TG%QWHF'[)>5[:.=\*:@X9V7U)"*YH.&V79YW'%RW'%RUF9M
XMTF)IRV-UQ5UOB#%5:!$U6A0_9B!+6AA$5Q5!8B%(9"-*<Q]*C#AC@RU!A2]#
XM?B@^;QDO:19%8Q _5 \W;BE1PH.+VINCM'!TP7V!ET-C:14U>"8KK5M@SWY^
XMSGU]QGEPR7QSTXAZTXAZTXEYTHAXT(=ZSH5XSH1\71Y$<3)8@S%8@2]6DU!J
XMCTQFF7%XJX.*T9:;KW1YK$=6LTY=HT]8W8F2ZM+)>&!73PPP5!$U6Q,T6A(S
XM8QDY;2-#:B-(8AM 6Q=!40TW818[?#%6N5QUH$-<H#,_J3Q(Q45-RDI2T4]6
XMU%)9U%-6U517V5A9W%M<W%U=WV!@WV1EXF=HWVILX6QNXFYRY'!TXVQOY6YQ
XMY'-TYW9WY7QZYGU[X7][X7][X8%\Y(1_Y8-_X7][XGQYXGQYXWAWWG-R[W!X
XM[&UUX&9LV5]EUV-GXFYRY'A\YGI^TW)RZ8B(^:2B_Z^M_+*L\ZFCWYN5THZ(
XMXG^"VG=ZWG-TVF]PU&1KTV-JQEYPMDY@<AL_90XR6Q5 9!Y)6AA$51,_7AU$
XM9R9-<AY)DS]J@BQ BC1(?B@^<APR;!E(8@\^51 X8!M#M'5]TY2<LV]SO7E]
XMCSM;<AX^@S$VN&9KRGEYRWIZRWYURWYUU8I\TXAZTHAXT8=WSX9YSH5XS8-[
XM8!4\<B=.G5=RGEASFFANF6=MLHB!U:NDSH6%H%=7FS1!OE=DQW:&]*.SNIRC
XM0B0K6Q5"8AQ):!U%9!E!91@]:AU":1]':!Y&8AU%51 X8A4Z?"]4MUISH$-<
XMH35#JS]-Q$5-R4I2T5%7U%1:UE58UE58V%=8VEE:WEU>X%]@XF1FY&9HWVAK
XMX&ELX6MPXVURY&INYFQPY7%SZ75WYWIZZ'M[Y'Y[XWUZXH!\Y8-_Y8-_X7][
XMWWUYX'YZX7QYWGEVXFMPXFMPVVMNVFIMU'5RXH. X9.-YYF3RH=]W)F/[JZE
XM^+BO]K:MZZNBW)R4T9&)XGJ WG9\WG)XUVMQTV9RU&=SME=PDS1-81,[91<_
XM61E%6!A$6QM$6!A!8!T_;BM-<A]&ED-J?B@ZBC1&?B4\=ATT=!]/:!-#6! Y
XM5P\XIVAPS(V5MG%SNW9XAS1/?BM&FT9"R71PR'9ORGAQSH)TS(!RU8Q]TXI[
XMSXEYSHAXS89]S(5\S8)^8A<^?C-:O':1KVF$LH"&S)J@TJBASZ6>E$M+D$='
XMGSA%T&EV\:"PXI&A7D!'02,J6A1!71=$9QQ$;2)*<B5*<21);2-+;2-+:"-+
XM6!,[8A4Z>BU2M5AQH$-<I#A&L$12QD=/RTQ4U%1:V%A>V5A;V%=:V5A9VUI;
XMWEU>X6!AXF1FY&9HWVAKWVAKX&IOXFQQXVEMY6MOY7%SZ75WYWIZZ'M[Y'Y[
XMXWUZXH!\Y8-_Y8-_X7][WGQXX'YZX7QYWWIWY6YSY6YSWV]RWV]RW7Y[[8Z+
XM\J2>_:^IVYB.Y:*8\+"G]K:M\[.JZ:F@VIJ2S8V%X'A^W75[W'!VU6EOUFEU
XMV&MWKU!I?!TV81,[;!Y&6AI&4Q,_7AY'7AY'8A]!<S!2<A]&ET1K>B0VB3-%
XM>R(Y=QXU>214;AE)7A8_6! YIF=OS8Z6OWI\P'M]BC=2CCM6K5A4U'][QW5N
XMR7=PT(1VS(!RU8Q]U8Q]SXEYSHAXS89]RX1[S8)^BS-5RW.5P)&<NXR7N9>/
XMRJB@Z:>BP7]ZGT-'FCY"DT1.NVQV[JW"=S9+3 PK6!@W71=%71=%:!I#9QE"
XM9Q4\<1]&=2=/;!Y&7Q4]8QE!60PQ;B%&KU1LHD=?IC],J4)/Q$A/S%!7TU5:
XMTE19TU16UUA:VUI;VEE:WEU>X%]@X6-EY&9HXFALXFALWVAMWVAMWV5IXFAL
XMX6QNXFUOY'-TZ'=XY7IYY7IYWGAUX7MXXWUZXWUZX7QYWWIWWGEVWGEVWG%S
XMY'=YWWU[VGAVU8A_[)^6\K6I];BLW:B9UZ*3Z;2G^,.V[K6JYZZCX:&9R(B
XMXG>"S6)MY7J%W'%\Q6!QQV)SD3M99A N615!8!Q(3Q1!4A=$6AM!7!U#<"A'
XM:B)!>25(CSM>?24UABX^>2 W>R(Y:A5'9A%#5@XY4 @SCDY5PX.*R(&"P7I[
XMB#-+HTYFO&-8SW9KSGMNRG=JS(!QTX=XS8=WS8=WS(=YRX9XRH1]R8-\RH)]
XMES]AUGZ@N(F4LH..SZVEXL"XV):1EU50GD)&K%!4CT!*[I^ICDUB6QHO6!@W
XM4Q,R8AQ*7QE'9QE"91= 9!(Y;QU$=BA0<")*7Q4]8QE!6PXS:QY#K5)JHD=?
XMJ4)/IC],PD9-RDY5TE19TU5:U%57UUA:VUI;VUI;WEU>X%]@X6-EY&9HXFAL
XMXVEMX&ENWVAMY6MOY6MOX6QNXVYPY'-TZ'=XY'EXXWAWWWEVX7MXXGQYX7MX
XMW7AUW'=TVW9SW'=TWW)TYGE[WWU[W'IXV(N"[Z*9][JN_<"TWJF:U:"1Y;"C
XM]\*U\+>LY*N@W)R4R8F!W7)]V6YYVF]ZU&ETS&=XN%-D?BA&9Q$O615!81U)
XM419#4QA%61I 7!U#<2E(;25$@2U0D3U@@"@XAR\_?",Z?B4\;QI,:11&61$\
XM40DTBDI1PX.*R8*#O'5VC#=/JU9NO619SW9KSGMNRG=JS8%RTX=XS8=WSHAX
XMS8AZS(=YRX5^RH1]RX-^DT=8Q'B)JX*!MHV,Y+BQW[.LP6MQB3,YGD-/GD-/
XMP8J6L'F%3!,K21 H:PX\<!-!:2%,8QM&9Q@^9!4[9! Q<!P]>RI,>2A*818[
XM8Q@]7@\S9Q@\J$]HH$=@K$=6H#M*OD1*QTU3SU-8T55:U598V5I<W%M<W%M<
XMWEU>X%]@XF-EY&5GXV=LY&AMXFANXFANXFMNWVAKW69IWVAKX6UOY'!RXG%R
XMX7!QXW1TY'5UY'=WXW9VX'-SX'-SX'5TX79UWW1UY7I[WWY\WGU[X(Z']Z6>
XM_[RS_\2[ZJJ?X:&6[:NC_KRT^[6N[*:?X921T82!U6QYX7B%RV9US&=VQVN!
XMESM1818[71(W4QA'72)141E)4QM+7!D^7AM >2E%=R=#A3%2C#A9?B8UA"P[
XM?"$Y>R X<1I-9Q!#71,_4@@TA$1+PH*)S(6$M&ULE#]5M6!VQ&=9TW9HT'IL
XMS7=IT(%SU89XS(=WS8AXRXA\RXA\RH=]R89\S(1^H%1EM6EZN9"/U:RKUZND
XMK8%ZHTU3ED!&G4).MUQHTYRH62(N310L4!<O=1A&A"=59Q]*8!A#918\918\
XM9A(S<AX_?2Q.?2Q.91H_818[8!$U8Q0XI4QEG$-<KTI9FS9%N3]%PTE/S5%6
XMT%19UE=9VEM=W5Q=W%M<WEU>X%]@X6)DY&5GXV=LY&AMXVEOXVEOX&ELVV1G
XMVF-FWF=JX&QNX6UOWVYOWVYOW&UMW6YNW7!PW7!PW7!PW7!PWG-RX79UX'5V
XMY7I[X']]XH%_X8^(\J"9^K2K_[JQ\+"E\;&F]K2L][6M][&J\*JCXI62S8!]
XMSF5RW72!R61STVY]N5US?" V7!$V6Q U5!E(7B-24QM+5!Q,7!D^7QQ!>RM'
XM>2E%AC)3AC)3?R<VABX]?B,[>!TU<QQ/8PP_6A \40<S>SM"P("'T8J)K69E
XMG$==N61ZR&M=U7AJT'ILSGAJTH-UU89XS(=WSHEYRXA\RH=[R89\R(5[RX-]
XMM(^%LXZ$ZK"M];NXSGJ#GTM4G$13HTM:IF5TV)>F=D181Q4I50XQ6A,VD"M>
XME3!C8AM 6A,X8Q4S:!HX;1<S=B \?RU*@"Y+;B%"8!,T81,T8!(SH4ICE#U6
XMKTM>E3%$L3H_O$5*RE!4SE18U5=9V5M=W5Q=W%M<W5Q=WUY?X&%CXF-EXV5J
XMY6=LXVEOY&IPX&MMW&=IWF=JXVQOY&UPX6IMX6IMY&UPWF=JX&ELX6IMXFMN
XMX&MMX&MMXFUOXVYPY71WZ'=ZYWI\YGE[YWY^[X:&\H^0]9*3^YR;_ZBG_Z&C
XM\)"2\I&3^)>9YH.'RVALR&-PSFEVRVM]U'2&FD5>8PXG71E!51$Y41M.6R58
XM4QQ-5!U.81E 8QM"@"E#?B=!BS55AC!0ARX[CC5"A2I">1XV>R189@]#50HY
XM3P0S<S XO7J"UHZ+J6%>IU%CNV5WSF]BUWAKTGEJT7AIU(5WUH=YRX9XSXI\
XMR(=ZQX9YQX9[QH5ZR8)YY+^UV[:L^L"]UYV:IE);ET-,H$A7I$Q;VIFHK6Q[
XM1Q4I3QTQ3P@K6Q0WAB%4G3AK7Q@]5Q U8A0R:APZ;QDU=B \?BQ)?BQ)>"M,
XM7 \P8!(S8!(SH4ICC#5.K4E<DBY!JS0YN$%&QTU1S5-7U%98V5M=W5Q=W%M<
XMW%M<W5Q=WE]AX&%CX6-HY&9KXFANXVEOWVILW&=IX&ELXVQOW69ITEM>T%E<
XMUE]BW69IX&ELXFMNXVQOX&MMWFEKWFEKWFEKW&MNW6QOV6QNUFEKTFEITVIJ
XMT&UNTW!QVWQ[Z(F(V7E[PF)DRVILUG5WR&5ILU!4R&-PR61QT'""Q&1V?RI#
XM7PHC8!Q$5Q,[4AQ/6B1741I+51Y/91U$9Q]&@"E#>B,]BC14?RE)B3 ]CC5"
XMA2I"=!DQ?RA<:1)&5 DX408U:B<OM'%YUX^,IU]<M5]QNV5WTG-FV'ELT7AI
XMTGEJU89XUH=YRX9XSXI\QX9YQX9YQH5ZQ81YR(%XW-J\T]&S[IV=L6!@KS9.
XMMSY6GT]CO6V!OI>E328T62$_3!0R90TX:1$\: <YF#=I8QLZ61$P8Q,M:QLU
XM;ADO<QXT>RA!?2I#@C1360LJ7A Q81,THDMEA"U'J49:D"U!IB\TLSQ!Q$I.
XMRU%5U%98V5M=W%M<VUI;VUI;W%M<W%U?WE]AX&)GXF1IXV=NY&AOWFEKWFEK
XMXVQOX6IMTUE=OD1(N3U"P45*R4U2SE)7TU=<UEI?UEI?U5E>U%A=U%A=S%!7
XMRT]6R$Q3QDI1Q4E0R$Q3S%%:TE=@U5ICUUQEP$A2LSM%PTM5RE)<P$A3OT=2
XMRFAVSVU[RV^!GD)4:AHV81$M4Q4_6!I$4!U15B-73A=*51Y1:2!&:R)(A"=#
XM>ATYB3-1>B1"B3 ]BS(_@",\;1 IA"I?<1=,60T\6 P[9"$IJ&5MU8V(IU]:
XMQ&Z OFAZUG5IVGEMT7AKTWIMUXA[UH=ZR8=XSHQ]QXAZQH=YQH5XQ81WR(-W
XMUM2VR\FKRGEYCSX^MSY6OT9>I55I\*"T>%%?11XL3A8T6" ^<QM&9P\Z8@$S
XMC"M=9AX]6Q,R8Q,M:AHT;!<M<!LQ>"4^?"E"B#I95PDH70\P8Q4VHTQF?RA"
XMID-7CRQ HRPQL3H_PDA,RU%5TU57V5M=W%M<VEE:VEE:VUI;VUQ>W5Y@WV%F
XMX6-HXF9MXV=NY&]QY&]QZ7)UXVQOSE18LC@\JR\TLS<\IRLPK3$VM3D^NS]$
XMOT-(P$1)P45*P45*MCI!LS<^L34\LC8]M3E O$!'QTQ5T%5>U%EBRD]8L#A"
XML3E#QDY8QDY8P4E4T5EDS6MYVWF'QFI\@"0V8Q,O:1DU20LU7!Y(4!U152)6
XM319)5!U0:R)(;21*@R9"=ADUCCA6?"9$C31!BS(_?R([; \HBS%F>B!57A)!
XM71% 8!TEH5YFTXN&J6%<SGB*PFQ^V'=KVWINT7AKU'MNUXA[UXA[R8=XSHQ]
XMR(E[QXAZQX9YQH5XR81X_ZZT^J:LG5!7GE%8?3A$I%]KY*>WL'.#5ADR5ADR
XM6Q@Z7!D[7!(Z6Q$Y9A9"<"!,;B%&8A4Z7Q(W:!M ;R)%;!]";1\^<R5$AC94
XM:AHX81$M8Q,OF4AB?BU'D4!:B3A2GS%!J3M+ND=3PD];S%!5SU-8UU=5V5E7
XMV%-3V514UUA:VEM=VF!FW6-IVV9OW&=PXW)QX7!OX&ULW6IIW&5FV&%BUUE<
XMTE17RD9+QD)'QSU$RD!'U49/VTQ5WT]8WT]8QU!?RE-BR%1FQU-EPU-HQ55J
XMREUTT61[SV=YX'B*S6ETOEIESVYPTW)TRFIEU75PSGF1R'.+E45A9!0P6A(S
XM81DZ7!A"8AY(81M&7!9!60XV8QA >RA->29+=1T_>"!"DSA2A"E#ABM%DC=1
XM?" ^;1$O>BQ-@#)35Q0X7!D]51,NC$IEV(N4OG%ZU'UURG-KTWYPT'MMSW]O
XMU85UU8EXTX=VSX9VT(=WRX=URX=URX9VRX9VS(9V_[.YMF)HH%-:F$M2KVIV
XMVI6AT92D;S)"6ATV6ATV7QP^7QP^7A0\6Q$Y9!1 ;1U);2!%8A4Z7A$V9AD^
XM;!]":AU ;1\^<B1#@#!.;!PZ914Q914QDT)<>2A"C3Q6BCE3FBP\I3='MD-/
XMP$U9RT]4S5%6U%12UU=5V514V514V%E;VUQ>VF!FW6-IVV9OW&=PXW)QX7!O
XMX6YMX&ULX&EJVV1EVEQ?U5=:V%19UU-8VE!7V4]6W4Y7X%%:Y55>Z%AAWVAW
XMY6Y]ZW>)\7V/\H*7^(B=_I&H_YFP_YFK_YBJXGZ)RV=RTG%SUG5WSV]JT'!K
XMRG6-K%=O>RM'81$M6Q,T7A8W6Q=!8AY(7!9!7!9!7A,[9AM#=R1)<A]$<AH\
XM?"1&ECM5@B=!BB])D#5/?" ^<Q<U=BA)A#976!4Y7!D]5A0OBTEDUXJ3P71]
XMU7YVS'5MU8!RT7QNSW]OU(1TU(AWTX=VSX9VT8AXRX=URX=URX9VRX9VS(9V
XMRGEWHE%/H5A;JV)EYZ.QUY.AB$EB6QPU6QT]7!X^81Y#81Y#8!<]6A$W7Q$Y
XM9AA :A]$8!4Z7Q(W91@]:AU :AU ;1] <B1%>RI*;QX^:!@V9Q<UBCI4="0^
XMB3A2B3A2DR8ZG3!$L#],NDE6QTQ5R4Y7T5!1TU)3UE-2UU13UU97VEE:V%U?
XMVV!BVF-HVV1IX7!QX7!QXV]QY'!RY&UPX&ELW6%FV%QAVEA?W%IAX%IBWEA@
XMW%%;W%%;XU=AZ%QF[&Q\\W.#^W^2_X:9_XJ=_XV@_Y&H_Y2K_Z"S_Y&DY7B$
XMT61PU&IOX'9[X'=WV&]OO6J%AS1/7Q$P7Q$P7A4[710Z71E#8AY(5A [7!9!
XM8Q@_:1Y%<R!#:A<Z;Q<V@2E(F#]8?B4^D390C#%+>Q\[>Q\[<B%#C3Q>6A4Z
XM7!<\6!4PB49AUHF0Q7A_U7]WSGAPUH-TTG]PSGYNTX-ST8=WT8=WSHAWT(IY
XMS(=WS(=WS(=YS(=YS(=YED5#LF%?K&-FYYZAWIJHF%1B5A<P8B,\6AP\6QT]
XM8A]$8A]$81@^6A$W7A X9!8^:1Y#8A<\810Y9AD^:AU :AU ;B!!<R5&>RI*
XM="-#:1DW:!@VA35/=B9 B#=1AC5/CB$UF"L_JCE&MD52Q$E2QTQ5SDU.STY/
XMTU!/U%%0U%-4UE56U5I<UUQ>UE]DUV!EW6QMWFUNXFYPY7%SYW!SY&UPX&1I
XMW&!EV%9=V5=>W5=?W%9>W%%;W5)<XE9@YEIDX6%QZ&AX[G*%\W>*\'B+[G:)
XMZW2+ZG.*\'Z1XW&$U6ATSV)NTFAMXGA]Y7Q\UFUMIU1O<1XY5PDH8A0S7Q8\
XM81@^8Q])7QM%5Q$\7!9!8Q@_:1Y%<1Y!9A,V;A8U@RM*FD%:?20]ECM5B2Y(
XM?2$]@25!;1P^DD%C71@]6Q8[6A<RAD->U8B/RGV$UH!XT7MSV(5VTX!QSW]O
XMTH)RT8=WT(9VSHAWT8MZS(=WS(=WS(=YS(=YS(=YK6)8M6I@UX^2_K:YG%=K
XM:B4Y921)4Q(W6QE&71M(8Q]+9B).8QQ!718[8A4V:!L\:!U$9!E 8Q@]9AM
XM:QY!;2!#;R)#<B5&>BQ+=BA':!@V:!@V@C).?"Q(AS=3@3%-B1XWD28_HS-&
XMKS]2O491P4I5R4M.RDQ/ST]-T%!.TE-1U%53UEE8V5Q;UUY<V6!>V6AIVVIK
XMX&QNXV]QY7!RXVYPX&9JW&)FW5]DVEQAV%A>V%A>VUE@W%IAW5E@W%A?VUIG
XMX6!MZ&AV[FY\[G& [&]^Z&Q]YFI[W&5TVV1SW6IXWVQZW6]YXW5_W6]WR%IB
XMAS9::!<[70\W8A0\6Q,\8AI#9B!+6Q5 7AE!7AE!81<Y:!Y <" ^9A8T;ADR
XMA3!)F#]8@"= ECM3B"U%@25!@R=#;!D\ED-F8QP_718Y71HT@T!:T(:,S8.)
XMUH)WTW]TV89YU(%TSG]QTH-UT(=XSX9WS8AXT(M[RHAYRHAYRHAYRHAYS(=[
XMSH-YUXR"_[R_OW=Z<2Q 7ADM921)61@]7AQ)8!Y+9B).:2519A]$81H_9QH[
XM;2!!91I!91I!9AM :1Y#;2!#;B%$<"-$<21%>"I)>2M*9Q<U:1DW?BY*?R]+
XMAS=3@#!,AQPUCB,\G2U J3E,N$%,O491Q4=*QDA+ST]-T%!.T5)0U594UUI9
XMVEU<V6!>VV)@UF5FV&=HW&AJX&QNXVYPXFUOX6=KW6-GXV5JWF!EVEI@V5E?
XMW%IAVUE@V55<U5%8U%-@V%=DVEIHWEYLWF%PW%]NV5UNUUMLTUQKWVAWY'%_
XMYW2"YGB"WW%[REQDLT5-;1Q 9Q8Z8Q4]7Q$Y61$Z81E"8QU(6A0_9B%)81Q$
XM8!8X9QT_<2$_:!@V<1PUBC5.DSI3ABU&DC=/B2Y&ABI&@"1 ;AL^E$%D:"%$
XM7A<Z81XX@#U7SH2*THB.U8%VU(!UV89YU(%TT(%STX1VT8AYT(=XS8AXSXIZ
XMRXEZRXEZRXEZRXEZS8A\U(Z%][&HUY.7=# T92(]6A<R71A&9R)07QQ181Y3
XM9R!1:2)391Y#8!D^9!LW:R(^8!4\9!E :!U$:R!';"%&;2)';B%$;B%$<")#
XM>BQ-:!HX:!HX=2A#>BU(A351@3%-@APZAR$_E"E"GC-,KCQ-M4-4O$1.O45/
XMQTQ-R$U.S5!-T511U5A3V5Q7VUY9W6!;V&1HV65IVF9JW6EMX6MPX6MPWFAM
XMVV5JW&5JVF-HUV!EU5YCUEQBU%I@TEA>T%9<S%1<S%1<RE):RU-;RU5<RU5<
XMRE5>RE5>U6-LY')[W7!\V6QXX'F&T6IWJD52EC$^7Q,^8Q="7A1 60\[7A5#
XM8!=%71="8QU(;B9-9Q]&8QDY:!X^<" \9A8R<A\XD#U6BC1*BS5+BS!(C#%)
XMC#%+>R Z<AX_DCY?;21(8!<[9"$[?SQ6S(.&U(N.TH%UTX)VUH5YTH%USX-U
XMTX=YT8I]SXA[RHAYRXEZRHE\RHE\RHE\RHE\RHE^Z**9[ZF@=C(V9R,G618Q
XM6Q@S="]=5 \]7QQ18!U291Y/91Y/8AM 6Q0Y81@T9QXZ71(Y8Q@_:1Y%:R!'
XM;"%&;2)';2!#:QY!:AP]>RU.:APZ:1LY;R(]=BE$@S-/A#10@1LYA1\]D"4^
XMFB](JCA)L3]0N4%+ND),PD=(PTA)R4Q)S5!-T51/U5A3V%M6VEU8V65IV65I
XMV65IW&ALX&IOX&IOWFAMW&9KV6)GVV1IWF=LVV1IV5]EUEQBV%YDVV%GU%QD
XMTEIBT%A@T5EAU%YEV6-JW&=PWVISYG1]\X&*VVYZSV)NVG. QE]LE3 ]@1PI
XM8!0_91E$6A \6 XZ91Q*8!=%6Q5 ;2=2<"A/:B))9QT]:B! ;Q\[9!0P="$Z
XMED-<AC!&CSE/ARQ$C3)*D#5/=QPV=2%"CSM<;R9*8!<[9B,]?CM5RX*%UHV0
XMTH%UTX)VU81XTH%UT(1VU(AZTHM^SXA[RHAYRHAYRHE\RHE\RHE\RHE\RHE^
XM^[FZF5=86!<D7ATJ92)$618X5Q)$8AU/7AA.8AQ2:2)3:R159A]"8!D\9!TX
XM;"5 8AA 9QU%9QY$8QI 91I!;"%(;R5';")$;!] <B5&<B9$;" ^9QDW;!X\
XM=2=%>RU+A"9'=QDZAB5!DS).E"M!GC5+M$54LT13N$))NT5,Q$M,RU)3TE=6
XMU5I9UEE6U5A5VF1IVV5JVF9JW&ALWFINWFINVVIMV6AKVFELV&=JU&1GTV-F
XMU65HV6ELVVYPWG%SV71UWGEZXGM[X7IZX'IWXGQYXGM[X'EYX'V WGM^S6]X
XMT7-\S76%FT-3<!LQ@"M!7QE'6Q5#5Q$_5Q$_7!9#81M(9!]'92!(<"=-81@^
XM9ADZ9ADZ:!@T81$M:A<PF$5>BSE,@"Y!DSI/C31)@",^@",^?2='B3-3=2M-
XM91L]:",[;RI"Q7Q_WI68T(%SV(E[QWIORWYSSX1XT89ZSHE]S8A\RHE\RHE\
XMR(A]R(A]R(A_R(A_R(A_KVUN>#8W5Q8C8!\L9"%#7QP^7AE+7QI,6Q5+8!I0
XM9R!1:"%28QP_718Y81HU:B,^81<_9AQ$9QY$8AD_8A<^:!U$;")$;")$;!]
XM<21%<B9$:Q\]9QDW:QT[<R5#>"I(A"9'=1<X@2 \CRY*D"<]E2Q"K#U,L4)1
XMO4=.OTE0QDU.RE%2SE-2T595UEE6UUI7V&)GV&)GV&1HV65IVV=KW&ALVFEL
XMV6AKVFELW6QOWFYQW6UPW&QOWFYQX71VYGE[YX*#ZX:'[8:&ZH.#Z()_Z8.
XMYX" Y'U]X'V V'5XSW%ZU7> O&1T@RL[9Q(H@"M!71=%6A1"5Q$_61-!71=$
XM8AQ)92!(92!(<"=-8QI :AT^:!L\:1DU8Q,O;1HSG$EBBSE,@2]"E#M0CC5*
XM@B5 A"="@"I*C#96<2=)9!H\92 X;2A QWZ!X)>:U89XW(U_QWIOS8!UTH=[
XMU8I^T(M_SHE]RXI]S(M^R(A]R(A]R(A_R(A_R(A_:2M!6QTS6!DU71XZ7AM
XM81Y#8QY,71A&71=%81M)9R%,:")-8AL^6Q0W8!HX:B1"714\8QM"9AQ$81<_
XM7A4[81@^:!U";"%&:QY!<"-&<"-$:AT^91DW:1T[<") ="9$?2E*;!@Y=1T\
XM@RM*@B5 @",^E2]$HCQ1K#Y.L4-3O$=1P4Q6QT]7S55=V%QAWV-HV6-JV6-J
XMVF1KVV5LVFANVVEOVFUQVVYRUVMOWG)VXGM]XGM]WGEZW7AYX'U^Y8*#YY"/
XMZI.2ZY..YHZ)YXR#YHN"XX>!WH)\W8*"SW1TSWJ&T7R(FTYE8A4L61$N=2U*
XM5Q9%511#5A1!6!9#7AI&8AY*9Q](:"!);R1+9AM";B%":QX_:AHX914S<!X]
XMH$YMC#Q.@C)$ECU2D#=,@R8_ARI#A"Q-CC97<21':QY!8QXV;"<_R(&"WYB9
XMU8EZVX^ Q'EOS(%WTXE_UHR"SHN!RXA^R8E^RXN Q8A^Q8A^Q8=_Q8=_Q8=_
XM9B@^7B V7A\[71XZ6!4Z71H_8QY,7AE'7QE'9!Y,:R50:B1/8QP_7!4X8APZ
XM;2=%7!0[81E 91M#81<_6Q(X7!,Y9!D^:R!%:AU ;R)%;R)#:1P]9AHX:!PZ
XM;B ^;R$_>R=(;1DZ<QLZ@2E(@B5 =ADTA!XSDRU"GS%!ICA(M4!*ND5/P4E1
XMQT]7U%A=W6%FUV%HV&)IV6-JVF1KV6=MVVEOW&]SWW)VV6UQWW-WXWQ^YX""
XMYH&"Y8"!Y(&"YH.$YH^.Z9*1Z9&,Y8V(YXR#YXR#Y(B"WH)\W8*"TG=WUX*.
XMRG6!@C5,6PXE8QLX<2E&5A5$5A5$6!9#6QE&8!Q(8Q]+:"!):2%*:R!'9QQ#
XM<"-$;!] :1DW9A8T<R% I%)QCCY0A35'ESY3CS9+@R8_B"M$A"Q-BS-4<R9)
XM=2A+8QXV:R8^RH.$W)66TX=XV(Q]PG=MRX!VTXE_U8N!S8J R89\QX=\RHI_
XMQ(=]Q(=]Q(9^Q(9^Q(9^>3IH8R127!Q(7AY*6QI#6QI#8AU#7QI 8!P^9B)$
XM;B=*;29)8QP_6Q0W8AL^;RA+7!0]8!A!8QM"8AI!71,[6A X7Q8Z9QY"9QT_
XM:R%#;")"9QT]9QLY:1T[;" ^:Q\]<B5&;!] ;1\^>2M*?2I';1HW;Q(M>QXY
XMD"I!F#))J3E,L$!3N4-4ODA9R$]=SU9DTUMCU5UEUV%HV&)IUF1JV6=MVFYR
XMWW-WVG-UW'5WW'M[Y(.#YXJ)Z(N*Y(F'X8:$XHV,Y(^.YHZ+Y(R)Z8Z%ZY"'
XMZHN&Y(6 UWM]U7E[UX*1MF%P;1\^8!(Q;R=0:"!)51E&5AI'6AI&7!Q(7QY'
XM8B%*:B)):R-*:!U$9AM";R)':AU":!<Y:!<Y=21(I%-WCT%2ACA)F$!2CC9(
XM@R8_B2Q%A2I,B2Y0<R5&?S%28ATS:20ZS(6&VY25TXEWUXU[PGAPRH!XSXA_
XMTHN"RXF!R8=_QHE_R(N!PX=^PX=^PX> PX> PX> =SAF71Y,5Q=#8B).9"-,
XM7QY'81Q"7AD_8!P^9B)$;B=*;"5(81H]61(U81H];RA+714^7Q= 8QM"91U$
XM81<_7!(Z7A4Y9!L_91L]:B!":R%!:!X^:!PZ:Q\];" ^:AX\;R)#<"-$;B _
XM=2=&@"U*<R ]; \J<10O?A@OAB WF2D\I35(LSU.O4=8R$]=SU9DT%A@TUMC
XMUV%HV6-JV&9LVFANW'!TX75YWG=YW'5WVGEYXH&!Z8R+[9"/Z(V+XXB&Y(^.
XMY9"/YHZ+YHZ+[)&(\)6,[H^*YXB#SW-UU'AZSWJ)H4Q;8!(Q91<V="Q581E"
XM61U*6AY+7AY*7Q]+8!](8B%*:R-*;B9-9AM"9!E ;2!%9QH_:1@Z:QH\=R9*
XMHU)VD$)3ASE*F4%3C35'@R8_BRY'ARQ.B"U/;R%"A#978!LQ9R(XSXB)VY25
XMUHQZVI!^QGQTRH!XS(5\SXA_RXF!RXF!QXJ QXJ PH9]PH9]PH9_PH9_PH9_
XM9"5B51936!A.82%78B%*7QY'8AX^71DY8QTY:B1 <"I(;BA&81H]61(U8AI!
XM<2E08!A!7Q= 8QM":"!'91U$7A8]710X81@\9!H\:!Y :R%!:!X^:AX\;2$_
XM;2$_:AX\:2)#<"E*:B! :R%!?C!/>2M*;14T:Q,R;0PH<A$MA1@ODB4\I3%'
XMLS]5P$A;QT]BR%!8S55=U%YEUV%HU&1IUF9KV&YQW7-VUW1UUW1UU7AWVWY]
XMXH>%YXR*Y(Z*XXV)Z)&3Z)&3Z(V+YHN)[8V([X^*ZXF%XX%]T'!SUG9YR&V#
XMF3Y480\V9A0[<2159!=(72--7B1.82--7R%+8!]&8B%(;25,<2E09AM"8Q@_
XM;!U#9Q@^:A@_<!Y%>BA/HU%XCT%0ASE(ET%3BS5'A2A!D#-,C#%1C#%1;R%"
XMBSU>8!LQ9B$WT(F*V9*3UHQZV(Y\QWUUQGQTQ'YUQX%XR(9^R8=_Q8=_PX5]
XMOX9\OX9\OX9^OX9^P85^61I75QA57Q]57Q]56!= 61A!8AX^71DY9R$];2=#
XM="Y,<2M)9!U 7!4X91U$="Q381E"7Q= 8QM":B)):2%(81E 710X7Q8Z8QD[
XM:!Y :B! :1\_:Q\];B) ;B) :Q\]:"%"<2I+:!X^91L[?S%0@#)1=!P[;14T
XM<Q(N<A$M?Q(IAADPEB(XHBY$K35(LCI-O$1,PDI2R5-:S5=>REI?S%QAS6-F
XMTVELT6YOTW!QTW9UUWIYVG]]WX2"X8N'XXV)Z)&3YY"2Y8J(XH>%Z(B#Z(B#
XMXH!\V7=STG)UUG9YPVA^ESQ291,Z8Q$X;!]0:1Q-8"9082=18R5/8"),8!]&
XM8B%(;25,<RM29QQ#8Q@_:QQ"9A<];!I!<R%(?2M2HU%XC3].ASE(ET%3C#9(
XMARI#E#=0D396D#55<R5&DD1E8ATS9B$WT(F*UH^0THAVU(IXQ7MSP7=OO7=N
XMP'IQPX%YQ8-[P8-[OH!XOX9\OX9\OX9^OX9^P85^1!A 1QM#4!Q$4AY&7Q]*
XM8"!+91M'8QE%:1E%>RM7>"I3>2M45PXT7Q8\7QL]<R]181E"7A8_8!A!9AY'
XM9AY'81E"81<_9!I"5PXT7Q8\:A]&;"%(:1Y#:1Y#<"-(=BE.="0^=24_=2)%
XM<R!#>R))@RI1ARM+@B9&?AXS=Q<L=A8H>AHL@1PS@1PSA!X_BB1%D"DUF#$]
XMH3U(J450KDI3M5%:O5MCQ6-KR6=MS6MQT7%VU75ZV'A[W'Q_W8""X(.%Y(V-
XMWH>'V8& VH*!VX. VH)_TGMZRG-RPW%TR'9YK69SAC],9"$Y7ALS6QX^6!L[
XM4B!84R%98"):7!Y67Q5+:B!6<BE7:!]-9R1(81Y"7A\Y7R Z9!PS9Q\VA#-+
XMGTYFE$A;B#Q/CT%.CT%.@S(_B#=$E$!3B#1'?RI#BC5.=R4ZAC1)S("$V8V1
XMUH^$R(%VR7)TO&5GM5]AO6=IP'%SP7)TOW1TQ'EYPGU^PWY_P(& P(& P82#
XM3R-+32%)52%)7BI22@HU6!A#9!I&81=#<"!,@C)>?C!9>RU661 V7Q8\7QL]
XM<2U/8!A!7A8_7Q= 9!Q%9!Q%8!A!8!8^8QE!710Z7Q8\91I!:1Y%:R!%;2)'
XM<"-(<"-(<" Z<2$[<1Y!;QP_>!]&@BE0BBY.B2U-A"0Y@2$VA24WCR]!F31+
XMG#=.H3M<IT%BJ$%-KD=3LT]:ME)=MU-<N55>O5MCPV%IRVEOT&YTU'1YV'A]
XMW'Q_WGZ!WX*$X82&WXB(W(6%VH*!VH*!VH)_UW]\T'EXRG-RO&IMP6]RI5YK
XM>#$^51(J5Q0L92A(<3146REA52-;7R%98B1<:1]5<"9<;R948AE'9B-'81Y"
XM7A\Y8"$[9AXU:2$XA31,G4QDE$A;B#Q/D$)/D$)/@S(_AS9#DS]2B35(?BE"
XMA3!)>"8[@S%&TH:*UHJ.U8Z#PWQQO69HM5Y@L5M=M5]AM69HN6ILN6YNNW!P
XMMW)SN71UMWAWN'EXN7Q[EFF/9SI@2!0[214\71U&5!0]60\Y9!I$;B!)?S%:
XM?C!8=2=/6 \S7!,W7QL[;RM+71A 7!<_71A 8!M#8AI#8!A!7Q<^81E 8QI
XM8!<]8!4\91I!;2)'<"5*;2)':1Y#;B$\;B$\;1P^:AD[<!M!>R9,BBY.CC)2
XMCR]"DC)%GCM'K$E5N%!BO%1FP59QQ5IUT&ARTVMUUV]WUV]WTVUTTFQSU&YS
XMUW%VSVQPU'%UVG=ZWWQ_X'^!X8""XH&#XX*$YXZ/YXZ/Z9&0ZI*1Z)*,YI"*
XMX8^*X(Z)XY:3Z)N8TY&4K&IM@493;C- 7B@[4QTP5RM-3R-%7"-)6R)(6A1!
XM6Q5":")/;2=48!]&7!M"7!P[7Q\^9QXZ:R(^A3)+FD=@E$A=B3U2D4-2D4-2
XM@C$_A31"DSY4C#=-@"M$@"M$?"H_@C!%VX^3T86)TXQ_NW1GK5=9KEA:K%E:
XMJ597J%E;KV!BL61EL&-DK69GKVAIKVQLLF]OLW%RRY[$I'>=:35<, C:RM4
XM514^6A Z9QU';!Y'?"Y7?S%9<")*61 T7!,W9B)"<R]/71A 71A 7AE!7QI"
XM81E"81E"81E 81E 91Q"8AD_8!4\8Q@_:R!%;R1);"%&:!U"<B5 <",^;1P^
XM9Q8X:A4[=!]%ABI*CS-3F3E,H$!3L$U9O%EEQEYPQU]QR5YYR5YYS65OT&AR
XMTVMSU&QTTFQST6MRTFQQU&YST&UQU7)VW'E\X'V X8""X'^!X'^!X'^!UGU^
XMV8"!W(2#WH:%WHB"XHR&Y)*-Z9>2\:2A^*NH\K"SZZFLV9ZKQ(F6F6-V=D!3
XM3B)$1AH\62!&9"M191],7QE&8QU*9!Y+71Q#6AE 6AHY71T\9QXZ;B5!A3)+
XMED-<E4E>B#Q1D$)1DD13@C$_A#-!DCU3CCE/A3!)?RI#@2]$A#)'Y)B<S("$
XMSH=ZLVQ?J%)4L%I<KUQ=IE-4H5)4J%E;JEU>IUI;I5Y?IV!AIV1DJF=GJFAI
XMNHZPR9V_L'VA9C-74!(X4A0Z9!]%9!]%;B-(?3)7@SE;;B1&7Q<V8!@W<2M)
XM>C127AE!7QI"7QI"7QI"81E"8QM$8QM"8AI!8QI 8QI 8AD_8QI 9QQ!:A]$
XM:R!%;"%&;R9 ;",]:1P]9!<X9Q0Y;QQ!A"I'D3=4G3Y-ITA7NU5:Q%YCS%]I
XMS%]IS%IKRUEJQUEAREQDS&!GSF)ISV-IT&1JT6=JTFAKU6MNV6]RW79VX7IZ
XMX7IZX'EYWGEXWGEXSW)TTG5WTWAVU'EWTGYUV85\X).(Z9R1YZ28[*F=Z*^E
XM[[:L\<&\\L*]V["PQ9J:F'-T=$]082X\628T6ALW71XZ921+9B5,7!Q%61E"
XM6AH]71U :B$^<RI'BC12ET%?EDE@ASI1CD!1D4-4@C%!@S)"D#M1C3A.B3-/
XM@2M'AC1)C#I/Z9VARGZ"R(%TKVA;JEE9M&-CM61DK%M;I%57J%E;J5Q=I5A9
XMIEI=IEI=IUM>J%Q?I5Q?M8FKHG:8K'F=PY"T7!Y$5A@^71@^8QY$<"5*?C-8
XMACQ>:1]!7A8U7!0S<"I(=S%/7QI"81Q$8!M#7AE!8!A!9!Q%91U$8QM"81@^
XM8QI 9!M!8QI 9!D^9AM :R!%<"5*:B$[:2 Z:1P]9ADZ:!4Z;AM A2M(E3M8
XMG3Y-JDM:OEA=Q%YCREUGRUYHS5MLREAISF!HT&)JT65LTV=NUFIPUVMQV&YQ
XMV&YQU&IMUVUPVG-SW'5UW'5UVW1TV71SV71SV'M]V7Q^V'U[V7Y\V(1[X(R#
XMYYJ/\*.8[:J>]+&E\+>M[K6KYK:QZKJUZ;Z^Z;Z^Y<#!QJ&BJ7:$?TQ:7!TY
XM4!$M6QI!9"-*7!Q%6AI#6!@[6AH]:B$^=BU*C3=5ET%?F$MBA#=.B3M,CD!1
XM@C%!@C%!CSI0BS9,AS%-@RU)A3-(E4-8Z)R@R7V!PWQOL&E<MF5ENVIJO&MK
XMMV9FKV!BKE]AK6!AJUY?IUM>IEI=I5E<HU=:GU99R)FZ?D]P>D=IP(VOEUQ_
XM9"E,3PPP8R!$:"%"=S!1@CI98!@W6A(O6! M<"I&=C!,71E!8!Q$7QM#6Q<_
XM7!<_81Q$8QY$8!M!8!D^81H_8AD_8AD_8AD]91Q ;"%&<"5*:2([:"$Z:1\_
XM:!X^9Q@\:AL_@2I&DCM7GT!+K4Y9PEA;Q5M>S%M<SEU>TUMCT%A@S%I@S5MA
XMS5UBT&!ETV-HUF9KU&=IU&=IU6AHV&MKVF]NVW!OVG!LV6]KV6]KVG!LTW-U
XMTW-UTW9UUGEXUX-XWXN X9B(YYZ.XJ2.[:^9[;RE[;REY;NFZ+ZIZ,6P[,FT
XMX+VDY\2K\L6[VZZDKW: A$M59BI%31$L5!L]41@Z4!,V410W8QLZ<RM*BC14
XMDCQ<FTYG@C5.A#5)BSQ0@S%$@S%$CCE1B31,@"I&@BQ(@2]$G4M@XY>:RW^"
XMOWAKMF]BNW!NNF]MNVYMO7!ONFUNM&=HLF5FM&=HKV!DK5YBJ5I>IE=;I%1:
XMP)&RCV"!<3Y@;SQ>OH.F=CM>5!$U92)&91X_="U.@CI97Q<V714R7!0Q=S%-
XM?#926Q<_7QM#7AI"614]6A4]8!M#8AU#7QI 8AM 8!D^8!<]8!<]8AD]9QY"
XM;2)'<"5*;"4^:R0];2-#;")":!D]9Q@\?"5!CC=3H4)-KU!;PUE<Q%I=R5A9
XMS%M<T5EASE9>RUE?S%I@S5UBT6%FUF9KV6ENUVILUVILUFEIV&MKV6YMV6YM
XMUVUIUVUIUVUIV&YJSV]QT7%SU7AWVWY]WXN YY.(YIV-Z:"0[[&;\+*<Z+>@
XMZ;BAZ+ZIZ\&LY,&LXK^JZ\BOX\"G[+^U\,.Y\KG#W:2NJFZ)<#1/3A4W2A$S
XM2 LN2 LN7!0S;25$A2]/BS55G$]H@#-,@#%%B3I.@S%$@S%$C3A0AS)*>B1
XM@"I&?"H_H4]DWI*5S("#O79INW1GOW1RN6YLNVYMPG5TPG5VN6QMMFEJNFUN
XMM69JLV1HKE]CJEM?J%A>LH.D>4IK=4)D:#57BE%SK7266AL^929)8Q\_<2U-
XM>3-18QT[5Q$M4 HF>#!-=BY+6Q<_7AI"7AI"6Q<_614]7!A 8QY$9B%'9!U"
XM8AM 8!D^7Q@]81@\91Q :2!$;"-'<"@_;R<^>"Y.9QT]8!$U:1H^=1\]B3-1
XMH$%.K4Y;NU)2O%-3RU95S%=6T5-6UUE<SUMAT%QBT5UATU]CU61GUV9IUF=G
XMU69FV&EIVFMKVFYKVV]LV6UJV6UJV6UIVFYJTG!NUW5SVGYXX(1^W8Q_Y).&
XMY9^,[*:3Z["7Z["7YK:9Y[>:Y+R<Y;V=Y+Z>Y;^?[,FBZL>@Z[^EZKZD]<&Z
XM^,2][+? W*>PAU9J62@\0@TF210M6A8T8AX\?RY0D#]AFTUK?2]-A#5,@C-*
XM>RD^AC1)A3!)@"M$A2]+@"I&=B0YMF1YTX>*SX.&O7=GP7MKP7EVP7EVP7EV
XMP'AUP'5UOG-SO'%QNF]ON&INMVEMMF=KM&5ILF)HJ7J;I7:7<C]A52)$@4AJ
XMJ7"2HV2'518Y8Q\_;2E)="Y,81LY61,O4PTI>S-0>#!-71E!7QM#8!Q$7!A
XM6A8^7!A 8AU#9B%':2)'9A]$8QQ!8!D^81@\9!L_:!]#:B%%<"@_<2E >S%1
XM:R%!8Q0X:AL_=1\]B3-1GT!-K4Y;NU)2O%-3S%=6S%=6T5-6UUE<T5UCT5UC
XMT5UATEYBU&-FUV9IV6IJVFMKV6IJVVQLVFYKV6UJV&QIV&QIVFYJW'!LU')P
XMV7=UW(!ZX85_WHV Y).&Y)Z+ZZ62ZJ^6ZJ^6Y+27YK:9X[N;Y+R<X[V=Y+Z>
XMY,&:Z,6>[L*H[L*H]<&Z^<6^]L'*[KG"W*N_H&^#93!)3!<P6!0R:"1"?BU/
XM?2Q.F4MI>RU+@S1+@3))>RD^AC1)AC%*@2Q%@RU)?"9"=B0YNVE^U(B+RW^"
XMO'9FQ'YNPWMXPWMXPWMXPGIWPG=WP'5UOG-SO'%QO&YRNVUQN6INMVALMF9L
XM?$MOHG&5C5I^82Y28"I-@4MNO(&D;S1782%"9B9';"A(7!@X7!8T6!(P?C95
XM>3%07AU$7QY%7QY%71Q#7!A 7!A 8!U"92)';"=,:21)9A]$8AM 81H]8QP_
XM9A]":"%$="<^=2@_@C13="9%:1<^;!I!=!X^B3-3G3]0K4]@O%)5O%)5S597
XMSUA9TU-7V%A<T5UCT5UCT5UCTU]EU&-FV&=JW&QOWV]RVVQLW&UMV6QLUVIJ
XMUFIGUVMHVV]LWG)OV'9PW7MUWX1[XH=^WXZ!Y).&Y)Z+Z:.0Z*V4Z*V4YK*4
XMY[.5YK:7Y[>8Y[F8Z+J9X[B6Z\">]L.E]<*D],"J]\.M]\B[^,F\^]71X;NW
XML8>.=DQ361XU5!DP:B!"<RE+E$9G=RE*@#!*?R])>2<^AC1+AS)+@BU&?RE'
XM=!X\=B0YQ'*'UHJ-QGI]NG1DR8-SQ7Y[Q7Y[Q'UZPWQYPGMZP'EXOW9VOG5U
XMOG5WO71VO'!SNFYQN6UQ83!47RY2H6Z2D%V!5!Y!9S%4E%E\J6Z19"1%9"1%
XM9B)"6A8V7A@V6A0R?C95=R].82!'8!]&82!'8!]&7AI"7!A 7QQ!92)';RI/
XM:R9+9R!%8QQ!8AL^9!U 9R!#:B-&=2@_>"M"ASE8>RU,;1M";!I!<QT]BC14
XMFSU.K4]@O5-6O%)5S597T5I;U559UU=;SEI@T%QBU&!FUF)HUV9IVFELW6UP
XMX'!SW6YNW&UMV&MKUFEIU&AEUFIGVV]LWW-PW'ITX'YXX89]Y(F WXZ!XY*%
XMXYV*Z**/YJN2YJN2Y+"2Y;&3Y+25Y;66Y;>6YKB7Y+F7ZK^=\\"B\K^A[[NE
XM\;VG\<*U]L>ZZ<._^M30\\G0P9>>B$UD61XU7A0V<RE+CD!A<2-$>RM%>RM%
XM=R4\A#))AC%*@BU&?"9$;!8T=B0YS'J/UXN.P75XNG1DS8=WQG]\QG]\Q7Y[
XMQ'UZPGMZP7IYP7AXP'=WP7AZP'=YP'1WOG)UO'!T=T9M-00KAU-ZOHJQ:319
XM;CE>=CUAQHVQ9RA,8R1(8R!$618Z7A<Z61(U?3-5=BQ.8B%(8!]&82!'8B%(
XM8!Q$6Q<_7AM 92)';BE.:B5*92!%81Q!8AL^91Y!:B-&;29)>B@]?BQ!CCQ<
XM@S%1<!Q&:Q=!<1H^BS18ESM/K%!DO%1<NE):S%9=TEQCUE9>UU=?QU5=S5MC
XMU&)JV6=OVFIQVVMRW&QQW6URVVYPVFUOV&MMU6AJTVAGU6IIVW!OWW1SWGUU
XMXH%YXH=]Y8J WXZ!XY*%XIR)YZ&.YZ>2Z*B3Y:R2YJV3Z*^3ZK&5Z[.5Z[.5
XM[;>B[KBC\+J?\;N@\;V<\KZ=[<2A\<BEZ,FL\M.V]M3*ZLB^Q)*B>$96618X
XM92)$B#E=:QQ =B9"=R=#<R Y@2Y'A"Y*@"I&>B1"9Q$O=R4ZT7^4U8F,OW-V
XMNW5ES8=WQ(!\Q(!\PGYZP7UYP'QZOWMYOWMYOGIXOWI[OGEZNWAXN79VMW1U
X
Xend
END_OF_FILE
if test 32122 -ne `wc -c <'timg.ppm.u.b'`; then
echo shar: \"'timg.ppm.u.b'\" unpacked with wrong size!
elif [ -f timg.ppm.u.a ]; then
echo shar: Combining \"'timg.ppm.u.a'\" and \"'timg.ppm.u.b'\"
cat timg.ppm.u.a timg.ppm.u.b > testimg.ppm.u
echo shar: Removing \"'timg.ppm.u.a'\" and \"'timg.ppm.u.b'\"
rm timg.ppm.u.a timg.ppm.u.b
echo shar: Uudecoding \"'testimg.ppm.u'\"
cat testimg.ppm.u | uudecode
if [ -f testimg.ppm ]; then
echo shar: Removing \"'testimg.ppm.u'\"
rm testimg.ppm.u
fi
fi
# end of 'timg.ppm.u.b'
fi
echo shar: End of archive 8 \(of 18\).
cp /dev/null ark8isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: example.c jmemnobs.c jquant1.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:46 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 9 (of 18)."'
if test -f 'example.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'example.c'\"
else
echo shar: Extracting \"'example.c'\" \(26472 characters\)
sed "s/^X//" >'example.c' <<'END_OF_FILE'
X/*
X * example.c
X *
X * This file is not actually part of the JPEG software. Rather, it provides
X * a skeleton that may be useful for constructing applications that use the
X * JPEG software as subroutines. This code will NOT do anything useful as is.
X *
X * This file illustrates how to use the JPEG code as a subroutine library
X * to read or write JPEG image files. We assume here that you are not
X * merely interested in converting the image to yet another image file format
X * (if you are, you should be adding another I/O module to cjpeg/djpeg, not
X * constructing a new application). Instead, we show how to pass the
X * decompressed image data into or out of routines that you provide. For
X * example, a viewer program might use the JPEG decompressor together with
X * routines that write the decompressed image directly to a display.
X *
X * We present these routines in the same coding style used in the JPEG code
X * (ANSI function definitions, etc); but you are of course free to code your
X * routines in a different style if you prefer.
X */
X
X/*
X * Include file for declaring JPEG data structures.
X * This file also includes some system headers like <stdio.h>;
X * if you prefer, you can include "jconfig.h" and "jpegdata.h" instead.
X */
X
X#include "jinclude.h"
X
X/*
X * <setjmp.h> is used for the optional error recovery mechanism shown in
X * the second part of the example.
X */
X
X#include <setjmp.h>
X
X
X
X/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
X
X/* This half of the example shows how to feed data into the JPEG compressor.
X * We present a minimal version that does not worry about refinements such
X * as error recovery (the JPEG code will just exit() if it gets an error).
X */
X
X
X/*
X * To supply the image data for compression, you must define three routines
X * input_init, get_input_row, and input_term. These routines will be called
X * from the JPEG compressor via function pointer values that you store in the
X * cinfo data structure; hence they need not be globally visible and the exact
X * names don't matter. (In fact, the "METHODDEF" macro expands to "static" if
X * you use the unmodified JPEG include files.)
X *
X * The input file reading modules (jrdppm.c, jrdgif.c, jrdtarga.c, etc) may be
X * useful examples of what these routines should actually do, although each of
X * them is encrusted with a lot of specialized code for its own file format.
X */
X
X
XMETHODDEF void
Xinput_init (compress_info_ptr cinfo)
X/* Initialize for input; return image size and component data. */
X{
X /* This routine must return five pieces of information about the incoming
X * image, and must do any setup needed for the get_input_row routine.
X * The image information is returned in fields of the cinfo struct.
X * (If you don't care about modularity, you could initialize these fields
X * in the main JPEG calling routine, and make this routine be a no-op.)
X * We show some example values here.
X */
X cinfo->image_width = 640; /* width in pixels */
X cinfo->image_height = 480; /* height in pixels */
X /* JPEG views an image as being a rectangular array of pixels, with each
X * pixel having the same number of "component" values (color channels).
X * You must specify how many components there are and the colorspace
X * interpretation of the components. Most applications will use RGB data or
X * grayscale data. If you want to use something else, you'll need to study
X * and perhaps modify jcdeflts.c, jccolor.c, and jdcolor.c.
X */
X cinfo->input_components = 3; /* or 1 for grayscale */
X cinfo->in_color_space = CS_RGB; /* or CS_GRAYSCALE for grayscale */
X cinfo->data_precision = 8; /* bits per pixel component value */
X /* In the current JPEG software, data_precision must be set equal to
X * BITS_IN_JSAMPLE, which is 8 unless you twiddle jconfig.h. Future
X * versions might allow you to say either 8 or 12 if compiled with
X * 12-bit JSAMPLEs, or up to 16 in lossless mode. In any case,
X * it is up to you to scale incoming pixel values to the range
X * 0 .. (1<<data_precision)-1.
X * If your image data format is fixed at a byte per component,
X * then saying "8" is probably the best long-term solution.
X */
X}
X
X
X/*
X * This function is called repeatedly and must supply the next row of pixels
X * on each call. The rows MUST be returned in top-to-bottom order if you want
X * your JPEG files to be compatible with everyone else's. (If you cannot
X * readily read your data in that order, you'll need an intermediate array to
X * hold the image. See jrdtarga.c or jrdrle.c for examples of handling
X * bottom-to-top source data using the JPEG code's portable mechanisms.)
X * The data is to be returned into a 2-D array of JSAMPLEs, indexed as
X * JSAMPLE pixel_row[component][column]
X * where component runs from 0 to cinfo->input_components-1, and column runs
X * from 0 to cinfo->image_width-1 (column 0 is left edge of image). Note that
X * this is actually an array of pointers to arrays rather than a true 2D array,
X * since C does not support variable-size multidimensional arrays.
X * JSAMPLE is typically typedef'd as "unsigned char".
X */
X
X
XMETHODDEF void
Xget_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* Read next row of pixels into pixel_row[][] */
X{
X /* This example shows how you might read RGB data (3 components)
X * from an input file in which the data is stored 3 bytes per pixel
X * in left-to-right, top-to-bottom order.
X */
X register FILE * infile = cinfo->input_file;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = 0; col < cinfo->image_width; col++) {
X *ptr0++ = (JSAMPLE) getc(infile); /* red */
X *ptr1++ = (JSAMPLE) getc(infile); /* green */
X *ptr2++ = (JSAMPLE) getc(infile); /* blue */
X }
X}
X
X
XMETHODDEF void
Xinput_term (compress_info_ptr cinfo)
X/* Finish up at the end of the input */
X{
X /* This termination routine will very often have no work to do, */
X /* but you must provide it anyway. */
X /* Note that the JPEG code will only call it during successful exit; */
X /* if you want it called during error exit, you gotta do that yourself. */
X}
X
X
X/*
X * That's it for the routines that deal with reading the input image data.
X * Now we have overall control and parameter selection routines.
X */
X
X
X/*
X * This routine must determine what output JPEG file format is to be written,
X * and make any other compression parameter changes that are desirable.
X * This routine gets control after the input file header has been read
X * (i.e., right after input_init has been called). You could combine its
X * functions into input_init, or even into the main control routine, but
X * if you have several different input_init routines, it's a definite win
X * to keep this separate. You MUST supply this routine even if it's a no-op.
X */
X
XMETHODDEF void
Xc_ui_method_selection (compress_info_ptr cinfo)
X{
X /* If the input is gray scale, generate a monochrome JPEG file. */
X if (cinfo->in_color_space == CS_GRAYSCALE)
X j_monochrome_default(cinfo);
X /* For now, always select JFIF output format. */
X jselwjfif(cinfo);
X}
X
X
X/*
X * OK, here is the main function that actually causes everything to happen.
X * We assume here that the target filename is supplied by the caller of this
X * routine, and that all JPEG compression parameters can be default values.
X */
X
XGLOBAL void
Xwrite_JPEG_file (char * filename)
X{
X /* These three structs contain JPEG parameters and working data.
X * They must survive for the duration of parameter setup and one
X * call to jpeg_compress; typically, making them local data in the
X * calling routine is the best strategy.
X */
X struct compress_info_struct cinfo;
X struct compress_methods_struct c_methods;
X struct external_methods_struct e_methods;
X
X /* Initialize the system-dependent method pointers. */
X cinfo.methods = &c_methods; /* links to method structs */
X cinfo.emethods = &e_methods;
X /* Here we use the default JPEG error handler, which will just print
X * an error message on stderr and call exit(). See the second half of
X * this file for an example of more graceful error recovery.
X */
X jselerror(&e_methods); /* select std error/trace message routines */
X /* Here we use the standard memory manager provided with the JPEG code.
X * In some cases you might want to replace the memory manager, or at
X * least the system-dependent part of it, with your own code.
X */
X jselmemmgr(&e_methods); /* select std memory allocation routines */
X /* If the compressor requires full-image buffers (for entropy-coding
X * optimization or a noninterleaved JPEG file), it will create temporary
X * files for anything that doesn't fit within the maximum-memory setting.
X * (Note that temp files are NOT needed if you use the default parameters.)
X * You can change the default maximum-memory setting by changing
X * e_methods.max_memory_to_use after jselmemmgr returns.
X * On some systems you may also need to set up a signal handler to
X * ensure that temporary files are deleted if the program is interrupted.
X * (This is most important if you are on MS-DOS and use the jmemdos.c
X * memory manager back end; it will try to grab extended memory for
X * temp files, and that space will NOT be freed automatically.)
X * See jcmain.c or jdmain.c for an example signal handler.
X */
X
X /* Here, set up pointers to your own routines for input data handling
X * and post-init parameter selection.
X */
X c_methods.input_init = input_init;
X c_methods.get_input_row = get_input_row;
X c_methods.input_term = input_term;
X c_methods.c_ui_method_selection = c_ui_method_selection;
X
X /* Set up default JPEG parameters in the cinfo data structure. */
X j_c_defaults(&cinfo, 75, FALSE);
X /* Note: 75 is the recommended default quality level; you may instead pass
X * a user-specified quality level. Be aware that values below 25 will cause
X * non-baseline JPEG files to be created (and a warning message to that
X * effect to be emitted on stderr). This won't bother our decoder, but some
X * commercial JPEG implementations may choke on non-baseline JPEG files.
X * If you want to force baseline compatibility, pass TRUE instead of FALSE.
X * (If non-baseline files are fine, but you could do without that warning
X * message, set e_methods.trace_level to -1.)
X */
X
X /* At this point you can modify the default parameters set by j_c_defaults
X * as needed. For a minimal implementation, you shouldn't need to change
X * anything. See jcmain.c for some examples of what you might change.
X */
X
X /* Select the input and output files.
X * Note that cinfo.input_file is only used if your input reading routines
X * use it; otherwise, you can just make it NULL.
X * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
X * requires it in order to write binary files.
X */
X
X cinfo.input_file = NULL; /* if no actual input file involved */
X
X if ((cinfo.output_file = fopen(filename, "wb")) == NULL) {
X fprintf(stderr, "can't open %s\n", filename);
X exit(1);
X }
X
X /* Here we go! */
X jpeg_compress(&cinfo);
X
X /* That's it, son. Nothin' else to do, except close files. */
X /* Here we assume only the output file need be closed. */
X fclose(cinfo.output_file);
X
X /* Note: if you want to compress more than one image, we recommend you
X * repeat this whole routine. You MUST repeat the j_c_defaults()/alter
X * parameters/jpeg_compress() sequence, as some data structures allocated
X * in j_c_defaults are freed upon exit from jpeg_compress.
X */
X}
X
X
X
X/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
X
X/* This half of the example shows how to read data from the JPEG decompressor.
X * It's a little more refined than the above in that we show how to do your
X * own error recovery. If you don't care about that, you don't need these
X * next two routines.
X */
X
X
X/*
X * These routines replace the default trace/error routines included with the
X * JPEG code. The example trace_message routine shown here is actually the
X * same as the standard one, but you could modify it if you don't want messages
X * sent to stderr. The example error_exit routine is set up to return
X * control to read_JPEG_file() rather than calling exit(). You can use the
X * same routines for both compression and decompression error recovery.
X */
X
X/* These static variables are needed by the error routines. */
Xstatic jmp_buf setjmp_buffer; /* for return to caller */
Xstatic external_methods_ptr emethods; /* needed for access to message_parm */
X
X
X/* This routine is used for any and all trace, debug, or error printouts
X * from the JPEG code. The parameter is a printf format string; up to 8
X * integer data values for the format string have been stored in the
X * message_parm[] field of the external_methods struct.
X */
X
XMETHODDEF void
Xtrace_message (const char *msgtext)
X{
X fprintf(stderr, msgtext,
X emethods->message_parm[0], emethods->message_parm[1],
X emethods->message_parm[2], emethods->message_parm[3],
X emethods->message_parm[4], emethods->message_parm[5],
X emethods->message_parm[6], emethods->message_parm[7]);
X fprintf(stderr, "\n"); /* there is no \n in the format string! */
X}
X
X/*
X * The error_exit() routine should not return to its caller. The default
X * routine calls exit(), but here we assume that we want to return to
X * read_JPEG_data, which has set up a setjmp context for the purpose.
X * You should make sure that the free_all method is called, either within
X * error_exit or after the return to the outer-level routine.
X */
X
XMETHODDEF void
Xerror_exit (const char *msgtext)
X{
X trace_message(msgtext); /* report the error message */
X (*emethods->free_all) (); /* clean up memory allocation & temp files */
X longjmp(setjmp_buffer, 1); /* return control to outer routine */
X}
X
X
X
X/*
X * To accept the image data from decompression, you must define four routines
X * output_init, put_color_map, put_pixel_rows, and output_term.
X *
X * You must understand the distinction between full color output mode
X * (N independent color components) and colormapped output mode (a single
X * output component representing an index into a color map). You should use
X * colormapped mode to write to a colormapped display screen or output file.
X * Colormapped mode is also useful for reducing grayscale output to a small
X * number of gray levels: when using the 1-pass quantizer on grayscale data,
X * the colormap entries will be evenly spaced from 0 to MAX_JSAMPLE, so you
X * can regard the indexes are directly representing gray levels at reduced
X * precision. In any other case, you should not depend on the colormap
X * entries having any particular order.
X * To get colormapped output, set cinfo->quantize_colors to TRUE and set
X * cinfo->desired_number_of_colors to the maximum number of entries in the
X * colormap. This can be done either in your main routine or in
X * d_ui_method_selection. For grayscale quantization, also set
X * cinfo->two_pass_quantize to FALSE to ensure the 1-pass quantizer is used
X * (presently this is the default, but it may not be so in the future).
X *
X * The output file writing modules (jwrppm.c, jwrgif.c, jwrtarga.c, etc) may be
X * useful examples of what these routines should actually do, although each of
X * them is encrusted with a lot of specialized code for its own file format.
X */
X
X
XMETHODDEF void
Xoutput_init (decompress_info_ptr cinfo)
X/* This routine should do any setup required */
X{
X /* This routine can initialize for output based on the data passed in cinfo.
X * Useful fields include:
X * image_width, image_height Pretty obvious, I hope.
X * data_precision bits per pixel value; typically 8.
X * out_color_space output colorspace previously requested
X * color_out_comps number of color components in same
X * final_out_comps number of components actually output
X * final_out_comps is 1 if quantize_colors is true, else it is equal to
X * color_out_comps.
X *
X * If you have requested color quantization, the colormap is NOT yet set.
X * You may wish to defer output initialization until put_color_map is called.
X */
X}
X
X
X/*
X * This routine is called if and only if you have set cinfo->quantize_colors
X * to TRUE. It is given the selected colormap and can complete any required
X * initialization. This call will occur after output_init and before any
X * calls to put_pixel_rows. Note that the colormap pointer is also placed
X * in a cinfo field, whence it can be used by put_pixel_rows or output_term.
X * num_colors will be less than or equal to desired_number_of_colors.
X *
X * The colormap data is supplied as a 2-D array of JSAMPLEs, indexed as
X * JSAMPLE colormap[component][indexvalue]
X * where component runs from 0 to cinfo->color_out_comps-1, and indexvalue
X * runs from 0 to num_colors-1. Note that this is actually an array of
X * pointers to arrays rather than a true 2D array, since C does not support
X * variable-size multidimensional arrays.
X * JSAMPLE is typically typedef'd as "unsigned char". If you want your code
X * to be as portable as the JPEG code proper, you should always access JSAMPLE
X * values with the GETJSAMPLE() macro, which will do the right thing if the
X * machine has only signed chars.
X */
X
XMETHODDEF void
Xput_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
X/* Write the color map */
X{
X /* You need not provide this routine if you always set cinfo->quantize_colors
X * FALSE; but a safer practice is to provide it and have it just print an
X * error message, like this:
X */
X fprintf(stderr, "put_color_map called: there's a bug here somewhere!\n");
X}
X
X
X/*
X * This function is called repeatedly, with a few more rows of pixels supplied
X * on each call. With the current JPEG code, some multiple of 8 rows will be
X * passed on each call except the last, but it is extremely bad form to depend
X * on this. You CAN assume num_rows > 0.
X * The data is supplied in top-to-bottom row order (the standard order within
X * a JPEG file). If you cannot readily use the data in that order, you'll
X * need an intermediate array to hold the image. See jwrrle.c for an example
X * of outputting data in bottom-to-top order.
X *
X * The data is supplied as a 3-D array of JSAMPLEs, indexed as
X * JSAMPLE pixel_data[component][row][column]
X * where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
X * num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
X * left edge of image). Note that this is actually an array of pointers to
X * pointers to arrays rather than a true 3D array, since C does not support
X * variable-size multidimensional arrays.
X * JSAMPLE is typically typedef'd as "unsigned char". If you want your code
X * to be as portable as the JPEG code proper, you should always access JSAMPLE
X * values with the GETJSAMPLE() macro, which will do the right thing if the
X * machine has only signed chars.
X *
X * If quantize_colors is true, then there is only one component, and its values
X * are indexes into the previously supplied colormap. Otherwise the values
X * are actual data in your selected output colorspace.
X */
X
X
XMETHODDEF void
Xput_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
X/* Write some rows of output data */
X{
X /* This example shows how you might write full-color RGB data (3 components)
X * to an output file in which the data is stored 3 bytes per pixel.
X */
X register FILE * outfile = cinfo->output_file;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X register int row;
X
X for (row = 0; row < num_rows; row++) {
X ptr0 = pixel_data[0][row];
X ptr1 = pixel_data[1][row];
X ptr2 = pixel_data[2][row];
X for (col = 0; col < cinfo->image_width; col++) {
X putc(GETJSAMPLE(*ptr0), outfile); /* red */
X ptr0++;
X putc(GETJSAMPLE(*ptr1), outfile); /* green */
X ptr1++;
X putc(GETJSAMPLE(*ptr2), outfile); /* blue */
X ptr2++;
X }
X }
X}
X
X
XMETHODDEF void
Xoutput_term (decompress_info_ptr cinfo)
X/* Finish up at the end of the output */
X{
X /* This termination routine may not need to do anything. */
X /* Note that the JPEG code will only call it during successful exit; */
X /* if you want it called during error exit, you gotta do that yourself. */
X}
X
X
X/*
X * That's it for the routines that deal with writing the output image.
X * Now we have overall control and parameter selection routines.
X */
X
X
X/*
X * This routine gets control after the JPEG file header has been read;
X * at this point the image size and colorspace are known.
X * The routine must determine what output routines are to be used, and make
X * any decompression parameter changes that are desirable. For example,
X * if it is found that the JPEG file is grayscale, you might want to do
X * things differently than if it is color. You can also delay setting
X * quantize_colors and associated options until this point.
X *
X * j_d_defaults initializes out_color_space to CS_RGB. If you want grayscale
X * output you should set out_color_space to CS_GRAYSCALE. Note that you can
X * force grayscale output from a color JPEG file (though not vice versa).
X */
X
XMETHODDEF void
Xd_ui_method_selection (decompress_info_ptr cinfo)
X{
X /* if grayscale input, force grayscale output; */
X /* else leave the output colorspace as set by main routine. */
X if (cinfo->jpeg_color_space == CS_GRAYSCALE)
X cinfo->out_color_space = CS_GRAYSCALE;
X
X /* select output routines */
X cinfo->methods->output_init = output_init;
X cinfo->methods->put_color_map = put_color_map;
X cinfo->methods->put_pixel_rows = put_pixel_rows;
X cinfo->methods->output_term = output_term;
X}
X
X
X/*
X * OK, here is the main function that actually causes everything to happen.
X * We assume here that the JPEG filename is supplied by the caller of this
X * routine, and that all decompression parameters can be default values.
X * The routine returns 1 if successful, 0 if not.
X */
X
XGLOBAL int
Xread_JPEG_file (char * filename)
X{
X /* These three structs contain JPEG parameters and working data.
X * They must survive for the duration of parameter setup and one
X * call to jpeg_decompress; typically, making them local data in the
X * calling routine is the best strategy.
X */
X struct decompress_info_struct cinfo;
X struct decompress_methods_struct dc_methods;
X struct external_methods_struct e_methods;
X
X /* Select the input and output files.
X * In this example we want to open the input file before doing anything else,
X * so that the setjmp() error recovery below can assume the file is open.
X * Note that cinfo.output_file is only used if your output handling routines
X * use it; otherwise, you can just make it NULL.
X * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
X * requires it in order to read binary files.
X */
X
X if ((cinfo.input_file = fopen(filename, "rb")) == NULL) {
X fprintf(stderr, "can't open %s\n", filename);
X return 0;
X }
X
X cinfo.output_file = NULL; /* if no actual output file involved */
X
X /* Initialize the system-dependent method pointers. */
X cinfo.methods = &dc_methods; /* links to method structs */
X cinfo.emethods = &e_methods;
X /* Here we supply our own error handler; compare to use of standard error
X * handler in the previous write_JPEG_file example.
X */
X emethods = &e_methods; /* save struct addr for possible access */
X e_methods.error_exit = error_exit; /* supply error-exit routine */
X e_methods.trace_message = trace_message; /* supply trace-message routine */
X
X /* prepare setjmp context for possible exit from error_exit */
X if (setjmp(setjmp_buffer)) {
X /* If we get here, the JPEG code has signaled an error.
X * Memory allocation has already been cleaned up (see free_all call in
X * error_exit), but we need to close the input file before returning.
X * You might also need to close an output file, etc.
X */
X fclose(cinfo.input_file);
X return 0;
X }
X
X /* Here we use the standard memory manager provided with the JPEG code.
X * In some cases you might want to replace the memory manager, or at
X * least the system-dependent part of it, with your own code.
X */
X jselmemmgr(&e_methods); /* select std memory allocation routines */
X /* If the decompressor requires full-image buffers (for two-pass color
X * quantization or a noninterleaved JPEG file), it will create temporary
X * files for anything that doesn't fit within the maximum-memory setting.
X * You can change the default maximum-memory setting by changing
X * e_methods.max_memory_to_use after jselmemmgr returns.
X * On some systems you may also need to set up a signal handler to
X * ensure that temporary files are deleted if the program is interrupted.
X * (This is most important if you are on MS-DOS and use the jmemdos.c
X * memory manager back end; it will try to grab extended memory for
X * temp files, and that space will NOT be freed automatically.)
X * See jcmain.c or jdmain.c for an example signal handler.
X */
X
X /* Here, set up the pointer to your own routine for post-header-reading
X * parameter selection. You could also initialize the pointers to the
X * output data handling routines here, if they are not dependent on the
X * image type.
X */
X dc_methods.d_ui_method_selection = d_ui_method_selection;
X
X /* Set up default decompression parameters. */
X j_d_defaults(&cinfo, TRUE);
X /* TRUE indicates that an input buffer should be allocated.
X * In unusual cases you may want to allocate the input buffer yourself;
X * see jddeflts.c for commentary.
X */
X
X /* At this point you can modify the default parameters set by j_d_defaults
X * as needed; for example, you can request color quantization or force
X * grayscale output. See jdmain.c for examples of what you might change.
X */
X
X /* Set up to read a JFIF or baseline-JPEG file. */
X /* This is the only JPEG file format currently supported. */
X jselrjfif(&cinfo);
X
X /* Here we go! */
X jpeg_decompress(&cinfo);
X
X /* That's it, son. Nothin' else to do, except close files. */
X /* Here we assume only the input file need be closed. */
X fclose(cinfo.input_file);
X
X return 1; /* indicate success */
X
X /* Note: if you want to decompress more than one image, we recommend you
X * repeat this whole routine. You MUST repeat the j_d_defaults()/alter
X * parameters/jpeg_decompress() sequence, as some data structures allocated
X * in j_d_defaults are freed upon exit from jpeg_decompress.
X */
X}
END_OF_FILE
if test 26472 -ne `wc -c <'example.c'`; then
echo shar: \"'example.c'\" unpacked with wrong size!
fi
# end of 'example.c'
fi
if test -f 'jmemnobs.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemnobs.c'\"
else
echo shar: Extracting \"'jmemnobs.c'\" \(2263 characters\)
sed "s/^X//" >'jmemnobs.c' <<'END_OF_FILE'
X/*
X * jmemnobs.c (jmemsys.c)
X *
X * Copyright (C) 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file provides a really simple implementation of the system-
X * dependent portion of the JPEG memory manager. This implementation
X * assumes that no backing-store files are needed: all required space
X * can be obtained from malloc().
X * This is very portable in the sense that it'll compile on almost anything,
X * but you'd better have lots of main memory (or virtual memory) if you want
X * to process big images.
X * Note that the max_memory_to_use option is ignored by this implementation.
X */
X
X#include "jinclude.h"
X#include "jmemsys.h"
X
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare malloc(), free() */
X#else
Xextern void * malloc PP((size_t size));
Xextern void free PP((void *ptr));
X#endif
X
X
Xstatic external_methods_ptr methods; /* saved for access to error_exit */
X
X
X/*
X * Memory allocation and freeing are controlled by the regular library
X * routines malloc() and free().
X */
X
XGLOBAL void *
Xjget_small (size_t sizeofobject)
X{
X return (void *) malloc(sizeofobject);
X}
X
XGLOBAL void
Xjfree_small (void * object)
X{
X free(object);
X}
X
X/*
X * We assume NEED_FAR_POINTERS is not defined and so the separate entry points
X * jget_large, jfree_large are not needed.
X */
X
X
X/*
X * This routine computes the total memory space available for allocation.
X * Here we always say, "we got all you want bud!"
X */
X
XGLOBAL long
Xjmem_available (long min_bytes_needed, long max_bytes_needed)
X{
X return max_bytes_needed;
X}
X
X
X/*
X * Backing store (temporary file) management.
X * This should never be called and we just error out.
X */
X
XGLOBAL void
Xjopen_backing_store (backing_store_ptr info, long total_bytes_needed)
X{
X ERREXIT(methods, "Backing store not supported");
X}
X
X
X/*
X * These routines take care of any system-dependent initialization and
X * cleanup required. Keep in mind that jmem_term may be called more than
X * once.
X */
X
XGLOBAL void
Xjmem_init (external_methods_ptr emethods)
X{
X methods = emethods; /* save struct addr for error exit access */
X emethods->max_memory_to_use = 0;
X}
X
XGLOBAL void
Xjmem_term (void)
X{
X /* no work */
X}
END_OF_FILE
if test 2263 -ne `wc -c <'jmemnobs.c'`; then
echo shar: \"'jmemnobs.c'\" unpacked with wrong size!
fi
# end of 'jmemnobs.c'
fi
if test -f 'jquant1.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jquant1.c'\"
else
echo shar: Extracting \"'jquant1.c'\" \(21850 characters\)
sed "s/^X//" >'jquant1.c' <<'END_OF_FILE'
X/*
X * jquant1.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains 1-pass color quantization (color mapping) routines.
X * These routines are invoked via the methods color_quantize
X * and color_quant_init/term.
X */
X
X#include "jinclude.h"
X
X#ifdef QUANT_1PASS_SUPPORTED
X
X
X/*
X * The main purpose of 1-pass quantization is to provide a fast, if not very
X * high quality, colormapped output capability. A 2-pass quantizer usually
X * gives better visual quality; however, for quantized grayscale output this
X * quantizer is perfectly adequate. Dithering is highly recommended with this
X * quantizer, though you can turn it off if you really want to.
X *
X * This implementation quantizes in the output colorspace. This has a couple
X * of disadvantages: each pixel must be individually color-converted, and if
X * the color conversion includes gamma correction then quantization is done in
X * a nonlinear space, which is less desirable. The major advantage is that
X * with the usual output color spaces (RGB, grayscale) an orthogonal grid of
X * representative colors can be used, thus permitting the very simple and fast
X * color lookup scheme used here. The standard JPEG colorspace (YCbCr) cannot
X * be effectively handled this way, because only about a quarter of an
X * orthogonal grid would fall within the gamut of realizable colors. Another
X * advantage is that when the user wants quantized grayscale output from a
X * color JPEG file, this quantizer can provide a high-quality result with no
X * special hacking.
X *
X * The gamma-correction problem could be eliminated by adjusting the grid
X * spacing to counteract the gamma correction applied by color_convert.
X * At this writing, gamma correction is not implemented by jdcolor, so
X * nothing is done here.
X *
X * In 1-pass quantization the colormap must be chosen in advance of seeing the
X * image. We use a map consisting of all combinations of Ncolors[i] color
X * values for the i'th component. The Ncolors[] values are chosen so that
X * their product, the total number of colors, is no more than that requested.
X * (In most cases, the product will be somewhat less.)
X *
X * Since the colormap is orthogonal, the representative value for each color
X * component can be determined without considering the other components;
X * then these indexes can be combined into a colormap index by a standard
X * N-dimensional-array-subscript calculation. Most of the arithmetic involved
X * can be precalculated and stored in the lookup table colorindex[].
X * colorindex[i][j] maps pixel value j in component i to the nearest
X * representative value (grid plane) for that component; this index is
X * multiplied by the array stride for component i, so that the
X * index of the colormap entry closest to a given pixel value is just
X * sum( colorindex[component-number][pixel-component-value] )
X * Aside from being fast, this scheme allows for variable spacing between
X * representative values with no additional lookup cost.
X */
X
X
X#define MAX_COMPONENTS 4 /* max components I can handle */
X
Xstatic JSAMPARRAY colormap; /* The actual color map */
X/* colormap[i][j] = value of i'th color component for output pixel value j */
X
Xstatic JSAMPARRAY colorindex; /* Precomputed mapping for speed */
X/* colorindex[i][j] = index of color closest to pixel value j in component i,
X * premultiplied as described above. Since colormap indexes must fit into
X * JSAMPLEs, the entries of this array will too.
X */
X
Xstatic JSAMPARRAY input_buffer; /* color conversion workspace */
X/* Since our input data is presented in the JPEG colorspace, we have to call
X * color_convert to get it into the output colorspace. input_buffer is a
X * one-row-high workspace for the result of color_convert.
X */
X
X
X/* Declarations for Floyd-Steinberg dithering.
X *
X * Errors are accumulated into the arrays evenrowerrs[] and oddrowerrs[].
X * These have resolutions of 1/16th of a pixel count. The error at a given
X * pixel is propagated to its unprocessed neighbors using the standard F-S
X * fractions,
X * ... (here) 7/16
X * 3/16 5/16 1/16
X * We work left-to-right on even rows, right-to-left on odd rows.
X *
X * In each of the xxxrowerrs[] arrays, indexing is [component#][position].
X * We provide (#columns + 2) entries per component; the extra entry at each
X * end saves us from special-casing the first and last pixels.
X * In evenrowerrs[], the entries for a component are stored left-to-right, but
X * in oddrowerrs[] they are stored right-to-left. This means we always
X * process the current row's error entries in increasing order and the next
X * row's error entries in decreasing order, regardless of whether we are
X * working L-to-R or R-to-L in the pixel data!
X *
X * Note: on a wide image, we might not have enough room in a PC's near data
X * segment to hold the error arrays; so they are allocated with alloc_medium.
X */
X
X#ifdef EIGHT_BIT_SAMPLES
Xtypedef INT16 FSERROR; /* 16 bits should be enough */
X#else
Xtypedef INT32 FSERROR; /* may need more than 16 bits? */
X#endif
X
Xtypedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
X
Xstatic FSERRPTR evenrowerrs[MAX_COMPONENTS]; /* errors for even rows */
Xstatic FSERRPTR oddrowerrs[MAX_COMPONENTS]; /* errors for odd rows */
Xstatic boolean on_odd_row; /* flag to remember which row we are on */
X
X
X/*
X * Policy-making subroutines for color_quant_init: these routines determine
X * the colormap to be used. The rest of the module only assumes that the
X * colormap is orthogonal.
X *
X * * select_ncolors decides how to divvy up the available colors
X * among the components.
X * * output_value defines the set of representative values for a component.
X * * largest_input_value defines the mapping from input values to
X * representative values for a component.
X * Note that the latter two routines may impose different policies for
X * different components, though this is not currently done.
X */
X
X
XLOCAL int
Xselect_ncolors (decompress_info_ptr cinfo, int Ncolors[])
X/* Determine allocation of desired colors to components, */
X/* and fill in Ncolors[] array to indicate choice. */
X/* Return value is total number of colors (product of Ncolors[] values). */
X{
X int nc = cinfo->color_out_comps; /* number of color components */
X int max_colors = cinfo->desired_number_of_colors;
X int total_colors, iroot, i;
X long temp;
X boolean changed;
X
X /* We can allocate at least the nc'th root of max_colors per component. */
X /* Compute floor(nc'th root of max_colors). */
X iroot = 1;
X do {
X iroot++;
X temp = iroot; /* set temp = iroot ** nc */
X for (i = 1; i < nc; i++)
X temp *= iroot;
X } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
X iroot--; /* now iroot = floor(root) */
X
X /* Must have at least 2 color values per component */
X if (iroot < 2)
X ERREXIT1(cinfo->emethods, "Cannot quantize to fewer than %d colors",
X (int) temp);
X
X if (cinfo->out_color_space == CS_RGB && nc == 3) {
X /* We provide a special policy for quantizing in RGB space.
X * If 256 colors are requested, we allocate 8 red, 8 green, 4 blue levels;
X * this corresponds to the common 3/3/2-bit scheme. For other totals,
X * the counts are set so that the number of colors allocated to each
X * component are roughly in the proportion R 3, G 4, B 2.
X * For low color counts, it's easier to hardwire the optimal choices
X * than try to tweak the algorithm to generate them.
X */
X if (max_colors == 256) {
X Ncolors[0] = 8; Ncolors[1] = 8; Ncolors[2] = 4;
X return 256;
X }
X if (max_colors < 12) {
X /* Fixed mapping for 8 colors */
X Ncolors[0] = Ncolors[1] = Ncolors[2] = 2;
X } else if (max_colors < 18) {
X /* Fixed mapping for 12 colors */
X Ncolors[0] = 2; Ncolors[1] = 3; Ncolors[2] = 2;
X } else if (max_colors < 24) {
X /* Fixed mapping for 18 colors */
X Ncolors[0] = 3; Ncolors[1] = 3; Ncolors[2] = 2;
X } else if (max_colors < 27) {
X /* Fixed mapping for 24 colors */
X Ncolors[0] = 3; Ncolors[1] = 4; Ncolors[2] = 2;
X } else if (max_colors < 36) {
X /* Fixed mapping for 27 colors */
X Ncolors[0] = 3; Ncolors[1] = 3; Ncolors[2] = 3;
X } else {
X /* these weights are readily derived with a little algebra */
X Ncolors[0] = (iroot * 266) >> 8; /* R weight is 1.0400 */
X Ncolors[1] = (iroot * 355) >> 8; /* G weight is 1.3867 */
X Ncolors[2] = (iroot * 177) >> 8; /* B weight is 0.6934 */
X }
X total_colors = Ncolors[0] * Ncolors[1] * Ncolors[2];
X /* The above computation produces "floor" values, so we may be able to
X * increment the count for one or more components without exceeding
X * max_colors. We try in the order B, G, R.
X */
X do {
X changed = FALSE;
X for (i = 2; i >= 0; i--) {
X /* calculate new total_colors if Ncolors[i] is incremented */
X temp = total_colors / Ncolors[i];
X temp *= Ncolors[i]+1; /* done in long arith to avoid oflo */
X if (temp <= (long) max_colors) {
X Ncolors[i]++; /* OK, apply the increment */
X total_colors = (int) temp;
X changed = TRUE;
X }
X }
X } while (changed); /* loop until no increment is possible */
X } else {
X /* For any colorspace besides RGB, treat all the components equally. */
X
X /* Initialize to iroot color values for each component */
X total_colors = 1;
X for (i = 0; i < nc; i++) {
X Ncolors[i] = iroot;
X total_colors *= iroot;
X }
X /* We may be able to increment the count for one or more components without
X * exceeding max_colors, though we know not all can be incremented.
X */
X for (i = 0; i < nc; i++) {
X /* calculate new total_colors if Ncolors[i] is incremented */
X temp = total_colors / Ncolors[i];
X temp *= Ncolors[i]+1; /* done in long arith to avoid oflo */
X if (temp > (long) max_colors)
X break; /* won't fit, done */
X Ncolors[i]++; /* OK, apply the increment */
X total_colors = (int) temp;
X }
X }
X
X return total_colors;
X}
X
X
XLOCAL int
Xoutput_value (decompress_info_ptr cinfo, int ci, int j, int maxj)
X/* Return j'th output value, where j will range from 0 to maxj */
X/* The output values must fall in 0..MAXJSAMPLE in increasing order */
X{
X /* We always provide values 0 and MAXJSAMPLE for each component;
X * any additional values are equally spaced between these limits.
X * (Forcing the upper and lower values to the limits ensures that
X * dithering can't produce a color outside the selected gamut.)
X */
X return (j * MAXJSAMPLE + maxj/2) / maxj;
X}
X
X
XLOCAL int
Xlargest_input_value (decompress_info_ptr cinfo, int ci, int j, int maxj)
X/* Return largest input value that should map to j'th output value */
X/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
X{
X /* Breakpoints are halfway between values returned by output_value */
X return ((2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj);
X}
X
X
X/*
X * Initialize for one-pass color quantization.
X */
X
XMETHODDEF void
Xcolor_quant_init (decompress_info_ptr cinfo)
X{
X int total_colors; /* Number of distinct output colors */
X int Ncolors[MAX_COMPONENTS]; /* # of values alloced to each component */
X int i,j,k, nci, blksize, blkdist, ptr, val;
X
X /* Make sure my internal arrays won't overflow */
X if (cinfo->num_components > MAX_COMPONENTS ||
X cinfo->color_out_comps > MAX_COMPONENTS)
X ERREXIT1(cinfo->emethods, "Cannot quantize more than %d color components",
X MAX_COMPONENTS);
X /* Make sure colormap indexes can be represented by JSAMPLEs */
X if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
X ERREXIT1(cinfo->emethods, "Cannot request more than %d quantized colors",
X MAXJSAMPLE+1);
X
X /* Select number of colors for each component */
X total_colors = select_ncolors(cinfo, Ncolors);
X
X /* Report selected color counts */
X if (cinfo->color_out_comps == 3)
X TRACEMS4(cinfo->emethods, 1, "Quantizing to %d = %d*%d*%d colors",
X total_colors, Ncolors[0], Ncolors[1], Ncolors[2]);
X else
X TRACEMS1(cinfo->emethods, 1, "Quantizing to %d colors", total_colors);
X
X /* Allocate and fill in the colormap and color index. */
X /* The colors are ordered in the map in standard row-major order, */
X /* i.e. rightmost (highest-indexed) color changes most rapidly. */
X
X colormap = (*cinfo->emethods->alloc_small_sarray)
X ((long) total_colors, (long) cinfo->color_out_comps);
X colorindex = (*cinfo->emethods->alloc_small_sarray)
X ((long) (MAXJSAMPLE+1), (long) cinfo->color_out_comps);
X
X /* blksize is number of adjacent repeated entries for a component */
X /* blkdist is distance between groups of identical entries for a component */
X blkdist = total_colors;
X
X for (i = 0; i < cinfo->color_out_comps; i++) {
X /* fill in colormap entries for i'th color component */
X nci = Ncolors[i]; /* # of distinct values for this color */
X blksize = blkdist / nci;
X for (j = 0; j < nci; j++) {
X /* Compute j'th output value (out of nci) for component */
X val = output_value(cinfo, i, j, nci-1);
X /* Fill in all colormap entries that have this value of this component */
X for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
X /* fill in blksize entries beginning at ptr */
X for (k = 0; k < blksize; k++)
X colormap[i][ptr+k] = (JSAMPLE) val;
X }
X }
X blkdist = blksize; /* blksize of this color is blkdist of next */
X
X /* fill in colorindex entries for i'th color component */
X /* in loop, val = index of current output value, */
X /* and k = largest j that maps to current val */
X val = 0;
X k = largest_input_value(cinfo, i, 0, nci-1);
X for (j = 0; j <= MAXJSAMPLE; j++) {
X while (j > k) /* advance val if past boundary */
X k = largest_input_value(cinfo, i, ++val, nci-1);
X /* premultiply so that no multiplication needed in main processing */
X colorindex[i][j] = (JSAMPLE) (val * blksize);
X }
X }
X
X /* Pass the colormap to the output module. */
X /* NB: the output module may continue to use the colormap until shutdown. */
X cinfo->colormap = colormap;
X cinfo->actual_number_of_colors = total_colors;
X (*cinfo->methods->put_color_map) (cinfo, total_colors, colormap);
X
X /* Allocate workspace to hold one row of color-converted data */
X input_buffer = (*cinfo->emethods->alloc_small_sarray)
X (cinfo->image_width, (long) cinfo->color_out_comps);
X
X /* Allocate Floyd-Steinberg workspace if necessary */
X if (cinfo->use_dithering) {
X size_t arraysize = (size_t) ((cinfo->image_width + 2L) * SIZEOF(FSERROR));
X
X for (i = 0; i < cinfo->color_out_comps; i++) {
X evenrowerrs[i] = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
X oddrowerrs[i] = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
X /* we only need to zero the forward contribution for current row. */
X jzero_far((void FAR *) evenrowerrs[i], arraysize);
X }
X on_odd_row = FALSE;
X }
X}
X
X
X/*
X * Subroutines for color conversion methods.
X */
X
XLOCAL void
Xdo_color_conversion (decompress_info_ptr cinfo, JSAMPIMAGE input_data, int row)
X/* Convert the indicated row of the input data into output colorspace */
X/* in input_buffer. This requires a little trickery since color_convert */
X/* expects to deal with 3-D arrays; fortunately we can fake it out */
X/* at fairly low cost. */
X{
X short ci;
X JSAMPARRAY input_hack[MAX_COMPONENTS];
X JSAMPARRAY output_hack[MAX_COMPONENTS];
X
X /* create JSAMPIMAGE pointing at specified row of input_data */
X for (ci = 0; ci < cinfo->num_components; ci++)
X input_hack[ci] = input_data[ci] + row;
X /* Create JSAMPIMAGE pointing at input_buffer */
X for (ci = 0; ci < cinfo->color_out_comps; ci++)
X output_hack[ci] = &(input_buffer[ci]);
X
X (*cinfo->methods->color_convert) (cinfo, 1, cinfo->image_width,
X input_hack, output_hack);
X}
X
X
X/*
X * Map some rows of pixels to the output colormapped representation.
X */
X
XMETHODDEF void
Xcolor_quantize (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE input_data, JSAMPARRAY output_data)
X/* General case, no dithering */
X{
X register int pixcode, ci;
X register JSAMPROW ptrout;
X register long col;
X int row;
X long width = cinfo->image_width;
X register int nc = cinfo->color_out_comps;
X
X for (row = 0; row < num_rows; row++) {
X do_color_conversion(cinfo, input_data, row);
X ptrout = output_data[row];
X for (col = 0; col < width; col++) {
X pixcode = 0;
X for (ci = 0; ci < nc; ci++) {
X pixcode += GETJSAMPLE(colorindex[ci]
X [GETJSAMPLE(input_buffer[ci][col])]);
X }
X *ptrout++ = (JSAMPLE) pixcode;
X }
X }
X}
X
X
XMETHODDEF void
Xcolor_quantize3 (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE input_data, JSAMPARRAY output_data)
X/* Fast path for color_out_comps==3, no dithering */
X{
X register int pixcode;
X register JSAMPROW ptr0, ptr1, ptr2, ptrout;
X register long col;
X int row;
X long width = cinfo->image_width;
X
X for (row = 0; row < num_rows; row++) {
X do_color_conversion(cinfo, input_data, row);
X ptr0 = input_buffer[0];
X ptr1 = input_buffer[1];
X ptr2 = input_buffer[2];
X ptrout = output_data[row];
X for (col = width; col > 0; col--) {
X pixcode = GETJSAMPLE(colorindex[0][GETJSAMPLE(*ptr0++)]);
X pixcode += GETJSAMPLE(colorindex[1][GETJSAMPLE(*ptr1++)]);
X pixcode += GETJSAMPLE(colorindex[2][GETJSAMPLE(*ptr2++)]);
X *ptrout++ = (JSAMPLE) pixcode;
X }
X }
X}
X
X
XMETHODDEF void
Xcolor_quantize_dither (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE input_data, JSAMPARRAY output_data)
X/* General case, with Floyd-Steinberg dithering */
X{
X register FSERROR val;
X FSERROR two_val;
X register FSERRPTR thisrowerr, nextrowerr;
X register JSAMPROW input_ptr;
X register JSAMPROW output_ptr;
X JSAMPROW colorindex_ci;
X JSAMPROW colormap_ci;
X register int pixcode;
X int dir; /* 1 for left-to-right, -1 for right-to-left */
X int ci;
X int nc = cinfo->color_out_comps;
X int row;
X long col_counter;
X long width = cinfo->image_width;
X
X for (row = 0; row < num_rows; row++) {
X do_color_conversion(cinfo, input_data, row);
X /* Initialize output values to 0 so can process components separately */
X jzero_far((void FAR *) output_data[row],
X (size_t) (width * SIZEOF(JSAMPLE)));
X for (ci = 0; ci < nc; ci++) {
X if (on_odd_row) {
X /* work right to left in this row */
X dir = -1;
X input_ptr = input_buffer[ci] + (width-1);
X output_ptr = output_data[row] + (width-1);
X thisrowerr = oddrowerrs[ci] + 1;
X nextrowerr = evenrowerrs[ci] + width;
X } else {
X /* work left to right in this row */
X dir = 1;
X input_ptr = input_buffer[ci];
X output_ptr = output_data[row];
X thisrowerr = evenrowerrs[ci] + 1;
X nextrowerr = oddrowerrs[ci] + width;
X }
X colorindex_ci = colorindex[ci];
X colormap_ci = colormap[ci];
X *nextrowerr = 0; /* need only initialize this one entry */
X for (col_counter = width; col_counter > 0; col_counter--) {
X /* Compute pixel value + accumulated error for this component */
X val = (((FSERROR) GETJSAMPLE(*input_ptr)) << 4) + *thisrowerr;
X if (val < 0) val = 0; /* must watch for range overflow! */
X else {
X val += 8; /* divide by 16 with proper rounding */
X val >>= 4;
X if (val > MAXJSAMPLE) val = MAXJSAMPLE;
X }
X /* Select output value, accumulate into output code for this pixel */
X pixcode = GETJSAMPLE(*output_ptr);
X pixcode += GETJSAMPLE(colorindex_ci[val]);
X *output_ptr = (JSAMPLE) pixcode;
X /* Compute actual representation error at this pixel */
X /* Note: we can do this even though we don't yet have the final */
X /* value of pixcode, because the colormap is orthogonal. */
X val -= (FSERROR) GETJSAMPLE(colormap_ci[pixcode]);
X /* Propagate error to (same component of) adjacent pixels */
X /* Remember that nextrowerr entries are in reverse order! */
X two_val = val * 2;
X nextrowerr[-1] = val; /* not +=, since not initialized yet */
X val += two_val; /* form error * 3 */
X nextrowerr[ 1] += val;
X val += two_val; /* form error * 5 */
X nextrowerr[ 0] += val;
X val += two_val; /* form error * 7 */
X thisrowerr[ 1] += val;
X input_ptr += dir; /* advance input ptr to next column */
X output_ptr += dir; /* advance output ptr to next column */
X thisrowerr++; /* cur-row error ptr advances to right */
X nextrowerr--; /* next-row error ptr advances to left */
X }
X }
X on_odd_row = (on_odd_row ? FALSE : TRUE);
X }
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xcolor_quant_term (decompress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X /* Note that we *mustn't* free the colormap before free_all, */
X /* since output module may use it! */
X}
X
X
X/*
X * Prescan some rows of pixels.
X * Not used in one-pass case.
X */
X
XMETHODDEF void
Xcolor_quant_prescan (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE image_data, JSAMPARRAY workspace)
X{
X ERREXIT(cinfo->emethods, "Should not get here!");
X}
X
X
X/*
X * Do two-pass quantization.
X * Not used in one-pass case.
X */
X
XMETHODDEF void
Xcolor_quant_doit (decompress_info_ptr cinfo, quantize_caller_ptr source_method)
X{
X ERREXIT(cinfo->emethods, "Should not get here!");
X}
X
X
X/*
X * The method selection routine for 1-pass color quantization.
X */
X
XGLOBAL void
Xjsel1quantize (decompress_info_ptr cinfo)
X{
X if (! cinfo->two_pass_quantize) {
X cinfo->methods->color_quant_init = color_quant_init;
X if (cinfo->use_dithering) {
X cinfo->methods->color_quantize = color_quantize_dither;
X } else {
X if (cinfo->color_out_comps == 3)
X cinfo->methods->color_quantize = color_quantize3;
X else
X cinfo->methods->color_quantize = color_quantize;
X }
X cinfo->methods->color_quant_prescan = color_quant_prescan;
X cinfo->methods->color_quant_doit = color_quant_doit;
X cinfo->methods->color_quant_term = color_quant_term;
X }
X}
X
X#endif /* QUANT_1PASS_SUPPORTED */
END_OF_FILE
if test 21850 -ne `wc -c <'jquant1.c'`; then
echo shar: \"'jquant1.c'\" unpacked with wrong size!
fi
# end of 'jquant1.c'
fi
echo shar: End of archive 9 \(of 18\).
cp /dev/null ark9isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jbsmooth.c jcpipe.c testimg.gif.u
# Wrapped by kent@sparky on Mon Mar 23 16:02:48 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 10 (of 18)."'
if test -f 'jbsmooth.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jbsmooth.c'\"
else
echo shar: Extracting \"'jbsmooth.c'\" \(3258 characters\)
sed "s/^X//" >'jbsmooth.c' <<'END_OF_FILE'
X/*
X * jbsmooth.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains cross-block smoothing routines.
X * These routines are invoked via the smooth_coefficients method.
X */
X
X#include "jinclude.h"
X
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X
X
X/*
X * Cross-block coefficient smoothing.
X */
X
XMETHODDEF void
Xsmooth_coefficients (decompress_info_ptr cinfo,
X jpeg_component_info *compptr,
X JBLOCKROW above,
X JBLOCKROW currow,
X JBLOCKROW below,
X JBLOCKROW output)
X{
X QUANT_TBL_PTR Qptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
X long blocks_in_row = compptr->subsampled_width / DCTSIZE;
X long col;
X
X /* First, copy the block row as-is.
X * This takes care of the first & last blocks in the row, the top/bottom
X * special cases, and the higher-order coefficients in each block.
X */
X jcopy_block_row(currow, output, blocks_in_row);
X
X /* Now apply the smoothing calculation, but not to any blocks on the
X * edges of the image.
X */
X
X if (above != NULL && below != NULL) {
X for (col = 1; col < blocks_in_row-1; col++) {
X
X /* See section K.8 of the JPEG standard.
X *
X * As I understand it, this produces approximations
X * for the low frequency AC components, based on the
X * DC values of the block and its eight neighboring blocks.
X * (Thus it can't be used for blocks on the image edges.)
X */
X
X /* The layout of these variables corresponds to text and figure in K.8 */
X
X JCOEF DC1, DC2, DC3;
X JCOEF DC4, DC5, DC6;
X JCOEF DC7, DC8, DC9;
X
X long AC01, AC02;
X long AC10, AC11;
X long AC20;
X
X DC1 = above [col-1][0];
X DC2 = above [col ][0];
X DC3 = above [col+1][0];
X DC4 = currow[col-1][0];
X DC5 = currow[col ][0];
X DC6 = currow[col+1][0];
X DC7 = below [col-1][0];
X DC8 = below [col ][0];
X DC9 = below [col+1][0];
X
X#define DIVIDE_256(x) x = ( (x) < 0 ? -((128-(x))/256) : ((x)+128)/256 )
X
X AC01 = (36 * (DC4 - DC6));
X DIVIDE_256(AC01);
X AC10 = (36 * (DC2 - DC8));
X DIVIDE_256(AC10);
X AC20 = (9 * (DC2 + DC8 - 2*DC5));
X DIVIDE_256(AC20);
X AC11 = (5 * ((DC1 - DC3) - (DC7 - DC9)));
X DIVIDE_256(AC11);
X AC02 = (9 * (DC4 + DC6 - 2*DC5));
X DIVIDE_256(AC02);
X
X /* I think that this checks to see if the quantisation
X * on the transmitting side would have produced this
X * answer. If so, then we use our (hopefully better)
X * estimate.
X */
X
X#define ABS(x) ((x) < 0 ? -(x) : (x))
X
X#define COND_ASSIGN(_ac,_n,_z) if ((ABS(output[col][_n] - (_ac))<<1) <= Qptr[_z]) output[col][_n] = (JCOEF) (_ac)
X
X COND_ASSIGN(AC01, 1, 1);
X COND_ASSIGN(AC02, 2, 5);
X COND_ASSIGN(AC10, 8, 2);
X COND_ASSIGN(AC11, 9, 4);
X COND_ASSIGN(AC20, 16, 3);
X }
X }
X}
X
X
X/*
X * The method selection routine for cross-block smoothing.
X */
X
XGLOBAL void
Xjselbsmooth (decompress_info_ptr cinfo)
X{
X /* just one implementation for now */
X cinfo->methods->smooth_coefficients = smooth_coefficients;
X}
X
X#endif /* BLOCK_SMOOTHING_SUPPORTED */
END_OF_FILE
if test 3258 -ne `wc -c <'jbsmooth.c'`; then
echo shar: \"'jbsmooth.c'\" unpacked with wrong size!
fi
# end of 'jbsmooth.c'
fi
if test -f 'jcpipe.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcpipe.c'\"
else
echo shar: Extracting \"'jcpipe.c'\" \(26133 characters\)
sed "s/^X//" >'jcpipe.c' <<'END_OF_FILE'
X/*
X * jcpipe.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains compression pipeline controllers.
X * These routines are invoked via the c_pipeline_controller method.
X *
X * There are four basic pipeline controllers, one for each combination of:
X * single-scan JPEG file (single component or fully interleaved)
X * vs. multiple-scan JPEG file (noninterleaved or partially interleaved).
X *
X * optimization of entropy encoding parameters
X * vs. usage of default encoding parameters.
X *
X * Note that these conditions determine the needs for "big" arrays:
X * multiple scans imply a big array for splitting the color components;
X * entropy encoding optimization needs a big array for the MCU data.
X *
X * All but the simplest controller (single-scan, no optimization) can be
X * compiled out through configuration options, if you need to make a minimal
X * implementation.
X */
X
X#include "jinclude.h"
X
X
X/*
X * About the data structures:
X *
X * The processing chunk size for subsampling is referred to in this file as
X * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
X * any component after subsampling, or Vmax (max_v_samp_factor) unsubsampled
X * rows. In an interleaved scan each MCU row contains exactly DCTSIZE row
X * groups of each component in the scan. In a noninterleaved scan an MCU row
X * is one row of blocks, which might not be an integral number of row groups;
X * for convenience we use a buffer of the same size as in interleaved scans,
X * and process Vk MCU rows in each burst of subsampling.
X * To provide context for the subsampling step, we have to retain the last
X * two row groups of the previous MCU row while reading in the next MCU row
X * (or set of Vk MCU rows). To do this without copying data about, we create
X * a rather strange data structure. Exactly DCTSIZE+2 row groups of samples
X * are allocated, but we create two different sets of pointers to this array.
X * The second set swaps the last two pairs of row groups. By working
X * alternately with the two sets of pointers, we can access the data in the
X * desired order.
X */
X
X
X
X/*
X * Utility routines: common code for pipeline controllers
X */
X
XLOCAL void
Xinterleaved_scan_setup (compress_info_ptr cinfo)
X (*cinfo->methods->c_per_scan_method_selection) (cinfo);
X}
X
X
XLOCAL void
Xnoninterleaved_scan_setup (compress_info_ptr cinfo)
X/* Compute all derived info for a noninterleaved (single-component) scan */
X/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
X{
X jpeg_component_info *compptr = cinfo->cur_comp_info[0];
X
X /* for noninterleaved scan, always one block per MCU */
X compptr->MCU_width = 1;
X compptr->MCU_height = 1;
X compptr->MCU_blocks = 1;
X /* compute physical dimensions of component */
X compptr->subsampled_width = jround_up(compptr->true_comp_width,
X (long) DCTSIZE);
X compptr->subsampled_height = jround_up(compptr->true_comp_height,
X (long) DCTSIZE);
X
X cinfo->MCUs_per_row = compptr->subsampled_width / DCTSIZE;
X cinfo->MCU_rows_in_scan = compptr->subsampled_height / DCTSIZE;
X
X /* Prepare array describing MCU composition */
X cinfo->blocks_in_MCU = 1;
X cinfo->MCU_membership[0] = 0;
X
X (*cinfo->methods->c_per_scan_method_selection) (cinfo);
X}
X
X
X
XLOCAL void
Xalloc_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2],
X long fullsize_width)
X/* Create a pre-subsampling data buffer having the desired structure */
X/* (see comments at head of file) */
X{
X short ci, vs, i;
X
X vs = cinfo->max_v_samp_factor; /* row group height */
X
X /* Get top-level space for array pointers */
X fullsize_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->num_components * SIZEOF(JSAMPARRAY));
X fullsize_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->num_components * SIZEOF(JSAMPARRAY));
X
X for (ci = 0; ci < cinfo->num_components; ci++) {
X /* Allocate the real storage */
X fullsize_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
X (fullsize_width,
X (long) (vs * (DCTSIZE+2)));
X /* Create space for the scrambled-order pointers */
X fullsize_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
X (vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
X /* Duplicate the first DCTSIZE-2 row groups */
X for (i = 0; i < vs * (DCTSIZE-2); i++) {
X fullsize_data[1][ci][i] = fullsize_data[0][ci][i];
X }
X /* Copy the last four row groups in swapped order */
X for (i = 0; i < vs * 2; i++) {
X fullsize_data[1][ci][vs*DCTSIZE + i] = fullsize_data[0][ci][vs*(DCTSIZE-2) + i];
X fullsize_data[1][ci][vs*(DCTSIZE-2) + i] = fullsize_data[0][ci][vs*DCTSIZE + i];
X }
X }
X}
X
X
X#if 0 /* this routine not currently needed */
X
XLOCAL void
Xfree_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2])
X/* Release a sampling buffer created by alloc_sampling_buffer */
X{
X short ci;
X
X for (ci = 0; ci < cinfo->num_components; ci++) {
X /* Free the real storage */
X (*cinfo->emethods->free_small_sarray) (fullsize_data[0][ci]);
X /* Free the scrambled-order pointers */
X (*cinfo->emethods->free_small) ((void *) fullsize_data[1][ci]);
X }
X
X /* Free the top-level space */
X (*cinfo->emethods->free_small) ((void *) fullsize_data[0]);
X (*cinfo->emethods->free_small) ((void *) fullsize_data[1]);
X}
X
X#endif
X
X
XLOCAL void
Xsubsample (compress_info_ptr cinfo,
X JSAMPIMAGE fullsize_data, JSAMPIMAGE subsampled_data,
X long fullsize_width,
X short above, short current, short below, short out)
X/* Do subsampling of a single row group (of each component). */
X/* above, current, below are indexes of row groups in fullsize_data; */
X/* out is the index of the target row group in subsampled_data. */
X/* Special case: above, below can be -1 to indicate top, bottom of image. */
X{
X jpeg_component_info *compptr;
X JSAMPARRAY above_ptr, below_ptr;
X JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for subsample expansion at top/bottom */
X short ci, vs, i;
X
X vs = cinfo->max_v_samp_factor; /* row group height */
X
X for (ci = 0; ci < cinfo->num_components; ci++) {
X compptr = & cinfo->comp_info[ci];
X
X if (above >= 0)
X above_ptr = fullsize_data[ci] + above * vs;
X else {
X /* Top of image: make a dummy above-context with copies of 1st row */
X /* We assume current=0 in this case */
X for (i = 0; i < vs; i++)
X dummy[i] = fullsize_data[ci][0];
X above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
X }
X
X if (below >= 0)
X below_ptr = fullsize_data[ci] + below * vs;
X else {
X /* Bot of image: make a dummy below-context with copies of last row */
X for (i = 0; i < vs; i++)
X dummy[i] = fullsize_data[ci][(current+1)*vs-1];
X below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
X }
X
X (*cinfo->methods->subsample[ci])
X (cinfo, (int) ci,
X fullsize_width, (int) vs,
X compptr->subsampled_width, (int) compptr->v_samp_factor,
X above_ptr,
X fullsize_data[ci] + current * vs,
X below_ptr,
X subsampled_data[ci] + out * compptr->v_samp_factor);
X }
X}
X
X
X/* These vars are initialized by the pipeline controller for use by
X * MCU_output_catcher.
X * To avoid a lot of row-pointer overhead, we cram as many MCUs into each
X * row of whole_scan_MCUs as we can get without exceeding 64KB per row.
X */
X
X#define MAX_WHOLE_ROW_BLOCKS ((int) (65500 / SIZEOF(JBLOCK))) /* max blocks/row */
X
Xstatic big_barray_ptr whole_scan_MCUs; /* Big array for saving the MCUs */
Xstatic int MCUs_in_big_row; /* # of MCUs in each row of whole_scan_MCUs */
Xstatic long next_whole_row; /* next row to access in whole_scan_MCUs */
Xstatic int next_MCU_index; /* next MCU in current row */
X
X
XMETHODDEF void
XMCU_output_catcher (compress_info_ptr cinfo, JBLOCK *MCU_data)
X/* Output method for siphoning off extract_MCUs output into a big array */
X{
X static JBLOCKARRAY rowptr;
X
X if (next_MCU_index >= MCUs_in_big_row) {
X rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
X next_whole_row, TRUE);
X next_whole_row++;
X next_MCU_index = 0;
X }
X
X /*
X * note that on 80x86, the cast applied to MCU_data implies
X * near to far pointer conversion.
X */
X jcopy_block_row((JBLOCKROW) MCU_data,
X rowptr[0] + next_MCU_index * cinfo->blocks_in_MCU,
X (long) cinfo->blocks_in_MCU);
X next_MCU_index++;
X}
X
X
XMETHODDEF void
Xdump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
X/* Dump the MCUs saved in whole_scan_MCUs to the output method. */
X/* The method may be either the entropy encoder or some routine supplied */
X/* by the entropy optimizer. */
X{
X /* On an 80x86 machine, the entropy encoder expects the passed data block
X * to be in NEAR memory (for performance reasons), so we have to copy it
X * back from the big array to a local array. On less brain-damaged CPUs
X * we needn't do that.
X */
X#ifdef NEED_FAR_POINTERS
X JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
X#endif
X long mcurow, mcuindex, next_row;
X int next_index;
X JBLOCKARRAY rowptr = NULL; /* init only to suppress compiler complaint */
X
X next_row = 0;
X next_index = MCUs_in_big_row;
X
X for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) {
X (*cinfo->methods->progress_monitor) (cinfo, mcurow,
X cinfo->MCU_rows_in_scan);
X for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
X if (next_index >= MCUs_in_big_row) {
X rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
X next_row, FALSE);
X next_row++;
X next_index = 0;
X }
X#ifdef NEED_FAR_POINTERS
X jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU,
X (JBLOCKROW) MCU_data, /* casts near to far pointer! */
X (long) cinfo->blocks_in_MCU);
X (*output_method) (cinfo, MCU_data);
X#else
X (*output_method) (cinfo, rowptr[0] + next_index * cinfo->blocks_in_MCU);
X#endif
X next_index++;
X }
X }
X
X cinfo->completed_passes++;
X}
X
X
X
X/*
X * Compression pipeline controller used for single-scan files
X * with no optimization of entropy parameters.
X */
X
XMETHODDEF void
Xsingle_ccontroller (compress_info_ptr cinfo)
X{
X int rows_in_mem; /* # of sample rows in full-size buffers */
X long fullsize_width; /* # of samples per row in full-size buffers */
X long cur_pixel_row; /* counts # of pixel rows processed */
X long mcu_rows_output; /* # of MCU rows actually emitted */
X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
X /* Work buffer for pre-subsampling data (see comments at head of file) */
X JSAMPIMAGE fullsize_data[2];
X /* Work buffer for subsampled data */
X JSAMPIMAGE subsampled_data;
X int rows_this_time;
X short ci, whichss, i;
X
X /* Prepare for single scan containing all components */
X if (cinfo->num_components > MAX_COMPS_IN_SCAN)
X ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
X cinfo->comps_in_scan = cinfo->num_components;
X for (ci = 0; ci < cinfo->num_components; ci++) {
X cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
X }
X if (cinfo->comps_in_scan == 1) {
X noninterleaved_scan_setup(cinfo);
X /* Vk block rows constitute the same number of MCU rows */
X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
X } else {
X interleaved_scan_setup(cinfo);
X /* in an interleaved scan, one MCU row contains Vk block rows */
X mcu_rows_per_loop = 1;
X }
X cinfo->total_passes++;
X
X /* Compute dimensions of full-size pixel buffers */
X /* Note these are the same whether interleaved or not. */
X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
X fullsize_width = jround_up(cinfo->image_width,
X (long) (cinfo->max_h_samp_factor * DCTSIZE));
X
X /* Allocate working memory: */
X /* fullsize_data is sample data before subsampling */
X alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
X /* subsampled_data is sample data after subsampling */
X subsampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->num_components * SIZEOF(JSAMPARRAY));
X for (ci = 0; ci < cinfo->num_components; ci++) {
X subsampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
X (cinfo->comp_info[ci].subsampled_width,
X (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
X }
X
X /* Tell the memory manager to instantiate big arrays.
X * We don't need any big arrays in this controller,
X * but some other module (like the input file reader) may need one.
X */
X (*cinfo->emethods->alloc_big_arrays)
X ((long) 0, /* no more small sarrays */
X (long) 0, /* no more small barrays */
X (long) 0); /* no more "medium" objects */
X
X /* Initialize output file & do per-scan object init */
X
X (*cinfo->methods->write_scan_header) (cinfo);
X cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
X (*cinfo->methods->entropy_encoder_init) (cinfo);
X (*cinfo->methods->subsample_init) (cinfo);
X (*cinfo->methods->extract_init) (cinfo);
X
X /* Loop over input image: rows_in_mem pixel rows are processed per loop */
X
X mcu_rows_output = 0;
X whichss = 1; /* arrange to start with fullsize_data[0] */
X
X for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
X cur_pixel_row += rows_in_mem) {
X (*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
X cinfo->image_height);
X
X whichss ^= 1; /* switch to other fullsize_data buffer */
X
X /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
X /* Then we have exactly DCTSIZE row groups for subsampling. */
X rows_this_time = (int) MIN((long) rows_in_mem,
X cinfo->image_height - cur_pixel_row);
X
X (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
X fullsize_data[whichss]);
X (*cinfo->methods->edge_expand) (cinfo,
X cinfo->image_width, rows_this_time,
X fullsize_width, rows_in_mem,
X fullsize_data[whichss]);
X
X /* Subsample the data (all components) */
X /* First time through is a special case */
X
X if (cur_pixel_row) {
X /* Subsample last row group of previous set */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
X (short) (DCTSIZE-1));
X /* and dump the previous set's subsampled data */
X (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data,
X mcu_rows_per_loop,
X cinfo->methods->entropy_encode);
X mcu_rows_output += mcu_rows_per_loop;
X /* Subsample first row group of this set */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (DCTSIZE+1), (short) 0, (short) 1,
X (short) 0);
X } else {
X /* Subsample first row group with dummy above-context */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (-1), (short) 0, (short) 1,
X (short) 0);
X }
X /* Subsample second through next-to-last row groups of this set */
X for (i = 1; i <= DCTSIZE-2; i++) {
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (i-1), (short) i, (short) (i+1),
X (short) i);
X }
X } /* end of outer loop */
X
X /* Subsample the last row group with dummy below-context */
X /* Note whichss points to last buffer side used */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
X (short) (DCTSIZE-1));
X /* Dump the remaining data (may be less than full height if uninterleaved) */
X (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data,
X (int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
X cinfo->methods->entropy_encode);
X
X /* Finish output file */
X (*cinfo->methods->extract_term) (cinfo);
X (*cinfo->methods->subsample_term) (cinfo);
X (*cinfo->methods->entropy_encoder_term) (cinfo);
X (*cinfo->methods->write_scan_trailer) (cinfo);
X cinfo->completed_passes++;
X
X /* Release working memory */
X /* (no work -- we let free_all release what's needful) */
X}
X
X
X/*
X * Compression pipeline controller used for single-scan files
X * with optimization of entropy parameters.
X */
X
X#ifdef ENTROPY_OPT_SUPPORTED
X
XMETHODDEF void
Xsingle_eopt_ccontroller (compress_info_ptr cinfo)
X{
X int rows_in_mem; /* # of sample rows in full-size buffers */
X long fullsize_width; /* # of samples per row in full-size buffers */
X long cur_pixel_row; /* counts # of pixel rows processed */
X long mcu_rows_output; /* # of MCU rows actually emitted */
X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
X /* Work buffer for pre-subsampling data (see comments at head of file) */
X JSAMPIMAGE fullsize_data[2];
X /* Work buffer for subsampled data */
X JSAMPIMAGE subsampled_data;
X int rows_this_time;
X int blocks_in_big_row;
X short ci, whichss, i;
X
X /* Prepare for single scan containing all components */
X if (cinfo->num_components > MAX_COMPS_IN_SCAN)
X ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
X cinfo->comps_in_scan = cinfo->num_components;
X for (ci = 0; ci < cinfo->num_components; ci++) {
X cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
X }
X if (cinfo->comps_in_scan == 1) {
X noninterleaved_scan_setup(cinfo);
X /* Vk block rows constitute the same number of MCU rows */
X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
X } else {
X interleaved_scan_setup(cinfo);
X /* in an interleaved scan, one MCU row contains Vk block rows */
X mcu_rows_per_loop = 1;
X }
X cinfo->total_passes += 2; /* entropy encoder must add # passes it uses */
X
X /* Compute dimensions of full-size pixel buffers */
X /* Note these are the same whether interleaved or not. */
X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
X fullsize_width = jround_up(cinfo->image_width,
X (long) (cinfo->max_h_samp_factor * DCTSIZE));
X
X /* Allocate working memory: */
X /* fullsize_data is sample data before subsampling */
X alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
X /* subsampled_data is sample data after subsampling */
X subsampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
X (cinfo->num_components * SIZEOF(JSAMPARRAY));
X for (ci = 0; ci < cinfo->num_components; ci++) {
X subsampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
X (cinfo->comp_info[ci].subsampled_width,
X (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
X }
X
X /* Figure # of MCUs to be packed in a row of whole_scan_MCUs */
X MCUs_in_big_row = MAX_WHOLE_ROW_BLOCKS / cinfo->blocks_in_MCU;
X blocks_in_big_row = MCUs_in_big_row * cinfo->blocks_in_MCU;
X
X /* Request a big array: whole_scan_MCUs saves the MCU data for the scan */
X whole_scan_MCUs = (*cinfo->emethods->request_big_barray)
X ((long) blocks_in_big_row,
X (long) (cinfo->MCUs_per_row * cinfo->MCU_rows_in_scan
X + MCUs_in_big_row-1) / MCUs_in_big_row,
X 1L); /* unit height is 1 row */
X
X next_whole_row = 0; /* init output ptr for MCU_output_catcher */
X next_MCU_index = MCUs_in_big_row; /* forces access on first call! */
X
X /* Tell the memory manager to instantiate big arrays */
X (*cinfo->emethods->alloc_big_arrays)
X ((long) 0, /* no more small sarrays */
X (long) 0, /* no more small barrays */
X (long) 0); /* no more "medium" objects */
X
X /* Do per-scan object init */
X
X (*cinfo->methods->subsample_init) (cinfo);
X (*cinfo->methods->extract_init) (cinfo);
X
X /* Loop over input image: rows_in_mem pixel rows are processed per loop */
X /* MCU data goes into whole_scan_MCUs, not to the entropy encoder */
X
X mcu_rows_output = 0;
X whichss = 1; /* arrange to start with fullsize_data[0] */
X
X for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
X cur_pixel_row += rows_in_mem) {
X (*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
X cinfo->image_height);
X
X whichss ^= 1; /* switch to other fullsize_data buffer */
X
X /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
X /* Then we have exactly DCTSIZE row groups for subsampling. */
X rows_this_time = (int) MIN((long) rows_in_mem,
X cinfo->image_height - cur_pixel_row);
X
X (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
X fullsize_data[whichss]);
X (*cinfo->methods->edge_expand) (cinfo,
X cinfo->image_width, rows_this_time,
X fullsize_width, rows_in_mem,
X fullsize_data[whichss]);
X
X /* Subsample the data (all components) */
X /* First time through is a special case */
X
X if (cur_pixel_row) {
X /* Subsample last row group of previous set */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
X (short) (DCTSIZE-1));
X /* and dump the previous set's subsampled data */
X (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data,
X mcu_rows_per_loop,
X MCU_output_catcher);
X mcu_rows_output += mcu_rows_per_loop;
X /* Subsample first row group of this set */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (DCTSIZE+1), (short) 0, (short) 1,
X (short) 0);
X } else {
X /* Subsample first row group with dummy above-context */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (-1), (short) 0, (short) 1,
X (short) 0);
X }
X /* Subsample second through next-to-last row groups of this set */
X for (i = 1; i <= DCTSIZE-2; i++) {
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (i-1), (short) i, (short) (i+1),
X (short) i);
X }
X } /* end of outer loop */
X
X /* Subsample the last row group with dummy below-context */
X /* Note whichss points to last buffer side used */
X subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
X (short) (DCTSIZE-1));
X /* Dump the remaining data (may be less than full height if uninterleaved) */
X (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data,
X (int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
X MCU_output_catcher);
X
X /* Clean up after that stuff, then find the optimal entropy parameters */
X
X (*cinfo->methods->extract_term) (cinfo);
X (*cinfo->methods->subsample_term) (cinfo);
X
X cinfo->completed_passes++;
X
X (*cinfo->methods->entropy_optimize) (cinfo, dump_scan_MCUs);
X
X /* Emit scan to output file */
X /* Note: we can't do write_scan_header until entropy parameters are set! */
X
X (*cinfo->methods->write_scan_header) (cinfo);
X cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
X (*cinfo->methods->entropy_encoder_init) (cinfo);
X dump_scan_MCUs(cinfo, cinfo->methods->entropy_encode);
X (*cinfo->methods->entropy_encoder_term) (cinfo);
X (*cinfo->methods->write_scan_trailer) (cinfo);
X
X /* Release working memory */
X /* (no work -- we let free_all release what's needful) */
X}
X
X#endif /* ENTROPY_OPT_SUPPORTED */
X
X
X/*
X * Compression pipeline controller used for multiple-scan files
X * with no optimization of entropy parameters.
X */
X
X#ifdef MULTISCAN_FILES_SUPPORTED
X
XMETHODDEF void
Xmulti_ccontroller (compress_info_ptr cinfo)
X{
X ERREXIT(cinfo->emethods, "Not implemented yet");
X}
X
X#endif /* MULTISCAN_FILES_SUPPORTED */
X
X
X/*
X * Compression pipeline controller used for multiple-scan files
X * with optimization of entropy parameters.
X */
X
X#ifdef MULTISCAN_FILES_SUPPORTED
X#ifdef ENTROPY_OPT_SUPPORTED
X
XMETHODDEF void
Xmulti_eopt_ccontroller (compress_info_ptr cinfo)
X{
X ERREXIT(cinfo->emethods, "Not implemented yet");
X}
X
X#endif /* ENTROPY_OPT_SUPPORTED */
X#endif /* MULTISCAN_FILES_SUPPORTED */
X
X
X/*
X * The method selection routine for compression pipeline controllers.
X */
X
XGLOBAL void
Xjselcpipeline (compress_info_ptr cinfo)
X{
X if (cinfo->interleave || cinfo->num_components == 1) {
X /* single scan needed */
X#ifdef ENTROPY_OPT_SUPPORTED
X if (cinfo->optimize_coding)
X cinfo->methods->c_pipeline_controller = single_eopt_ccontroller;
X else
X#endif
X cinfo->methods->c_pipeline_controller = single_ccontroller;
X } else {
X /* multiple scans needed */
X#ifdef MULTISCAN_FILES_SUPPORTED
X#ifdef ENTROPY_OPT_SUPPORTED
X if (cinfo->optimize_coding)
X cinfo->methods->c_pipeline_controller = multi_eopt_ccontroller;
X else
X#endif
X cinfo->methods->c_pipeline_controller = multi_ccontroller;
X#else
X ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
X#endif
X }
X}
END_OF_FILE
if test 26133 -ne `wc -c <'jcpipe.c'`; then
echo shar: \"'jcpipe.c'\" unpacked with wrong size!
fi
# end of 'jcpipe.c'
fi
if test -f 'testimg.gif.u' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'testimg.gif.u'\"
else
echo shar: Extracting \"'testimg.gif.u'\" \(21738 characters\)
sed "s/^X//" >'testimg.gif.u' <<'END_OF_FILE'
Xbegin 666 testimg.gif
XM1TE&.#=A?0!] /< "L!"*!N=F,[,M.LH'AA4LV'=T<;+:5GC:E"3HHH+O+-
XMLL>?EF@,(LIY;>VADZ5<7L&$IWI)4VTA-+E27)LW0N%]=^NZH\]:8^B1AH9*
XM?48()%$20+-XG=UL;V\P8/NSKM.:IOG7S*UW?+).67X=-].1@)E<CWU <TH+
XM2]*NLX8G4&,D5*]QE[2 @Y<U85T &9]66.R=L[54<.>)@=O$M?W$N==E:UP>
XM.I0Q/$T1+',^29-3AUL<3,=W?_6KHZXR.^>SG-R:B7<W:LM/5*1$8*1<<Y!'
XM5,%O<GL90[^9D\F.L>R.L=:AKKEG:G03-:U,:.F[M,"+C+5CBF,S-M]^B/*8
XMDYQCEX5%>&DJ6HQ/:$D(-ZMWN>)U=Z=OKUX4)J(_2I19</_*PN&?F-2/DWHP
XM0.//O_^5I']#8,)SE]NSO-)D@C\");T^1H@I0LI<>H!+EO^XM,V5P>2&CZ<K
XM-&<62LU]A;]M@K=E>N_!N\%:9._$JNV/F%\.0F,N>?_0S,)&39X4&]& I/2H
XMNY9/4&T+-X\O6[ULD)=O9F,E0_JNP7,^B6H#)X(U6(M6H=ZVK<.0RO/1QO_6
XMTDX-/(5)9L^?R'0G2I=BK2\ *&<Z4N"HH*!GHYP@,<^GGL^ <^Z@I+N(PHL_
XM4)DX4O!W>.!679=&>E0&);N H^]B>WLJ7O^DLM^3J(,B.J=6BHLZ;FX=4;V&
XMA:$Z:/^2L+Y9=/S!SN9;96<8/)$P2H,W2I].@O^?F[0X0=N8F(,R9M)46:EB
XM>X A2MB)K<^%B_!TAY=*95T3-9]2;7HM4/')P>BMO$L (OI^D?_,V_?2M_CA
XMTN&FLUP -.#)NED+*N69KG4I//^+GJU<D)% ='4D6%0#-_9I@I\^6/_'U(L\
XM8,EZGO^'FO^:N&\@1&0"/.BPK*UD9ED(/)%"9CH &JIP=5Q"1->PI-&+>T<B
XM+:EKDZU&4H\K-LNCFFX/*.^FEZE@8,*(L7$E.+M78)\[1N.!>^Z_IM-?9>Z4
XMBXM.@4D-*%851+=\H^!P=2P ?0!] (_P#;Y:OSS\81@__RC:AGHT>'
XM'A7J=#C2H$&G...@UFR.ETA,J>8#/440FR2\ZN,4%0CJE0 D.0$B5>!E.WZ^28
XM76)(!A&3R4&FE#A5C5&U*U.) E&"6 "220RG3$"@'-,#I:JCJX[27*51%4\:
XM*'BXEL$#[9BC,:_&>)+3HP%*<0J.=.ADHXD-@_F:Y+G0X-^1?_\:.&S0@; <
XMBYUZ=)*#8<R]8/?VI!09C I,.25F!"G0J<08S\%JBLE9(@E,F&)JWAS#NG0)
XM3D &\!P Q )8?%5I8*61(@T-WS2@01'.53BT,L<6O$H2;U>=(_?&.("B@(O#
XM@]A'Y#MRA N7PG+;<O^W6.$(1"J5@U4(QI[UF#IC@HT1L^=S'8X%=NF+Z:"
XMNILU!2$@3"?9%%\+!00!!!"<!#$ ;57I@<=50&P%A&X8<A4<#<%!XV$9960R
XM1E+.=<*:.IG4D$D#=TUD0Q[U3"#77-:Y:-=?5-Q#42?HS3!&#SW,L,MC!033
XM0WORE<!6"?<$4<48!9BDTF0CEK!+"5&$%E\4G^V2#A#I!/%E5!8X J8CZ6"U
XMU5;#D=6F<""60<-R)]519 D-!..#'X=<T 1V%]0S1!.%-?3=04TTD4\#]U30
XM@WE4R!&,')+6(1][P=1A1P!'W/% $:$%4]^DZF!6ZB[RQ2=4,%RR%DP!=HK_
XM4680[]!F@6UEQC9 FFKJ5A58T(0%#0UE#%M&"- PD>I]P1PACP@EX+$,&789
XM%&BB_W!QT#\]&%37=IW4T<!V#7CTW!U-H'O''6@$T\(==K30Q#!&V"$':_>R
XM9Y(ZP6 GZ2J=+-J?$>\$D0FF83)R9=<64!#A6CRF@Z&CG#5%5G#$BOGL8XD
XM(=2C\L @<@% ;".& =O94,]"VP5F4 ??VD58M]SU\$^F=\A0Q!,R%$-$,45(
XM(441$ 0RCQU@W,%!#X$$HHHJ/;0 9# @! -,-[Y44TXW3;\2M8(6B)$$;%0Y
XM H6:O*[)(8=5&;?VL'B4,0L4G$1!A1H3P&"/ (.\_S) #=N H4$>=4TP0AY]
XM->1M$_7XV0%!35P '154]#""$;( >8<L1113#BCE%/-*(""H(D(Q0'<>0"!9
XM6@I&#U+488HO)C""B!2!2+T+4S&E@P\>4&BH)H6Z5;SV[\,%/^QQ-. !R3'I
XMC'@' K?@8,0@300!10UXW*#!BR-,0.A#+N:UUXT-;==1#W:L:T</ADA1C/S%
XM<,,-%J3, XP2\QC"P@%68,<.3""$?9B !2P 0Q;.L (A>. $^R@%(UH #'&(
XM0QU1J-6"*I:5"WFP5QS"AX;>=IPR@.48W/,!%9HP @I8;Q!?>$ )+'",;4PB
XM!S=8V>%LP"+LU.5\BYN(0__JL,()L L-OB#"SAC!"&-< Q&D, 4:XH &")C
XM%\78009.( 0PG,$84S &)H1P@Q5LH!\\B$8E@B&(*KVC-DNQF-K09+RK.$QY
XMP2F6V4!T#"B(H5DP, (%[$$!"L3P%>D01PA:( $-\&$$"PE/7NZB%S]YRP:R
XM,$CEU)"S.]0!#;(@!2Z*T8K0X4((K3"!";8@!7\,T(%]V( BK)"!#6!!$1O@
XM 0^TT(]>:J$2 7!&E3AA 7R(D$*[N=#$)E9'M@4OC\BIP5E:4 \8%G*0H,">
XM.L0 !3\D A/$6,<C)R Y%_TP#^@[PG:VHP8NU 4!LD!##ZJA1$/( A>&,$0U
XM&''_ FM<@10FV,$^/("%%:Q H"M0A!"$@ D>],, DH H%O;1 E6 0 1)P(<%
XM]'"K#0[O8>E@IO&"%SSCE0$2$XK".09A!% ,TAY?^((1ZM&$3H@#"LX0!QCX
XM<0-B: &=#8'90=Q0#\+9P09NP.1V'F*#3L)+!JP(6A=800I6M$((KL""5D\0
XMT'V<X 17:,17A8"%?BBB#ROH!PH@:H!)4"(3(G@%3H+G, X.3VT0HP%N-#2<
XM8T!"'"UXP"! 04@<V*,=B&W' PH0DP\(0@1DR$$.B$%91?VE W?P$XPN<-28
XMJ>$?$\F##"9@!SL8H@@RJ 8K8.$"1E2"#BO(*A8\L(\=_W0!@ES%A!7VL0*T
XM*N(**-BE%A!A E.,H0DBV,798L.PVE2(5\I$4_%*Z@@\X.$8)LQ$"P:A \)2
XMP*5?&,3AFI @<< !"G:8 C\V@(@-W +*>N67O8"U".X 9TPZX$:;$"$>KA/
XM"C(@12M<P(M6M,(5='#%"NC@@4;L0Q-@70$$37 %3%28!XKPP"7Z(0E$'$*8
XMYSB$&/ Q +,M($UI2\>N(+;,K=CF*UP9 BB( )Y? $![?B"/>R! ",>03X.
XM" (^:A ,">1 ANH!3_X@(BCYL,.^<B#+/RDJ*/F@7!4.(B?X*G?.Q"A$->H
XM!"^L80Q>U((./$#S#EA!844$%_\+.U@! 3+0!RR@P(']6,,Z_#'C!X@@-A;(
XM1!)V]:60%OI+R>Q5Q:K"B180 ;I@L$@$&"/A=CA7S=Q !!\\(K(;H"R-W %
XM(FKAK4 5U0T7<(.BKMR$;OT#7G9P 1H,@8M6>( .^,L *C: "32N0!*MT 0N
XMK( *.J#Q#5?HPQ97H 4M[$ (V&A%#]YS#G4XUQ&9>%"AS80F71DZI!<*3G5[
XM P(A# ,,8&B!")Q%$4;- ,N$5 FH!",*93""S>H1:AO@.:#Y,%P,DCU!=30
XM!!D452\'44/EB%"-8O BJZW@(@^(P0,SWH 'KC !+G;0BGYLP ,[V($'T)$!
XM+&@AN-;_\ H.*"*(QR"9+G*]@ <$-('$1K<S05I.C@1G%=,@A'<8$06P."+
XM(U%A!N]^-P9:$H1X+",*9'A!#KQ V5K$EM\=:(+A)I '-]@W'V[@^A&T3@1X
XMFO8)K6"$*SR "@>"8P.VO $V>, '(53# QW'^!LTL0-%O&$=_5C!.GB0 3
XMHP[K+D F;I6P 62"$X1^$.1O[L$S&?,825C@#3#!@7.C^Q7!$ /2X4UZ!UB@
XM!B4 A09X"FH>@(,'M>"!7NKAWWQ<0!;U4+4L\N$0O7Q!!C)X A&,L?:K7F,%
XM%2<HAWF B!/L .,H<,4^]G&%#.R@#RA0A)L]P '6%>$08X#"_Z8MH&*GV#P=
XM#A@ )QH$>8E]"3?I$,$4#)"%")#!$.P 0Q%\(8(>W$,=2@=O0 ''Q $TU *
XM_" !^L9OH?9ZM1 ^0+4Y$R +,N &\*(&I24#A< -A< (UH *J' "O#!;6+ !
XMUY %$T<.B&!@J, '"[8";W!5^R $*/ &5K "&F %"^ /8)!<XF !XK @-0=Y
XMZ;=^Z_<.ZT<;)69'9W$.M\ -P #8"!T+% $5N +15 '4: 9^@!O\: '\= $
XM[G #I1 -Q)!DM= /=( (KG!F"^$G%R!ELB!E Z<&%"@+H; *TZ "X, -(<@+
XM0J!+%9<!5X -'N<*&9!W=;<"U\ ##?^V#BBP!6^ IC @%0!,EE&]R&)C*G
XM8NM'*^\@!K6"8A%C0>HP#A& SI !N4 !AE0!.QP $60!7:B#BZ! ?@ !_HP
XM"%Z 0]&0 [50"TGF"J$6>[5P<'?@!F#G!A4(+SD3?,4...@8.5P#;S@ 4*P F75
XM;$+ #L:@!<0 6Q^HACQP#7U !W<VB7T 82=@!6 0 2( %9NH8IXH<YGP#DD0
XM!)/G -Q6?HM7!06 Q30#J# #<-P!B> 0.A6,(RE#_&0"T' BPE8"DDV:L30
XM#\:PAFU(#(EB T?5/LQX!VK@!A8H T1@#:W5"M1X J3 QN@!;IT NS DA5'
XMC1[ !W30!^3_((@GX&:*8 F-\ D!< :'$ 5 <%-@4B$VEX2/MP#XN"OGQPD1
XMXP,?X -R< 3VT 8_DT598 (<((OGX!^Y@ ] T X,'6UD ,; YT0 RQ98PK
XMH&]\T 1J8%^B50^R()+!)PM20 2H0(VMP LGD &DX '(MTLKL ^X,'&NP AI
XM!EO7\)=78 U]L ,G@ 5OT A@L 4F$ !)( ;?AI2<\ [9)HI.L0NAZ'@J]B".
XM8$%@,96>T $3$ JVX *^P K\= <P *MUA,ET X2T(M><$8VB7%J60NN YG
XM1EF9I75/8)<6>)>&P HN8 Q( ((>4< (>X% L>0U"< (&M0*H_X!Q:<8'
XM/( *)>@*X#D%;_ &#Q8 _O .M9)^-2>?2&B?G$":G+ +^<DKXK":4/ !KJD,
XM%T $H0!T67 %_&0'[' $+: .#3 . N %5$=Q=$<'QDF,&MI3?$ ,^7 ']6!P
XM264'LD $3V!/UL +QH *KK!VWRD$J%"8/'"-(=@*R$<.&T .:&:3&S!W,9H!
XM#C0)/1@%29 $2*A^Z[< "["?"X 3[X 3^WF/:7(V4,":Q22@9G $(V /OX $
XM'I %)U )OL ./5 'CP(#"< /%=H/-LF&X' #X!"GR-E3Q+ 0N[=?=N &=D $
XMI" #PQ!T+&IL#%:-#428_< +CL@*^U""Y/_I"N;)!WS0#]'01<\F!"S0!4F@
XM!/@H!DHH!DIJI$NJ?C6QGS@Q;U5AI3\HH!_@ -D@"^V@ DYP U]J#)-@""+0
XM#:]@!S P!12: Y)P1@G6@'00I[!'#!W:#A/P9!R):C(0"D'7HD)@#&G&I@WD
XM0(#I"A_7HCM@!6?PJQZ7AI15=?/#"&!@ DE@"N] ">]@:+'Q#J[!E$^Q"QA$
XM$EY2%;@1H#Y@K[?B V9P#WF (6 !!<7=)7 NP2#&@P#/1 #&;XC<%8"W**
XM"'$:C.$Z@?E@ VJ0%[)0#+9 I1E#(R !<.9DX!HC;S0!_T0H^=I!2: ?'2P
XM 1U*#M&0#+=3#)/_D 6FP +^8 I,D *[0!M@X@"F81H+()J"YADXX0/BD*^_
XM\@'V:DQ+D0L8X ;:8 LJ<):5P V(< >&@ ; 8 >,( '$4 L=6I&(@*%R6@GT
XM4 OAZJ%@1WM29D2AP+#@<(U:8)[&-H[6Z)W70 =899,GP $9D &3@ 7$D S1
XM$ W@4 3 , S%T .4D 2<F0+(D +BD ;9YJY)H Z=Z7@I01)BH+0^@ ]*BP_'
XM(*!XH ?0H ?XH >Y4 4VT XNT 9PYP6W8 S#P#7 @ ;&4'5M&XS@(+'3 X*
XM6*%T@&HK,P'U\ 0(0 1M0'5 APB_.IP4YYT><+VNH A]NW8LL)UT)PGD_V .
XMX. +W7 'PP ,SA %$' (\\ $3VJYCQ<$FVL:LK$ \^H)0> )4NFT]^JT>O"_
XM>E #>O !GL %]: -)#!9Q# -C$ &7*,*A@ .OIMO^8:<<4H/Q/N[^3 $3_ $
XM;: -C .@.BH5\ +' 9JKF"VX'!KL74"Y,@#Z7@"&[ &_< /:T ,Q1 ,=P #
XM,\0E(' .1!H%G) &ZJ>D5F(E53 #+!%O/I )2FL;'X ;N)&ZQZ -5 #'Y +
XMQ^6\3K (D"H$E5 $2J *$# -M2 !^09;Q%@+B% )E8 (%/FP-T +]< &%- &
XMW& ,X-"B=$ 'N' -9P0.L84(_<"6:*:R8&6C_?_P56NE!1J P^PS#J$G(&,
XM @$0!44[ "G@")Q0M#6Q"T&@Q!4P _J@#_KK SX !/P+!50A(0$LP#4 !SZ
XM 3;P! %+")+ !RM<#OM3!V0@ :/&QF<6O,%;"7':4U0'IVJ@!L%G/Z_GJ#:Y
XM WR@!;A6":X >VEV _VPG7QP!3O0"+R04 ?@4)= #+38 W?0 SXQ!@,P!DP@
XM D+,"9O,R:4Q(.I1 $U2!6+@ *@L#D[[ 1:0NJR,!PJ !S5@Q36 #U70 ",P
XM!TA ".$0J4VD!&. !A& P?EVMJY7S&_,MJ 6C++0"QU\"[&WQ[G,!]:09L@G
XMR,:HTJX07*303R> "8K_8 J8L 9K< 8M8 =%T .I(2;UF )1$ 5*L #H!N<
XMD 2?$1_NA@'Z( ;ZP,]2J<H!^CNLF[H'?<6Q' ^=( ,NL F$0 Z0B@G@X#2F
XMH+"UX 6NMX;$7,P]10<970O!IP(7>0. ";-\@ U"P UDE& K@+<81YC8L )7
XMD%#CR0,09@YDX$DT-0,.@!.QD0)"C5%,\!6I 1-CH X%P%A!X!+Z$ 3\/'X
XM'=!P8-55K "H+<"YH X7\ 6_ CD<+?@4 D'H K!D 7TT%-LG& 2*['&7*R-
XMR0->#0Y(<+99( 0Y20?8@ 75F)8>$'NNP*8%A0IHA 5^RP<H@ (01 ]D*@]-
XM_R 9P: @:9(&C18 "[":(M(J)0 98P!OG_W44JW*%@#0'X 'N"$A5HS:5FP!
XM06 '[6 +2, #V,!OC% ,(# &PX#&8WNV$ANGO<VV&)IOQ'!@N,9A5R"(QL:6
XMB, #K8 )=."";"H$N+9@NO1\V$ .M:!_/9 H%> ,] HEEBDBVYE.L)NT %
XM!5 !_W</,"$94#T:\;!I/C#?\XT/40P'^*W?![VJ'=!"FT '.DH,C# )P" -
XM8&#&%3S(LRVQ+7UF='>U'F ,DN!L+,P'KG"W*Y %K8 *L1W==' "_:!@+FL)
XMKK &&Y ,66 'OC "ZN %: .): ."T ##R+9KQ"*-O^!'B Q!D*" 6)0!:"]
XMSU)-Y/]L3*E+T*BM!PJ #P[0 _7P RK !QL0#1;)"! 0 U>>;[O-T:]%IV>V
XM8.:)"L]'PU>@"&:$9I7PI2=@#!RVHRO0"BBP HV 9EC5#]C !\;@"X%4 *)W
XM&B6PKAU# ^^P ,Y0$I'"&,J@)#,@&57@"0[PV?N<"?$PY!^@RJI\WYB>WYQN
XMP/8P!U NZI7 "#W !%) #SK QL3GVV\LP6O8[SE@YH?92RA F?U S70P1B?
XM"&\)LVDVCBA !RG]YB[+!RS0 [?P"KE0 *4<!.J@#NO*3.^ ##[0!/(0'D>W
XM!T*R[8_N "S/\O$P[N4.T/[_; %P8%W_B]IA <6, ,-[01\D,O$@ C&8 @Q
XM %G&4 MNS(9MK,<]Q6]6]^%KQPMNIDN6< +>2@?'APAF](TP&ULK@ *H<.%8
XM(.(;X 1$$ S%< @LKPZ@S?$% !NKZ0.H,@&W$)!7MAV1H@Q[T.V>L/<M[P!!
XM/N2I3.Y&;N0!G,6YX !<, )MX 2$@ +1H,MA[ QH J(( &5$%NS;0P=_8U.
XM3W'9NP-VIMV:P*C4R@,&L +1D&]J*)XU*0174'<3IP&A4 ?%, @\$1- $ ]'
XM$069<!7^/ ;R0 &#H$,Y=F/UT!%[8 :>4 484 4.4 (N/_A+:P'D#@5P$,MA
XM 08_] $_ #) /RBT)08\(Q> ,MUW,L[T"27^VNLWZQ( *K; /:K4"&6 %
XM'J %79_Y,\KZ>7L- '%B!2\L*U;PRX&I1QX8!<0D 9(.7[H2!4H @9(I5R<;
XM1SI4Z)$OSX@O[A*XLT<D7YT]U*I4<: OB(-X/GP \2$.)Y /<.#D<C##QHAV
XM]MJ0($%($A]BM<!%B!&HB 1$E59<0V0,$;A:-YK><.6U%J,W*S;P>(-IQQ4M
XM&_AX\(!H!29&7C>00T%'2*LK&TX0XT=,2J<1ZC*I$Y,.") %!:)D@B).S+]Z
XM3?[=J]-!3N9>3WZTV90 1SL;,_3IPX!A9DV<F7;ZL.!IS/\1>5\HC"9JSP4=
XM/DQO5&(D+8JO*4XQ@4-5"5'76LRY_C[#BP</(1EX8#*Q84,MZ?WZK9A4B5P.
XM/N2ID^HG1 .Q21PN-' 09$$Z3C0&1(GR+N>8%D-Z=; AGPLFJ( *+NX8Z0D*
XMYFACCA$TFR'"$O1Q *>;8 ,BGB#J:**H"=H9H9<FGH!%%U=XX&,#8HPA X1
XMI&"D*4;HP,(8KHBYH;D<<S1F&%3Z$*(1#]:1Q 17O./%@ W6P:(83(@Q+T5L
XMA%@!&WYNX"" /*H(8J;Z+$AG@8O$*>&!"/Y@XX\_FF"#! 0ZR(,(79X80@8Z
XMB6@GGTXJ4&<&U5C[0*=X@ BBDR;_8!@A45WL00 !"FSAQ945:B&&&$R,426*
XM.R*HM!5BKK'Q!M^8JP411HI802 KL$!A R'8XN&$?B0Y2PA<>$"!APV\4Y$8
XM+Z*1H8<G2NC2 8GP 6* !<2!H@=M;+'GEF*F(:&-5:)1@9M:G*BE$#ME&6*(
XM/)JP@0M19JB PG3TP,>F#_09HX<[?)$ % DDJ(6$7_;]185:^"AE16. ::8
XM822X02M4N.J*CNEXJ&4#"8:Q8P5%A-!D!2W2JZ0?.G;8N%4>3+B"C@VTX*&?
XM#0);XQ8[9#DBGGC$""(>"_ !,YU,>@"E#9]7<<*)I&HAI*EHB"'$B5^($"8?
XMD?*QX1]1_\[%H$(++/ !#A\\D2<48T@ QU<OG* '";-5"(L8;&I);@P0BAB&
XM'G",<67A6OKY%^+I<JBEF!X\R. $2[#86(A^/+C!!)3[T4(27G;800A)).$!
XML%*\Z,&.)G810Y\%XG'$ D<P\L19H>EQPFA*:_&B$B,8D<"+%Y[9Y E:U,B'
XMW'^XR"9"!RP P@(X:JAB GN;(Z:251@6F@XDFDNQ%AL#4>6.+,B0X#A7&"9&
XM[\J)F::('DYX8Q\35D#A\ U0X8&5AS>@]?$K5DB9'RV2R:*.8>KP 8,2W@D>
XM#4;W@3H@P!TD<((7&)"O!"Z"*EE0@A**0 8&T X)3B.7#3IPBO_+S.!8"JA!
XM/";@A56,C0RGDH(1X!$->)B-6]LA!AV,<8- @, 7H" #.!BQ/>@UIW*5N\$M
XMI!",M>PC RKCP0HHMX$K2(<'2R'&"D0E!"&08RDWJ(,OQN$#,7@B$P, @T$
XMB \JC" !FU@%/+P@ 5N 0P+&*,4-=*"#%$"!$B*X!0EP,(=P]0)J43M%!921
XM"0O4P \?: "^O% *Z4FA"*J0 AF\ ]P<*M2_[K!-<!1A^I%X!8Z!,>D*G4#
XMB.&-&(@81@_JT(@W-.($N^H'BE0DA"),1Q)>X8$6M" IRM4"#"R @30^$(R9
XMI$.,-$C6"+0QATT 0HU3( (WVL"(:5S_"A-I@ (4G'$$'(1"!FF:0!.@QD%1
XM8"!X"O!#"08Q#0F0@1[2*P<N5-$#(M##"X2@@R5%)3U$=(,)=K@%*(QQ!E2X
XMHCFUH,,-Z$",?MS@5&CH@15.H E%Q-([-]@ '5:P@VLPE!@:@!C\DM$;8Q0A
XM"_(00T62P E'X$,/- C".1 P@B?8HQ" D, JM"$+6[2!&Z 0P &. 8590$$.
XMQ?C!$-3DGPO8P :GN(<W?( '/^"C ?9X !G* 0M&< ,<: &&HI!#T+<$Z$Q
XM)(8KC%$+-,1 !(P8AC&\*DJ((6*A39F$'7K0 TN<H M'3!D/CB0)]JS@.\38
XM "+Z08[%IJP(_R;=110<8DP!.B(=1S!"'B[0BUZXP1;Y(H(,AF&+[!4A!;-(
XMPS;20 4[L$$6?PA7/?*0CU-DXQ[4L$ 8(I&)<\#@#D6X!3>X48@B+&&>VK G
XM(8A6*8;.#1&&< 9 XWH&<-!!1^ (2S^:D@4[V.$(^U"$%?:1Q%PJMGM=X0$B
XM;A!'5TB"''0@!S?0D+_#<((3H@N> _) &LW:00TV^*8M1E /-[@A6#%(1#83
XM$8,Z',$&0SA%N"[@-%ITX+90\(,?!B /"@2@"5)XPC ,L808+,$.H B:! B!
XMKQA*;V&^4,48= *;M -$7P0%8["=@-ZB$\$1] $#QYA!45L !.5@__?>7D
XMC@W<@,FED$0IOIJ%)HCC'06(!V6AL(L'3, &];@ N7J@!C?4XP]$&,$=U& (
XM*H !,B LR?D0 4U#&$4O="L@&@!53-\( S, $(##O&$.V3.$,!80B#L0(0\
XM3F,5VZ(4.'A@C$J XY' ,,(M)L&(ZC:E4G9U,B-\D;DC;*$/C[A"!!3A 5XA
XMEE(_G)06HE&*:%#,"&,@TSN 1X,R!$$>NAB"@#JR5R[TX!2T -<(ZN2&(]RA
XM"7H=@S+VH(Q_W-F/ J)M!?: X3 X8@SQ4J5_[> &(MC#)"2PA2W,YA4ZS&T%
XM$B@"",90C%L,PRJUJ)S'P,&C88A 7D"V D7_=V"%7'IEE-IM"@_(,VMCV*$8
XM1<C$&,0P (G0@!,<MO-_.M"#!O3@'W4XQ2F$<0I9/&$$>="<%GM !2K((1LV
XMX"S4]%PN;V X!%L>0['O( ,9R$(&H<"!.W#035L$[=,RO,8-BJ$*50 W"^"H
XM[MV( 0Y$-.461?#NC]]@@BX<8@M"R,%T2$FI&VAW.MB(,C'RT(.&[.(B[TB'
XM L0P APHVPW'WETGZE !+OSC'U1PL%-MT(.-KWP,=3 0S$?A5&R?H@?Z$$<8
XM;KZ+> 'H"&&^P @HP"@$? $')$ ",:+1;DKW30G5TX%7?]@]JC<%%'<0P1V.
XM<(03[* 1?_5 0:*A_UWMXK@6*- 8-DK!B#H\8'.[" (G@,",=,# 'O:0 6<U
XM6.P*%(CEQ>Y ![!?AW\$@PICF+,<YKQXQD^8%E380R9J$()C.&,7&&!Y#VQP
XMAPN8>00?:H<M]/5IM4ZJ&&X#*$ZSKN]9 7"(!@G@+LTY@AYX P)0A$; A'U
XM!%W!$>;*$8_A VR0 %\X@A%H #$0@TP0 P4XAD/8!#5A@P#IA6PPEPJXAQF0
XM QC$@!FX!SDH$&G;@SW8!?&+OU$X!<$S/RY(/SQ@/Q]P!AKL.\&S@3P8 ONS
XM!R38!*9HMX4AAF( !K>JL4I *[S)D1RPM.[ZL4ZPA#XX 47PAQ- F?-"+/\<
XMTZCT(8?]:8<'$ ,-T0,]@((6$( ?L(<A<(-@^P<;J !1N(=S@<$9*($(T0=E
XMF($<W$$=E(,=/ ):B)H "9!\Z %E2(/U:S\QF,$7S P;N(#-JH<A&($V>1ZG
XMF+2PR8(QB($>,(*LX(,5Z!ZT6A%?^+'9"P83R( V()#P(3$ @<^X(&%4I$)
XM= MPZ($F0 !BB0@HP(,QD(!;^ '8XJRFZH#=H8(94(89Q =W(,@& -]>+]O
XMW -]V(-[^(?"<ZI18,=1Z J4+\0**H4D F6RS[&&X5PF0!=4(&DF#IPJ(2%
XMXH8QD(9YN(6U2BL4<8JD 84FZ($C$($&* $"T(3_+0 #(<@","@'1D"1Z>B'
XM=3B+RBF&)93#3$@'1] F : ',M"%/^ L/]*@W1'$1<0 .8 ),2C'7:B"72#'
XM(%!$[OL'^;,!6J"%4<B'(X!'.& _1QB 78#!.N""_R+*?. L&4" 52"!Y@ '
XM4&$=;@@$:0@&(R"#2I%%O*D%!I" =K"#!FB"!GB%$C !(5B'=< $-)"",V"$
XM6B"LE/$.[V"K)O# +,,'**"!8M )Z -O"/F'NJW>&"%_03?7B)*@!!RA0#
XMRJR"1$278DO'H1P%-U@\*A #I=P&*$@!#-B%Z_M#6LB'4=BL//B"HV@*@$0%
XM2C&&8!".(JB$B+D;ZT*:_U4H@MF+R )0AS= @4O@ 6Y@@7,HAK421L3B@1MH
XM"[]A"#$P%CR@ 1'( 0EP B+X@PGHA<TB/\>\AVPLQSVX3,SLG,LT1QJD K[S
XMN*$L2EHX BX0@P\( 4B DYPRAE@.37XP<6C2EG0!:1H#K7*RQ6) E6H SN@
XME-%3PVBP!8<\@@9PRQ(PG!M A%NX@WD!!7I0*/C9%7Y !'EY@$ZP@$Q R7=8
XMAQ>0@#8(!9<,3YB,FMUQ03\I1YAX"?;D$GV($+[C B[HA-5<O,6SSP]8AA#
XM@Q0PQ#D3!2Y81U#,@WK0AE](G>8P!H2DAT 8 P[H 42(!A6!F%I8!'@P@MD[
XM@O\6($X,[8=2R %0.(=F.Q@M*(5=61EB2*4[@(&;R 0:2(<(X(<ULH5"D+#P
XM',J8Y )AJ !AB$P==0 'N,P@0 T:!-)K)-)\H$\NV 5Q\ ,E'8 @B$&62T?6
XMI(7-^CD$0AY4R,MH (=@ (8>B()*.!H^""5*08(G0--.*($24(?:C(9:&(0B
XM>(!@ "C D(0<.!EZ:((F>( CP =F20,1T( IF#H5L =J#$7RBYH@O=%M? D'
XMT-'3F$$DY(+LNT?7-,JH&0,?J(%(*(/3' /_S(;.E,3Z&X&BL]7DB9%?[8%Y
XM"@104)'$6JA:: /QF3V+V%4^H ,O( 8C<+X'8(([R$O_;&B<#0B%'I '& "
XM3X""8^"$=3" =7 ".M@$6*!&USQ46G!,OHL0TY#,EY )#/!1)/0[CP"0UA30
XM?Y #3SB&93B&IG1/*DC'4X :)GR"-B :IU@1%2"&@&D!8'B%>1.]3\F16J"
XM.^B$@^V2$JBD2B !&%A6,BB"8/ 'AB6&-4"$(YB 9LVF-#@&3""2&U !0K"%
XM'T V)HP\ML@J>$"*B!$F<W,U.#&"!&%"NB ?+A9&[ V\I,#!Z"J,DB'&1@#
XMS/ [ F0"X@3$K@DKD %;FA:";B#,;"#%C $"=""4Z(4"<#5AVP A"V!O%R%
XM6Y"'[[.7.P@$<+ ??C@#>3B"_P<H@0^H 6AH 43@ARM1 9(MA#2QL]8\U&OD
XM@D"$S,A$#<$=U^KK $D,$-9D3!NX!S.P.4<XQ/?,ANR31 &A4A+@ ^7B"D:(
XM$48J@C%XA3J0@O7"MTBKAX<\@DY8TQ)@VEL@-&GP@6+P E!@!W#0@&10NB-H
XM@BVB*@@P -8 RU8 15P A7X <4<@@LPRL6K,,<4!49M63\17#^9@:DIU_*]
XM7,XRRG>L BB0/&B0@WNH * $P@'Y)#[ FTHSAO;U@O\+AD 0 7 HA9"JA5N@
XMT ;0WUTM !(@@R=XK#$0A#O EQC1@#4@ Q%H@B_X73P0!W0P V0-7!P 2AT
XM >5U3?_F'<I_.(46/)=[@,S4".'J6TWF-4K."C8;Z(0]\ 3)*X,94(?W+%<
XM8<T.05J%K85IT*%":%HO& 0N#88[,(8<J)1?)8*UK%!UP&1,YM [N 6Q]85A
XMT"[<309&CH)Z.(0/T -G* (-D$Y^V(!?T 82<(?$Q%NCE,0*<UYS$<3JJX"6
XM'=<2[DS7G+ 4MC,;Z!UQJ(%F"($]4(?G34+&JX<O <OB*45J80=7F10"(8H
XMJ ,6 (5*V8 <H(=B6$ +)4YU*( "V)\[P"$CL)$P)89DJ)=#@ '?G9DDN $
XMT( D<P4B6 714-[PY."AO,8U;D%>#N$?%06_LS9,94T!@<G_3E"&/5;F$KB'
XM!C"0.<Z'"<"!U*&#A36&7]CA7XF&6^@!_NB!85BH,+T%F*E0B<3D='Z]#BT'
XM(PB+%(D&'C#808"!!FB!,3B'&[@!5R:&1?B%HUT%6O:/UL14@N8@QWQ>%W1C
XM&B37=!P%EW1'P2M*3-59]6L&2$"7'@A2RPU%,ZJ4:L[2+!4;";"#,0B$;B@"
XM, T,(] K).Z$>XCI I" *3""J:@%.M4";."#2?@V3([(7<B$"%B'-5B'W@B'
XM2G@"' #HD\59@K;4('U>-Y;A%W1C<TG'7G!)7.[,UKR #I@!3UB_/BZ #N@$
XM*'4:S$4 $IA5'B $8Y@&8U"!7_&"_QNX@TP)!E^0Q?7P&X[KA$Z(:73F@V@P
XM(L-YAG"HA5( @"A(@@68B5U !A PG(@>TF!L*";%M( *5NQ]:4Q.SSNR?5
XMY>K3;$I-PJON!0W*QU$@RF+^ASWP"2C0.[Z+F@X(LPDP!H;"X4EQ!=)"6N;R
XMA3&(@AX(@%^(AFCP O'9JP; Z[P&!Q/@@!NXA UP!4)(AF28@G> ")E!ABC(
XM;@UX 17!J.0A EN8@PO&5G9TZ'_H8*AN0<UVX\(5A<,=@@#Y@V;:!#903)2=
XM 9L0@PH8TD"&N3O0!E>(!F'T&%=PA39X42=(WQPP@6_#8D98A%J@ASRH PLU
XM[KPN "Q@ ?\6D,7MT -\()5W%0P0@8IJ 4-0 @O:#(5,88G #H$".A>:$>B
XM5-GSGAJ^A5X;[SL9OP!)' )=^ %= '(UF8 \" 8'\(1=0,?*=:H+D %%3I'N
XM<3)4( ,2F 9NH0-^L(8H '8XX9HH <*4*4%-&Z\KH!T-H$B< 5^J(3?H#I0
XM@(%S&(,22 (+X =,/%[N8$<2'%C^+E%AZW%9,?YO-YT]#L/ENJIEF'KS0<[
XM:T=V'((TR8,C.&TQ<,H&^(<&N-[+(P+TQ;=^D NU(H-5"'6$*@4/,/4F: %M
XM4'6_"08+Y1-T3N<" (,KB&>Z ,"*()SF 9J(<C&(!WJ+I]IH?_XV H23X5
XM(L"!+UCV.V-'Q4UC2\UQF9QVS>;E=)RPRB[5/##M*O"$F2D!.8AVIVH"-XB1
XM?@ '[P@E)&B%-KB%59 8JR$5P"!-"6"?#G1+V^ 3";.=)ZT0H"K+ B %M@%
XM$0"181@#2" HO8"I]@W/I $Z9$%(E#V/E)A\G[V&9=V]7Y!7JX F:1$&_V'
XMT_Z #_ !<+P'+B#W2Q\!<"@:AVFR H0%,K"%=^^-&[ #$#B''N &"7 'AR1N
XM=$;G6.^$4@CB$0VB!=(@"&*" ^Q4$)5B'AC*H [4K.Y>%8: ;5 3%>9S
XM^;;L@MZ@)Q7$S:;!:K?>>[R,(-B# M@%_Q_X 'R8]!+(Z YP,!FPA81KJ(:J
XMM'+ >:SL-$D(@-D0 5L@ R.PT-;557Y/Y\?GA1:0 @Y8@(4?!",(!1N( 55
XMA\:&F.U1#E>H.NF1@7(+Z&SO!3\GWVLT;QPW>]GW[&BO R(AP\(@DP "!\6
XM/H@+$H5+G7\V%LH@P0<<CPT\5M3"!&X8/1ST2*"B0VQ#DR@M>C "-:%3@P8%
XM.JEK66!EL$)HQD1)PBE3CR_VC!Q!IH,?,1X\:A$%9PP<G1ODP,D@\@7!GR&]
XM>@T9U<O&J ZT.G#=2NL?5RZB*@CC4J'"O0I<.G'Y9Y:+.@<?+&0* J4&$'%B
XMU%')1^7?'36@B/\%W=#OQHU*X'YQ(]%F8RT^?$IEJ5.GP:TG>5*F5/?R\ZM.
XML *9:I&"QBX87T: \I3EAI<-=(9Z!'<-7+]:Q&XT10!5:B^KHX9[U0KVWZD.
XM__Z-Y6+V[%JW_Z"7D%MC0! @>/!EVA7E^,()QN#UX]'O,(]*B%1P6W6+Q"I7
XM=#;P,_(JRI%;#S:G['3O\TN=%#!,#RU$X8@C39"!@!%1B) #4$Y01!0Q2!A3
XM"86U/#%,.Z%$555P6-E RU8=B%+<5LLMYQR+;CEW5@4S^ !'&/&((0X<'\2S
XM2P4]<&&(&G:$0E@_*Y1W6"5D% +**@ELY HA?& 301W!-&&$+$W\T]__9YZ]
XM%$PQYT21P@ BP&#/%WDPL4YLKJA0RU"Z66B,;H0]H<T(%+ 157#Y$$=B<<K1
XM,J)RA2JGHHMGS5#=!W#X ,0'D?H01!UJ<)%/#[*0\%&1YB&FPC2,,)( &:N0
XMX H?Q/!S2POJC#-,$S9P5H%G7A806A2O. )%'8,@,(@ONYQA0#0;%.+"?%[4
XMX@0]9*@ #F'$$ '*$SCHPF<O^= RRH@ETB(*5UPM)VZ)X:XXEC#WS*!/%?&D
XMD@L&>U0AAPU-!/G/,%[,-U%Y0K6Q"B,JN'-+&R1<0P<YV C0PQCRP'!' UNJ
XMI Y+M][:"0V.U)#:%\., ,(Y_*Q3"C&_P$(8_U$2D* "&<9$6XPM(^"@)W#<
XM#C<*H%UU,*)"5@TJ+E<V[!ST0D)S,4,=L?:0SPCYJ $8&8O<()%0/"3U6"%D
XMW((#&4ZH@' I$HC0<!Y-=-! !6C7^LI*H94!32;U?-$.$78HL<X-!H132SBM
XMZ.:%$Q)(,(T*C$1##"%$D$&$+7-<*]7-.',;J+BC_+'G$%5%/DKF0WPXQ 7Y
XMY'/Y'[W\,<(1=O2@C1,?55W>"NN1P,@J[MBRBA,=\4&.!..4\( =1Z"=T@PO
XM><EV)V70T ,%[?Q1##(1K(,W.(0L4DB=$L CP2K3@%)*-+44HT([[CC.IY_I
XMXUP<N.#V\@/\<_R@R_^>>_ZABR[STR_5!4/@G_D?+F #*MAA%5ZX@19>QP-$
XM@*,-3@A%)7!PBU7 HQ"_^,@-'A ,>=3A"";JS-I>$IH/ &$0,+A%$9 A F*L
XM@P\WX$,_Z .:!&C%C.<(2-JX04O*(X;MZ# %_Y0CYH)9W): 9=6!F65/Y N
XM<U:12A[J(8->N$$-:J""#61PA']LL1L]@(47:GB#JDGD0N! BC:T(;WU,(8
XMC-B #HTPAB-T@HX-\,]_ /09..0!!L.X PC&0 ;$\. &T7(%.'1C0QM6PA@2
XM:)T1*@&*4.#@!^W(W%2$$R*O(+$!7!E.<*JBN:S\0QC*4,8>8O$-,\0"BSW_
XMX*(->B #,D3K=4&I!!(6$XIIV.)V3JC$+38PM4F,H0<H29N 7*+' O0 !C"0
XMAS-4,0G$("8IJ;(ARFPX0S(DLA:V"-4MW($#-HS@0U,)SBCR431/(E$K?MH<
XMSK)A2F]0@QJQ,$,J6KD0Y_S#$(R(UFXB,L89+HL,H6B#+1A! A* @QN[\<(D
XM@M&#M%6@$Q:M@/$ ] HCU&,<G@ !##: B-VLX 8>(08=B,*'1<[0&"0@"B.F
XM<8M") ']F!BYZ@2''262Q1(W-;-1ID<81!5&%3(AC*X8 -U<N$>-B@&"4A6
XMPT(2(S?8])H1?@$*6_QB%> HAR&)P8TQO")M][!H_\4*8*N7R*,)8_@ &.B!
XM"*K5@B(H0T12M F.1F*H%LZZA4+=H2><YK1/D_,DN; "S^'8X!3RS 9RU& #
XM2TGG CDD#!]X@)ND$(.@$FB#-E81"C*HL1;ET,T-(D"%8*Q$'17%:$;UJ(X:
XM]( ,7D $(6-7TD42Y08W-,HTEF4,,C#"%B1(P!SL83]S[K0!62D76(1&"]'=
XM+)/J+)H;\G$*+F3C+WD8 5$B,U4^(").$EA620QJ"Q6LPK3@0 PC@A$, 9U5
XM0&J]+X!*\($Q"* 68W0%#URQ E?XMQ:(J(4,9\C EM9B<,8 +'QL <3E8O)F
XM12N75D:T5#]=X)R8K,=4;/_0EAY000WMP,%*^Y'9H:2'*(@X+PFV:HM;S)BA
XM+CCP#4 1C#%T K;&6ZLZHJ .,?B #!(@#"JH-F >U!"U=?UM&\\K 6 6 CYM
XMF,,7V*!EPF:26UH)U\X&-2+1J3,?%SBS.M70@6S(X1]N^,<%</!2CT@"P?VH
XM!!8.?$8O2$!Q:>PE"2K!C40B@A%U* %]>ZS,^T;A)7" P0&/7!XZ#'@%[ZT%
XM/31;8$O_%ASG39(*G(#0F;$!!EN&W%2<JS.B%4UH*Z("%<12 5@3\!]H&(83
XMR& >/LAFH'V]@0Z=8(0T;G4:J_C%+>@TY1;L@25WC&T!&AWM C1! <LKU R
XM.V#_0QH8P7C5)@/I48GSUF(:E7 @"6Q14_IQ.5N,7<BJ#>46M,AA!LI05UK^
XMTH$ZW"$!7F@#,7CMP@ CPA6^)8JRB$"PK?ZB#4JJ!&+H48<@W*,$SVX)QE\B
XM;8@?$#$KF VE#;X;:)G4D,#N=(/W^B82D'8:./C"(.P'N09<F"LT5PYTS#*#
XM/>@# S/X^0SN084&6*88833&><XSE((G<H9'!D<Q0&'0@[:!/3.\ 3U>L0MU
XM6)PE)?!2$M@6A4;3@YK"G(U0*F'7&XPT*1YQH8*[:4-Q.Z&!JY />9029F'
XMB%M"<W4#S'*/P:M+#GN(%] '3^(>W"(:B4GZ& G.Z?""_^,)H+B%-@C6!F/8
XMHA+C1L3$[Z&..V9<A&Q[Q2N$4-)"LMC Z@$''"MQ&&O"T;\*3GDM%+/7KL&#
XM'@F@P"!B7CIW+U5H':@ SH%>;SD$00X8>'Z]Z] )*O@""5Y03[^&8FD&:K,H
XM1;A\YM78!D: @Q$WD$ P=E$ BS? )=(6X4N$8)YM%]+U[]U-)5R85\*</)'G
XM];33)0D]P,/V)$ "_,">R,,YM5H'K,5:W(,<Z,,>S, 8')[S58'/_4,/U$$[
XMU) Q5(U0W("E80&"^5_N/8$1W((1X, JK)<ME-_Y!4,0<%T#L$V031OJY2 6
XM",4*3 1J[17$W=)0W(#!>82+O?_7#=D?.)!!UW@! 0+"[^T)59 9O"U'X,6(
XM')3 SB'>\P7=*]F!-A"&?.A6>3$0AAR<#1D#+H ?P<Q8(324?^V8%J;$*ZA$
XMH^7@Z8$@DP$;(B#"A>PAG5A-P7';R:6<!("#'\+4>VP/ 1J@M001MEQ K'@2
XMT6'A#.S"!-I;T&G@/PA)#1G<"H1B286B,:142M6"FWS?+7P!P80"-X0".!A!
XM#): 6K5 XA [3 K9S>+FX U4R$2=4"*AB#,41#4GC 5-45G-0".?@6 _E6
XM)="#N)V1,:@1"4@ ('A! BR4(\+<'SQ +\2*!QD3%52 '-1;,%1 ,-S#91Q!
XM#]P!* #_&R%-A-6L "K$#C6=URT,PS" B@8@=;8PRV0P3?=0AV, :(U0!Z,
XM0Q,(#R[68"Z^0M6L #_$$"HRPC!N /[106ZX75"@##@@DNX=XF)P7AML8TW-
XMS%,,PNE,@$OFP06,(T+ &CK.VEEM24,6@;6)%";TP42$XC5\W('A5H/= A$,
XMV[!MS>4A&PG<0C!D80,T@3QT5!-491.(P!&(0 NT@!5@@@%(1#_ $3CP B-4
XM O]!''HLHW]YA&;IGJ<1!1)40B'8 @[85#M,0#UDB:Q0(LWU)1>4(^'M0KP$
XM0;R4 /-5P1@T0020 2*LPPHXIGEH%A:,$6(<XCX.@PK:@]:$_P+!D,$TM,$8
XM!(,Z',$$/, $P, #C -#'D(3',(1- $E=$$?7 (F:.2 $2,-^:$+Z5_)Y16X
XM8=H9%84*W$(H&,$(U,,=Y(,;N$&LV, 1+(0'>=!?"ETYU@&LW<,8S &5($G
XM? R^ 31($)Z /K,-$ !BE)05BV!#F]>,_#LPDD=8:J1^UP< $.,P(/(##
XMZ*=J!L \4$(+8((D"!,BBLJ!$4,E8,(R,IG;K26P(=)>20"P$4(#A4(HM$,]
XM-$'HG!E,B@X#^LA;J$4#], =^4<0B($#/ H4X $>.$(2!$ $3 $U]:&G0.,M
XME -F_N-FSM1FBH'T'<($,.1I/A-J/O^ D3X !+! %SR"(1726 X:8302B_5F
XM, :CZ[U8>-5"&W"#/1SGF;G!!617/CRG<YZ-JSE'Q 0>%4Q?C 1!BOH %, I
XM%$ !--# .[! !-Q #BQ0(?5#9QD#-VA#CH("UW"F+7">$<1 2EAE5<K#.$SE
XM Z"F,\4! 9S /( !%O # V&"^7W$%!C#&-6"GRZ0;@RA?[G"YW53 W'#:M0#
XM3)X9K(9.JRT$8HF+)_G(^NF#&(@!$%@ /C@"/N#!,3@"-)1!.HB $2!"#DR-
XM+]Y J+A ,=S"+4@=C0TDRPS#+EQ&0QX!MS(JI)YF$IB $.@ !+S1@0$J87B!
XM&P7%#8PJG*S_)]R]GEQU$QJM1A[D02^<62]TJ#H-C?&=3=#T0 ?TF'8Z@ ,
XM@4 3[@ PU8 #3@ Q0< Q1D CO4)H0 !3@4PCXR@M;8 AELU;F1P1.H7U9&
XM91,LJK<:J2F<0 1@PCZP -O= #%.32FTS.RQJS+ZIF:!PS30PU'4$#T4PFI,
XM "8%!ZQ>EW/^Z[]Z$EJ40! $03S$ Q!,K054K04HP,):0 T<0R*D0!8@@@;D
XMP&Z003D4@Y+< B\Y"VG1PQVP%F<\)"YRZSE8Y3BPP!;(7P1T@2_T0Q^"JA?D
XM ,>RWM3 R3.*ZLDQT#181&>!PRK"P A,P+X:K>@($+PIK2>!!=HL_\H,.(#4
XM3JWG-JROZD&P;BT4I [3($!_*DQ#,.#>2:/;AX)W($ZO,+)VN(MWF*WOF95
XM3D( - (ZK, DF (FL)U9?L0M8$)2L-ANN (B6)H\&M@TA H]$,7LK,800.Y4
XM;*B'NIK-_9URH(VZE &&&SG>J["*JP>I*\>;&T(T$ +Y.DZ[-4P)$DA\!+!
XMN!0], QGU*$MUB$N8F6W]@$F!, .K ,F[ +]"%NA1$C& ->E1=EKL"%]*89
XM$M=1U (2,((]V"?D=M@HH%G1&,K.5.%9J,L,/"W4'JSY4JWH^NHQU >A$ 9
XM),%K$ .@6@@9T,/]MA<X,$Q6%H!*^&\N"F]/"V3E$9S )>S )V ")@B!$C1O
XMNQH2,?(I1 1%'SJO[2&"P[D (R"!#15"*!PGY)H9YU"N\8%%]S*M?_R<^))O
XMU):OPE;MPBZL N@!),BP$D2 2'%#N54"R[',+WC!*LB7\-P*1-9A+HXH5HI
X$0 .U;M
X
Xend
END_OF_FILE
if test 21738 -ne `wc -c <'testimg.gif.u'`; then
echo shar: \"'testimg.gif.u'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'testimg.gif'\"
cat testimg.gif.u | uudecode
if [ -f testimg.gif ]; then
rm testimg.gif.u
fi
fi
# end of 'testimg.gif.u'
fi
echo shar: End of archive 10 \(of 18\).
cp /dev/null ark10isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jchuff.c jcmain.c jrdgif.c makljpeg.cf
# Wrapped by kent@sparky on Mon Mar 23 16:02:49 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 11 (of 18)."'
if test -f 'jchuff.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jchuff.c'\"
else
echo shar: Extracting \"'jchuff.c'\" \(20071 characters\)
sed "s/^X//" >'jchuff.c' <<'END_OF_FILE'
X/*
X * jchuff.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains Huffman entropy encoding routines.
X * These routines are invoked via the methods entropy_encode,
X * entropy_encoder_init/term, and entropy_optimize.
X */
X
X#include "jinclude.h"
X
X
X/* Static variables to avoid passing 'round extra parameters */
X
Xstatic compress_info_ptr cinfo;
X
Xstatic INT32 huff_put_buffer; /* current bit-accumulation buffer */
Xstatic int huff_put_bits; /* # of bits now in it */
X
Xstatic char * output_buffer; /* output buffer */
Xstatic int bytes_in_buffer;
X
X
X
XLOCAL void
Xfix_huff_tbl (HUFF_TBL * htbl)
X/* Compute derived values for a Huffman table */
X{
X int p, i, l, lastp, si;
X char huffsize[257];
X UINT16 huffcode[257];
X UINT16 code;
X
X /* Figure C.1: make table of Huffman code length for each symbol */
X /* Note that this is in code-length order. */
X
X p = 0;
X for (l = 1; l <= 16; l++) {
X for (i = 1; i <= (int) htbl->bits[l]; i++)
X huffsize[p++] = (char) l;
X }
X huffsize[p] = 0;
X lastp = p;
X
X /* Figure C.2: generate the codes themselves */
X /* Note that this is in code-length order. */
X
X code = 0;
X si = huffsize[0];
X p = 0;
X while (huffsize[p]) {
X while (((int) huffsize[p]) == si) {
X huffcode[p++] = code;
X code++;
X }
X code <<= 1;
X si++;
X }
X
X /* Figure C.3: generate encoding tables */
X /* These are code and size indexed by symbol value */
X
X /* Set any codeless symbols to have code length 0;
X * this allows emit_bits to detect any attempt to emit such symbols.
X */
X MEMZERO((void *) htbl->ehufsi, SIZEOF(htbl->ehufsi));
X
X for (p = 0; p < lastp; p++) {
X htbl->ehufco[htbl->huffval[p]] = huffcode[p];
X htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
X }
X
X /* We don't bother to fill in the decoding tables mincode[], maxcode[], */
X /* and valptr[], since they are not used for encoding. */
X}
X
X
X/* Outputting bytes to the file */
X
XLOCAL void
Xflush_bytes (void)
X{
X if (bytes_in_buffer)
X (*cinfo->methods->entropy_output) (cinfo, output_buffer, bytes_in_buffer);
X bytes_in_buffer = 0;
X}
X
X
X#define emit_byte(val) \
X MAKESTMT( if (bytes_in_buffer >= JPEG_BUF_SIZE) \
X flush_bytes(); \
X output_buffer[bytes_in_buffer++] = (char) (val); )
X
X
X
X/* Outputting bits to the file */
X
X/* Only the right 24 bits of huff_put_buffer are used; the valid bits are
X * left-justified in this part. At most 16 bits can be passed to emit_bits
X * in one call, and we never retain more than 7 bits in huff_put_buffer
X * between calls, so 24 bits are sufficient.
X */
X
XLOCAL void
Xemit_bits (UINT16 code, int size)
X{
X /* This routine is heavily used, so it's worth coding tightly. */
X register INT32 put_buffer = code;
X register int put_bits = huff_put_bits;
X
X /* if size is 0, caller used an invalid Huffman table entry */
X if (size == 0)
X ERREXIT(cinfo->emethods, "Missing Huffman code table entry");
X
X put_buffer &= (((INT32) 1) << size) - 1; /* Mask off any excess bits in code */
X
X put_bits += size; /* new number of bits in buffer */
X
X put_buffer <<= 24 - put_bits; /* align incoming bits */
X
X put_buffer |= huff_put_buffer; /* and merge with old buffer contents */
X
X while (put_bits >= 8) {
X int c = (int) ((put_buffer >> 16) & 0xFF);
X
X emit_byte(c);
X if (c == 0xFF) { /* need to stuff a zero byte? */
X emit_byte(0);
X }
X put_buffer <<= 8;
X put_bits -= 8;
X }
X
X huff_put_buffer = put_buffer; /* Update global variables */
X huff_put_bits = put_bits;
X}
X
X
XLOCAL void
Xflush_bits (void)
X{
X emit_bits((UINT16) 0x7F, 7); /* fill any partial byte with ones */
X huff_put_buffer = 0; /* and reset bit-buffer to empty */
X huff_put_bits = 0;
X}
X
X
X
X/* Encode a single block's worth of coefficients */
X/* Note that the DC coefficient has already been converted to a difference */
X
XLOCAL void
Xencode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
X{
X register int temp, temp2;
X register int nbits;
X register int k, r, i;
X
X /* Encode the DC coefficient difference per section F.1.2.1 */
X
X temp = temp2 = block[0];
X
X if (temp < 0) {
X temp = -temp; /* temp is abs value of input */
X /* For a negative input, want temp2 = bitwise complement of abs(input) */
X /* This code assumes we are on a two's complement machine */
X temp2--;
X }
X
X /* Find the number of bits needed for the magnitude of the coefficient */
X nbits = 0;
X while (temp) {
X nbits++;
X temp >>= 1;
X }
X
X /* Emit the Huffman-coded symbol for the number of bits */
X emit_bits(dctbl->ehufco[nbits], dctbl->ehufsi[nbits]);
X
X /* Emit that number of bits of the value, if positive, */
X /* or the complement of its magnitude, if negative. */
X if (nbits) /* emit_bits rejects calls with size 0 */
X emit_bits((UINT16) temp2, nbits);
X
X /* Encode the AC coefficients per section F.1.2.2 */
X
X r = 0; /* r = run length of zeros */
X
X for (k = 1; k < DCTSIZE2; k++) {
X if ((temp = block[k]) == 0) {
X r++;
X } else {
X /* if run length > 15, must emit special run-length-16 codes (0xF0) */
X while (r > 15) {
X emit_bits(actbl->ehufco[0xF0], actbl->ehufsi[0xF0]);
X r -= 16;
X }
X
X temp2 = temp;
X if (temp < 0) {
X temp = -temp; /* temp is abs value of input */
X /* This code assumes we are on a two's complement machine */
X temp2--;
X }
X
X /* Find the number of bits needed for the magnitude of the coefficient */
X nbits = 1; /* there must be at least one 1 bit */
X while (temp >>= 1)
X nbits++;
X
X /* Emit Huffman symbol for run length / number of bits */
X i = (r << 4) + nbits;
X emit_bits(actbl->ehufco[i], actbl->ehufsi[i]);
X
X /* Emit that number of bits of the value, if positive, */
X /* or the complement of its magnitude, if negative. */
X emit_bits((UINT16) temp2, nbits);
X
X r = 0;
X }
X }
X
X /* If the last coef(s) were zero, emit an end-of-block code */
X if (r > 0)
X emit_bits(actbl->ehufco[0], actbl->ehufsi[0]);
X}
X
X
X
X/*
X * Initialize for a Huffman-compressed scan.
X * This is invoked after writing the SOS marker.
X * The pipeline controller must establish the entropy_output method pointer
X * before calling this routine.
X */
X
XMETHODDEF void
Xhuff_init (compress_info_ptr xinfo)
X{
X short ci;
X jpeg_component_info * compptr;
X
X /* Initialize static variables */
X cinfo = xinfo;
X huff_put_buffer = 0;
X huff_put_bits = 0;
X
X /* Initialize the output buffer */
X output_buffer = (char *) (*cinfo->emethods->alloc_small)
X ((size_t) JPEG_BUF_SIZE);
X bytes_in_buffer = 0;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X /* Make sure requested tables are present */
X if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
X ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
X /* Compute derived values for Huffman tables */
X /* We may do this more than once for same table, but it's not a big deal */
X fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
X fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
X /* Initialize DC predictions to 0 */
X cinfo->last_dc_val[ci] = 0;
X }
X
X /* Initialize restart stuff */
X cinfo->restarts_to_go = cinfo->restart_interval;
X cinfo->next_restart_num = 0;
X}
X
X
X/*
X * Emit a restart marker & resynchronize predictions.
X */
X
XLOCAL void
Xemit_restart (compress_info_ptr cinfo)
X{
X short ci;
X
X flush_bits();
X
X emit_byte(0xFF);
X emit_byte(RST0 + cinfo->next_restart_num);
X
X /* Re-initialize DC predictions to 0 */
X for (ci = 0; ci < cinfo->comps_in_scan; ci++)
X cinfo->last_dc_val[ci] = 0;
X
X /* Update restart state */
X cinfo->restarts_to_go = cinfo->restart_interval;
X cinfo->next_restart_num++;
X cinfo->next_restart_num &= 7;
X}
X
X
X/*
X * Encode and output one MCU's worth of Huffman-compressed coefficients.
X */
X
XMETHODDEF void
Xhuff_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
X{
X short blkn, ci;
X jpeg_component_info * compptr;
X JCOEF temp;
X
X /* Account for restart interval, emit restart marker if needed */
X if (cinfo->restart_interval) {
X if (cinfo->restarts_to_go == 0)
X emit_restart(cinfo);
X cinfo->restarts_to_go--;
X }
X
X for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
X ci = cinfo->MCU_membership[blkn];
X compptr = cinfo->cur_comp_info[ci];
X /* Convert DC value to difference, update last_dc_val */
X temp = MCU_data[blkn][0];
X MCU_data[blkn][0] -= cinfo->last_dc_val[ci];
X cinfo->last_dc_val[ci] = temp;
X encode_one_block(MCU_data[blkn],
X cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no],
X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
X }
X}
X
X
X/*
X * Finish up at the end of a Huffman-compressed scan.
X */
X
XMETHODDEF void
Xhuff_term (compress_info_ptr cinfo)
X{
X /* Flush out the last data */
X flush_bits();
X flush_bytes();
X /* Release the I/O buffer */
X (*cinfo->emethods->free_small) ((void *) output_buffer);
X}
X
X
X
X
X/*
X * Huffman coding optimization.
X *
X * This actually is optimization, in the sense that we find the best possible
X * Huffman table(s) for the given data. We first scan the supplied data and
X * count the number of uses of each symbol that is to be Huffman-coded.
X * (This process must agree with the code above.) Then we build an
X * optimal Huffman coding tree for the observed counts.
X */
X
X#ifdef ENTROPY_OPT_SUPPORTED
X
X
X/* These are static so htest_one_block can find 'em */
Xstatic long * dc_count_ptrs[NUM_HUFF_TBLS];
Xstatic long * ac_count_ptrs[NUM_HUFF_TBLS];
X
X
XLOCAL void
Xgen_huff_coding (compress_info_ptr cinfo, HUFF_TBL *htbl, long freq[])
X/* Generate the optimal coding for the given counts */
X{
X#define MAX_CLEN 32 /* assumed maximum initial code length */
X UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
X short codesize[257]; /* codesize[k] = code length of symbol k */
X short others[257]; /* next symbol in current branch of tree */
X int c1, c2;
X int p, i, j;
X long v;
X
X /* This algorithm is explained in section K.2 of the JPEG standard */
X
X MEMZERO((void *) bits, SIZEOF(bits));
X MEMZERO((void *) codesize, SIZEOF(codesize));
X for (i = 0; i < 257; i++)
X others[i] = -1; /* init links to empty */
X
X freq[256] = 1; /* make sure there is a nonzero count */
X /* including the pseudo-symbol 256 in the Huffman procedure guarantees
X * that no real symbol is given code-value of all ones, because 256
X * will be placed in the largest codeword category.
X */
X
X /* Huffman's basic algorithm to assign optimal code lengths to symbols */
X
X for (;;) {
X /* Find the smallest nonzero frequency, set c1 = its symbol */
X /* In case of ties, take the larger symbol number */
X c1 = -1;
X v = 1000000000L;
X for (i = 0; i <= 256; i++) {
X if (freq[i] && freq[i] <= v) {
X v = freq[i];
X c1 = i;
X }
X }
X
X /* Find the next smallest nonzero frequency, set c2 = its symbol */
X /* In case of ties, take the larger symbol number */
X c2 = -1;
X v = 1000000000L;
X for (i = 0; i <= 256; i++) {
X if (freq[i] && freq[i] <= v && i != c1) {
X v = freq[i];
X c2 = i;
X }
X }
X
X /* Done if we've merged everything into one frequency */
X if (c2 < 0)
X break;
X
X /* Else merge the two counts/trees */
X freq[c1] += freq[c2];
X freq[c2] = 0;
X
X /* Increment the codesize of everything in c1's tree branch */
X codesize[c1]++;
X while (others[c1] >= 0) {
X c1 = others[c1];
X codesize[c1]++;
X }
X
X others[c1] = c2; /* chain c2 onto c1's tree branch */
X
X /* Increment the codesize of everything in c2's tree branch */
X codesize[c2]++;
X while (others[c2] >= 0) {
X c2 = others[c2];
X codesize[c2]++;
X }
X }
X
X /* Now count the number of symbols of each code length */
X for (i = 0; i <= 256; i++) {
X if (codesize[i]) {
X /* The JPEG standard seems to think that this can't happen, */
X /* but I'm paranoid... */
X if (codesize[i] > MAX_CLEN)
X ERREXIT(cinfo->emethods, "Huffman code size table overflow");
X
X bits[codesize[i]]++;
X }
X }
X
X /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
X * Huffman procedure assigned any such lengths, we must adjust the coding.
X * Here is what the JPEG spec says about how this next bit works:
X * Since symbols are paired for the longest Huffman code, the symbols are
X * removed from this length category two at a time. The prefix for the pair
X * (which is one bit shorter) is allocated to one of the pair; then,
X * skipping the BITS entry for that prefix length, a code word from the next
X * shortest nonzero BITS entry is converted into a prefix for two code words
X * one bit longer.
X */
X
X for (i = MAX_CLEN; i > 16; i--) {
X while (bits[i] > 0) {
X j = i - 2; /* find length of new prefix to be used */
X while (bits[j] == 0)
X j--;
X
X bits[i] -= 2; /* remove two symbols */
X bits[i-1]++; /* one goes in this length */
X bits[j+1] += 2; /* two new symbols in this length */
X bits[j]--; /* symbol of this length is now a prefix */
X }
X }
X
X /* Remove the count for the pseudo-symbol 256 from the largest codelength */
X while (bits[i] == 0) /* find largest codelength still in use */
X i--;
X bits[i]--;
X
X /* Return final symbol counts (only for lengths 0..16) */
X memcpy((void *) htbl->bits, (void *) bits, SIZEOF(htbl->bits));
X
X /* Return a list of the symbols sorted by code length */
X /* It's not real clear to me why we don't need to consider the codelength
X * changes made above, but the JPEG spec seems to think this works.
X */
X p = 0;
X for (i = 1; i <= MAX_CLEN; i++) {
X for (j = 0; j <= 255; j++) {
X if (codesize[j] == i) {
X htbl->huffval[p] = (UINT8) j;
X p++;
X }
X }
X }
X}
X
X
X/* Process a single block's worth of coefficients */
X/* Note that the DC coefficient has already been converted to a difference */
X
XLOCAL void
Xhtest_one_block (JBLOCK block, JCOEF block0,
X long dc_counts[], long ac_counts[])
X{
X register INT32 temp;
X register int nbits;
X register int k, r;
X
X /* Encode the DC coefficient difference per section F.1.2.1 */
X
X /* Find the number of bits needed for the magnitude of the coefficient */
X temp = block0;
X if (temp < 0) temp = -temp;
X
X for (nbits = 0; temp; nbits++)
X temp >>= 1;
X
X /* Count the Huffman symbol for the number of bits */
X dc_counts[nbits]++;
X
X /* Encode the AC coefficients per section F.1.2.2 */
X
X r = 0; /* r = run length of zeros */
X
X for (k = 1; k < DCTSIZE2; k++) {
X if ((temp = block[k]) == 0) {
X r++;
X } else {
X /* if run length > 15, must emit special run-length-16 codes (0xF0) */
X while (r > 15) {
X ac_counts[0xF0]++;
X r -= 16;
X }
X
X /* Find the number of bits needed for the magnitude of the coefficient */
X if (temp < 0) temp = -temp;
X
X for (nbits = 0; temp; nbits++)
X temp >>= 1;
X
X /* Count Huffman symbol for run length / number of bits */
X ac_counts[(r << 4) + nbits]++;
X
X r = 0;
X }
X }
X
X /* If the last coef(s) were zero, emit an end-of-block code */
X if (r > 0)
X ac_counts[0]++;
X}
X
X
X
X/*
X * Trial-encode one MCU's worth of Huffman-compressed coefficients.
X */
X
XLOCAL void
Xhtest_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
X{
X short blkn, ci;
X jpeg_component_info * compptr;
X
X /* Take care of restart intervals if needed */
X if (cinfo->restart_interval) {
X if (cinfo->restarts_to_go == 0) {
X /* Re-initialize DC predictions to 0 */
X for (ci = 0; ci < cinfo->comps_in_scan; ci++)
X cinfo->last_dc_val[ci] = 0;
X /* Update restart state */
X cinfo->restarts_to_go = cinfo->restart_interval;
X }
X cinfo->restarts_to_go--;
X }
X
X for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
X ci = cinfo->MCU_membership[blkn];
X compptr = cinfo->cur_comp_info[ci];
X /* NB: unlike the real entropy encoder, we may not change the input data */
X htest_one_block(MCU_data[blkn],
X (JCOEF) (MCU_data[blkn][0] - cinfo->last_dc_val[ci]),
X dc_count_ptrs[compptr->dc_tbl_no],
X ac_count_ptrs[compptr->ac_tbl_no]);
X cinfo->last_dc_val[ci] = MCU_data[blkn][0];
X }
X}
X
X
X
X/*
X * Find the best coding parameters for a Huffman-coded scan.
X * When called, the scan data has already been converted to a sequence of
X * MCU groups of quantized coefficients, which are stored in a "big" array.
X * The source_method knows how to iterate through that array.
X * On return, the MCU data is unmodified, but the Huffman tables referenced
X * by the scan components may have been altered.
X */
X
XMETHODDEF void
Xhuff_optimize (compress_info_ptr cinfo, MCU_output_caller_ptr source_method)
X/* Optimize Huffman-coding parameters (Huffman symbol table) */
X{
X int i, tbl;
X HUFF_TBL **htblptr;
X
X /* Allocate and zero the count tables */
X /* Note that gen_huff_coding expects 257 entries in each table! */
X
X for (i = 0; i < NUM_HUFF_TBLS; i++) {
X dc_count_ptrs[i] = NULL;
X ac_count_ptrs[i] = NULL;
X }
X
X for (i = 0; i < cinfo->comps_in_scan; i++) {
X /* Create DC table */
X tbl = cinfo->cur_comp_info[i]->dc_tbl_no;
X if (dc_count_ptrs[tbl] == NULL) {
X dc_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
X (257 * SIZEOF(long));
X MEMZERO((void *) dc_count_ptrs[tbl], 257 * SIZEOF(long));
X }
X /* Create AC table */
X tbl = cinfo->cur_comp_info[i]->ac_tbl_no;
X if (ac_count_ptrs[tbl] == NULL) {
X ac_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
X (257 * SIZEOF(long));
X MEMZERO((void *) ac_count_ptrs[tbl], 257 * SIZEOF(long));
X }
X }
X
X /* Initialize DC predictions to 0 */
X for (i = 0; i < cinfo->comps_in_scan; i++) {
X cinfo->last_dc_val[i] = 0;
X }
X /* Initialize restart stuff */
X cinfo->restarts_to_go = cinfo->restart_interval;
X
X /* Scan the MCU data, count symbol uses */
X (*source_method) (cinfo, htest_encode);
X
X /* Now generate optimal Huffman tables */
X for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {
X if (dc_count_ptrs[tbl] != NULL) {
X htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
X if (*htblptr == NULL)
X *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
X /* Set sent_table FALSE so updated table will be written to JPEG file. */
X (*htblptr)->sent_table = FALSE;
X /* Compute the optimal Huffman encoding */
X gen_huff_coding(cinfo, *htblptr, dc_count_ptrs[tbl]);
X /* Release the count table */
X (*cinfo->emethods->free_small) ((void *) dc_count_ptrs[tbl]);
X }
X if (ac_count_ptrs[tbl] != NULL) {
X htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
X if (*htblptr == NULL)
X *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
X /* Set sent_table FALSE so updated table will be written to JPEG file. */
X (*htblptr)->sent_table = FALSE;
X /* Compute the optimal Huffman encoding */
X gen_huff_coding(cinfo, *htblptr, ac_count_ptrs[tbl]);
X /* Release the count table */
X (*cinfo->emethods->free_small) ((void *) ac_count_ptrs[tbl]);
X }
X }
X}
X
X
X#endif /* ENTROPY_OPT_SUPPORTED */
X
X
X/*
X * The method selection routine for Huffman entropy encoding.
X */
X
XGLOBAL void
Xjselchuffman (compress_info_ptr cinfo)
X{
X if (! cinfo->arith_code) {
X cinfo->methods->entropy_encoder_init = huff_init;
X cinfo->methods->entropy_encode = huff_encode;
X cinfo->methods->entropy_encoder_term = huff_term;
X#ifdef ENTROPY_OPT_SUPPORTED
X cinfo->methods->entropy_optimize = huff_optimize;
X /* The standard Huffman tables are only valid for 8-bit data precision.
X * If the precision is higher, force optimization on so that usable
X * tables will be computed. This test can be removed if default tables
X * are supplied that are valid for the desired precision.
X */
X if (cinfo->data_precision > 8)
X cinfo->optimize_coding = TRUE;
X if (cinfo->optimize_coding)
X cinfo->total_passes++; /* one pass needed for entropy optimization */
X#endif
X }
X}
END_OF_FILE
if test 20071 -ne `wc -c <'jchuff.c'`; then
echo shar: \"'jchuff.c'\" unpacked with wrong size!
fi
# end of 'jchuff.c'
fi
if test -f 'jcmain.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcmain.c'\"
else
echo shar: Extracting \"'jcmain.c'\" \(9991 characters\)
sed "s/^X//" >'jcmain.c' <<'END_OF_FILE'
X/*
X * jcmain.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains a trivial test user interface for the JPEG compressor.
X * It should work on any system with Unix- or MS-DOS-style command lines.
X *
X * Two different command line styles are permitted, depending on the
X * compile-time switch TWO_FILE_COMMANDLINE:
X * cjpeg [options] inputfile outputfile
X * cjpeg [options] [inputfile]
X * In the second style, output is always to standard output, which you'd
X * normally redirect to a file or pipe to some other program. Input is
X * either from a named file or from standard input (typically redirected).
X * The second style is convenient on Unix but is unhelpful on systems that
X * don't support pipes. Also, you MUST use the first style if your system
X * doesn't do binary I/O to stdin/stdout.
X */
X
X#include "jinclude.h"
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare exit() */
X#endif
X#ifdef NEED_SIGNAL_CATCHER
X#include <signal.h> /* to declare signal() */
X#endif
X
X#ifdef THINK_C
X#include <console.h> /* command-line reader for Macintosh */
X#endif
X
X#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
X#define READ_BINARY "r"
X#define WRITE_BINARY "w"
X#else
X#define READ_BINARY "rb"
X#define WRITE_BINARY "wb"
X#endif
X
X#ifndef EXIT_FAILURE /* define exit() codes if not provided */
X#define EXIT_FAILURE 1
X#endif
X#ifndef EXIT_SUCCESS
X#ifdef VMS
X#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
X#else
X#define EXIT_SUCCESS 0
X#endif
X#endif
X
X
X#include "jversion.h" /* for version message */
X
X
X/*
X * PD version of getopt(3).
X */
X
X#include "egetopt.c"
X
X
X/*
X * This routine determines what format the input file is,
X * and selects the appropriate input-reading module.
X *
X * To determine which family of input formats the file belongs to,
X * we may look only at the first byte of the file, since C does not
X * guarantee that more than one character can be pushed back with ungetc.
X * Looking at additional bytes would require one of these approaches:
X * 1) assume we can fseek() the input file (fails for piped input);
X * 2) assume we can push back more than one character (works in
X * some C implementations, but unportable);
X * 3) provide our own buffering as is done in djpeg (breaks input readers
X * that want to use stdio directly, such as the RLE library);
X * or 4) don't put back the data, and modify the input_init methods to assume
X * they start reading after the start of file (also breaks RLE library).
X * #1 is attractive for MS-DOS but is untenable on Unix.
X *
X * The most portable solution for file types that can't be identified by their
X * first byte is to make the user tell us what they are. This is also the
X * only approach for "raw" file types that contain only arbitrary values.
X * We presently apply this method for Targa files. Most of the time Targa
X * files start with 0x00, so we recognize that case. Potentially, however,
X * a Targa file could start with any byte value (byte 0 is the length of the
X * seldom-used ID field), so we accept a -T switch to force Targa input mode.
X */
X
Xstatic boolean is_targa; /* records user -T switch */
X
X
XLOCAL void
Xselect_file_type (compress_info_ptr cinfo)
X{
X int c;
X
X if (is_targa) {
X#ifdef TARGA_SUPPORTED
X jselrtarga(cinfo);
X#else
X ERREXIT(cinfo->emethods, "Targa support was not compiled");
X#endif
X return;
X }
X
X if ((c = getc(cinfo->input_file)) == EOF)
X ERREXIT(cinfo->emethods, "Empty input file");
X
X switch (c) {
X#ifdef GIF_SUPPORTED
X case 'G':
X jselrgif(cinfo);
X break;
X#endif
X#ifdef PPM_SUPPORTED
X case 'P':
X jselrppm(cinfo);
X break;
X#endif
X#ifdef RLE_SUPPORTED
X case 'R':
X jselrrle(cinfo);
X break;
X#endif
X#ifdef TARGA_SUPPORTED
X case 0x00:
X jselrtarga(cinfo);
X break;
X#endif
X default:
X#ifdef TARGA_SUPPORTED
X ERREXIT(cinfo->emethods, "Unrecognized input file format --- did you forget -T ?");
X#else
X ERREXIT(cinfo->emethods, "Unrecognized input file format");
X#endif
X break;
X }
X
X if (ungetc(c, cinfo->input_file) == EOF)
X ERREXIT(cinfo->emethods, "ungetc failed");
X}
X
X
X/*
X * This routine gets control after the input file header has been read.
X * It must determine what output JPEG file format is to be written,
X * and make any other compression parameter changes that are desirable.
X */
X
XMETHODDEF void
Xc_ui_method_selection (compress_info_ptr cinfo)
X{
X /* If the input is gray scale, generate a monochrome JPEG file. */
X if (cinfo->in_color_space == CS_GRAYSCALE)
X j_monochrome_default(cinfo);
X /* For now, always select JFIF output format. */
X#ifdef JFIF_SUPPORTED
X jselwjfif(cinfo);
X#else
X You shoulda defined JFIF_SUPPORTED. /* deliberate syntax error */
X#endif
X}
X
X
X/*
X * Signal catcher to ensure that temporary files are removed before aborting.
X * NB: for Amiga Manx C this is actually a global routine named _abort();
X * see -Dsignal_catcher=_abort in CFLAGS. Talk about bogus...
X */
X
X#ifdef NEED_SIGNAL_CATCHER
X
Xstatic external_methods_ptr emethods; /* for access to free_all */
X
XGLOBAL void
Xsignal_catcher (int signum)
X{
X emethods->trace_level = 0; /* turn off trace output */
X (*emethods->free_all) (); /* clean up memory allocation & temp files */
X exit(EXIT_FAILURE);
X}
X
X#endif
X
X
XLOCAL void
Xusage (char * progname)
X/* complain about bad command line */
X{
X fprintf(stderr, "usage: %s ", progname);
X fprintf(stderr, "[-Q quality 0..100] [-o] [-T] [-I] [-a] [-d] [-m mem]");
X#ifdef TWO_FILE_COMMANDLINE
X fprintf(stderr, " inputfile outputfile\n");
X#else
X fprintf(stderr, " [inputfile]\n");
X#endif
X exit(EXIT_FAILURE);
X}
X
X
X/*
X * The main program.
X */
X
XGLOBAL int
Xmain (int argc, char **argv)
X{
X struct compress_info_struct cinfo;
X struct compress_methods_struct c_methods;
X struct external_methods_struct e_methods;
X int c;
X
X /* On Mac, fetch a command line. */
X#ifdef THINK_C
X argc = ccommand(&argv);
X#endif
X
X /* Initialize the system-dependent method pointers. */
X cinfo.methods = &c_methods;
X cinfo.emethods = &e_methods;
X jselerror(&e_methods); /* error/trace message routines */
X jselmemmgr(&e_methods); /* memory allocation routines */
X c_methods.c_ui_method_selection = c_ui_method_selection;
X
X /* Now OK to enable signal catcher. */
X#ifdef NEED_SIGNAL_CATCHER
X emethods = &e_methods;
X signal(SIGINT, signal_catcher);
X#ifdef SIGTERM /* not all systems have SIGTERM */
X signal(SIGTERM, signal_catcher);
X#endif
X#endif
X
X /* Set up default JPEG parameters. */
X j_c_defaults(&cinfo, 75, FALSE); /* default quality level = 75 */
X is_targa = FALSE;
X
X /* Scan command line options, adjust parameters */
X
X while ((c = egetopt(argc, argv, "IQ:Taom:d")) != EOF)
X switch (c) {
X case 'I': /* Create noninterleaved file. */
X#ifdef MULTISCAN_FILES_SUPPORTED
X cinfo.interleave = FALSE;
X#else
X fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n",
X argv[0]);
X exit(EXIT_FAILURE);
X#endif
X break;
X case 'Q': /* Quality factor. */
X { int val;
X if (optarg == NULL)
X usage(argv[0]);
X if (sscanf(optarg, "%d", &val) != 1)
X usage(argv[0]);
X /* Note: for now, we make force_baseline FALSE.
X * This means non-baseline JPEG files can be created with low Q values.
X * To ensure only baseline files are generated, pass TRUE instead.
X */
X j_set_quality(&cinfo, val, FALSE);
X }
X break;
X case 'T': /* Input file is Targa format. */
X is_targa = TRUE;
X break;
X case 'a': /* Use arithmetic coding. */
X#ifdef ARITH_CODING_SUPPORTED
X cinfo.arith_code = TRUE;
X#else
X fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
X argv[0]);
X exit(EXIT_FAILURE);
X#endif
X break;
X case 'o': /* Enable entropy parm optimization. */
X#ifdef ENTROPY_OPT_SUPPORTED
X cinfo.optimize_coding = TRUE;
X#else
X fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
X argv[0]);
X exit(EXIT_FAILURE);
X#endif
X break;
X case 'm': /* Maximum memory in Kb (or Mb with 'm'). */
X { long lval;
X char ch = 'x';
X
X if (optarg == NULL)
X usage(argv[0]);
X if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
X usage(argv[0]);
X if (ch == 'm' || ch == 'M')
X lval *= 1000L;
X e_methods.max_memory_to_use = lval * 1000L;
X }
X break;
X case 'd': /* Debugging. */
X e_methods.trace_level++;
X break;
X case '?':
X default:
X usage(argv[0]);
X break;
X }
X
X /* If -d appeared, print version identification */
X if (e_methods.trace_level > 0)
X fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n",
X JVERSION, JCOPYRIGHT);
X
X /* Select the input and output files */
X
X#ifdef TWO_FILE_COMMANDLINE
X
X if (optind != argc-2) {
X fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
X usage(argv[0]);
X }
X if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
X exit(EXIT_FAILURE);
X }
X if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
X exit(EXIT_FAILURE);
X }
X
X#else /* not TWO_FILE_COMMANDLINE -- use Unix style */
X
X cinfo.input_file = stdin; /* default input file */
X cinfo.output_file = stdout; /* always the output file */
X
X if (optind < argc-1) {
X fprintf(stderr, "%s: only one input file\n", argv[0]);
X usage(argv[0]);
X }
X if (optind < argc) {
X if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
X exit(EXIT_FAILURE);
X }
X }
X
X#endif /* TWO_FILE_COMMANDLINE */
X
X /* Figure out the input file format, and set up to read it. */
X select_file_type(&cinfo);
X
X /* Do it to it! */
X jpeg_compress(&cinfo);
X
X /* All done. */
X exit(EXIT_SUCCESS);
X return 0; /* suppress no-return-value warnings */
X}
END_OF_FILE
if test 9991 -ne `wc -c <'jcmain.c'`; then
echo shar: \"'jcmain.c'\" unpacked with wrong size!
fi
# end of 'jcmain.c'
fi
if test -f 'jrdgif.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jrdgif.c'\"
else
echo shar: Extracting \"'jrdgif.c'\" \(19830 characters\)
sed "s/^X//" >'jrdgif.c' <<'END_OF_FILE'
X/*
X * jrdgif.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to read input images in GIF format.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume input from
X * an ordinary stdio stream. They further assume that reading begins
X * at the start of the file; input_init may need work if the
X * user interface has already read some data (e.g., to determine that
X * the file is indeed GIF format).
X *
X * These routines are invoked via the methods get_input_row
X * and input_init/term.
X */
X
X/*
X * This code is loosely based on giftoppm from the PBMPLUS distribution
X * of Feb. 1991. That file contains the following copyright notice:
X * +-------------------------------------------------------------------+
X * | Copyright 1990, David Koblas. |
X * | Permission to use, copy, modify, and distribute this software |
X * | and its documentation for any purpose and without fee is hereby |
X * | granted, provided that the above copyright notice appear in all |
X * | copies and that both that copyright notice and this permission |
X * | notice appear in supporting documentation. This software is |
X * | provided "as is" without express or implied warranty. |
X * +-------------------------------------------------------------------+
X *
X * We are also required to state that
X * "The Graphics Interchange Format(c) is the Copyright property of
X * CompuServe Incorporated. GIF(sm) is a Service Mark property of
X * CompuServe Incorporated."
X */
X
X#include "jinclude.h"
X
X#ifdef GIF_SUPPORTED
X
X
X#define MAXCOLORMAPSIZE 256 /* max # of colors in a GIF colormap */
X#define NUMCOLORS 3 /* # of colors */
X#define CM_RED 0 /* color component numbers */
X#define CM_GREEN 1
X#define CM_BLUE 2
X
Xstatic JSAMPARRAY colormap; /* the colormap to use */
X/* colormap[i][j] = value of i'th color component for pixel value j */
X
X#define MAX_LZW_BITS 12 /* maximum LZW code size */
X#define LZW_TABLE_SIZE (1<<MAX_LZW_BITS) /* # of possible LZW symbols */
X
X/* Macros for extracting header data --- note we assume chars may be signed */
X
X#define LM_to_uint(a,b) ((((b)&0xFF) << 8) | ((a)&0xFF))
X
X#define BitSet(byte, bit) ((byte) & (bit))
X#define INTERLACE 0x40 /* mask for bit signifying interlaced image */
X#define COLORMAPFLAG 0x80 /* mask for bit signifying colormap presence */
X
X#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
X
X/* Static vars for GetCode and LZWReadByte */
X
Xstatic char code_buf[256+4]; /* current input data block */
Xstatic int last_byte; /* # of bytes in code_buf */
Xstatic int last_bit; /* # of bits in code_buf */
Xstatic int cur_bit; /* next bit index to read */
Xstatic boolean out_of_blocks; /* TRUE if hit terminator data block */
X
Xstatic int input_code_size; /* codesize given in GIF file */
Xstatic int clear_code,end_code; /* values for Clear and End codes */
X
Xstatic int code_size; /* current actual code size */
Xstatic int limit_code; /* 2^code_size */
Xstatic int max_code; /* first unused code value */
Xstatic boolean first_time; /* flags first call to LZWReadByte */
X
X/* LZW decompression tables:
X * symbol_head[K] = prefix symbol of any LZW symbol K (0..LZW_TABLE_SIZE-1)
X * symbol_tail[K] = suffix byte of any LZW symbol K (0..LZW_TABLE_SIZE-1)
X * Note that entries 0..end_code of the above tables are not used,
X * since those symbols represent raw bytes or special codes.
X *
X * The stack represents the not-yet-used expansion of the last LZW symbol.
X * In the worst case, a symbol could expand to as many bytes as there are
X * LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
X * (This is conservative since that number includes the raw-byte symbols.)
X *
X * The tables are allocated from FAR heap space since they would use up
X * rather a lot of the near data space in a PC.
X */
X
Xstatic UINT16 FAR *symbol_head; /* => table of prefix symbols */
Xstatic UINT8 FAR *symbol_tail; /* => table of suffix bytes */
Xstatic UINT8 FAR *symbol_stack; /* stack for symbol expansions */
Xstatic UINT8 FAR *sp; /* stack pointer */
X
X/* Static state for interlaced image processing */
X
Xstatic boolean is_interlaced; /* TRUE if have interlaced image */
Xstatic big_sarray_ptr interlaced_image; /* full image in interlaced order */
Xstatic long cur_row_number; /* need to know actual row number */
Xstatic long pass2_offset; /* # of pixel rows in pass 1 */
Xstatic long pass3_offset; /* # of pixel rows in passes 1&2 */
Xstatic long pass4_offset; /* # of pixel rows in passes 1,2,3 */
X
X
X/* Forward declarations */
XMETHODDEF void load_interlaced_image PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
XMETHODDEF void get_interlaced_row PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
X
X
X
XLOCAL int
XReadByte (compress_info_ptr cinfo)
X/* Read next byte from GIF file */
X{
X register FILE * infile = cinfo->input_file;
X int c;
X
X if ((c = getc(infile)) == EOF)
X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
X return c;
X}
X
X
XLOCAL int
XGetDataBlock (compress_info_ptr cinfo, char *buf)
X/* Read a GIF data block, which has a leading count byte */
X/* A zero-length block marks the end of a data block sequence */
X{
X int count;
X
X count = ReadByte(cinfo);
X if (count > 0) {
X if (! ReadOK(cinfo->input_file, buf, count))
X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
X }
X return count;
X}
X
X
XLOCAL void
XSkipDataBlocks (compress_info_ptr cinfo)
X/* Skip a series of data blocks, until a block terminator is found */
X{
X char buf[256];
X
X while (GetDataBlock(cinfo, buf) > 0)
X /* skip */;
X}
X
X
XLOCAL void
XReInitLZW (void)
X/* (Re)initialize LZW state; shared code for startup and Clear processing */
X{
X code_size = input_code_size+1;
X limit_code = clear_code << 1; /* 2^code_size */
X max_code = clear_code + 2; /* first unused code value */
X sp = symbol_stack; /* init stack to empty */
X}
X
X
XLOCAL void
XInitLZWCode (void)
X/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
X{
X /* GetCode initialization */
X last_byte = 2; /* make safe to "recopy last two bytes" */
X last_bit = 0; /* nothing in the buffer */
X cur_bit = 0; /* force buffer load on first call */
X out_of_blocks = FALSE;
X
X /* LZWReadByte initialization */
X clear_code = 1 << input_code_size; /* compute special code values */
X end_code = clear_code + 1; /* note that these do not change */
X first_time = TRUE;
X ReInitLZW();
X}
X
X
XLOCAL int
XGetCode (compress_info_ptr cinfo)
X/* Fetch the next code_size bits from the GIF data */
X/* We assume code_size is less than 16 */
X{
X register INT32 accum;
X int offs, ret, count;
X
X if ( (cur_bit+code_size) > last_bit) {
X /* Time to reload the buffer */
X if (out_of_blocks) {
X TRACEMS(cinfo->emethods, 1, "Ran out of GIF bits");
X return end_code; /* fake something useful */
X }
X /* preserve last two bytes of what we have -- assume code_size <= 16 */
X code_buf[0] = code_buf[last_byte-2];
X code_buf[1] = code_buf[last_byte-1];
X /* Load more bytes; set flag if we reach the terminator block */
X if ((count = GetDataBlock(cinfo, &code_buf[2])) == 0) {
X out_of_blocks = TRUE;
X TRACEMS(cinfo->emethods, 1, "Ran out of GIF bits");
X return end_code; /* fake something useful */
X }
X /* Reset counters */
X cur_bit = (cur_bit - last_bit) + 16;
X last_byte = 2 + count;
X last_bit = last_byte * 8;
X }
X
X /* Form up next 24 bits in accum */
X offs = cur_bit >> 3; /* byte containing cur_bit */
X#ifdef CHAR_IS_UNSIGNED
X accum = code_buf[offs+2];
X accum <<= 8;
X accum |= code_buf[offs+1];
X accum <<= 8;
X accum |= code_buf[offs];
X#else
X accum = code_buf[offs+2] & 0xFF;
X accum <<= 8;
X accum |= code_buf[offs+1] & 0xFF;
X accum <<= 8;
X accum |= code_buf[offs] & 0xFF;
X#endif
X
X /* Right-align cur_bit in accum, then mask off desired number of bits */
X accum >>= (cur_bit & 7);
X ret = ((int) accum) & ((1 << code_size) - 1);
X
X cur_bit += code_size;
X return ret;
X}
X
X
XLOCAL int
XLZWReadByte (compress_info_ptr cinfo)
X/* Read an LZW-compressed byte */
X{
X static int oldcode; /* previous LZW symbol */
X static int firstcode; /* first byte of oldcode's expansion */
X register int code; /* current working code */
X int incode; /* saves actual input code */
X
X /* First time, just eat the expected Clear code(s) and return next code, */
X /* which is assumed to be a raw byte. */
X if (first_time) {
X first_time = FALSE;
X do {
X code = GetCode(cinfo);
X } while (code == clear_code);
X firstcode = oldcode = code; /* make firstcode, oldcode valid! */
X return code;
X }
X
X /* If any codes are stacked from a previously read symbol, return them */
X if (sp > symbol_stack)
X return (int) *(--sp);
X
X code = GetCode(cinfo);
X
X if (code == clear_code) {
X /* Reinit static state, swallow any extra Clear codes, and return */
X ReInitLZW();
X do {
X code = GetCode(cinfo);
X } while (code == clear_code);
X firstcode = oldcode = code; /* gotta reinit these too */
X return code;
X }
X
X if (code == end_code) {
X /* Skip the rest of the image, unless GetCode already read terminator */
X if (! out_of_blocks)
X SkipDataBlocks(cinfo);
X return -1;
X }
X
X /* Normal raw byte or LZW symbol */
X incode = code; /* save for a moment */
X
X if (code >= max_code) { /* special case for not-yet-defined symbol */
X *sp++ = (UINT8) firstcode; /* it will be defined as oldcode/firstcode */
X code = oldcode;
X }
X
X /* If it's a symbol, expand it into the stack */
X while (code >= clear_code) {
X *sp++ = symbol_tail[code]; /* tail of symbol: a simple byte value */
X code = symbol_head[code]; /* head of symbol: another LZW symbol */
X }
X /* At this point code just represents a raw byte */
X firstcode = code; /* save for possible future use */
X
X /* If there's room in table, */
X if ((code = max_code) < LZW_TABLE_SIZE) {
X /* Define a new symbol = prev sym + head of this sym's expansion */
X symbol_head[code] = oldcode;
X symbol_tail[code] = (UINT8) firstcode;
X max_code++;
X /* Is it time to increase code_size? */
X if ((max_code >= limit_code) && (code_size < MAX_LZW_BITS)) {
X code_size++;
X limit_code <<= 1; /* keep equal to 2^code_size */
X }
X }
X
X oldcode = incode; /* save last input symbol for future use */
X return firstcode; /* return first byte of symbol's expansion */
X}
X
X
XLOCAL void
XReadColorMap (compress_info_ptr cinfo, int cmaplen, JSAMPARRAY cmap)
X/* Read a GIF colormap */
X{
X int i;
X
X for (i = 0; i < cmaplen; i++) {
X cmap[CM_RED][i] = (JSAMPLE) ReadByte(cinfo);
X cmap[CM_GREEN][i] = (JSAMPLE) ReadByte(cinfo);
X cmap[CM_BLUE][i] = (JSAMPLE) ReadByte(cinfo);
X }
X}
X
X
XLOCAL void
XDoExtension (compress_info_ptr cinfo)
X/* Process an extension block */
X/* Currently we ignore 'em all */
X{
X int extlabel;
X
X /* Read extension label byte */
X extlabel = ReadByte(cinfo);
X TRACEMS1(cinfo->emethods, 1, "Ignoring GIF extension block of type 0x%02x",
X extlabel);
X /* Skip the data block(s) associated with the extension */
X SkipDataBlocks(cinfo);
X}
X
X
X/*
X * Read the file header; return image size and component count.
X */
X
XMETHODDEF void
Xinput_init (compress_info_ptr cinfo)
X{
X char hdrbuf[10]; /* workspace for reading control blocks */
X UINT16 width, height; /* image dimensions */
X int colormaplen, aspectRatio;
X int c;
X
X /* Allocate space to store the colormap */
X colormap = (*cinfo->emethods->alloc_small_sarray)
X ((long) MAXCOLORMAPSIZE, (long) NUMCOLORS);
X
X /* Read and verify GIF Header */
X if (! ReadOK(cinfo->input_file, hdrbuf, 6))
X ERREXIT(cinfo->emethods, "Not a GIF file");
X if (strncmp(hdrbuf, "GIF", 3) != 0)
X ERREXIT(cinfo->emethods, "Not a GIF file");
X /* Check for expected version numbers.
X * If unknown version, give warning and try to process anyway;
X * this is per recommendation in GIF89a standard.
X */
X if ((strncmp(hdrbuf+3, "87a", 3) != 0) &&
X (strncmp(hdrbuf+3, "89a", 3) != 0))
X TRACEMS3(cinfo->emethods, 1,
X "Warning: unexpected GIF version number '%c%c%c'",
X hdrbuf[3], hdrbuf[4], hdrbuf[5]);
X
X /* Read and decipher Logical Screen Descriptor */
X if (! ReadOK(cinfo->input_file, hdrbuf, 7))
X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
X width = LM_to_uint(hdrbuf[0],hdrbuf[1]);
X height = LM_to_uint(hdrbuf[2],hdrbuf[3]);
X colormaplen = 2 << (hdrbuf[4] & 0x07);
X /* we ignore the color resolution, sort flag, and background color index */
X aspectRatio = hdrbuf[6] & 0xFF;
X if (aspectRatio != 0 && aspectRatio != 49)
X TRACEMS(cinfo->emethods, 1, "Warning: nonsquare pixels in input");
X
X /* Read global colormap if header indicates it is present */
X if (BitSet(hdrbuf[4], COLORMAPFLAG))
X ReadColorMap(cinfo, colormaplen, colormap);
X
X /* Scan until we reach start of desired image.
X * We don't currently support skipping images, but could add it easily.
X */
X for (;;) {
X c = ReadByte(cinfo);
X
X if (c == ';') /* GIF terminator?? */
X ERREXIT(cinfo->emethods, "Too few images in GIF file");
X
X if (c == '!') { /* Extension */
X DoExtension(cinfo);
X continue;
X }
X
X if (c != ',') { /* Not an image separator? */
X TRACEMS1(cinfo->emethods, 1, "Bogus input char 0x%02x, ignoring", c);
X continue;
X }
X
X /* Read and decipher Local Image Descriptor */
X if (! ReadOK(cinfo->input_file, hdrbuf, 9))
X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
X /* we ignore top/left position info, also sort flag */
X width = LM_to_uint(hdrbuf[4],hdrbuf[5]);
X height = LM_to_uint(hdrbuf[6],hdrbuf[7]);
X is_interlaced = BitSet(hdrbuf[8], INTERLACE);
X colormaplen = 2 << (hdrbuf[8] & 0x07);
X
X /* Read local colormap if header indicates it is present */
X /* Note: if we wanted to support skipping images, */
X /* we'd need to skip rather than read colormap for ignored images */
X if (BitSet(hdrbuf[8], COLORMAPFLAG))
X ReadColorMap(cinfo, colormaplen, colormap);
X
X input_code_size = ReadByte(cinfo); /* get minimum-code-size byte */
X if (input_code_size < 2 || input_code_size >= MAX_LZW_BITS)
X ERREXIT1(cinfo->emethods, "Bogus codesize %d", input_code_size);
X
X /* Reached desired image, so break out of loop */
X /* If we wanted to skip this image, */
X /* we'd call SkipDataBlocks and then continue the loop */
X break;
X }
X
X /* Prepare to read selected image: first initialize LZW decompressor */
X symbol_head = (UINT16 FAR *) (*cinfo->emethods->alloc_medium)
X (LZW_TABLE_SIZE * SIZEOF(UINT16));
X symbol_tail = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
X (LZW_TABLE_SIZE * SIZEOF(UINT8));
X symbol_stack = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
X (LZW_TABLE_SIZE * SIZEOF(UINT8));
X InitLZWCode();
X
X /*
X * If image is interlaced, we read it into a full-size sample array,
X * decompressing as we go; then get_input_row selects rows from the
X * sample array in the proper order.
X */
X if (is_interlaced) {
X /* We request the big array now, but can't access it until the pipeline
X * controller causes all the big arrays to be allocated. Hence, the
X * actual work of reading the image is postponed until the first call
X * of get_input_row.
X */
X interlaced_image = (*cinfo->emethods->request_big_sarray)
X ((long) width, (long) height, 1L);
X cinfo->methods->get_input_row = load_interlaced_image;
X cinfo->total_passes++; /* count file reading as separate pass */
X }
X
X /* Return info about the image. */
X cinfo->input_components = NUMCOLORS;
X cinfo->in_color_space = CS_RGB;
X cinfo->image_width = width;
X cinfo->image_height = height;
X cinfo->data_precision = 8; /* always, even if 12-bit JSAMPLEs */
X}
X
X
X/*
X * Read one row of pixels.
X * This version is used for noninterlaced GIF images:
X * we read directly from the GIF file.
X */
X
XMETHODDEF void
Xget_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X register int c;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X if ((c = LZWReadByte(cinfo)) < 0)
X ERREXIT(cinfo->emethods, "Premature end of GIF image");
X *ptr0++ = colormap[CM_RED][c];
X *ptr1++ = colormap[CM_GREEN][c];
X *ptr2++ = colormap[CM_BLUE][c];
X }
X}
X
X
X/*
X * Read one row of pixels.
X * This version is used for the first call on get_input_row when
X * reading an interlaced GIF file: we read the whole image into memory.
X */
X
XMETHODDEF void
Xload_interlaced_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X JSAMPARRAY image_ptr;
X register JSAMPROW sptr;
X register long col;
X register int c;
X long row;
X
X /* Read the interlaced image into the big array we've created. */
X for (row = 0; row < cinfo->image_height; row++) {
X (*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
X image_ptr = (*cinfo->emethods->access_big_sarray)
X (interlaced_image, row, TRUE);
X sptr = image_ptr[0];
X for (col = cinfo->image_width; col > 0; col--) {
X if ((c = LZWReadByte(cinfo)) < 0)
X ERREXIT(cinfo->emethods, "Premature end of GIF image");
X *sptr++ = (JSAMPLE) c;
X }
X }
X cinfo->completed_passes++;
X
X /* Replace method pointer so subsequent calls don't come here. */
X cinfo->methods->get_input_row = get_interlaced_row;
X /* Initialize for get_interlaced_row, and perform first call on it. */
X cur_row_number = 0;
X pass2_offset = (cinfo->image_height + 7L) / 8L;
X pass3_offset = pass2_offset + (cinfo->image_height + 3L) / 8L;
X pass4_offset = pass3_offset + (cinfo->image_height + 1L) / 4L;
X
X get_interlaced_row(cinfo, pixel_row);
X}
X
X
X/*
X * Read one row of pixels.
X * This version is used for interlaced GIF images:
X * we read from the big in-memory image.
X */
X
XMETHODDEF void
Xget_interlaced_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X JSAMPARRAY image_ptr;
X register JSAMPROW sptr, ptr0, ptr1, ptr2;
X register long col;
X register int c;
X long irow;
X
X /* Figure out which row of interlaced image is needed, and access it. */
X switch ((int) (cur_row_number & 7L)) {
X case 0: /* first-pass row */
X irow = cur_row_number >> 3;
X break;
X case 4: /* second-pass row */
X irow = (cur_row_number >> 3) + pass2_offset;
X break;
X case 2: /* third-pass row */
X case 6:
X irow = (cur_row_number >> 2) + pass3_offset;
X break;
X default: /* fourth-pass row */
X irow = (cur_row_number >> 1) + pass4_offset;
X break;
X }
X image_ptr = (*cinfo->emethods->access_big_sarray)
X (interlaced_image, irow, FALSE);
X /* Scan the row, expand colormap, and output */
X sptr = image_ptr[0];
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X c = GETJSAMPLE(*sptr++);
X *ptr0++ = colormap[CM_RED][c];
X *ptr1++ = colormap[CM_GREEN][c];
X *ptr2++ = colormap[CM_BLUE][c];
X }
X cur_row_number++; /* for next time */
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xinput_term (compress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for GIF format input.
X * Note that this must be called by the user interface before calling
X * jpeg_compress. If multiple input formats are supported, the
X * user interface is responsible for discovering the file format and
X * calling the appropriate method selection routine.
X */
X
XGLOBAL void
Xjselrgif (compress_info_ptr cinfo)
X{
X cinfo->methods->input_init = input_init;
X cinfo->methods->get_input_row = get_input_row; /* assume uninterlaced */
X cinfo->methods->input_term = input_term;
X}
X
X#endif /* GIF_SUPPORTED */
END_OF_FILE
if test 19830 -ne `wc -c <'jrdgif.c'`; then
echo shar: \"'jrdgif.c'\" unpacked with wrong size!
fi
# end of 'jrdgif.c'
fi
if test -f 'makljpeg.cf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makljpeg.cf'\"
else
echo shar: Extracting \"'makljpeg.cf'\" \(439 characters\)
sed "s/^X//" >'makljpeg.cf' <<'END_OF_FILE'
Xjcmaster.mix,jcdeflts.mix,jcarith.mix,jccolor.mix,jcexpand.mix,jchuff.mix
Xjcmcu.mix,jcpipe.mix,jcsample.mix,jfwddct.mix,jwrjfif.mix,jrdgif.mix
Xjrdppm.mix,jrdrle.mix,jrdtarga.mix,jdmaster.mix,jddeflts.mix,jbsmooth.mix
Xjdarith.mix,jdcolor.mix,jdhuff.mix,jdmcu.mix,jdpipe.mix,jdsample.mix
Xjquant1.mix,jquant2.mix,jrevdct.mix,jrdjfif.mix,jwrgif.mix,jwrppm.mix
Xjwrrle.mix,jwrtarga.mix,jutils.mix,jerror.mix,jmemmgr.mix,jmemsys.mix
Xjmemdosa.mix
END_OF_FILE
if test 439 -ne `wc -c <'makljpeg.cf'`; then
echo shar: \"'makljpeg.cf'\" unpacked with wrong size!
fi
# end of 'makljpeg.cf'
fi
echo shar: End of archive 11 \(of 18\).
cp /dev/null ark11isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: ansi2knr.c jmemansi.c jmemdos.c jversion.h jwrjfif.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:50 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 12 (of 18)."'
if test -f 'ansi2knr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ansi2knr.c'\"
else
echo shar: Extracting \"'ansi2knr.c'\" \(16258 characters\)
sed "s/^X//" >'ansi2knr.c' <<'END_OF_FILE'
X/*
X * Received from Peter Deutsch (gh...@aladdin.com)
X * Fri, 26 Apr 91 10:10:10 PDT
X * Small portability improvements by Tom Lane
X */
X
X/* Copyright (C) 1989, 1991 Aladdin Enterprises. All rights reserved.
X Distributed by Free Software Foundation, Inc.
X
XThis file is part of Ghostscript.
X
XGhostscript is distributed in the hope that it will be useful, but
XWITHOUT ANY WARRANTY. No author or distributor accepts responsibility
Xto anyone for the consequences of using it or for whether it serves any
Xparticular purpose or works at all, unless he says so in writing. Refer
Xto the Ghostscript General Public License for full details.
X
XEveryone is granted permission to copy, modify and redistribute
XGhostscript, but only under the conditions described in the Ghostscript
XGeneral Public License. A copy of this license is supposed to have been
Xgiven to you along with Ghostscript so you can know your rights and
Xresponsibilities. It should be in a file named COPYING. Among other
Xthings, the copyright notice and this notice must be preserved on all
Xcopies. */
X
X/*
X---------- Here is the GhostScript file COPYING, referred to above ----------
X----- These terms do NOT apply to the JPEG software itself; see README ------
X
X GHOSTSCRIPT GENERAL PUBLIC LICENSE
X (Clarified 11 Feb 1988)
X
X Copyright (C) 1988 Richard M. Stallman
X Everyone is permitted to copy and distribute verbatim copies of this
X license, but changing it is not allowed. You can also use this wording
X to make the terms for other programs.
X
X The license agreements of most software companies keep you at the
Xmercy of those companies. By contrast, our general public license is
Xintended to give everyone the right to share Ghostscript. To make sure
Xthat you get the rights we want you to have, we need to make
Xrestrictions that forbid anyone to deny you these rights or to ask you
Xto surrender the rights. Hence this license agreement.
X
X Specifically, we want to make sure that you have the right to give
Xaway copies of Ghostscript, that you receive source code or else can get
Xit if you want it, that you can change Ghostscript or use pieces of it
Xin new free programs, and that you know you can do these things.
X
X To make sure that everyone has such rights, we have to forbid you to
Xdeprive anyone else of these rights. For example, if you distribute
Xcopies of Ghostscript, you must give the recipients all the rights that
Xyou have. You must make sure that they, too, receive or can get the
Xsource code. And you must tell them their rights.
X
X Also, for our own protection, we must make certain that everyone finds
Xout that there is no warranty for Ghostscript. If Ghostscript is
Xmodified by someone else and passed on, we want its recipients to know
Xthat what they have is not what we distributed, so that any problems
Xintroduced by others will not reflect on our reputation.
X
X Therefore we (Richard M. Stallman and the Free Software Foundation,
XInc.) make the following terms which say what you must do to be allowed
Xto distribute or change Ghostscript.
X
X
X COPYING POLICIES
X
X 1. You may copy and distribute verbatim copies of Ghostscript source
Xcode as you receive it, in any medium, provided that you conspicuously
Xand appropriately publish on each copy a valid copyright and license
Xnotice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved.
XDistributed by Free Software Foundation, Inc." (or with whatever year is
Xappropriate); keep intact the notices on all files that refer to this
XLicense Agreement and to the absence of any warranty; and give any other
Xrecipients of the Ghostscript program a copy of this License Agreement
Xalong with the program. You may charge a distribution fee for the
Xphysical act of transferring a copy.
X
X 2. You may modify your copy or copies of Ghostscript or any portion of
Xit, and copy and distribute such modifications under the terms of
XParagraph 1 above, provided that you also do the following:
X
X a) cause the modified files to carry prominent notices stating
X that you changed the files and the date of any change; and
X
X b) cause the whole of any work that you distribute or publish,
X that in whole or in part contains or is a derivative of Ghostscript
X or any part thereof, to be licensed at no charge to all third
X parties on terms identical to those contained in this License
X Agreement (except that you may choose to grant more extensive
X warranty protection to some or all third parties, at your option).
X
X c) You may charge a distribution fee for the physical act of
X transferring a copy, and you may at your option offer warranty
X protection in exchange for a fee.
X
XMere aggregation of another unrelated program with this program (or its
Xderivative) on a volume of a storage or distribution medium does not bring
Xthe other program under the scope of these terms.
X
X 3. You may copy and distribute Ghostscript (or a portion or derivative
Xof it, under Paragraph 2) in object code or executable form under the
Xterms of Paragraphs 1 and 2 above provided that you also do one of the
Xfollowing:
X
X a) accompany it with the complete corresponding machine-readable
X source code, which must be distributed under the terms of
X Paragraphs 1 and 2 above; or,
X
X b) accompany it with a written offer, valid for at least three
X years, to give any third party free (except for a nominal
X shipping charge) a complete machine-readable copy of the
X corresponding source code, to be distributed under the terms of
X Paragraphs 1 and 2 above; or,
X
X c) accompany it with the information you received as to where the
X corresponding source code may be obtained. (This alternative is
X allowed only for noncommercial distribution and only if you
X received the program in object code or executable form alone.)
X
XFor an executable file, complete source code means all the source code for
Xall modules it contains; but, as a special exception, it need not include
Xsource code for modules which are standard libraries that accompany the
Xoperating system on which the executable file runs.
X
X 4. You may not copy, sublicense, distribute or transfer Ghostscript
Xexcept as expressly provided under this License Agreement. Any attempt
Xotherwise to copy, sublicense, distribute or transfer Ghostscript is
Xvoid and your rights to use the program under this License agreement
Xshall be automatically terminated. However, parties who have received
Xcomputer software programs from you with this License Agreement will not
Xhave their licenses terminated so long as such parties remain in full
Xcompliance.
X
X 5. If you wish to incorporate parts of Ghostscript into other free
Xprograms whose distribution conditions are different, write to the Free
XSoftware Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not
Xyet worked out a simple rule that can be stated here, but we will often
Xpermit this. We will be guided by the two goals of preserving the free
Xstatus of all derivatives of our free software and of promoting the
Xsharing and reuse of software.
X
XYour comments and suggestions about our licensing policies and our
Xsoftware are welcome! Please contact the Free Software Foundation,
XInc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
X
X NO WARRANTY
X
X BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
XNO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
XM. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
XPROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
XEXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
XWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
XENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
XYOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
XNECESSARY SERVICING, REPAIR OR CORRECTION.
X
X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
XENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
XGHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
XANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
XCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
X(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
XINACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
XPROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
XHAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
XBY ANY OTHER PARTY.
X-------------------- End of file COPYING ------------------------------
X*/
X
X
X/* ansi2knr.c */
X/* Convert ANSI function declarations to K&R syntax */
X
X#include <stdio.h>
X#include <ctype.h>
X
X#ifdef BSD
X#include <strings.h>
X#define strchr index
X#else
X#ifdef VMS
X extern char *strcat(), *strchr(), *strcpy(), *strupr();
X extern int strcmp(), strlen(), strncmp();
X#else
X#include <string.h>
X#endif
X#endif
X
X#ifdef MSDOS
X#include <malloc.h>
X#else
X#ifdef VMS
X extern char *malloc();
X extern void free();
X#else
X extern char *malloc();
X extern int free();
X#endif
X#endif
X
X/* Usage:
X ansi2knr input_file output_file
X * If no output_file is supplied, output goes to stdout.
X * There are no error messages.
X *
X * ansi2knr recognizes functions by seeing a non-keyword identifier
X * at the left margin, followed by a left parenthesis,
X * with a right parenthesis as the last character on the line.
X * It will recognize a multi-line header if the last character
X * on each line but the last is a left parenthesis or comma.
X * These algorithms ignore whitespace and comments, except that
X * the function name must be the first thing on the line.
X * The following constructs will confuse it:
X - Any other construct that starts at the left margin and
X follows the above syntax (such as a macro or function call).
X - Macros that tinker with the syntax of the function header.
X */
X
X/* Scanning macros */
X#define isidchar(ch) (isalnum(ch) || (ch) == '_')
X#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
X
Xint
Xmain(argc, argv)
X int argc;
X char *argv[];
X{ FILE *in, *out;
X#define bufsize 500 /* arbitrary size */
X char buf[bufsize+1];
X char *line;
X switch ( argc )
X {
X default:
X printf("Usage: ansi2knr input_file [output_file]\n");
X exit(0);
X case 2:
X out = stdout; break;
X case 3:
X out = fopen(argv[2], "w");
X if ( out == NULL )
X { fprintf(stderr, "Cannot open %s\n", argv[2]);
X exit(1);
X }
X }
X in = fopen(argv[1], "r");
X if ( in == NULL )
X { fprintf(stderr, "Cannot open %s\n", argv[1]);
X exit(1);
X }
X fprintf(out, "#line 1 \"%s\"\n", argv[1]);
X line = buf;
X while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
X { switch ( test1(buf) )
X {
X case 1: /* a function */
X convert1(buf, out);
X break;
X case -1: /* maybe the start of a function */
X line = buf + strlen(buf);
X continue;
X default: /* not a function */
X fputs(buf, out);
X break;
X }
X line = buf;
X }
X if ( line != buf ) fputs(buf, out);
X fclose(out);
X fclose(in);
X return 0;
X}
X
X/* Skip over space and comments, in either direction. */
Xchar *
Xskipspace(p, dir)
X register char *p;
X register int dir; /* 1 for forward, -1 for backward */
X{ for ( ; ; )
X { while ( isspace(*p) ) p += dir;
X if ( !(*p == '/' && p[dir] == '*') ) break;
X p += dir; p += dir;
X while ( !(*p == '*' && p[dir] == '/') )
X { if ( *p == 0 ) return p; /* multi-line comment?? */
X p += dir;
X }
X p += dir; p += dir;
X }
X return p;
X}
X
X/*
X * Write blanks over part of a string.
X */
Xint
Xwriteblanks(start, end)
X char *start;
X char *end;
X{ char *p;
X for ( p = start; p < end; p++ ) *p = ' ';
X return 0;
X}
X
X/*
X * Test whether the string in buf is a function definition.
X * The string may contain and/or end with a newline.
X * Return as follows:
X * 0 - definitely not a function definition;
X * 1 - definitely a function definition;
X * -1 - may be the beginning of a function definition,
X * append another line and look again.
X */
Xint
Xtest1(buf)
X char *buf;
X{ register char *p = buf;
X char *bend;
X char *endfn;
X int contin;
X if ( !isidfirstchar(*p) )
X return 0; /* no name at left margin */
X bend = skipspace(buf + strlen(buf) - 1, -1);
X switch ( *bend )
X {
X case ')': contin = 1; break;
X case '(':
X case ',': contin = -1; break;
X default: return 0; /* not a function */
X }
X while ( isidchar(*p) ) p++;
X endfn = p;
X p = skipspace(p, 1);
X if ( *p++ != '(' )
X return 0; /* not a function */
X p = skipspace(p, 1);
X if ( *p == ')' )
X return 0; /* no parameters */
X /* Check that the apparent function name isn't a keyword. */
X /* We only need to check for keywords that could be followed */
X /* by a left parenthesis (which, unfortunately, is most of them). */
X { static char *words[] =
X { "asm", "auto", "case", "char", "const", "double",
X "extern", "float", "for", "if", "int", "long",
X "register", "return", "short", "signed", "sizeof",
X "static", "switch", "typedef", "unsigned",
X "void", "volatile", "while", 0
X };
X char **key = words;
X char *kp;
X int len = endfn - buf;
X while ( (kp = *key) != 0 )
X { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
X return 0; /* name is a keyword */
X key++;
X }
X }
X return contin;
X}
X
Xint
Xconvert1(buf, out)
X char *buf;
X FILE *out;
X{ char *endfn = strchr(buf, '(') + 1;
X register char *p;
X char **breaks;
X unsigned num_breaks = 2; /* for testing */
X char **btop;
X char **bp;
X char **ap;
Xtop: p = endfn;
X breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
X if ( breaks == 0 )
X { /* Couldn't allocate break table, give up */
X fprintf(stderr, "Unable to allocate break table!\n");
X fputs(buf, out);
X return -1;
X }
X btop = breaks + num_breaks * 2 - 2;
X bp = breaks;
X /* Parse the argument list */
X do
X { int level = 0;
X char *end = NULL;
X if ( bp >= btop )
X { /* Filled up break table. */
X /* Allocate a bigger one and start over. */
X free((char *)breaks);
X num_breaks <<= 1;
X goto top;
X }
X *bp++ = p;
X /* Find the end of the argument */
X for ( ; end == NULL; p++ )
X { switch(*p)
X {
X case ',': if ( !level ) end = p; break;
X case '(': level++; break;
X case ')': if ( --level < 0 ) end = p; break;
X case '/': p = skipspace(p, 1) - 1; break;
X default: ;
X }
X }
X p--; /* back up over terminator */
X /* Find the name being declared. */
X /* This is complicated because of procedure and */
X /* array modifiers. */
X for ( ; ; )
X { p = skipspace(p - 1, -1);
X switch ( *p )
X {
X case ']': /* skip array dimension(s) */
X case ')': /* skip procedure args OR name */
X { int level = 1;
X while ( level )
X switch ( *--p )
X {
X case ']': case ')': level++; break;
X case '[': case '(': level--; break;
X case '/': p = skipspace(p, -1) + 1; break;
X default: ;
X }
X }
X if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
X { /* We found the name being declared */
X while ( !isidfirstchar(*p) )
X p = skipspace(p, 1) + 1;
X goto found;
X }
X break;
X default: goto found;
X }
X }
Xfound: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
X { p++;
X if ( bp == breaks + 1 ) /* sole argument */
X writeblanks(breaks[0], p);
X else
X writeblanks(bp[-1] - 1, p);
X bp--;
X }
X else
X { while ( isidchar(*p) ) p--;
X *bp++ = p+1;
X }
X p = end;
X }
X while ( *p++ == ',' );
X *bp = p;
X /* Make a special check for 'void' arglist */
X if ( bp == breaks+2 )
X { p = skipspace(breaks[0], 1);
X if ( !strncmp(p, "void", 4) )
X { p = skipspace(p+4, 1);
X if ( p == breaks[2] - 1 )
X { bp = breaks; /* yup, pretend arglist is empty */
X writeblanks(breaks[0], p + 1);
X }
X }
X }
X /* Put out the function name */
X p = buf;
X while ( p != endfn ) putc(*p, out), p++;
X /* Put out the declaration */
X for ( ap = breaks+1; ap < bp; ap += 2 )
X { p = *ap;
X while ( isidchar(*p) ) putc(*p, out), p++;
X if ( ap < bp - 1 ) fputs(", ", out);
X }
X fputs(") ", out);
X /* Put out the argument declarations */
X for ( ap = breaks+2; ap <= bp; ap += 2 ) (*ap)[-1] = ';';
X fputs(breaks[0], out);
X free((char *)breaks);
X return 0;
X}
END_OF_FILE
if test 16258 -ne `wc -c <'ansi2knr.c'`; then
echo shar: \"'ansi2knr.c'\" unpacked with wrong size!
fi
# end of 'ansi2knr.c'
fi
if test -f 'jmemansi.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemansi.c'\"
else
echo shar: Extracting \"'jmemansi.c'\" \(4303 characters\)
sed "s/^X//" >'jmemansi.c' <<'END_OF_FILE'
X/*
X * jmemansi.c (jmemsys.c)
X *
X * Copyright (C) 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file provides a simple generic implementation of the system-
X * dependent portion of the JPEG memory manager. This implementation
X * assumes that you have the ANSI-standard library routine tmpfile().
X * Also, the problem of determining the amount of memory available
X * is shoved onto the user.
X */
X
X#include "jinclude.h"
X#include "jmemsys.h"
X
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare malloc(), free() */
X#else
Xextern void * malloc PP((size_t size));
Xextern void free PP((void *ptr));
X#endif
X
X#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
X#define SEEK_SET 0 /* if not, assume 0 is correct */
X#endif
X
X
Xstatic external_methods_ptr methods; /* saved for access to error_exit */
X
Xstatic long total_used; /* total memory requested so far */
X
X
X/*
X * Memory allocation and freeing are controlled by the regular library
X * routines malloc() and free().
X */
X
XGLOBAL void *
Xjget_small (size_t sizeofobject)
X{
X total_used += sizeofobject;
X return (void *) malloc(sizeofobject);
X}
X
XGLOBAL void
Xjfree_small (void * object)
X{
X free(object);
X}
X
X/*
X * We assume NEED_FAR_POINTERS is not defined and so the separate entry points
X * jget_large, jfree_large are not needed.
X */
X
X
X/*
X * This routine computes the total memory space available for allocation.
X * It's impossible to do this in a portable way; our current solution is
X * to make the user tell us (with a default value set at compile time).
X * If you can actually get the available space, it's a good idea to subtract
X * a slop factor of 5% or so.
X */
X
X#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
X#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
X#endif
X
XGLOBAL long
Xjmem_available (long min_bytes_needed, long max_bytes_needed)
X{
X return methods->max_memory_to_use - total_used;
X}
X
X
X/*
X * Backing store (temporary file) management.
X * Backing store objects are only used when the value returned by
X * jmem_available is less than the total space needed. You can dispense
X * with these routines if you have plenty of virtual memory; see jmemnobs.c.
X */
X
X
XMETHODDEF void
Xread_backing_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X if (fseek(info->temp_file, file_offset, SEEK_SET))
X ERREXIT(methods, "fseek failed on temporary file");
X if (JFREAD(info->temp_file, buffer_address, byte_count)
X != (size_t) byte_count)
X ERREXIT(methods, "fread failed on temporary file");
X}
X
X
XMETHODDEF void
Xwrite_backing_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X if (fseek(info->temp_file, file_offset, SEEK_SET))
X ERREXIT(methods, "fseek failed on temporary file");
X if (JFWRITE(info->temp_file, buffer_address, byte_count)
X != (size_t) byte_count)
X ERREXIT(methods, "fwrite failed on temporary file --- out of disk space?");
X}
X
X
XMETHODDEF void
Xclose_backing_store (backing_store_ptr info)
X{
X fclose(info->temp_file);
X /* Since this implementation uses tmpfile() to create the file,
X * no explicit file deletion is needed.
X */
X}
X
X
X/*
X * Initial opening of a backing-store object.
X *
X * This version uses tmpfile(), which constructs a suitable file name
X * behind the scenes. We don't have to use temp_name[] at all;
X * indeed, we can't even find out the actual name of the temp file.
X */
X
XGLOBAL void
Xjopen_backing_store (backing_store_ptr info, long total_bytes_needed)
X{
X if ((info->temp_file = tmpfile()) == NULL)
X ERREXIT(methods, "Failed to create temporary file");
X info->read_backing_store = read_backing_store;
X info->write_backing_store = write_backing_store;
X info->close_backing_store = close_backing_store;
X}
X
X
X/*
X * These routines take care of any system-dependent initialization and
X * cleanup required. Keep in mind that jmem_term may be called more than
X * once.
X */
X
XGLOBAL void
Xjmem_init (external_methods_ptr emethods)
X{
X methods = emethods; /* save struct addr for error exit access */
X emethods->max_memory_to_use = DEFAULT_MAX_MEM;
X total_used = 0;
X}
X
XGLOBAL void
Xjmem_term (void)
X{
X /* no work */
X}
END_OF_FILE
if test 4303 -ne `wc -c <'jmemansi.c'`; then
echo shar: \"'jmemansi.c'\" unpacked with wrong size!
fi
# end of 'jmemansi.c'
fi
if test -f 'jmemdos.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemdos.c'\"
else
echo shar: Extracting \"'jmemdos.c'\" \(17266 characters\)
sed "s/^X//" >'jmemdos.c' <<'END_OF_FILE'
X/*
X * jmemdos.c (jmemsys.c)
X *
X * Copyright (C) 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file provides an MS-DOS-compatible implementation of the system-
X * dependent portion of the JPEG memory manager. Temporary data can be
X * stored in extended or expanded memory as well as in regular DOS files.
X *
X * If you use this file, you must be sure that NEED_FAR_POINTERS is defined
X * if you compile in a small-data memory model; it should NOT be defined if
X * you use a large-data memory model. This file is not recommended if you
X * are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
X *
X * Based on code contributed by Ge' Weijers.
X */
X
X/*
X * If you have both extended and expanded memory, you may want to change the
X * order in which they are tried in jopen_backing_store. On a 286 machine
X * expanded memory is usually faster, since extended memory access involves
X * an expensive protected-mode-and-back switch. On 386 and better, extended
X * memory is usually faster. As distributed, the code tries extended memory
X * first (what? not everyone has a 386? :-).
X *
X * You can disable use of extended/expanded memory entirely by altering these
X * definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
X */
X
X#ifndef XMS_SUPPORTED
X#define XMS_SUPPORTED 1
X#endif
X#ifndef EMS_SUPPORTED
X#define EMS_SUPPORTED 1
X#endif
X
X
X#include "jinclude.h"
X#include "jmemsys.h"
X
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare malloc(), free() */
X#else
Xextern void * malloc PP((size_t size));
Xextern void free PP((void *ptr));
X#endif
X
X#ifdef NEED_FAR_POINTERS
X
X#ifdef __TURBOC__
X/* These definitions work for Borland C (Turbo C) */
X#include <alloc.h> /* need farmalloc(), farfree() */
X#define far_malloc(x) farmalloc(x)
X#define far_free(x) farfree(x)
X#else
X/* These definitions work for Microsoft C and compatible compilers */
X#include <malloc.h> /* need _fmalloc(), _ffree() */
X#define far_malloc(x) _fmalloc(x)
X#define far_free(x) _ffree(x)
X#endif
X
X#endif
X
X#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
X#define READ_BINARY "r"
X#else
X#define READ_BINARY "rb"
X#endif
X
X
X/*
X * Declarations for assembly-language support routines (see jmemdosa.asm).
X *
X * The functions are declared "far" as are all pointer arguments;
X * this ensures the assembly source code will work regardless of the
X * compiler memory model. We assume "short" is 16 bits, "long" is 32.
X */
X
Xtypedef void far * XMSDRIVER; /* actually a pointer to code */
Xtypedef struct { /* registers for calling XMS driver */
X unsigned short ax, dx, bx;
X void far * ds_si;
X } XMScontext;
Xtypedef struct { /* registers for calling EMS driver */
X unsigned short ax, dx, bx;
X void far * ds_si;
X } EMScontext;
X
XEXTERN short far jdos_open PP((short far * handle, char far * filename));
XEXTERN short far jdos_close PP((short handle));
XEXTERN short far jdos_seek PP((short handle, long offset));
XEXTERN short far jdos_read PP((short handle, void far * buffer,
X unsigned short count));
XEXTERN short far jdos_write PP((short handle, void far * buffer,
X unsigned short count));
XEXTERN void far jxms_getdriver PP((XMSDRIVER far *));
XEXTERN void far jxms_calldriver PP((XMSDRIVER, XMScontext far *));
XEXTERN short far jems_available PP((void));
XEXTERN void far jems_calldriver PP((EMScontext far *));
X
X
Xstatic external_methods_ptr methods; /* saved for access to error_exit */
X
Xstatic long total_used; /* total FAR memory requested so far */
X
X
X/*
X * Selection of a file name for a temporary file.
X * This is highly system-dependent, and you may want to customize it.
X */
X
Xstatic int next_file_num; /* to distinguish among several temp files */
X
XLOCAL void
Xselect_file_name (char * fname)
X{
X const char * env;
X char * ptr;
X FILE * tfile;
X
X /* Keep generating file names till we find one that's not in use */
X for (;;) {
X /* Get temp directory name from environment TMP or TEMP variable;
X * if none, use "."
X */
X if ((env = (const char *) getenv("TMP")) == NULL)
X if ((env = (const char *) getenv("TEMP")) == NULL)
X env = ".";
X if (*env == '\0') /* null string means "." */
X env = ".";
X ptr = fname; /* copy name to fname */
X while (*env != '\0')
X *ptr++ = *env++;
X if (ptr[-1] != '\\' && ptr[-1] != '/')
X *ptr++ = '\\'; /* append backslash if not in env variable */
X /* Append a suitable file name */
X next_file_num++; /* advance counter */
X sprintf(ptr, "JPG%03d.TMP", next_file_num);
X /* Probe to see if file name is already in use */
X if ((tfile = fopen(fname, READ_BINARY)) == NULL)
X break;
X fclose(tfile); /* oops, it's there; close tfile & try again */
X }
X}
X
X
X/*
X * Near-memory allocation and freeing are controlled by the regular library
X * routines malloc() and free().
X */
X
XGLOBAL void *
Xjget_small (size_t sizeofobject)
X{
X /* near data space is NOT counted in total_used */
X#ifndef NEED_FAR_POINTERS
X total_used += sizeofobject;
X#endif
X return (void *) malloc(sizeofobject);
X}
X
XGLOBAL void
Xjfree_small (void * object)
X{
X free(object);
X}
X
X
X/*
X * Far-memory allocation and freeing
X */
X
X#ifdef NEED_FAR_POINTERS
X
XGLOBAL void FAR *
Xjget_large (size_t sizeofobject)
X{
X total_used += sizeofobject;
X return (void FAR *) far_malloc(sizeofobject);
X}
X
XGLOBAL void
Xjfree_large (void FAR * object)
X{
X far_free(object);
X}
X
X#endif
X
X
X/*
X * This routine computes the total memory space available for allocation.
X * It's impossible to do this in a portable way; our current solution is
X * to make the user tell us (with a default value set at compile time).
X * If you can actually get the available space, it's a good idea to subtract
X * a slop factor of 5% or so.
X */
X
X#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
X#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */
X#endif
X
XGLOBAL long
Xjmem_available (long min_bytes_needed, long max_bytes_needed)
X{
X return methods->max_memory_to_use - total_used;
X}
X
X
X/*
X * Backing store (temporary file) management.
X * Backing store objects are only used when the value returned by
X * jmem_available is less than the total space needed. You can dispense
X * with these routines if you have plenty of virtual memory; see jmemnobs.c.
X */
X
X/*
X * For MS-DOS we support three types of backing storage:
X * 1. Conventional DOS files. We access these by direct DOS calls rather
X * than via the stdio package. This provides a bit better performance,
X * but the real reason is that the buffers to be read or written are FAR.
X * The stdio library for small-data memory models can't cope with that.
X * 2. Extended memory, accessed per the XMS V2.0 specification.
X * 3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
X * You'll need copies of those specs to make sense of the related code.
X * The specs are available by Internet FTP from SIMTEL20 and its various
X * mirror sites; see microsoft/xms20.arc and info/limems41.zip.
X */
X
X
X/*
X * Access methods for a DOS file.
X */
X
X
XMETHODDEF void
Xread_file_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X if (jdos_seek(info->handle.file_handle, file_offset))
X ERREXIT(methods, "seek failed on temporary file");
X /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
X if (byte_count > 65535L) /* safety check */
X ERREXIT(methods, "MAX_ALLOC_CHUNK should be less than 64K");
X if (jdos_read(info->handle.file_handle, buffer_address,
X (unsigned short) byte_count))
X ERREXIT(methods, "read failed on temporary file");
X}
X
X
XMETHODDEF void
Xwrite_file_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X if (jdos_seek(info->handle.file_handle, file_offset))
X ERREXIT(methods, "seek failed on temporary file");
X /* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
X if (byte_count > 65535L) /* safety check */
X ERREXIT(methods, "MAX_ALLOC_CHUNK should be less than 64K");
X if (jdos_write(info->handle.file_handle, buffer_address,
X (unsigned short) byte_count))
X ERREXIT(methods, "write failed on temporary file --- out of disk space?");
X}
X
X
XMETHODDEF void
Xclose_file_store (backing_store_ptr info)
X{
X jdos_close(info->handle.file_handle); /* close the file */
X remove(info->temp_name); /* delete the file */
X/* If your system doesn't have remove(), try unlink() instead.
X * remove() is the ANSI-standard name for this function, but
X * unlink() was more common in pre-ANSI systems.
X */
X TRACEMS1(methods, 1, "Closed DOS file %d", info->handle.file_handle);
X}
X
X
XLOCAL boolean
Xopen_file_store (backing_store_ptr info, long total_bytes_needed)
X{
X short handle;
X char tracemsg[TEMP_NAME_LENGTH+40];
X
X select_file_name(info->temp_name);
X if (jdos_open((short far *) & handle, (char far *) info->temp_name))
X return FALSE;
X info->handle.file_handle = handle;
X info->read_backing_store = read_file_store;
X info->write_backing_store = write_file_store;
X info->close_backing_store = close_file_store;
X /* hack to get around TRACEMS' inability to handle string parameters */
X sprintf(tracemsg, "Opened DOS file %d %s", handle, info->temp_name);
X TRACEMS(methods, 1, tracemsg);
X return TRUE; /* succeeded */
X}
X
X
X/*
X * Access methods for extended memory.
X */
X
X#if XMS_SUPPORTED
X
Xstatic XMSDRIVER xms_driver; /* saved address of XMS driver */
X
Xtypedef union { /* either long offset or real-mode pointer */
X long offset;
X void far * ptr;
X } XMSPTR;
X
Xtypedef struct { /* XMS move specification structure */
X long length;
X XMSH src_handle;
X XMSPTR src;
X XMSH dst_handle;
X XMSPTR dst;
X } XMSspec;
X
X#define ODD(X) (((X) & 1L) != 0)
X
X
XMETHODDEF void
Xread_xms_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X XMScontext ctx;
X XMSspec spec;
X char endbuffer[2];
X
X /* The XMS driver can't cope with an odd length, so handle the last byte
X * specially if byte_count is odd. We don't expect this to be common.
X */
X
X spec.length = byte_count & (~ 1L);
X spec.src_handle = info->handle.xms_handle;
X spec.src.offset = file_offset;
X spec.dst_handle = 0;
X spec.dst.ptr = buffer_address;
X
X ctx.ds_si = (void far *) & spec;
X ctx.ax = 0x0b00; /* EMB move */
X jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
X if (ctx.ax != 1)
X ERREXIT(methods, "read from extended memory failed");
X
X if (ODD(byte_count)) {
X read_xms_store(info, (void FAR *) endbuffer,
X file_offset + byte_count - 1L, 2L);
X ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
X }
X}
X
X
XMETHODDEF void
Xwrite_xms_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X XMScontext ctx;
X XMSspec spec;
X char endbuffer[2];
X
X /* The XMS driver can't cope with an odd length, so handle the last byte
X * specially if byte_count is odd. We don't expect this to be common.
X */
X
X spec.length = byte_count & (~ 1L);
X spec.src_handle = 0;
X spec.src.ptr = buffer_address;
X spec.dst_handle = info->handle.xms_handle;
X spec.dst.offset = file_offset;
X
X ctx.ds_si = (void far *) & spec;
X ctx.ax = 0x0b00; /* EMB move */
X jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
X if (ctx.ax != 1)
X ERREXIT(methods, "write to extended memory failed");
X
X if (ODD(byte_count)) {
X read_xms_store(info, (void FAR *) endbuffer,
X file_offset + byte_count - 1L, 2L);
X endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
X write_xms_store(info, (void FAR *) endbuffer,
X file_offset + byte_count - 1L, 2L);
X }
X}
X
X
XMETHODDEF void
Xclose_xms_store (backing_store_ptr info)
X{
X XMScontext ctx;
X
X ctx.dx = info->handle.xms_handle;
X ctx.ax = 0x0a00;
X jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
X TRACEMS1(methods, 1, "Freed XMS handle %u", info->handle.xms_handle);
X /* we ignore any error return from the driver */
X}
X
X
XLOCAL boolean
Xopen_xms_store (backing_store_ptr info, long total_bytes_needed)
X{
X XMScontext ctx;
X
X /* Get address of XMS driver */
X jxms_getdriver((XMSDRIVER far *) & xms_driver);
X if (xms_driver == NULL)
X return FALSE; /* no driver to be had */
X
X /* Get version number, must be >= 2.00 */
X ctx.ax = 0x0000;
X jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
X if (ctx.ax < (unsigned short) 0x0200)
X return FALSE;
X
X /* Try to get space (expressed in kilobytes) */
X ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
X ctx.ax = 0x0900;
X jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
X if (ctx.ax != 1)
X return FALSE;
X
X /* Succeeded, save the handle and away we go */
X info->handle.xms_handle = ctx.dx;
X info->read_backing_store = read_xms_store;
X info->write_backing_store = write_xms_store;
X info->close_backing_store = close_xms_store;
X TRACEMS1(methods, 1, "Obtained XMS handle %u", ctx.dx);
X return TRUE; /* succeeded */
X}
X
X#endif /* XMS_SUPPORTED */
X
X
X/*
X * Access methods for expanded memory.
X */
X
X#if EMS_SUPPORTED
X
Xtypedef union { /* either offset/page or real-mode pointer */
X struct { unsigned short offset, page; } ems;
X void far * ptr;
X } EMSPTR;
X
Xtypedef struct { /* EMS move specification structure */
X long length;
X char src_type; /* 1 = EMS, 0 = conventional memory */
X EMSH src_handle; /* use 0 if conventional memory */
X EMSPTR src;
X char dst_type;
X EMSH dst_handle;
X EMSPTR dst;
X } EMSspec;
X
X#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */
X
X#define HIBYTE(W) (((W) >> 8) & 0xFF)
X#define LOBYTE(W) ((W) & 0xFF)
X
X
XMETHODDEF void
Xread_ems_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X EMScontext ctx;
X EMSspec spec;
X
X spec.length = byte_count;
X spec.src_type = 1;
X spec.src_handle = info->handle.ems_handle;
X spec.src.ems.page = (unsigned short) (file_offset / EMSPAGESIZE);
X spec.src.ems.offset = (unsigned short) (file_offset % EMSPAGESIZE);
X spec.dst_type = 0;
X spec.dst_handle = 0;
X spec.dst.ptr = buffer_address;
X
X ctx.ds_si = (void far *) & spec;
X ctx.ax = 0x5700; /* move memory region */
X jems_calldriver((EMScontext far *) & ctx);
X if (HIBYTE(ctx.ax) != 0)
X ERREXIT(methods, "read from expanded memory failed");
X}
X
X
XMETHODDEF void
Xwrite_ems_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X EMScontext ctx;
X EMSspec spec;
X
X spec.length = byte_count;
X spec.src_type = 0;
X spec.src_handle = 0;
X spec.src.ptr = buffer_address;
X spec.dst_type = 1;
X spec.dst_handle = info->handle.ems_handle;
X spec.dst.ems.page = (unsigned short) (file_offset / EMSPAGESIZE);
X spec.dst.ems.offset = (unsigned short) (file_offset % EMSPAGESIZE);
X
X ctx.ds_si = (void far *) & spec;
X ctx.ax = 0x5700; /* move memory region */
X jems_calldriver((EMScontext far *) & ctx);
X if (HIBYTE(ctx.ax) != 0)
X ERREXIT(methods, "write to expanded memory failed");
X}
X
X
XMETHODDEF void
Xclose_ems_store (backing_store_ptr info)
X{
X EMScontext ctx;
X
X ctx.ax = 0x4500;
X ctx.dx = info->handle.ems_handle;
X jems_calldriver((EMScontext far *) & ctx);
X TRACEMS1(methods, 1, "Freed EMS handle %u", info->handle.ems_handle);
X /* we ignore any error return from the driver */
X}
X
X
XLOCAL boolean
Xopen_ems_store (backing_store_ptr info, long total_bytes_needed)
X{
X EMScontext ctx;
X
X /* Is EMS driver there? */
X if (! jems_available())
X return FALSE;
X
X /* Get status, make sure EMS is OK */
X ctx.ax = 0x4000;
X jems_calldriver((EMScontext far *) & ctx);
X if (HIBYTE(ctx.ax) != 0)
X return FALSE;
X
X /* Get version, must be >= 4.0 */
X ctx.ax = 0x4600;
X jems_calldriver((EMScontext far *) & ctx);
X if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
X return FALSE;
X
X /* Try to allocate requested space */
X ctx.ax = 0x4300;
X ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
X jems_calldriver((EMScontext far *) & ctx);
X if (HIBYTE(ctx.ax) != 0)
X return FALSE;
X
X /* Succeeded, save the handle and away we go */
X info->handle.ems_handle = ctx.dx;
X info->read_backing_store = read_ems_store;
X info->write_backing_store = write_ems_store;
X info->close_backing_store = close_ems_store;
X TRACEMS1(methods, 1, "Obtained EMS handle %u", ctx.dx);
X return TRUE; /* succeeded */
X}
X
X#endif /* EMS_SUPPORTED */
X
X
X/*
X * Initial opening of a backing-store object.
X */
X
XGLOBAL void
Xjopen_backing_store (backing_store_ptr info, long total_bytes_needed)
X{
X /* Try extended memory, then expanded memory, then regular file. */
X#if XMS_SUPPORTED
X if (open_xms_store(info, total_bytes_needed))
X return;
X#endif
X#if EMS_SUPPORTED
X if (open_ems_store(info, total_bytes_needed))
X return;
X#endif
X if (open_file_store(info, total_bytes_needed))
X return;
X ERREXIT(methods, "Failed to create temporary file");
X}
X
X
X/*
X * These routines take care of any system-dependent initialization and
X * cleanup required. Keep in mind that jmem_term may be called more than
X * once.
X */
X
XGLOBAL void
Xjmem_init (external_methods_ptr emethods)
X{
X methods = emethods; /* save struct addr for error exit access */
X emethods->max_memory_to_use = DEFAULT_MAX_MEM;
X total_used = 0;
X next_file_num = 0;
X}
X
XGLOBAL void
Xjmem_term (void)
X{
X /* no work */
X}
END_OF_FILE
if test 17266 -ne `wc -c <'jmemdos.c'`; then
echo shar: \"'jmemdos.c'\" unpacked with wrong size!
fi
# end of 'jmemdos.c'
fi
if test -f 'jversion.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jversion.h'\"
else
echo shar: Extracting \"'jversion.h'\" \(358 characters\)
sed "s/^X//" >'jversion.h' <<'END_OF_FILE'
X/*
X * jversion.h
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains software version identification.
X */
X
X
X#define JVERSION "3 17-Mar-92"
X
X#define JCOPYRIGHT "Copyright (C) 1992, Thomas G. Lane"
END_OF_FILE
if test 358 -ne `wc -c <'jversion.h'`; then
echo shar: \"'jversion.h'\" unpacked with wrong size!
fi
# end of 'jversion.h'
fi
if test -f 'jwrjfif.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jwrjfif.c'\"
else
echo shar: Extracting \"'jwrjfif.c'\" \(11708 characters\)
sed "s/^X//" >'jwrjfif.c' <<'END_OF_FILE'
X/*
X * jwrjfif.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to write standard JPEG file headers/markers.
X * The file format created is a raw JPEG data stream with (optionally) an
X * APP0 marker per the JFIF spec. This will handle baseline and
X * JFIF-convention JPEG files, although there is currently no provision
X * for inserting a thumbnail image in the JFIF header.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume output to
X * an ordinary stdio stream. However, the changes to write to something
X * else are localized in the macros appearing just below.
X *
X * These routines are invoked via the methods write_file_header,
X * write_scan_header, write_jpeg_data, write_scan_trailer, and
X * write_file_trailer.
X */
X
X#include "jinclude.h"
X
X#ifdef JFIF_SUPPORTED
X
X
X/*
X * To output to something other than a stdio stream, you'd need to redefine
X * these macros.
X */
X
X/* Write a single byte */
X#define emit_byte(cinfo,x) putc((x), cinfo->output_file)
X
X/* Write some bytes from a (char *) buffer */
X#define WRITE_BYTES(cinfo,dataptr,datacount) \
X { if (JFWRITE(cinfo->output_file, dataptr, datacount) \
X != (size_t) (datacount)) \
X ERREXIT(cinfo->emethods, "Output file write error"); }
X
X/* Clean up and verify successful output */
X#define CHECK_OUTPUT(cinfo) \
X { fflush(cinfo->output_file); \
X if (ferror(cinfo->output_file)) \
X ERREXIT(cinfo->emethods, "Output file write error"); }
X
X
X/* End of stdio-specific code. */
XLOCAL void
Xemit_marker (compress_info_ptr cinfo, JPEG_MARKER mark)
X/* Emit a marker code */
X{
X emit_byte(cinfo, 0xFF);
X emit_byte(cinfo, mark);
X}
X
X
XLOCAL void
Xemit_2bytes (compress_info_ptr cinfo, int value)
X/* Emit a 2-byte integer; these are always MSB first in JPEG files */
X{
X emit_byte(cinfo, (value >> 8) & 0xFF);
X emit_byte(cinfo, value & 0xFF);
X}
X
X
XLOCAL int
Xemit_dqt (compress_info_ptr cinfo, int index)
X/* Emit a DQT marker */
X/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
X{
X QUANT_TBL_PTR data = cinfo->quant_tbl_ptrs[index];
X int prec = 0;
X int i;
X
X for (i = 0; i < DCTSIZE2; i++) {
X if (data[i] > 255)
X prec = 1;
X }
X
X emit_marker(cinfo, M_DQT);
X
X emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
X
X emit_byte(cinfo, index + (prec<<4));
X
X for (i = 0; i < DCTSIZE2; i++) {
X if (prec)
X emit_byte(cinfo, data[i] >> 8);
X emit_byte(cinfo, data[i] & 0xFF);
X }
X
X return prec;
X}
X
X
XLOCAL void
Xemit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
X/* Emit a DHT marker */
X{
X HUFF_TBL * htbl;
X int length, i;
X
X if (is_ac) {
X htbl = cinfo->ac_huff_tbl_ptrs[index];
X index += 0x10; /* output index has AC bit set */
X } else {
X htbl = cinfo->dc_huff_tbl_ptrs[index];
X }
X
X if (htbl == NULL)
X ERREXIT1(cinfo->emethods, "Huffman table 0x%02x was not defined", index);
X
X if (! htbl->sent_table) {
X emit_marker(cinfo, M_DHT);
X
X length = 0;
X for (i = 1; i <= 16; i++)
X length += htbl->bits[i];
X
X emit_2bytes(cinfo, length + 2 + 1 + 16);
X emit_byte(cinfo, index);
X
X for (i = 1; i <= 16; i++)
X emit_byte(cinfo, htbl->bits[i]);
X
X for (i = 0; i < length; i++)
X emit_byte(cinfo, htbl->huffval[i]);
X
X htbl->sent_table = TRUE;
X }
X}
X
X
XLOCAL void
Xemit_dac (compress_info_ptr cinfo)
X/* Emit a DAC marker */
X/* Since the useful info is so small, we want to emit all the tables in */
X/* one DAC marker. Therefore this routine does its own scan of the table. */
X{
X char dc_in_use[NUM_ARITH_TBLS];
X char ac_in_use[NUM_ARITH_TBLS];
X int length, i;
X
X for (i = 0; i < NUM_ARITH_TBLS; i++)
X dc_in_use[i] = ac_in_use[i] = 0;
X
X for (i = 0; i < cinfo->num_components; i++) {
X dc_in_use[cinfo->comp_info[i].dc_tbl_no] = 1;
X ac_in_use[cinfo->comp_info[i].ac_tbl_no] = 1;
X }
X
X length = 0;
X for (i = 0; i < NUM_ARITH_TBLS; i++)
X length += dc_in_use[i] + ac_in_use[i];
X
X emit_marker(cinfo, M_DAC);
X
X emit_2bytes(cinfo, length*2 + 2);
X
X for (i = 0; i < NUM_ARITH_TBLS; i++) {
X if (dc_in_use[i]) {
X emit_byte(cinfo, i);
X emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
X }
X if (ac_in_use[i]) {
X emit_byte(cinfo, i + 0x10);
X emit_byte(cinfo, cinfo->arith_ac_K[i]);
X }
X }
X}
X
X
XLOCAL void
Xemit_dri (compress_info_ptr cinfo)
X/* Emit a DRI marker */
X{
X emit_marker(cinfo, M_DRI);
X
X emit_2bytes(cinfo, 4); /* fixed length */
X
X emit_2bytes(cinfo, (int) cinfo->restart_interval);
X}
X
X
XLOCAL void
Xemit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
X/* Emit a SOF marker */
X{
X int i;
X
X emit_marker(cinfo, code);
X
X emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
X
X if (cinfo->image_height > 65535L || cinfo->image_width > 65535L)
X ERREXIT(cinfo->emethods, "Maximum image dimension for JFIF is 65535 pixels");
X
X emit_byte(cinfo, cinfo->data_precision);
X emit_2bytes(cinfo, (int) cinfo->image_height);
X emit_2bytes(cinfo, (int) cinfo->image_width);
X
X emit_byte(cinfo, cinfo->num_components);
X
X for (i = 0; i < cinfo->num_components; i++) {
X emit_byte(cinfo, cinfo->comp_info[i].component_id);
X emit_byte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
X + cinfo->comp_info[i].v_samp_factor);
X emit_byte(cinfo, cinfo->comp_info[i].quant_tbl_no);
X }
X}
X
X
XLOCAL void
Xemit_sos (compress_info_ptr cinfo)
X/* Emit a SOS marker */
X{
X int i;
X
X emit_marker(cinfo, M_SOS);
X
X emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
X
X emit_byte(cinfo, cinfo->comps_in_scan);
X
X for (i = 0; i < cinfo->comps_in_scan; i++) {
X emit_byte(cinfo, cinfo->cur_comp_info[i]->component_id);
X emit_byte(cinfo, (cinfo->cur_comp_info[i]->dc_tbl_no << 4)
X + cinfo->cur_comp_info[i]->ac_tbl_no);
X }
X
X emit_byte(cinfo, 0); /* Spectral selection start */
X emit_byte(cinfo, DCTSIZE2-1); /* Spectral selection end */
X emit_byte(cinfo, 0); /* Successive approximation */
X}
X
X
XLOCAL void
Xemit_jfif_app0 (compress_info_ptr cinfo)
X/* Emit a JFIF-compliant APP0 marker */
X{
X /*
X * Length of APP0 block (2 bytes)
X * Block ID (4 bytes - ASCII "JFIF")
X * Zero byte (1 byte to terminate the ID string)
X * Version Major, Minor (2 bytes - 0x01, 0x01)
X * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
X * Xdpu (2 bytes - dots per unit horizontal)
X * Ydpu (2 bytes - dots per unit vertical)
X * Thumbnail X size (1 byte)
X * Thumbnail Y size (1 byte)
X */
X
X emit_marker(cinfo, M_APP0);
X
X emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
X
X emit_byte(cinfo, 'J'); /* Identifier */
X emit_byte(cinfo, 'F');
X emit_byte(cinfo, 'I');
X emit_byte(cinfo, 'F');
X emit_byte(cinfo, 0);
X emit_byte(cinfo, 1); /* Major version */
X emit_byte(cinfo, 1); /* Minor version */
X emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
X emit_2bytes(cinfo, (int) cinfo->X_density);
X emit_2bytes(cinfo, (int) cinfo->Y_density);
X emit_byte(cinfo, 0); /* No thumbnail image */
X emit_byte(cinfo, 0);
X}
X
X
X/*
X * Write the file header.
X */
X
X
XMETHODDEF void
Xwrite_file_header (compress_info_ptr cinfo)
X{
X char qt_in_use[NUM_QUANT_TBLS];
X int i, prec;
X boolean is_baseline;
X
X emit_marker(cinfo, M_SOI); /* first the SOI */
X
X if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
X emit_jfif_app0(cinfo);
X
X /* Emit DQT for each quantization table. */
X /* Note that doing it here means we can't adjust the QTs on-the-fly. */
X /* If we did want to do that, we'd have a problem with checking precision */
X /* for the is_baseline determination. */
X
X for (i = 0; i < NUM_QUANT_TBLS; i++)
X qt_in_use[i] = 0;
X
X for (i = 0; i < cinfo->num_components; i++)
X qt_in_use[cinfo->comp_info[i].quant_tbl_no] = 1;
X
X prec = 0;
X for (i = 0; i < NUM_QUANT_TBLS; i++) {
X if (qt_in_use[i])
X prec += emit_dqt(cinfo, i);
X }
X /* now prec is nonzero iff there are any 16-bit quant tables. */
X
X if (cinfo->restart_interval)
X emit_dri(cinfo);
X
X /* Check for a non-baseline specification. */
X /* Note we assume that Huffman table numbers won't be changed later. */
X is_baseline = TRUE;
X if (cinfo->arith_code || (cinfo->data_precision != 8))
X is_baseline = FALSE;
X for (i = 0; i < cinfo->num_components; i++) {
X if (cinfo->comp_info[i].dc_tbl_no > 1 || cinfo->comp_info[i].ac_tbl_no > 1)
X is_baseline = FALSE;
X }
X if (prec && is_baseline) {
X is_baseline = FALSE;
X /* If it's baseline except for quantizer size, warn the user */
X TRACEMS(cinfo->emethods, 0,
X "Caution: quantization tables are too coarse for baseline JPEG");
X }
X
X
X /* Emit the proper SOF marker */
X if (cinfo->arith_code)
X emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
X else if (is_baseline)
X emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
X else
X emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
X}
X
X
X/*
X * Write the start of a scan (everything through the SOS marker).
X */
X
XMETHODDEF void
Xwrite_scan_header (compress_info_ptr cinfo)
X{
X int i;
X
X if (cinfo->arith_code) {
X /* Emit arith conditioning info. We will have some duplication
X * if the file has multiple scans, but it's so small it's hardly
X * worth worrying about.
X */
X emit_dac(cinfo);
X } else {
X /* Emit Huffman tables. Note that emit_dht takes care of
X * suppressing duplicate tables.
X */
X for (i = 0; i < cinfo->comps_in_scan; i++) {
X emit_dht(cinfo, cinfo->cur_comp_info[i]->dc_tbl_no, FALSE);
X emit_dht(cinfo, cinfo->cur_comp_info[i]->ac_tbl_no, TRUE);
X }
X }
X
X emit_sos(cinfo);
X}
X
X
X/*
X * Write some bytes of compressed data within a scan.
X */
X
XMETHODDEF void
Xwrite_jpeg_data (compress_info_ptr cinfo, char *dataptr, int datacount)
X{
X WRITE_BYTES(cinfo, dataptr, datacount);
X}
X
X
X/*
X * Finish up after a compressed scan (series of write_jpeg_data calls).
X */
X
XMETHODDEF void
Xwrite_scan_trailer (compress_info_ptr cinfo)
X{
X /* no work needed in this format */
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xwrite_file_trailer (compress_info_ptr cinfo)
X{
X emit_marker(cinfo, M_EOI);
X /* Make sure we wrote the output file OK */
X CHECK_OUTPUT(cinfo);
X}
X
X
X/*
X * The method selection routine for standard JPEG header writing.
X * This should be called from c_ui_method_selection if appropriate.
X */
X
XGLOBAL void
Xjselwjfif (compress_info_ptr cinfo)
X{
X cinfo->methods->write_file_header = write_file_header;
X cinfo->methods->write_scan_header = write_scan_header;
X cinfo->methods->write_jpeg_data = write_jpeg_data;
X cinfo->methods->write_scan_trailer = write_scan_trailer;
X cinfo->methods->write_file_trailer = write_file_trailer;
X}
X
X#endif /* JFIF_SUPPORTED */
END_OF_FILE
if test 11708 -ne `wc -c <'jwrjfif.c'`; then
echo shar: \"'jwrjfif.c'\" unpacked with wrong size!
fi
# end of 'jwrjfif.c'
fi
echo shar: End of archive 12 \(of 18\).
cp /dev/null ark12isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: USAGE jconfig.h jdcolor.c jdmain.c jrdrle.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:53 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 13 (of 18)."'
if test -f 'USAGE' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'USAGE'\"
else
echo shar: Extracting \"'USAGE'\" \(9783 characters\)
sed "s/^X//" >'USAGE' <<'END_OF_FILE'
XUSAGE instructions for the Independent JPEG Group's JPEG software
X=================================================================
X
XINTRODUCTION
X
XThis distribution contains software to implement JPEG image compression and
Xdecompression. JPEG (pronounced "jay-peg") is a standardized compression
Xmethod for full-color and gray-scale images. JPEG is designed to handle
X"real-world" scenes, for example scanned photographs. Cartoons, line
Xdrawings, and other non-realistic images are not JPEG's strong suit; on this
Xsort of material you may get poor image quality and/or little compression.
X
XJPEG is lossy, meaning that the output image is not necessarily identical to
Xthe input image. Hence you should not use JPEG if you have to have identical
Xoutput bits. However, on typical real-world images, very good compression
Xlevels can be obtained with no visible change, and amazingly high compression
Xis possible if you can tolerate a low-quality image. You can trade off image
Xquality against file size by adjusting the compressor's "quality" setting.
X
XThis file describes usage of the standard programs "cjpeg" and "djpeg" that
Xcan be built directly from the distributed C code. See the README file for
Xhints on incorporating the JPEG software into other programs.
X
XIf you are on a Unix machine you may prefer to read the Unix-style manual
Xpages in files cjpeg.1 and djpeg.1.
X
XNOTE: at some point we will probably redesign the user interface, so the
Xcommand line switches described here will change.
X
X
XGENERAL USAGE
X
XWe provide two programs, cjpeg to compress an image file into JPEG format,
Xand djpeg to decompress a JPEG file back into a conventional image format.
X
XOn Unix-like systems, you say:
X cjpeg [switches] [imagefile] >jpegfile
Xor
X djpeg [switches] [jpegfile] >imagefile
XThe programs read the specified input file, or standard input if none is
Xnamed. They always write to standard output (with trace/error messages to
Xstandard error). These conventions are handy for piping images between
Xprograms.
X
XOn most non-Unix systems, you say:
X cjpeg [switches] imagefile jpegfile
Xor
X djpeg [switches] jpegfile imagefile
Xi.e., both the input and output files are named on the command line. This
Xstyle is a little more foolproof, and it loses no functionality if you don't
Xhave pipes. (You can get this style on Unix too, if you prefer, by defining
XTWO_FILE_COMMANDLINE when you compile the programs; see SETUP.)
X
XThe currently supported image file formats are: PPM (PBMPLUS color format),
XPGM (PBMPLUS gray-scale format), GIF, Targa, and RLE (Utah Raster Toolkit
Xformat). (RLE is supported only if the URT library is available.)
Xcjpeg recognizes the input image format automatically, with the exception
Xof some Targa-format files. You have to tell djpeg which format to generate.
X
XThe only JPEG file format currently supported is the JFIF format. Support for
Xthe TIFF/JPEG format will probably be added at some future date.
X
X
XCJPEG DETAILS
X
XThe command line switches for cjpeg are:
X
X -Q quality Scale quantization tables to adjust image quality.
X Quality is 0 (worst) to 100 (best); default is 75.
X (See below for more info.)
X
X -o Perform optimization of entropy encoding parameters.
X Without this, default encoding parameters are used.
X -o usually makes the JPEG file a little smaller, but
X cjpeg runs somewhat slower and needs much more memory.
X Image quality and speed of decompression are unaffected
X by -o.
X
X -T Input file is Targa format. Targa files that contain
X an "identification" field will not be automatically
X recognized by cjpeg; for such files you must specify
X -T to force cjpeg to treat the input as Targa format.
X
X -I Generate noninterleaved JPEG file (not yet supported).
X
X -a Use arithmetic coding rather than Huffman coding.
X (Not currently supported for legal reasons.)
X
X -d Enable debug printout. More -d's give more printout.
X Also, version information is printed at startup.
X
X -m memory Set limit for amount of memory to use in processing
X large images. Value is in thousands of bytes, or
X millions of bytes if "M" is attached to the number.
X For example, -m 4m selects 4000000 bytes. If more
X space is needed, temporary files will be used.
X
XThe -Q switch lets you trade off compressed file size against quality of the
Xreconstructed image: the higher the -Q setting, the larger the JPEG file, and
Xthe closer the output image will be to the original input. Normally you want
Xto use the lowest -Q setting (smallest file) that decompresses into something
Xvisually indistinguishable from the original image. For this purpose the -Q
Xsetting should be between 50 and 95; the default of 75 is often about right.
XIf you see defects at -Q 75, then go up 5 or 10 counts at a time until you are
Xhappy with the output image. (The optimal setting will vary from one image to
Xanother.)
X
X-Q 100 will generate a quantization table of all 1's, eliminating loss in the
Xquantization step (but there is still information loss in subsampling, as well
Xas roundoff error). This setting is mainly of interest for experimental
Xpurposes. -Q values above about 95 are NOT recommended for normal use; the
Xcompressed file size goes up dramatically for hardly any gain in output image
Xquality.
X
XIn the other direction, -Q values below 50 will produce very small files of
Xlow image quality. Settings around 5 to 10 might be useful in preparing an
Xindex of a large image library, for example. Try -Q 2 (or so) for some
Xamusing Cubist effects. (Note: -Q values below about 25 generate 2-byte
Xquantization tables, which are considered optional in the JPEG standard.
Xcjpeg emits a warning message when you give such a -Q value, because some
Xcommercial JPEG programs may be unable to decode the resulting file.)
X
X
XDJPEG DETAILS
X
XThe command line switches for djpeg are:
X
X -G Select GIF output format (implies -q, with default
X of 256 colors).
X
X -P Select PPM or PGM output format (this is the default).
X PGM is emitted if the JPEG file is gray-scale or if -g
X is specified.
X
X -R Select RLE output format. Requires URT library.
X
X -T Select Targa output format. Gray-scale format is
X emitted if the JPEG file is gray-scale or if -g is
X specified; otherwise, colormapped format is emitted
X if -q is specified; otherwise, 24-bit full-color
X format is emitted.
X
X -g Force gray-scale output even if input is color.
X
X -q N Quantize to N colors. This reduces the number of
X colors in the output image so that it can be displayed
X on a colormapped display or stored in a colormapped
X file format. For example, if you have an 8-bit
X display, you'd need to quantize to 256 or fewer colors.
X
X -D Do not use dithering in color quantization.
X By default, Floyd-Steinberg dithering is applied when
X quantizing colors, but on some images dithering may
X result in objectionable "graininess". If that
X happens, you can turn off dithering with -D.
X -D is ignored unless you also say -q or -G.
X
X -1 Use one-pass instead of two-pass color quantization.
X The one-pass method is faster and needs less memory,
X but it produces a lower-quality image.
X -1 is ignored unless you also say -q or -G. Also,
X the one-pass method is always used for gray-scale
X output (the two-pass method is no improvement then).
X
X -b Perform cross-block smoothing. This is quite
X memory-intensive and only seems to improve the image
X at very low quality settings (-Q 10 to 20 or so).
X At normal -Q settings it may make the image worse.
X
X -d Enable debug printout. More -d's give more printout.
X Also, version information is printed at startup.
X
X -m memory Set limit for amount of memory to use in processing
X large images. Value is in thousands of bytes, or
X millions of bytes if "M" is attached to the number.
X For example, -m 4m selects 4000000 bytes. If more
X space is needed, temporary files will be used.
X
X
XHINTS
X
XAvoid running an image through a series of JPEG compression/decompression
Xcycles. Image quality loss will accumulate; after ten or so cycles the image
Xmay be noticeably worse than it was after one cycle. It's best to use a
Xlossless format while manipulating an image, then convert to JPEG format when
Xyou are ready to file the image away.
X
XThe -o option to cjpeg is worth using when you are making a "final" version
Xfor posting or archiving. It's also a win when you are using low -Q settings
Xto make very small JPEG files; the percentage improvement is often a lot more
Xthan it is on larger files.
X
XThe default memory usage limit (-m) is set when the software is compiled.
XIf you get an "insufficient memory" error, try specifying a smaller -m value,
Xeven -m 0 to use the absolute minimum space. You may want to recompile with
Xa smaller default value if this happens often.
X
Xdjpeg with two-pass color quantization requires a good deal of space; on
XMS-DOS machines it may run out of memory even with -m 0. In that case you
Xcan still decompress, with some loss of image quality, by specifying -1
Xfor one-pass quantization.
X
XIf more space is needed than will fit in the available main memory (as
Xdetermined by -m), temporary files will be used. (MS-DOS versions will try to
Xget extended or expanded memory first.) The temporary files are often rather
Xlarge: in typical cases they occupy three bytes per pixel, for example
X3*800*600 = 1.44Mb for an 800x600 image. If you don't have enough free disk
Xspace, leave out -o (for cjpeg) or specify -1 (for djpeg). On MS-DOS, the
Xtemporary files are created in the directory named by the TMP or TEMP
Xenvironment variable, or in the current directory if neither of those exist.
XAmiga implementations put the temp files in the directory named by JPEGTMP:,
Xso be sure to assign JPEGTMP: to a disk partition with adequate free space.
END_OF_FILE
if test 9783 -ne `wc -c <'USAGE'`; then
echo shar: \"'USAGE'\" unpacked with wrong size!
fi
# end of 'USAGE'
fi
if test -f 'jconfig.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jconfig.h'\"
else
echo shar: Extracting \"'jconfig.h'\" \(11361 characters\)
sed "s/^X//" >'jconfig.h' <<'END_OF_FILE'
X/*
X * jconfig.h
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains preprocessor declarations that help customize
X * the JPEG software for a particular application, machine, or compiler.
X * Edit these declarations as needed (or add -D flags to the Makefile).
X */
X
X
X/*
X * These symbols indicate the properties of your machine or compiler.
X * The conditional definitions given may do the right thing already,
X * but you'd best look them over closely, especially if your compiler
X * does not handle full ANSI C. An ANSI-compliant C compiler should
X * provide all the necessary features; __STDC__ is supposed to be
X * predefined by such compilers.
X */
X
X/*
X * HAVE_STDC is tested below to see whether ANSI features are available.
X * We avoid testing __STDC__ directly for arcane reasons of portability.
X * (On some compilers, __STDC__ is only defined if a switch is given,
X * but the switch also disables machine-specific features we need to get at.
X * In that case, -DHAVE_STDC in the Makefile is a convenient solution.)
X */
X
X#ifdef __STDC__ /* if compiler claims to be ANSI, believe it */
X#define HAVE_STDC
X#endif
X
X
X/* Does your compiler support function prototypes? */
X/* (If not, you also need to use ansi2knr, see SETUP) */
X
X#ifdef HAVE_STDC /* ANSI C compilers always have prototypes */
X#define PROTO
X#else
X#ifdef __cplusplus /* So do C++ compilers */
X#define PROTO
X#endif
X#endif
X
X/* Does your compiler support the declaration "unsigned char" ? */
X/* How about "unsigned short" ? */
X
X#ifdef HAVE_STDC /* ANSI C compilers must support both */
X#define HAVE_UNSIGNED_CHAR
X#define HAVE_UNSIGNED_SHORT
X#endif
X
X/* Define this if an ordinary "char" type is unsigned.
X * If you're not sure, leaving it undefined will work at some cost in speed.
X * If you defined HAVE_UNSIGNED_CHAR then it doesn't matter very much.
X */
X
X/* #define CHAR_IS_UNSIGNED */
X
X/* Define this if your compiler implements ">>" on signed values as a logical
X * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
X * which is the normal and rational definition.
X */
X
X/* #define RIGHT_SHIFT_IS_UNSIGNED */
X
X/* Define "void" as "char" if your compiler doesn't know about type void.
X * NOTE: be sure to define void such that "void *" represents the most general
X * pointer type, e.g., that returned by malloc().
X */
X
X/* #define void char */
X
X/* Define const as empty if your compiler doesn't know the "const" keyword. */
X/* (Even if it does, defining const as empty won't break anything.) */
X
X#ifndef HAVE_STDC /* ANSI C and C++ compilers should know it. */
X#ifndef __cplusplus
X#define const
X#endif
X#endif
X
X/* For 80x86 machines, you need to define NEED_FAR_POINTERS,
X * unless you are using a large-data memory model or 80386 flat-memory mode.
X * On less brain-damaged CPUs this symbol must not be defined.
X * (Defining this symbol causes large data structures to be referenced through
X * "far" pointers and to be allocated with a special version of malloc.)
X */
X
X#ifdef MSDOS
X#define NEED_FAR_POINTERS
X#endif
X
X
X/* The next three symbols only affect the system-dependent user interface
X * modules (jcmain.c, jdmain.c). You can ignore these if you are supplying
X * your own user interface code.
X */
X
X/* Define this if you want to name both input and output files on the command
X * line, rather than using stdout and optionally stdin. You MUST do this if
X * your system can't cope with binary I/O to stdin/stdout. See comments at
X * head of jcmain.c or jdmain.c.
X */
X
X#ifdef MSDOS /* two-file style is needed for PCs */
X#define TWO_FILE_COMMANDLINE
X#endif
X#ifdef THINK_C /* needed for Macintosh too */
X#define TWO_FILE_COMMANDLINE
X#endif
X
X/* Define this if your system needs explicit cleanup of temporary files.
X * This is crucial under MS-DOS, where the temporary "files" may be areas
X * of extended memory; on most other systems it's not as important.
X */
X
X#ifdef MSDOS
X#define NEED_SIGNAL_CATCHER
X#endif
X
X/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
X * This is necessary on systems that distinguish text files from binary files,
X * and is harmless on most systems that don't. If you have one of the rare
X * systems that complains about the "b" spec, define this symbol.
X */
X
X/* #define DONT_USE_B_MODE */
X
X
X/* If you're getting bored, that's the end of the symbols you HAVE to
X * worry about. Go fix the makefile and compile.
X */
X
X
X/* On a few systems, type boolean and/or macros FALSE, TRUE may appear
X * in standard header files. Or you may have conflicts with application-
X * specific header files that you want to include together with these files.
X * In that case you need only comment out these definitions.
X */
X
Xtypedef int boolean;
X#undef FALSE /* in case these macros already exist */
X#undef TRUE
X#define FALSE 0 /* values of boolean */
X#define TRUE 1
X
X/* This defines the size of the I/O buffers for entropy compression
X * and decompression; you could reduce it if memory is tight.
X */
X
X#define JPEG_BUF_SIZE 4096 /* bytes */
X
X
X
X/* These symbols determine the JPEG functionality supported. */
X
X/*
X * These defines indicate whether to include various optional functions.
X * Undefining some of these symbols will produce a smaller but less capable
X * program file. Note that you can leave certain source files out of the
X * compilation/linking process if you've #undef'd the corresponding symbols.
X * (You may HAVE to do that if your compiler doesn't like null source files.)
X */
X
X/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
X#undef ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
X#define MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
X#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
X#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing during decoding? */
X#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
X#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
X/* these defines indicate which JPEG file formats are allowed */
X#define JFIF_SUPPORTED /* JFIF or "raw JPEG" files */
X#undef JTIFF_SUPPORTED /* JPEG-in-TIFF (not yet implemented) */
X/* these defines indicate which image (non-JPEG) file formats are allowed */
X#define GIF_SUPPORTED /* GIF image file format */
X/* #define RLE_SUPPORTED */ /* RLE image file format (by default, no) */
X#define PPM_SUPPORTED /* PPM/PGM image file format */
X#define TARGA_SUPPORTED /* Targa image file format */
X#undef TIFF_SUPPORTED /* TIFF image file format (not yet impl.) */
X
X/* more capability options later, no doubt */
X
X
X/*
X * Define exactly one of these three symbols to indicate whether you want
X * 8-bit, 12-bit, or 16-bit sample (pixel component) values. 8-bit is the
X * default and is nearly always the right thing to use. You can use 12-bit if
X * you need to support image formats with more than 8 bits of resolution in a
X * color value. 16-bit should only be used for the lossless JPEG mode (not
X * currently supported). Note that 12- and 16-bit values take up twice as
X * much memory as 8-bit!
X * Note: if you select 12- or 16-bit precision, it is dangerous to turn off
X * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
X * precision, so jchuff.c normally uses entropy optimization to compute
X * usable tables for higher precision. If you don't want to do optimization,
X * you'll have to supply different default Huffman tables.
X */
X
X#define EIGHT_BIT_SAMPLES
X#undef TWELVE_BIT_SAMPLES
X#undef SIXTEEN_BIT_SAMPLES
X
X
X
X/*
X * The remaining definitions don't need to be hand-edited in most cases.
X * You may need to change these if you have a machine with unusual data
X * types; for example, "char" not 8 bits, "short" not 16 bits,
X * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
X * but it had better be at least 16.
X */
X
X/* First define the representation of a single pixel element value. */
X
X#ifdef EIGHT_BIT_SAMPLES
X/* JSAMPLE should be the smallest type that will hold the values 0..255.
X * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
X * If you have only signed chars, and you are more worried about speed than
X * memory usage, it might be a win to make JSAMPLE be short.
X */
X
X#ifdef HAVE_UNSIGNED_CHAR
X
Xtypedef unsigned char JSAMPLE;
X#define GETJSAMPLE(value) (value)
X
X#else /* not HAVE_UNSIGNED_CHAR */
X#ifdef CHAR_IS_UNSIGNED
X
Xtypedef char JSAMPLE;
X#define GETJSAMPLE(value) (value)
X
X#else /* not CHAR_IS_UNSIGNED */
X
Xtypedef char JSAMPLE;
X#define GETJSAMPLE(value) ((value) & 0xFF)
X
X#endif /* CHAR_IS_UNSIGNED */
X#endif /* HAVE_UNSIGNED_CHAR */
X
X#define BITS_IN_JSAMPLE 8
X#define MAXJSAMPLE 255
X#define CENTERJSAMPLE 128
X
X#endif /* EIGHT_BIT_SAMPLES */
X
X
X#ifdef TWELVE_BIT_SAMPLES
X/* JSAMPLE should be the smallest type that will hold the values 0..4095. */
X/* On nearly all machines "short" will do nicely. */
X
Xtypedef short JSAMPLE;
X#define GETJSAMPLE(value) (value)
X
X#define BITS_IN_JSAMPLE 12
X#define MAXJSAMPLE 4095
X#define CENTERJSAMPLE 2048
X
X#endif /* TWELVE_BIT_SAMPLES */
X
X
X#ifdef SIXTEEN_BIT_SAMPLES
X/* JSAMPLE should be the smallest type that will hold the values 0..65535. */
X
X#ifdef HAVE_UNSIGNED_SHORT
X
Xtypedef unsigned short JSAMPLE;
X#define GETJSAMPLE(value) (value)
X
X#else /* not HAVE_UNSIGNED_SHORT */
X
X/* If int is 32 bits this'll be horrendously inefficient storage-wise.
X * But since we don't actually support 16-bit samples (ie lossless coding) yet,
X * I'm not going to worry about making a smarter definition ...
X */
Xtypedef unsigned int JSAMPLE;
X#define GETJSAMPLE(value) (value)
X
X#endif /* HAVE_UNSIGNED_SHORT */
X
X#define BITS_IN_JSAMPLE 16
X#define MAXJSAMPLE 65535
X#define CENTERJSAMPLE 32768
X
X#endif /* SIXTEEN_BIT_SAMPLES */
X
X
X/* Here we define the representation of a DCT frequency coefficient.
X * This should be a signed 16-bit value; "short" is usually right.
X * It's important that this be exactly 16 bits, no more and no less;
X * more will cost you a BIG hit of memory, less will give wrong answers.
X */
X
Xtypedef short JCOEF;
X
X
X/* The remaining typedefs are used for various table entries and so forth.
X * They must be at least as wide as specified; but making them too big
X * won't cost a huge amount of memory, so we don't provide special
X * extraction code like we did for JSAMPLE. (In other words, these
X * typedefs live at a different point on the speed/space tradeoff curve.)
X */
X
X/* UINT8 must hold at least the values 0..255. */
X
X#ifdef HAVE_UNSIGNED_CHAR
Xtypedef unsigned char UINT8;
X#else /* not HAVE_UNSIGNED_CHAR */
X#ifdef CHAR_IS_UNSIGNED
Xtypedef char UINT8;
X#else /* not CHAR_IS_UNSIGNED */
Xtypedef short UINT8;
X#endif /* CHAR_IS_UNSIGNED */
X#endif /* HAVE_UNSIGNED_CHAR */
X
X/* UINT16 must hold at least the values 0..65535. */
X
X#ifdef HAVE_UNSIGNED_SHORT
Xtypedef unsigned short UINT16;
X#else /* not HAVE_UNSIGNED_SHORT */
Xtypedef unsigned int UINT16;
X#endif /* HAVE_UNSIGNED_SHORT */
X
X/* INT16 must hold at least the values -32768..32767. */
X
X#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
Xtypedef short INT16;
X#endif
X
X/* INT32 must hold signed 32-bit values; if your machine happens */
X/* to have 64-bit longs, you might want to change this. */
X
X#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
Xtypedef long INT32;
X#endif
END_OF_FILE
if test 11361 -ne `wc -c <'jconfig.h'`; then
echo shar: \"'jconfig.h'\" unpacked with wrong size!
fi
# end of 'jconfig.h'
fi
if test -f 'jdcolor.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdcolor.c'\"
else
echo shar: Extracting \"'jdcolor.c'\" \(9030 characters\)
sed "s/^X//" >'jdcolor.c' <<'END_OF_FILE'
X/*
X * jdcolor.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains output colorspace conversion routines.
X * These routines are invoked via the methods color_convert
X * and colorout_init/term.
X */
X
X#include "jinclude.h"
X
X
X/**************** YCbCr -> RGB conversion: most common case **************/
X
X/*
X * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
X * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
X * The conversion equations to be implemented are therefore
X * R = Y + 1.40200 * Cr
X * G = Y - 0.34414 * Cb - 0.71414 * Cr
X * B = Y + 1.77200 * Cb
X * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
X * (These numbers are derived from TIFF Appendix O, draft of 4/10/91.)
X *
X * To avoid floating-point arithmetic, we represent the fractional constants
X * as integers scaled up by 2^14 (about 4 digits precision); we have to divide
X * the products by 2^14, with appropriate rounding, to get the correct answer.
X * Notice that Y, being an integral input, does not contribute any fraction
X * so it need not participate in the rounding.
X *
X * For even more speed, we avoid doing any multiplications in the inner loop
X * by precalculating the constants times Cb and Cr for all possible values.
X * For 8-bit JSAMPLEs this is very reasonable (only 256 table entries); for
X * 12-bit samples it is still acceptable. It's not very reasonable for 16-bit
X * samples, but if you want lossless storage you shouldn't be changing
X * colorspace anyway.
X * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
X * values for the G calculation are left scaled up, since we must add them
X * together before rounding.
X */
X
X#define SCALEBITS 14
X#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
X#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
X
Xstatic INT16 * Cr_r_tab; /* => table for Cr to R conversion */
Xstatic INT16 * Cb_b_tab; /* => table for Cb to B conversion */
Xstatic INT32 * Cr_g_tab; /* => table for Cr to G conversion */
Xstatic INT32 * Cb_g_tab; /* => table for Cb to G conversion */
X
X
X/*
X * Initialize for colorspace conversion.
X */
X
XMETHODDEF void
Xycc_rgb_init (decompress_info_ptr cinfo)
X{
X#ifdef SIXTEEN_BIT_SAMPLES
X INT32 i, x2;
X#else
X int i, x2; /* smart compiler may do 16x16=>32 multiply */
X#endif
X SHIFT_TEMPS
X
X Cr_r_tab = (INT16 *) (*cinfo->emethods->alloc_small)
X ((MAXJSAMPLE+1) * SIZEOF(INT16));
X Cb_b_tab = (INT16 *) (*cinfo->emethods->alloc_small)
X ((MAXJSAMPLE+1) * SIZEOF(INT16));
X Cr_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
X ((MAXJSAMPLE+1) * SIZEOF(INT32));
X Cb_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
X ((MAXJSAMPLE+1) * SIZEOF(INT32));
X
X for (i = 0; i <= MAXJSAMPLE; i++) {
X /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
X /* The Cb or Cr value we are thinking of is x = i - MAXJSAMPLE/2 */
X x2 = 2*i - MAXJSAMPLE; /* twice x */
X /* Cr=>R value is nearest int to 1.40200 * x */
X Cr_r_tab[i] = (INT16)
X RIGHT_SHIFT(FIX(1.40200/2) * x2 + ONE_HALF, SCALEBITS);
X /* Cb=>B value is nearest int to 1.77200 * x */
X Cb_b_tab[i] = (INT16)
X RIGHT_SHIFT(FIX(1.77200/2) * x2 + ONE_HALF, SCALEBITS);
X /* Cr=>G value is scaled-up -0.71414 * x */
X Cr_g_tab[i] = (- FIX(0.71414/2)) * x2;
X /* Cb=>G value is scaled-up -0.34414 * x */
X /* We also add in ONE_HALF so that need not do it in inner loop */
X Cb_g_tab[i] = (- FIX(0.34414/2)) * x2 + ONE_HALF;
X }
X}
X
X
X/*
X * Convert some rows of samples to the output colorspace.
X */
X
XMETHODDEF void
Xycc_rgb_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
X JSAMPIMAGE input_data, JSAMPIMAGE output_data)
X{
X#ifdef SIXTEEN_BIT_SAMPLES
X register UINT16 y, cb, cr;
X register INT32 x;
X#else
X register int y, cb, cr;
X register int x;
X#endif
X register JSAMPROW inptr0, inptr1, inptr2;
X register JSAMPROW outptr0, outptr1, outptr2;
X long col;
X int row;
X SHIFT_TEMPS
X
X for (row = 0; row < num_rows; row++) {
X inptr0 = input_data[0][row];
X inptr1 = input_data[1][row];
X inptr2 = input_data[2][row];
X outptr0 = output_data[0][row];
X outptr1 = output_data[1][row];
X outptr2 = output_data[2][row];
X for (col = num_cols; col > 0; col--) {
X y = GETJSAMPLE(*inptr0++);
X cb = GETJSAMPLE(*inptr1++);
X cr = GETJSAMPLE(*inptr2++);
X /* Note: if the inputs were computed directly from RGB values,
X * range-limiting would be unnecessary here; but due to possible
X * noise in the DCT/IDCT phase, we do need to apply range limits.
X */
X x = y + Cr_r_tab[cr]; /* red */
X if (x < 0) x = 0;
X else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
X *outptr0++ = (JSAMPLE) x;
X x = y + ((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS));
X if (x < 0) x = 0;
X else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
X *outptr1++ = (JSAMPLE) x;
X x = y + Cb_b_tab[cb]; /* blue */
X if (x < 0) x = 0;
X else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
X *outptr2++ = (JSAMPLE) x;
X }
X }
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xycc_rgb_term (decompress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X}
X
X
X/**************** Cases other than YCbCr -> RGB **************/
X
X
X/*
X * Initialize for colorspace conversion.
X */
X
XMETHODDEF void
Xnull_init (decompress_info_ptr cinfo)
X/* colorout_init for cases where no setup is needed */
X{
X /* no work needed */
X}
X
X
X/*
X * Color conversion for no colorspace change: just copy the data.
X */
X
XMETHODDEF void
Xnull_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
X JSAMPIMAGE input_data, JSAMPIMAGE output_data)
X{
X short ci;
X
X for (ci = 0; ci < cinfo->num_components; ci++) {
X jcopy_sample_rows(input_data[ci], 0, output_data[ci], 0,
X num_rows, num_cols);
X }
X}
X
X
X/*
X * Color conversion for grayscale: just copy the data.
X * This also works for YCbCr/YIQ -> grayscale conversion, in which
X * we just copy the Y (luminance) component and ignore chrominance.
X */
X
XMETHODDEF void
Xgrayscale_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
X JSAMPIMAGE input_data, JSAMPIMAGE output_data)
X{
X jcopy_sample_rows(input_data[0], 0, output_data[0], 0,
X num_rows, num_cols);
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xnull_term (decompress_info_ptr cinfo)
X/* colorout_term for cases where no teardown is needed */
X{
X /* no work needed */
X}
X
X
X
X/*
X * The method selection routine for output colorspace conversion.
X */
X
XGLOBAL void
Xjseldcolor (decompress_info_ptr cinfo)
X{
X /* Make sure num_components agrees with jpeg_color_space */
X switch (cinfo->jpeg_color_space) {
X case CS_GRAYSCALE:
X if (cinfo->num_components != 1)
X ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
X break;
X
X case CS_RGB:
X case CS_YCbCr:
X case CS_YIQ:
X if (cinfo->num_components != 3)
X ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
X break;
X
X case CS_CMYK:
X if (cinfo->num_components != 4)
X ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
X break;
X
X default:
X ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace");
X break;
X }
X
X /* Set color_out_comps and conversion method based on requested space */
X switch (cinfo->out_color_space) {
X case CS_GRAYSCALE:
X cinfo->color_out_comps = 1;
X if (cinfo->jpeg_color_space == CS_GRAYSCALE ||
X cinfo->jpeg_color_space == CS_YCbCr ||
X cinfo->jpeg_color_space == CS_YIQ) {
X cinfo->methods->color_convert = grayscale_convert;
X cinfo->methods->colorout_init = null_init;
X cinfo->methods->colorout_term = null_term;
X } else
X ERREXIT(cinfo->emethods, "Unsupported color conversion request");
X break;
X
X case CS_RGB:
X cinfo->color_out_comps = 3;
X if (cinfo->jpeg_color_space == CS_YCbCr) {
X cinfo->methods->color_convert = ycc_rgb_convert;
X cinfo->methods->colorout_init = ycc_rgb_init;
X cinfo->methods->colorout_term = ycc_rgb_term;
X } else if (cinfo->jpeg_color_space == CS_RGB) {
X cinfo->methods->color_convert = null_convert;
X cinfo->methods->colorout_init = null_init;
X cinfo->methods->colorout_term = null_term;
X } else
X ERREXIT(cinfo->emethods, "Unsupported color conversion request");
X break;
X
X default:
X /* Permit null conversion from CMYK or YCbCr to same output space */
X if (cinfo->out_color_space == cinfo->jpeg_color_space) {
X cinfo->color_out_comps = cinfo->num_components;
X cinfo->methods->color_convert = null_convert;
X cinfo->methods->colorout_init = null_init;
X cinfo->methods->colorout_term = null_term;
X } else /* unsupported non-null conversion */
X ERREXIT(cinfo->emethods, "Unsupported color conversion request");
X break;
X }
X
X if (cinfo->quantize_colors)
X cinfo->final_out_comps = 1; /* single colormapped output component */
X else
X cinfo->final_out_comps = cinfo->color_out_comps;
X}
END_OF_FILE
if test 9030 -ne `wc -c <'jdcolor.c'`; then
echo shar: \"'jdcolor.c'\" unpacked with wrong size!
fi
# end of 'jdcolor.c'
fi
if test -f 'jdmain.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdmain.c'\"
else
echo shar: Extracting \"'jdmain.c'\" \(8658 characters\)
sed "s/^X//" >'jdmain.c' <<'END_OF_FILE'
X/*
X * jdmain.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains a trivial test user interface for the JPEG decompressor.
X * It should work on any system with Unix- or MS-DOS-style command lines.
X *
X * Two different command line styles are permitted, depending on the
X * compile-time switch TWO_FILE_COMMANDLINE:
X * djpeg [options] inputfile outputfile
X * djpeg [options] [inputfile]
X * In the second style, output is always to standard output, which you'd
X * normally redirect to a file or pipe to some other program. Input is
X * either from a named file or from standard input (typically redirected).
X * The second style is convenient on Unix but is unhelpful on systems that
X * don't support pipes. Also, you MUST use the first style if your system
X * doesn't do binary I/O to stdin/stdout.
X */
X
X#include "jinclude.h"
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare exit() */
X#endif
X#ifdef NEED_SIGNAL_CATCHER
X#include <signal.h> /* to declare signal() */
X#endif
X
X#ifdef THINK_C
X#include <console.h> /* command-line reader for Macintosh */
X#endif
X
X#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
X#define READ_BINARY "r"
X#define WRITE_BINARY "w"
X#else
X#define READ_BINARY "rb"
X#define WRITE_BINARY "wb"
X#endif
X
X#ifndef EXIT_FAILURE /* define exit() codes if not provided */
X#define EXIT_FAILURE 1
X#endif
X#ifndef EXIT_SUCCESS
X#ifdef VMS
X#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
X#else
X#define EXIT_SUCCESS 0
X#endif
X#endif
X
X
X#include "jversion.h" /* for version message */
X
X
X/*
X * PD version of getopt(3).
X */
X
X#include "egetopt.c"
X
X
X/*
X * This list defines the known output image formats
X * (not all of which need be supported by a given version).
X * You can change the default output format by defining DEFAULT_FMT;
X * indeed, you had better do so if you undefine PPM_SUPPORTED.
X */
X
Xtypedef enum {
X FMT_GIF, /* GIF format */
X FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
X FMT_RLE, /* RLE format */
X FMT_TARGA, /* Targa format */
X FMT_TIFF /* TIFF format */
X} IMAGE_FORMATS;
X
X#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */
X#define DEFAULT_FMT FMT_PPM
X#endif
X
Xstatic IMAGE_FORMATS requested_fmt;
X
X
X/*
X * This routine gets control after the input file header has been read.
X * It must determine what output file format is to be written,
X * and make any other decompression parameter changes that are desirable.
X */
X
XMETHODDEF void
Xd_ui_method_selection (decompress_info_ptr cinfo)
X{
X /* if grayscale or CMYK input, force similar output; */
X /* else leave the output colorspace as set by options. */
X if (cinfo->jpeg_color_space == CS_GRAYSCALE)
X cinfo->out_color_space = CS_GRAYSCALE;
X else if (cinfo->jpeg_color_space == CS_CMYK)
X cinfo->out_color_space = CS_CMYK;
X
X /* select output file format */
X /* Note: jselwxxx routine may make additional parameter changes,
X * such as forcing color quantization if it's a colormapped format.
X */
X switch (requested_fmt) {
X#ifdef GIF_SUPPORTED
X case FMT_GIF:
X jselwgif(cinfo);
X break;
X#endif
X#ifdef PPM_SUPPORTED
X case FMT_PPM:
X jselwppm(cinfo);
X break;
X#endif
X#ifdef RLE_SUPPORTED
X case FMT_RLE:
X jselwrle(cinfo);
X break;
X#endif
X#ifdef TARGA_SUPPORTED
X case FMT_TARGA:
X jselwtarga(cinfo);
X break;
X#endif
X default:
X ERREXIT(cinfo->emethods, "Unsupported output file format");
X break;
X }
X}
X
X
X/*
X * Signal catcher to ensure that temporary files are removed before aborting.
X * NB: for Amiga Manx C this is actually a global routine named _abort();
X * see -Dsignal_catcher=_abort in CFLAGS. Talk about bogus...
X */
X
X#ifdef NEED_SIGNAL_CATCHER
X
Xstatic external_methods_ptr emethods; /* for access to free_all */
X
XGLOBAL void
Xsignal_catcher (int signum)
X{
X emethods->trace_level = 0; /* turn off trace output */
X (*emethods->free_all) (); /* clean up memory allocation & temp files */
X exit(EXIT_FAILURE);
X}
X
X#endif
X
X
XLOCAL void
Xusage (char * progname)
X/* complain about bad command line */
X{
X fprintf(stderr, "usage: %s ", progname);
X fprintf(stderr, "[-G] [-P] [-R] [-T] [-b] [-g] [-q colors] [-1] [-D] [-d] [-m mem]");
X#ifdef TWO_FILE_COMMANDLINE
X fprintf(stderr, " inputfile outputfile\n");
X#else
X fprintf(stderr, " [inputfile]\n");
X#endif
X exit(EXIT_FAILURE);
X}
X
X
X/*
X * The main program.
X */
X
XGLOBAL int
Xmain (int argc, char **argv)
X{
X struct decompress_info_struct cinfo;
X struct decompress_methods_struct dc_methods;
X struct external_methods_struct e_methods;
X int c;
X
X /* On Mac, fetch a command line. */
X#ifdef THINK_C
X argc = ccommand(&argv);
X#endif
X
X /* Initialize the system-dependent method pointers. */
X cinfo.methods = &dc_methods;
X cinfo.emethods = &e_methods;
X jselerror(&e_methods); /* error/trace message routines */
X jselmemmgr(&e_methods); /* memory allocation routines */
X dc_methods.d_ui_method_selection = d_ui_method_selection;
X
X /* Now OK to enable signal catcher. */
X#ifdef NEED_SIGNAL_CATCHER
X emethods = &e_methods;
X signal(SIGINT, signal_catcher);
X#ifdef SIGTERM /* not all systems have SIGTERM */
X signal(SIGTERM, signal_catcher);
X#endif
X#endif
X
X /* Set up default JPEG parameters. */
X j_d_defaults(&cinfo, TRUE);
X requested_fmt = DEFAULT_FMT; /* set default output file format */
X
X /* Scan command line options, adjust parameters */
X
X while ((c = egetopt(argc, argv, "GPRTbgq:1Dm:d")) != EOF)
X switch (c) {
X case 'G': /* GIF output format. */
X requested_fmt = FMT_GIF;
X break;
X case 'P': /* PPM output format. */
X requested_fmt = FMT_PPM;
X break;
X case 'R': /* RLE output format. */
X requested_fmt = FMT_RLE;
X break;
X case 'T': /* Targa output format. */
X requested_fmt = FMT_TARGA;
X break;
X case 'b': /* Enable cross-block smoothing. */
X cinfo.do_block_smoothing = TRUE;
X break;
X case 'g': /* Force grayscale output. */
X cinfo.out_color_space = CS_GRAYSCALE;
X break;
X case 'q': /* Do color quantization. */
X { int val;
X if (optarg == NULL)
X usage(argv[0]);
X if (sscanf(optarg, "%d", &val) != 1)
X usage(argv[0]);
X cinfo.desired_number_of_colors = val;
X }
X cinfo.quantize_colors = TRUE;
X break;
X case '1': /* Use fast one-pass quantization. */
X cinfo.two_pass_quantize = FALSE;
X break;
X case 'D': /* Suppress dithering in color quantization. */
X cinfo.use_dithering = FALSE;
X fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n",
X /* Set up to read a JFIF or baseline-JPEG file. */
X /* A smarter UI would inspect the first few bytes of the input file */
X /* to determine its type. */
X#ifdef JFIF_SUPPORTED
X jselrjfif(&cinfo);
X#else
X You shoulda defined JFIF_SUPPORTED. /* deliberate syntax error */
X#endif
X
X /* Do it to it! */
X jpeg_decompress(&cinfo);
X
X /* All done. */
X exit(EXIT_SUCCESS);
X return 0; /* suppress no-return-value warnings */
X}
END_OF_FILE
if test 8658 -ne `wc -c <'jdmain.c'`; then
echo shar: \"'jdmain.c'\" unpacked with wrong size!
fi
# end of 'jdmain.c'
fi
if test -f 'jrdrle.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jrdrle.c'\"
else
echo shar: Extracting \"'jrdrle.c'\" \(11363 characters\)
sed "s/^X//" >'jrdrle.c' <<'END_OF_FILE'
X/*
X * jrdrle.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to read input images in Utah RLE format.
X * The Utah Raster Toolkit library is required (version 3.0).
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume input from
X * an ordinary stdio stream. They further assume that reading begins
X * at the start of the file; input_init may need work if the
X * user interface has already read some data (e.g., to determine that
X * the file is indeed RLE format).
X *
X * These routines are invoked via the methods get_input_row
X * and input_init/term.
X *
X * Based on code contributed by Mike Lijewski.
X */
X
X#include "jinclude.h"
X
X#ifdef RLE_SUPPORTED
X
X/* rle.h is provided by the Utah Raster Toolkit. */
X
X#include <rle.h>
X
X
X/*
X * load_image assumes that JSAMPLE has the same representation as rle_pixel,
X * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples.
X */
X
X#ifndef EIGHT_BIT_SAMPLES
X Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
X#endif
X
X
X/*
X * We support the following types of RLE files:
X *
X * GRAYSCALE - 8 bits, no colormap
X * PSEUDOCOLOR - 8 bits, colormap
X * TRUECOLOR - 24 bits, colormap
X * DIRECTCOLOR - 24 bits, no colormap
X *
X * For now, we ignore any alpha channel in the image.
X */
X
Xtypedef enum { GRAYSCALE, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
X
Xstatic rle_kind visual; /* actual type of input file */
X
X/*
X * Since RLE stores scanlines bottom-to-top, we have to invert the image
X * to conform to JPEG's top-to-bottom order. To do this, we read the
X * incoming image into a virtual array on the first get_input_row call,
X * then fetch the required row from the virtual array on subsequent calls.
X */
X
Xstatic big_sarray_ptr image; /* single array for GRAYSCALE/PSEUDOCOLOR */
Xstatic big_sarray_ptr red_channel; /* three arrays for TRUECOLOR/DIRECTCOLOR */
Xstatic big_sarray_ptr green_channel;
Xstatic big_sarray_ptr blue_channel;
Xstatic long cur_row_number; /* last row# read from virtual array */
X
Xstatic rle_hdr header; /* Input file information */
Xstatic rle_map *colormap; /* RLE colormap, if any */
X
X
X/*
X * Read the file header; return image size and component count.
X */
X
XMETHODDEF void
Xinput_init (compress_info_ptr cinfo)
X{
X long width, height;
X
X /* Use RLE library routine to get the header info */
X header.rle_file = cinfo->input_file;
X switch (rle_get_setup(&header)) {
X case RLE_SUCCESS:
X /* A-OK */
X break;
X case RLE_NOT_RLE:
X ERREXIT(cinfo->emethods, "Not an RLE file");
X break;
X case RLE_NO_SPACE:
X ERREXIT(cinfo->emethods, "Insufficient memory for RLE header");
X break;
X case RLE_EMPTY:
X ERREXIT(cinfo->emethods, "Empty RLE file");
X break;
X case RLE_EOF:
X ERREXIT(cinfo->emethods, "Premature EOF in RLE header");
X break;
X default:
X ERREXIT(cinfo->emethods, "Bogus RLE error code");
X break;
X }
X
X /* Figure out what we have, set private vars and return values accordingly */
X
X width = header.xmax - header.xmin + 1;
X height = header.ymax - header.ymin + 1;
X header.xmin = 0; /* realign horizontally */
X header.xmax = width-1;
X
X cinfo->image_width = width;
X cinfo->image_height = height;
X cinfo->data_precision = 8; /* we can only handle 8 bit data */
X
X if (header.ncolors == 1 && header.ncmap == 0) {
X visual = GRAYSCALE;
X TRACEMS(cinfo->emethods, 1, "Gray-scale RLE file");
X } else if (header.ncolors == 1 && header.ncmap == 3) {
X visual = PSEUDOCOLOR;
X colormap = header.cmap;
X TRACEMS1(cinfo->emethods, 1, "Colormapped RLE file with map of length %d",
X 1 << header.cmaplen);
X } else if (header.ncolors == 3 && header.ncmap == 3) {
X visual = TRUECOLOR;
X colormap = header.cmap;
X TRACEMS1(cinfo->emethods, 1, "Full-color RLE file with map of length %d",
X 1 << header.cmaplen);
X } else if (header.ncolors == 3 && header.ncmap == 0) {
X visual = DIRECTCOLOR;
X TRACEMS(cinfo->emethods, 1, "Full-color RLE file");
X } else
X ERREXIT(cinfo->emethods, "Can't handle this RLE setup");
X
X switch (visual) {
X case GRAYSCALE:
X /* request one big array to hold the grayscale image */
X image = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
X cinfo->in_color_space = CS_GRAYSCALE;
X cinfo->input_components = 1;
X break;
X case PSEUDOCOLOR:
X /* request one big array to hold the pseudocolor image */
X image = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
X cinfo->in_color_space = CS_RGB;
X cinfo->input_components = 3;
X break;
X case TRUECOLOR:
X case DIRECTCOLOR:
X /* request three big arrays to hold the RGB channels */
X red_channel = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
X green_channel = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
X blue_channel = (*cinfo->emethods->request_big_sarray) (width, height, 1L);
X cinfo->in_color_space = CS_RGB;
X cinfo->input_components = 3;
X break;
X }
X
X cinfo->total_passes++; /* count file reading as separate pass */
X}
X
X
X/*
X * Read one row of pixels.
X * These are called only after load_image has read the image into
X * the virtual array(s).
X */
X
X
XMETHODDEF void
Xget_grayscale_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This is used for GRAYSCALE images */
X{
X JSAMPROW inputrows[1]; /* a pseudo JSAMPARRAY structure */
X
X cur_row_number--; /* work down in array */
X
X inputrows[0] = *((*cinfo->emethods->access_big_sarray)
X (image, cur_row_number, FALSE));
X
X jcopy_sample_rows(inputrows, 0, pixel_row, 0, 1, cinfo->image_width);
X}
X
X
XMETHODDEF void
Xget_pseudocolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This is used for PSEUDOCOLOR images */
X{
X long col;
X JSAMPROW image_ptr, ptr0, ptr1, ptr2;
X int val;
X
X cur_row_number--; /* work down in array */
X
X image_ptr = *((*cinfo->emethods->access_big_sarray)
X (image, cur_row_number, FALSE));
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X
X for (col = cinfo->image_width; col > 0; col--) {
X val = GETJSAMPLE(*image_ptr++);
X *ptr0++ = colormap[val ] >> 8;
X *ptr1++ = colormap[val + 256] >> 8;
X *ptr2++ = colormap[val + 512] >> 8;
X }
X}
X
X
XMETHODDEF void
Xget_truecolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This is used for TRUECOLOR images */
X/* The colormap consists of 3 independent lookup tables */
X{
X long col;
X JSAMPROW red_ptr, green_ptr, blue_ptr, ptr0, ptr1, ptr2;
X
X cur_row_number--; /* work down in array */
X
X red_ptr = *((*cinfo->emethods->access_big_sarray)
X (red_channel, cur_row_number, FALSE));
X green_ptr = *((*cinfo->emethods->access_big_sarray)
X (green_channel, cur_row_number, FALSE));
X blue_ptr = *((*cinfo->emethods->access_big_sarray)
X (blue_channel, cur_row_number, FALSE));
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X
X for (col = cinfo->image_width; col > 0; col--) {
X *ptr0++ = colormap[GETJSAMPLE(*red_ptr++) ] >> 8;
X *ptr1++ = colormap[GETJSAMPLE(*green_ptr++) + 256] >> 8;
X *ptr2++ = colormap[GETJSAMPLE(*blue_ptr++) + 512] >> 8;
X }
X}
X
X
XMETHODDEF void
Xget_directcolor_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X/* This is used for DIRECTCOLOR images */
X{
X JSAMPROW inputrows[3]; /* a pseudo JSAMPARRAY structure */
X
X cur_row_number--; /* work down in array */
X
X inputrows[0] = *((*cinfo->emethods->access_big_sarray)
X (red_channel, cur_row_number, FALSE));
X inputrows[1] = *((*cinfo->emethods->access_big_sarray)
X (green_channel, cur_row_number, FALSE));
X inputrows[2] = *((*cinfo->emethods->access_big_sarray)
X (blue_channel, cur_row_number, FALSE));
X
X jcopy_sample_rows(inputrows, 0, pixel_row, 0, 3, cinfo->image_width);
X}
X
X
X/*
X * Load the color channels into separate arrays. We have to do
X * this because RLE files start at the lower left while the JPEG standard
X * has them starting in the upper left. This is called the first time
X * we want to get a row of input. What we do is load the RLE data into
X * big arrays and then call the appropriate routine to read one row from
X * the big arrays. We also change cinfo->methods->get_input_row so that
X * subsequent calls go straight to the row-reading routine.
X */
X
XMETHODDEF void
Xload_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X long row;
X rle_pixel *rle_row[3];
X
X /* Read the RLE data into our virtual array(s).
X * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
X * and (b) we are not on a machine where FAR pointers differ from regular.
X */
X RLE_CLR_BIT(header, RLE_ALPHA); /* don't read the alpha channel */
X
X switch (visual) {
X case GRAYSCALE:
X case PSEUDOCOLOR:
X for (row = 0; row < cinfo->image_height; row++) {
X (*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
X /*
X * Read a row of the image directly into our big array.
X * Too bad this doesn't seem to return any indication of errors :-(.
X */
X rle_row[0] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
X (image, row, TRUE));
X rle_getrow(&header, rle_row);
X }
X break;
X case TRUECOLOR:
X case DIRECTCOLOR:
X for (row = 0; row < cinfo->image_height; row++) {
X (*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
X /*
X * Read a row of the image directly into our big arrays.
X * Too bad this doesn't seem to return any indication of errors :-(.
X */
X rle_row[0] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
X (red_channel, row, TRUE));
X rle_row[1] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
X (green_channel, row, TRUE));
X rle_row[2] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
X (blue_channel, row, TRUE));
X rle_getrow(&header, rle_row);
X }
X break;
X }
X cinfo->completed_passes++;
X
X /* Set up to call proper row-extraction routine in future */
X switch (visual) {
X case GRAYSCALE:
X cinfo->methods->get_input_row = get_grayscale_row;
X break;
X case PSEUDOCOLOR:
X cinfo->methods->get_input_row = get_pseudocolor_row;
X break;
X case TRUECOLOR:
X cinfo->methods->get_input_row = get_truecolor_row;
X break;
X case DIRECTCOLOR:
X cinfo->methods->get_input_row = get_directcolor_row;
X break;
X }
X
X /* And fetch the topmost (bottommost) row */
X cur_row_number = cinfo->image_height;
X (*cinfo->methods->get_input_row) (cinfo, pixel_row);
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xinput_term (compress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for RLE format input.
X * Note that this must be called by the user interface before calling
X * jpeg_compress. If multiple input formats are supported, the
X * user interface is responsible for discovering the file format and
X * calling the appropriate method selection routine.
X */
X
XGLOBAL void
Xjselrrle (compress_info_ptr cinfo)
X{
X cinfo->methods->input_init = input_init;
X cinfo->methods->get_input_row = load_image; /* until first call */
X cinfo->methods->input_term = input_term;
X}
X
X#endif /* RLE_SUPPORTED */
END_OF_FILE
if test 11363 -ne `wc -c <'jrdrle.c'`; then
echo shar: \"'jrdrle.c'\" unpacked with wrong size!
fi
# end of 'jrdrle.c'
fi
echo shar: End of archive 13 \(of 18\).
cp /dev/null ark13isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: egetopt.c jdhuff.c jfwddct.c jinclude.h jmemdosa.asm
# jmemname.c jrevdct.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:53 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 14 (of 18)."'
if test -f 'egetopt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'egetopt.c'\"
else
echo shar: Extracting \"'egetopt.c'\" \(7226 characters\)
sed "s/^X//" >'egetopt.c' <<'END_OF_FILE'
X/*
X * egetopt.c -- Extended 'getopt'.
X *
X * A while back, a public-domain version of getopt() was posted to the
X * net. A bit later, a gentleman by the name of Keith Bostic made some
X * enhancements and reposted it.
X *
X * In recent weeks (i.e., early-to-mid 1988) there's been some
X * heated discussion in comp.lang.c about the merits and drawbacks
X * of getopt(), especially with regard to its handling of '?'.
X *
X * In light of this, I have taken Mr. Bostic's public-domain getopt()
X * and have made some changes that I hope will be considered to be
X * improvements. I call this routine 'egetopt' ("Extended getopt").
X * The default behavior of this routine is the same as that of getopt(),
X * but it has some optional features that make it more useful. These
X * options are controlled by the settings of some global variables.
X * By not setting any of these extra global variables, you will have
X * the same functionality as getopt(), which should satisfy those
X * purists who believe getopt() is perfect and can never be improved.
X * If, on the other hand, you are someone who isn't satisfied with the
X * status quo, egetopt() may very well give you the added capabilities
X * you want.
X *
X * Look at the enclosed README file for a description of egetopt()'s
X * new features.
X *
X * The code was originally posted to the net as getopt.c by ...
X *
X * Keith Bostic
X * ARPA: keith@seismo
X * UUCP: seismo!keith
X *
X * Current version: added enhancements and comments, reformatted code.
X *
X * Lloyd Zusman
X * Master Byte Software
X * Los Gatos, California
X * Internet: l...@fx.com
X * UUCP: ...!ames!fxgrp!ljz
X *
X * May, 1988
X *
X * Modified for use in free JPEG code:
X *
X * Ed Hanway
X * UUCP: uunet!sisd!jeh
X *
X * October, 1991
X */
X
X/* The original egetopt.c was written not to need stdio.h.
X * For the JPEG code this is an unnecessary and unportable assumption.
X * Also, we make all the variables and routines "static" to avoid
X * possible conflicts with a system-library version of getopt.
X *
X * In the JPEG code, this file is compiled by #including it in jcmain.c
X * or jdmain.c. Since ANSI2KNR does not process include files, we can't
X * rely on it to convert function definitions to K&R style. Hence we
X * provide both styles of function header with an explicit #ifdef PROTO (ick).
X */
X
X#define GVAR static /* make empty to export these variables */
X
X/*
X * None of these constants are referenced in the executable portion of
X * the code ... their sole purpose is to initialize global variables.
X */
X#define BADCH (int)'?'
X#define NEEDSEP (int)':'
X#define MAYBESEP (int)'\0'
X#define EMSG ""
X#define START "-"
X
X/*
X * Here are all the pertinent global variables.
X */
XGVAR int opterr = 1; /* if true, output error message */
XGVAR int optind = 1; /* index into parent argv vector */
XGVAR int optopt; /* character checked for validity */
XGVAR int optbad = BADCH; /* character returned on error */
XGVAR int optchar = 0; /* character that begins returned option */
XGVAR int optneed = NEEDSEP; /* flag for mandatory argument */
XGVAR int optmaybe = MAYBESEP; /* flag for optional argument */
XGVAR const char *optarg; /* argument associated with option */
XGVAR const char *optstart = START; /* list of characters that start options */
X
X
X/*
X * Macros.
X */
X
X/*
X * Conditionally print out an error message and return (depends on the
X * setting of 'opterr').
X */
X#define TELL(S) { \
X if (opterr) \
X fprintf(stderr, "%s%s%c\n", *nargv, (S), optopt); \
X return (optbad); \
X}
X
X/*
X * This works similarly to index() and strchr(). I include it so that you
X * don't need to be concerned as to which one your system has.
X */
X
X#ifdef PROTO
XLOCAL const char *
X_sindex (const char *string, int ch)
X#else
XLOCAL const char *
X_sindex (string, ch)
X const char *string;
X int ch;
X#endif
X{
X if (string != NULL) {
X for (; *string != '\0'; ++string) {
X if (*string == (char)ch) {
X return (string);
X }
X }
X }
X
X return (NULL);
X}
X
X/*
X * Here it is:
X */
X
X#ifdef PROTO
XLOCAL int
Xegetopt (int nargc, char **nargv, const char *ostr)
X#else
XLOCAL int
Xegetopt (nargc, nargv, ostr)
X int nargc;
X char **nargv;
X const char *ostr;
X#endif
X{
X static const char *place = EMSG; /* option letter processing */
X register const char *oli; /* option letter list index */
X register const char *osi = NULL; /* option start list index */
X
X if (nargv == (char **)NULL) {
X return (EOF);
X }
X
X if (nargc <= optind || nargv[optind] == NULL) {
X return (EOF);
X }
X
X if (place == NULL) {
X place = EMSG;
X }
X
X /*
X * Update scanning pointer.
X */
X if (*place == '\0') {
X place = nargv[optind];
X if (place == NULL) {
X return (EOF);
X }
X osi = _sindex(optstart, *place);
X if (osi != NULL) {
X optchar = (int)*osi;
X }
X if (optind >= nargc || osi == NULL || *++place == '\0') {
X return (EOF);
X }
X
X /*
X * Two adjacent, identical flag characters were found.
X * This takes care of "--", for example.
X */
X if (*place == place[-1]) {
X ++optind;
X return (EOF);
X }
X }
X
X /*
X * If the option is a separator or the option isn't in the list,
X * we've got an error.
X */
X optopt = (int)*place++;
X oli = _sindex(ostr, optopt);
X if (optopt == optneed || optopt == optmaybe || oli == NULL) {
X /*
X * If we're at the end of the current argument, bump the
X * argument index.
X */
X if (*place == '\0') {
X ++optind;
X }
X TELL(": illegal option -- "); /* byebye */
X }
X
X /*
X * If there is no argument indicator, then we don't even try to
X * return an argument.
X */
X ++oli;
X if (*oli == '\0' || (*oli != optneed && *oli != optmaybe)) {
X /*
X * If we're at the end of the current argument, bump the
X * argument index.
X */
X if (*place == '\0') {
X ++optind;
X }
X optarg = NULL;
X }
X /*
X * If we're here, there's an argument indicator. It's handled
X * differently depending on whether it's a mandatory or an
X * optional argument.
X */
X else {
X /*
X * If there's no white space, use the rest of the
X * string as the argument. In this case, it doesn't
X * matter if the argument is mandatory or optional.
X */
X if (*place != '\0') {
X optarg = place;
X }
X /*
X * If we're here, there's whitespace after the option.
X *
X * Is it a mandatory argument? If so, return the
X * next command-line argument if there is one.
X */
X else if (*oli == optneed) {
X /*
X * If we're at the end of the argument list, there
X * isn't an argument and hence we have an error.
X * Otherwise, make 'optarg' point to the argument.
X */
X if (nargc <= ++optind) {
X place = EMSG;
X TELL(": option requires an argument -- ");
X }
X else {
X optarg = nargv[optind];
X }
X }
X /*
X * If we're here it must have been an optional argument.
X */
X else {
X if (nargc <= ++optind) {
X place = EMSG;
X optarg = NULL;
X }
X else {
X optarg = nargv[optind];
X if (optarg == NULL) {
X place = EMSG;
X }
X /*
X * If the next item begins with a flag
X * character, we treat it like a new
X * argument. This is accomplished by
X * decrementing 'optind' and returning
X * a null argument.
X */
X else if (_sindex(optstart, *optarg) != NULL) {
X --optind;
X optarg = NULL;
X }
X }
X }
X place = EMSG;
X ++optind;
X }
X
X /*
X * Return option letter.
X */
X return (optopt);
X}
END_OF_FILE
if test 7226 -ne `wc -c <'egetopt.c'`; then
echo shar: \"'egetopt.c'\" unpacked with wrong size!
fi
# end of 'egetopt.c'
fi
if test -f 'jdhuff.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdhuff.c'\"
else
echo shar: Extracting \"'jdhuff.c'\" \(7712 characters\)
sed "s/^X//" >'jdhuff.c' <<'END_OF_FILE'
X/*
X * jdhuff.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains Huffman entropy decoding routines.
X * These routines are invoked via the methods entropy_decode
X * and entropy_decoder_init/term.
X */
X
X#include "jinclude.h"
X
X
X/* Static variables to avoid passing 'round extra parameters */
X
Xstatic decompress_info_ptr dcinfo;
X
Xstatic INT32 get_buffer; /* current bit-extraction buffer */
Xstatic int bits_left; /* # of unused bits in it */
X
X
XLOCAL void
Xfix_huff_tbl (HUFF_TBL * htbl)
X/* Compute derived values for a Huffman table */
X{
X int p, i, l, si;
X char huffsize[257];
X UINT16 huffcode[257];
X UINT16 code;
X
X /* Figure C.1: make table of Huffman code length for each symbol */
X /* Note that this is in code-length order. */
X
X p = 0;
X for (l = 1; l <= 16; l++) {
X for (i = 1; i <= (int) htbl->bits[l]; i++)
X huffsize[p++] = (char) l;
X }
X huffsize[p] = 0;
X
X /* Figure C.2: generate the codes themselves */
X /* Note that this is in code-length order. */
X
X code = 0;
X si = huffsize[0];
X p = 0;
X while (huffsize[p]) {
X while (((int) huffsize[p]) == si) {
X huffcode[p++] = code;
X code++;
X }
X code <<= 1;
X si++;
X }
X
X /* We don't bother to fill in the encoding tables ehufco[] and ehufsi[], */
X /* since they are not used for decoding. */
X
X /* Figure F.15: generate decoding tables */
X
X p = 0;
X for (l = 1; l <= 16; l++) {
X if (htbl->bits[l]) {
X htbl->valptr[l] = p; /* huffval[] index of 1st sym of code len l */
X htbl->mincode[l] = huffcode[p]; /* minimum code of length l */
X p += htbl->bits[l];
X htbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
X } else {
X htbl->maxcode[l] = -1;
X }
X }
X htbl->maxcode[17] = 0xFFFFFL; /* ensures huff_DECODE terminates */
X}
X
X
X/* Extract the next N bits from the input stream (N <= 15) */
X
XLOCAL int
Xget_bits (int nbits)
X{
X int result;
X
X while (nbits > bits_left) {
X int c = JGETC(dcinfo);
X
X get_buffer <<= 8;
X get_buffer |= c;
X bits_left += 8;
X /* If it's 0xFF, check and discard stuffed zero byte */
X if (c == 0xff) {
X c = JGETC(dcinfo); /* Byte stuffing */
X if (c != 0)
X ERREXIT1(dcinfo->emethods,
X "Unexpected marker 0x%02x in compressed data", c);
X }
X }
X
X bits_left -= nbits;
X result = ((int) (get_buffer >> bits_left)) & ((1 << nbits) - 1);
X return result;
X}
X
X/* Macro to make things go at some speed! */
X
X#define get_bit() (bits_left ? \
X ((int) (get_buffer >> (--bits_left))) & 1 : \
X get_bits(1))
X
X
X/* Figure F.16: extract next coded symbol from input stream */
X
XLOCAL int
Xhuff_DECODE (HUFF_TBL * htbl)
X{
X int l, p;
X INT32 code;
X
X code = get_bit();
X l = 1;
X while (code > htbl->maxcode[l]) {
X code = (code << 1) + get_bit();
X l++;
X }
X
X /* With garbage input we may reach the sentinel value l = 17. */
X
X if (l > 16) {
X ERREXIT(dcinfo->emethods, "Corrupted data in JPEG file");
X }
X
X p = (int) (htbl->valptr[l] + (code - htbl->mincode[l]));
X
X return (int) htbl->huffval[p];
X}
X
X
X/* Figure F.12: extend sign bit */
X
X/* NB: on some compilers this will only work for s > 0 */
X
X#define huff_EXTEND(x, s) ((x) < (1 << ((s)-1)) ? \
X (x) + (-1 << (s)) + 1 : \
X (x))
X
X
X/* Decode a single block's worth of coefficients */
X/* Note that only the difference is returned for the DC coefficient */
X
XLOCAL void
Xdecode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
X{
X int s, k, r, n;
X
X /* zero out the coefficient block */
X
X MEMZERO((void *) block, SIZEOF(JBLOCK));
X
X /* Section F.2.2.1: decode the DC coefficient difference */
X
X s = huff_DECODE(dctbl);
X if (s) {
X r = get_bits(s);
X s = huff_EXTEND(r, s);
X }
X block[0] = s;
X
X /* Section F.2.2.2: decode the AC coefficients */
X
X for (k = 1; k < DCTSIZE2; k++) {
X r = huff_DECODE(actbl);
X
X s = r & 15;
X n = r >> 4;
X
X if (s) {
X k += n;
X r = get_bits(s);
X block[k] = huff_EXTEND(r, s);
X } else {
X if (n != 15)
X break;
X k += 15;
X }
X }
X}
X
X
X/*
X * Initialize for a Huffman-compressed scan.
X * This is invoked after reading the SOS marker.
X */
X
XMETHODDEF void
Xhuff_decoder_init (decompress_info_ptr cinfo)
X{
X short ci;
X jpeg_component_info * compptr;
X
X /* Initialize static variables */
X dcinfo = cinfo;
X bits_left = 0;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X /* Make sure requested tables are present */
X if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
X ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
X /* Compute derived values for Huffman tables */
X /* We may do this more than once for same table, but it's not a big deal */
X fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
X fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
X /* Initialize DC predictions to 0 */
X cinfo->last_dc_val[ci] = 0;
X }
X
X /* Initialize restart stuff */
X cinfo->restarts_to_go = cinfo->restart_interval;
X cinfo->next_restart_num = 0;
X}
X
X
X/*
X * Check for a restart marker & resynchronize decoder.
X */
X
XLOCAL void
Xprocess_restart (decompress_info_ptr cinfo)
X{
X int c, nbytes;
X short ci;
X
X /* Throw away any partial unread byte */
X bits_left = 0;
X
X /* Scan for next JPEG marker */
X nbytes = 0;
X do {
X do { /* skip any non-FF bytes */
X nbytes++;
X c = JGETC(cinfo);
X } while (c != 0xFF);
X do { /* skip any duplicate FFs */
X nbytes++;
X c = JGETC(cinfo);
X } while (c == 0xFF);
X } while (c == 0); /* repeat if it was a stuffed FF/00 */
X
X if (c != (RST0 + cinfo->next_restart_num))
X ERREXIT2(cinfo->emethods, "Found 0x%02x marker instead of RST%d",
X c, cinfo->next_restart_num);
X
X if (nbytes != 2)
X TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before RST%d",
X nbytes-2, cinfo->next_restart_num);
X else
X TRACEMS1(cinfo->emethods, 2, "RST%d", cinfo->next_restart_num);
X
X /* Re-initialize DC predictions to 0 */
X for (ci = 0; ci < cinfo->comps_in_scan; ci++)
X cinfo->last_dc_val[ci] = 0;
X
X /* Update restart state */
X cinfo->restarts_to_go = cinfo->restart_interval;
X cinfo->next_restart_num++;
X cinfo->next_restart_num &= 7;
X}
X
X
X/*
X * Decode and return one MCU's worth of Huffman-compressed coefficients.
X */
X
XMETHODDEF void
Xhuff_decode (decompress_info_ptr cinfo, JBLOCK *MCU_data)
X{
X short blkn, ci;
X jpeg_component_info * compptr;
X
X /* Account for restart interval, process restart marker if needed */
X if (cinfo->restart_interval) {
X if (cinfo->restarts_to_go == 0)
X process_restart(cinfo);
X cinfo->restarts_to_go--;
X }
X
X for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
X ci = cinfo->MCU_membership[blkn];
X compptr = cinfo->cur_comp_info[ci];
X decode_one_block(MCU_data[blkn],
X cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no],
X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
X /* Convert DC difference to actual value, update last_dc_val */
X MCU_data[blkn][0] += cinfo->last_dc_val[ci];
X cinfo->last_dc_val[ci] = MCU_data[blkn][0];
X }
X}
X
X
X/*
X * Finish up at the end of a Huffman-compressed scan.
X */
X
XMETHODDEF void
Xhuff_decoder_term (decompress_info_ptr cinfo)
X{
X /* No work needed */
X}
X
X
X/*
X * The method selection routine for Huffman entropy decoding.
X */
X
XGLOBAL void
Xjseldhuffman (decompress_info_ptr cinfo)
X{
X if (! cinfo->arith_code) {
X cinfo->methods->entropy_decoder_init = huff_decoder_init;
X cinfo->methods->entropy_decode = huff_decode;
X cinfo->methods->entropy_decoder_term = huff_decoder_term;
X }
X}
END_OF_FILE
if test 7712 -ne `wc -c <'jdhuff.c'`; then
echo shar: \"'jdhuff.c'\" unpacked with wrong size!
fi
# end of 'jdhuff.c'
fi
if test -f 'jfwddct.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jfwddct.c'\"
else
echo shar: Extracting \"'jfwddct.c'\" \(7246 characters\)
sed "s/^X//" >'jfwddct.c' <<'END_OF_FILE'
X/*
X * jfwddct.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains the basic DCT (Discrete Cosine Transform)
X * transformation subroutine.
X *
X * This implementation is based on Appendix A.2 of the book
X * "Discrete Cosine Transform---Algorithms, Advantages, Applications"
X * by K.R. Rao and P. Yip (Academic Press, Inc, London, 1990).
X * It uses scaled fixed-point arithmetic instead of floating point.
X */
X
X#include "jinclude.h"
X
X/*
X * This routine is specialized to the case DCTSIZE = 8.
X */
X
X#if DCTSIZE != 8
X Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
X#endif
X
X
X/* The poop on this scaling stuff is as follows:
X *
X * We have to do addition and subtraction of the integer inputs, which
X * is no problem, and multiplication by fractional constants, which is
X * a problem to do in integer arithmetic. We multiply all the constants
X * by DCT_SCALE and convert them to integer constants (thus retaining
X * LG2_DCT_SCALE bits of precision in the constants). After doing a
X * multiplication we have to divide the product by DCT_SCALE, with proper
X * rounding, to produce the correct output. The division can be implemented
X * cheaply as a right shift of LG2_DCT_SCALE bits. The DCT equations also
X * specify an additional division by 2 on the final outputs; this can be
X * folded into the right-shift by shifting one more bit (see UNFIXH).
X *
X * If you are planning to recode this in assembler, you might want to set
X * LG2_DCT_SCALE to 15. This loses a bit of precision, but then all the
X * multiplications are between 16-bit quantities (given 8-bit JSAMPLEs!)
X * so you could use a signed 16x16=>32 bit multiply instruction instead of
X * full 32x32 multiply. Unfortunately there's no way to describe such a
X * multiply portably in C, so we've gone for the extra bit of accuracy here.
X */
X
X#ifdef EIGHT_BIT_SAMPLES
X#define LG2_DCT_SCALE 16
X#else
X#define LG2_DCT_SCALE 15 /* lose a little precision to avoid overflow */
X#endif
X
X#define ONE ((INT32) 1)
X
X#define DCT_SCALE (ONE << LG2_DCT_SCALE)
X
X/* In some places we shift the inputs left by a couple more bits, */
X/* so that they can be added to fractional results without too much */
X/* loss of precision. */
X#define LG2_OVERSCALE 2
X#define OVERSCALE (ONE << LG2_OVERSCALE)
X#define OVERSHIFT(x) ((x) <<= LG2_OVERSCALE)
X
X/* Scale a fractional constant by DCT_SCALE */
X#define FIX(x) ((INT32) ((x) * DCT_SCALE + 0.5))
X
X/* Scale a fractional constant by DCT_SCALE/OVERSCALE */
X/* Such a constant can be multiplied with an overscaled input */
X/* to produce something that's scaled by DCT_SCALE */
X#define FIXO(x) ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5))
X
X/* Descale and correctly round a value that's scaled by DCT_SCALE */
X#define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
X
X/* Same with an additional division by 2, ie, correctly rounded UNFIX(x/2) */
X#define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
X
X/* Take a value scaled by DCT_SCALE and round to integer scaled by OVERSCALE */
X#define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)),\
X LG2_DCT_SCALE-LG2_OVERSCALE)
X
X/* Here are the constants we need */
X/* SIN_i_j is sine of i*pi/j, scaled by DCT_SCALE */
X/* COS_i_j is cosine of i*pi/j, scaled by DCT_SCALE */
X
X#define SIN_1_4 FIX(0.707106781)
X#define COS_1_4 SIN_1_4
X
X#define SIN_1_8 FIX(0.382683432)
X#define COS_1_8 FIX(0.923879533)
X#define SIN_3_8 COS_1_8
X#define COS_3_8 SIN_1_8
X
X#define SIN_1_16 FIX(0.195090322)
X#define COS_1_16 FIX(0.980785280)
X#define SIN_7_16 COS_1_16
X#define COS_7_16 SIN_1_16
X
X#define SIN_3_16 FIX(0.555570233)
X#define COS_3_16 FIX(0.831469612)
X#define SIN_5_16 COS_3_16
X#define COS_5_16 SIN_3_16
X
X/* OSIN_i_j is sine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
X/* OCOS_i_j is cosine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
X
X#define OSIN_1_4 FIXO(0.707106781)
X#define OCOS_1_4 OSIN_1_4
X
X#define OSIN_1_8 FIXO(0.382683432)
X#define OCOS_1_8 FIXO(0.923879533)
X#define OSIN_3_8 OCOS_1_8
X#define OCOS_3_8 OSIN_1_8
X
X#define OSIN_1_16 FIXO(0.195090322)
X#define OCOS_1_16 FIXO(0.980785280)
X#define OSIN_7_16 OCOS_1_16
X#define OCOS_7_16 OSIN_1_16
X
X#define OSIN_3_16 FIXO(0.555570233)
X#define OCOS_3_16 FIXO(0.831469612)
X#define OSIN_5_16 OCOS_3_16
X#define OCOS_5_16 OSIN_3_16
X
X
X/*
X * Perform the forward DCT on one block of samples.
X *
X * A 2-D DCT can be done by 1-D DCT on each row
X * followed by 1-D DCT on each column.
X */
X
XGLOBAL void
Xj_fwd_dct (DCTBLOCK data)
X{
X int pass, rowctr;
X register DCTELEM *inptr, *outptr;
X DCTBLOCK workspace;
X
X /* Each iteration of the inner loop performs one 8-point 1-D DCT.
X * It reads from a *row* of the input matrix and stores into a *column*
X * of the output matrix. In the first pass, we read from the data[] array
X * and store into the local workspace[]. In the second pass, we read from
X * the workspace[] array and store into data[], thus performing the
X * equivalent of a columnar DCT pass with no variable array indexing.
X */
X
X inptr = data; /* initialize pointers for first pass */
X outptr = workspace;
X for (pass = 1; pass >= 0; pass--) {
X for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
X /* many tmps have nonoverlapping lifetime -- flashy register colourers
X * should be able to do this lot very well
X */
X INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
X INT32 tmp10, tmp11, tmp12, tmp13;
X INT32 tmp14, tmp15, tmp16, tmp17;
X INT32 tmp25, tmp26;
X SHIFT_TEMPS
X
X tmp0 = inptr[7] + inptr[0];
X tmp1 = inptr[6] + inptr[1];
X tmp2 = inptr[5] + inptr[2];
X tmp3 = inptr[4] + inptr[3];
X tmp4 = inptr[3] - inptr[4];
X tmp5 = inptr[2] - inptr[5];
X tmp6 = inptr[1] - inptr[6];
X tmp7 = inptr[0] - inptr[7];
X
X tmp10 = tmp3 + tmp0;
X tmp11 = tmp2 + tmp1;
X tmp12 = tmp1 - tmp2;
X tmp13 = tmp0 - tmp3;
X
X outptr[ 0] = (DCTELEM) UNFIXH((tmp10 + tmp11) * SIN_1_4);
X outptr[DCTSIZE*4] = (DCTELEM) UNFIXH((tmp10 - tmp11) * COS_1_4);
X
X outptr[DCTSIZE*2] = (DCTELEM) UNFIXH(tmp13*COS_1_8 + tmp12*SIN_1_8);
X outptr[DCTSIZE*6] = (DCTELEM) UNFIXH(tmp13*SIN_1_8 - tmp12*COS_1_8);
X
X tmp16 = UNFIXO((tmp6 + tmp5) * SIN_1_4);
X tmp15 = UNFIXO((tmp6 - tmp5) * COS_1_4);
X
X OVERSHIFT(tmp4);
X OVERSHIFT(tmp7);
X
X /* tmp4, tmp7, tmp15, tmp16 are overscaled by OVERSCALE */
X
X tmp14 = tmp4 + tmp15;
X tmp25 = tmp4 - tmp15;
X tmp26 = tmp7 - tmp16;
X tmp17 = tmp7 + tmp16;
X
X outptr[DCTSIZE ] = (DCTELEM) UNFIXH(tmp17*OCOS_1_16 + tmp14*OSIN_1_16);
X outptr[DCTSIZE*7] = (DCTELEM) UNFIXH(tmp17*OCOS_7_16 - tmp14*OSIN_7_16);
X outptr[DCTSIZE*5] = (DCTELEM) UNFIXH(tmp26*OCOS_5_16 + tmp25*OSIN_5_16);
X outptr[DCTSIZE*3] = (DCTELEM) UNFIXH(tmp26*OCOS_3_16 - tmp25*OSIN_3_16);
X
X inptr += DCTSIZE; /* advance inptr to next row */
X outptr++; /* advance outptr to next column */
X }
X /* end of pass; in case it was pass 1, set up for pass 2 */
X inptr = workspace;
X outptr = data;
X }
X}
END_OF_FILE
if test 7246 -ne `wc -c <'jfwddct.c'`; then
echo shar: \"'jfwddct.c'\" unpacked with wrong size!
fi
# end of 'jfwddct.c'
fi
if test -f 'jinclude.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jinclude.h'\"
else
echo shar: Extracting \"'jinclude.h'\" \(3579 characters\)
sed "s/^X//" >'jinclude.h' <<'END_OF_FILE'
X/*
X * jinclude.h
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This is the central file that's #include'd by all the JPEG .c files.
X * Its purpose is to provide a single place to fix any problems with
X * including the wrong system include files.
X * You can edit these declarations if you use a system with nonstandard
X * system include files.
X */
X
X
X/*
X * Normally the __STDC__ macro can be taken as indicating that the system
X * include files conform to the ANSI C standard. However, if you are running
X * GCC on a machine with non-ANSI system include files, that is not the case.
X * In that case change the following, or add -DNONANSI_INCLUDES to your CFLAGS.
X */
X
X#ifdef __STDC__
X#ifndef NONANSI_INCLUDES
X#define INCLUDES_ARE_ANSI /* this is what's tested before including */
X#endif
X#endif
X
X/*
X * <stdio.h> is included to get the FILE typedef and NULL macro.
X * Note that the core portable-JPEG files do not actually do any I/O
X * using the stdio library; only the user interface, error handler,
X * and file reading/writing modules invoke any stdio functions.
X * (Well, we did cheat a bit in jmemmgr.c, but only if MEM_STATS is defined.)
X */
X
X#include <stdio.h>
X
X/*
X * We need the size_t typedef, which defines the parameter type of malloc().
X * In an ANSI-conforming implementation this is provided by <stdio.h>,
X * but on non-ANSI systems it's more likely to be in <sys/types.h>.
X * On some not-quite-ANSI systems you may find it in <stddef.h>.
X */
X
X#ifndef INCLUDES_ARE_ANSI /* shouldn't need this if ANSI C */
X#include <sys/types.h>
X#endif
X#ifdef __SASC /* Amiga SAS C provides it in stddef.h. */
X#include <stddef.h>
X#endif
X
X/*
X * In ANSI C, and indeed any rational implementation, size_t is also the
X * type returned by sizeof(). However, it seems there are some irrational
X * implementations out there, in which sizeof() returns an int even though
X * size_t is defined as long or unsigned long. To ensure consistent results
X * we always use this SIZEOF() macro in place of using sizeof() directly.
X */
X
X#undef SIZEOF /* in case you included X11/xmd.h */
X#define SIZEOF(object) ((size_t) sizeof(object))
X
X/*
X * fread() and fwrite() are always invoked through these macros.
X * On some systems you may need to twiddle the argument casts.
X * CAUTION: argument order is different from underlying functions!
X */
X
X#define JFREAD(file,buf,sizeofbuf) \
X ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
X#define JFWRITE(file,buf,sizeofbuf) \
X ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
X
X/*
X * We need the memcpy() and strcmp() functions, plus memory zeroing.
X * ANSI and System V implementations declare these in <string.h>.
X * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
X * NOTE: we assume the size parameters to these functions are of type size_t.
X * Insert casts in these macros if not!
X */
X
X#ifdef INCLUDES_ARE_ANSI
X#include <string.h>
X#define MEMZERO(voidptr,size) memset((voidptr), 0, (size))
X#else /* not ANSI */
X#ifdef BSD
X#include <strings.h>
X#define MEMZERO(voidptr,size) bzero((voidptr), (size))
X#define memcpy(dest,src,size) bcopy((src), (dest), (size))
X#else /* not BSD, assume Sys V or compatible */
X#include <string.h>
X#define MEMZERO(voidptr,size) memset((voidptr), 0, (size))
X#endif /* BSD */
X#endif /* ANSI */
X
X
X/* Now include the portable JPEG definition files. */
X
X#include "jconfig.h"
X
X#include "jpegdata.h"
END_OF_FILE
if test 3579 -ne `wc -c <'jinclude.h'`; then
echo shar: \"'jinclude.h'\" unpacked with wrong size!
fi
# end of 'jinclude.h'
fi
if test -f 'jmemdosa.asm' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemdosa.asm'\"
else
echo shar: Extracting \"'jmemdosa.asm'\" \(8314 characters\)
sed "s/^X//" >'jmemdosa.asm' <<'END_OF_FILE'
X;
X; jmemdosa.asm
X;
X; Copyright (C) 1992, Thomas G. Lane.
X; This file is part of the Independent JPEG Group's software.
X; For conditions of distribution and use, see the accompanying README file.
X;
X; This file contains low-level interface routines to support the MS-DOS
X; backing store manager (jmemdos.c). Routines are provided to access disk
X; files through direct DOS calls, and to access XMS and EMS drivers.
X;
X; This file should assemble with Microsoft's MASM or any compatible
X; assembler (including Borland's Turbo Assembler). If you haven't got
X; a compatible assembler, better fall back to jmemansi.c or jmemname.c.
X;
X; To minimize dependence on the C compiler's register usage conventions,
X; we save and restore all 8086 registers, even though most compilers only
X; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return
X; values, which everybody returns in AX.
X;
X; Based on code contributed by Ge' Weijers.
X;
X
XJMEMDOSA_TXT segment byte public 'CODE'
X
X assume cs:JMEMDOSA_TXT
X
X public _jdos_open
X public _jdos_close
X public _jdos_seek
X public _jdos_read
X public _jdos_write
X public _jxms_getdriver
X public _jxms_calldriver
X public _jems_available
X public _jems_calldriver
X
X;
X; short far jdos_open (short far * handle, char far * filename)
X;
X; Create and open a temporary file
X;
X_jdos_open proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X mov cx,0 ; normal file attributes
X lds dx,dword ptr [bp+10] ; get filename pointer
X mov ah,3ch ; create file
X int 21h
X jc open_err ; if failed, return error code
X lds bx,dword ptr [bp+6] ; get handle pointer
X mov word ptr [bx],ax ; save the handle
X xor ax,ax ; return zero for OK
Xopen_err: pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jdos_open endp
X
X
X;
X; short far jdos_close (short handle)
X;
X; Close the file handle
X;
X_jdos_close proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X mov bx,word ptr [bp+6] ; file handle
X mov ah,3eh ; close file
X int 21h
X jc close_err ; if failed, return error code
X xor ax,ax ; return zero for OK
Xclose_err: pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jdos_close endp
X
X
X;
X; short far jdos_seek (short handle, long offset)
X;
X; Set file position
X;
X_jdos_seek proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X mov bx,word ptr [bp+6] ; file handle
X mov dx,word ptr [bp+8] ; LS offset
X mov cx,word ptr [bp+10] ; MS offset
X mov ax,4200h ; absolute seek
X int 21h
X jc seek_err ; if failed, return error code
X xor ax,ax ; return zero for OK
Xseek_err: pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jdos_seek endp
X
X
X;
X; short far jdos_read (short handle, void far * buffer, unsigned short count)
X;
X; Read from file
X;
X_jdos_read proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X mov bx,word ptr [bp+6] ; file handle
X lds dx,dword ptr [bp+8] ; buffer address
X mov cx,word ptr [bp+12] ; number of bytes
X mov ah,3fh ; read file
X int 21h
X jc read_err ; if failed, return error code
X cmp ax,word ptr [bp+12] ; make sure all bytes were read
X je read_ok
X mov ax,1 ; else return 1 for not OK
X jmp short read_err
Xread_ok: xor ax,ax ; return zero for OK
Xread_err: pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jdos_read endp
X
X
X;
X; short far jdos_write (short handle, void far * buffer, unsigned short count)
X;
X; Write to file
X;
X_jdos_write proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X mov bx,word ptr [bp+6] ; file handle
X lds dx,dword ptr [bp+8] ; buffer address
X mov cx,word ptr [bp+12] ; number of bytes
X mov ah,40h ; write file
X int 21h
X jc write_err ; if failed, return error code
X cmp ax,word ptr [bp+12] ; make sure all bytes written
X je write_ok
X mov ax,1 ; else return 1 for not OK
X jmp short write_err
Xwrite_ok: xor ax,ax ; return zero for OK
Xwrite_err: pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jdos_write endp
X
X
X;
X; void far jxms_getdriver (XMSDRIVER far *)
X;
X; Get the address of the XMS driver, or NULL if not available
X;
X_jxms_getdriver proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X mov ax,4300h ; call multiplex interrupt with
X int 2fh ; a magic cookie, hex 4300
X cmp al,80h ; AL should contain hex 80
X je xmsavail
X xor dx,dx ; no XMS driver available
X xor ax,ax ; return a nil pointer
X jmp short xmsavail_done
Xxmsavail: mov ax,4310h ; fetch driver address with
X int 2fh ; another magic cookie
X mov dx,es ; copy address to dx:ax
X mov ax,bx
Xxmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value
X mov word ptr es:[bx],ax
X mov word ptr es:[bx+2],dx
X pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jxms_getdriver endp
X
X
X;
X; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
X;
X; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.
X; These are loaded, the XMS call is performed, and the new values of the
X; AX,DX,BX registers are written back to the context structure.
X;
X_jxms_calldriver proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X les bx,dword ptr [bp+10] ; get XMScontext pointer
X mov ax,word ptr es:[bx] ; load registers
X mov dx,word ptr es:[bx+2]
X mov si,word ptr es:[bx+6]
X mov ds,word ptr es:[bx+8]
X mov bx,word ptr es:[bx+4]
X call dword ptr [bp+6] ; call the driver
X mov cx,bx ; save returned BX for a sec
X les bx,dword ptr [bp+10] ; get XMScontext pointer
X mov word ptr es:[bx],ax ; put back ax,dx,bx
X mov word ptr es:[bx+2],dx
X mov word ptr es:[bx+4],cx
X pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jxms_calldriver endp
X
X
X;
X; short far jems_available (void)
X;
X; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
X;
X_jems_available proc far
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X mov ax,3567h ; get interrupt vector 67h
X int 21h
X push cs
X pop ds
X mov di,000ah ; check offs 10 in returned seg
X lea si,ASCII_device_name ; against literal string
X mov cx,8
X cld
X repe cmpsb
X jne no_ems
X mov ax,1 ; match, it's there
X jmp short avail_done
Xno_ems: xor ax,ax ; it's not there
Xavail_done: pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X ret
X
XASCII_device_name db "EMMXXXX0"
X
X_jems_available endp
X
X
X;
X; void far jems_calldriver (EMScontext far *)
X;
X; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers.
X; These are loaded, the EMS trap is performed, and the new values of the
X; AX,DX,BX registers are written back to the context structure.
X;
X_jems_calldriver proc far
X push bp ; linkage
X mov bp,sp
X push si ; save all registers for safety
X push di
X push bx
X push cx
X push dx
X push es
X push ds
X les bx,dword ptr [bp+6] ; get EMScontext pointer
X mov ax,word ptr es:[bx] ; load registers
X mov dx,word ptr es:[bx+2]
X mov si,word ptr es:[bx+6]
X mov ds,word ptr es:[bx+8]
X mov bx,word ptr es:[bx+4]
X int 67h ; call the EMS driver
X mov cx,bx ; save returned BX for a sec
X les bx,dword ptr [bp+6] ; get EMScontext pointer
X mov word ptr es:[bx],ax ; put back ax,dx,bx
X mov word ptr es:[bx+2],dx
X mov word ptr es:[bx+4],cx
X pop ds ; restore registers and exit
X pop es
X pop dx
X pop cx
X pop bx
X pop di
X pop si
X pop bp
X ret
X_jems_calldriver endp
X
XJMEMDOSA_TXT ends
X
X end
END_OF_FILE
if test 8314 -ne `wc -c <'jmemdosa.asm'`; then
echo shar: \"'jmemdosa.asm'\" unpacked with wrong size!
fi
# end of 'jmemdosa.asm'
fi
if test -f 'jmemname.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemname.c'\"
else
echo shar: Extracting \"'jmemname.c'\" \(7643 characters\)
sed "s/^X//" >'jmemname.c' <<'END_OF_FILE'
X/*
X * jmemname.c (jmemsys.c)
X *
X * Copyright (C) 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file provides a generic implementation of the system-dependent
X * portion of the JPEG memory manager. This implementation assumes that
X * you must explicitly construct a name for each temp file.
X * Also, the problem of determining the amount of memory available
X * is shoved onto the user.
X */
X
X#include "jinclude.h"
X#include "jmemsys.h"
X
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare malloc(), free() */
X#else
Xextern void * malloc PP((size_t size));
Xextern void free PP((void *ptr));
X#endif
X
X#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
X#define SEEK_SET 0 /* if not, assume 0 is correct */
X#endif
X
X#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
X#define READ_BINARY "r"
X#define RW_BINARY "w+"
X#else
X#define READ_BINARY "rb"
X#define RW_BINARY "w+b"
X#endif
X
X
Xstatic external_methods_ptr methods; /* saved for access to error_exit */
X
Xstatic long total_used; /* total memory requested so far */
X
X
X/*
X * Selection of a file name for a temporary file.
X * This is system-dependent!
X *
X * The code as given is suitable for most Unix systems, and it is easily
X * modified for most non-Unix systems. Some notes:
X * 1. The temp file is created in the directory named by TEMP_DIRECTORY.
X * The default value is /usr/tmp, which is the conventional place for
X * creating large temp files on Unix. On other systems you'll probably
X * want to change the file location. You can do this by editing the
X * #define, or by defining TEMP_DIRECTORY in CFLAGS in the Makefile.
X * For example, you might say
X * CFLAGS= ... '-DTEMP_DIRECTORY="/tmp/"'
X * Note that double quotes are needed in the text of the macro.
X * With most make systems you have to put single quotes around the
X * -D construct to preserve the double quotes.
X * (Amiga SAS C has trouble with ":" and such in command-line options,
X * so we've put in a special case for the preferred Amiga temp directory.)
X *
X * 2. If you need to change the file name as well as its location,
X * you can override the TEMP_FILE_NAME macro. (Note that this is
X * actually a printf format string; it must contain %s and %d.)
X * Few people should need to do this.
X *
X * 3. mktemp() is used to ensure that multiple processes running
X * simultaneously won't select the same file names. If your system
X * doesn't have mktemp(), define NO_MKTEMP to do it the hard way.
X *
X * 4. You probably want to define NEED_SIGNAL_CATCHER so that jcmain/jdmain
X * will cause the temp files to be removed if you stop the program early.
X */
X
X#ifndef TEMP_DIRECTORY /* so can override from Makefile */
X#ifdef AMIGA
X#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
X#else
X#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */
X#endif
X#endif
X
Xstatic int next_file_num; /* to distinguish among several temp files */
X
X#ifdef NO_MKTEMP
X
X#ifndef TEMP_FILE_NAME /* so can override from Makefile */
X#define TEMP_FILE_NAME "%sJPG%03d.TMP"
X#endif
X
XLOCAL void
Xselect_file_name (char * fname)
X{
X FILE * tfile;
X
X /* Keep generating file names till we find one that's not in use */
X for (;;) {
X next_file_num++; /* advance counter */
X sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
X if ((tfile = fopen(fname, READ_BINARY)) == NULL)
X break;
X fclose(tfile); /* oops, it's there; close tfile & try again */
X }
X}
X
X#else /* ! NO_MKTEMP */
X
X/* Note that mktemp() requires the initial filename to end in six X's */
X#ifndef TEMP_FILE_NAME /* so can override from Makefile */
X#define TEMP_FILE_NAME "%sJPG%dXXXXXX"
X#endif
X
XLOCAL void
Xselect_file_name (char * fname)
X{
X next_file_num++; /* advance counter */
X sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
X mktemp(fname); /* make sure file name is unique */
X /* mktemp replaces the trailing XXXXXX with a unique string of characters */
X}
X
X#endif /* NO_MKTEMP */
X
X
X/*
X * Memory allocation and freeing are controlled by the regular library
X * routines malloc() and free().
X */
X
XGLOBAL void *
Xjget_small (size_t sizeofobject)
X{
X total_used += sizeofobject;
X return (void *) malloc(sizeofobject);
X}
X
XGLOBAL void
Xjfree_small (void * object)
X{
X free(object);
X}
X
X/*
X * We assume NEED_FAR_POINTERS is not defined and so the separate entry points
X * jget_large, jfree_large are not needed.
X */
X
X
X/*
X * This routine computes the total memory space available for allocation.
X * It's impossible to do this in a portable way; our current solution is
X * to make the user tell us (with a default value set at compile time).
X * If you can actually get the available space, it's a good idea to subtract
X * a slop factor of 5% or so.
X */
X
X#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
X#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
X#endif
X
XGLOBAL long
Xjmem_available (long min_bytes_needed, long max_bytes_needed)
X{
X return methods->max_memory_to_use - total_used;
X}
X
X
X/*
X * Backing store (temporary file) management.
X * Backing store objects are only used when the value returned by
X * jmem_available is less than the total space needed. You can dispense
X * with these routines if you have plenty of virtual memory; see jmemnobs.c.
X */
X
X
XMETHODDEF void
Xread_backing_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X if (fseek(info->temp_file, file_offset, SEEK_SET))
X ERREXIT(methods, "fseek failed on temporary file");
X if (JFREAD(info->temp_file, buffer_address, byte_count)
X != (size_t) byte_count)
X ERREXIT(methods, "fread failed on temporary file");
X}
X
X
XMETHODDEF void
Xwrite_backing_store (backing_store_ptr info, void FAR * buffer_address,
X long file_offset, long byte_count)
X{
X if (fseek(info->temp_file, file_offset, SEEK_SET))
X ERREXIT(methods, "fseek failed on temporary file");
X if (JFWRITE(info->temp_file, buffer_address, byte_count)
X != (size_t) byte_count)
X ERREXIT(methods, "fwrite failed on temporary file --- out of disk space?");
X}
X
X
XMETHODDEF void
Xclose_backing_store (backing_store_ptr info)
X{
X fclose(info->temp_file); /* close the file */
X unlink(info->temp_name); /* delete the file */
X/* If your system doesn't have unlink(), use remove() instead.
X * remove() is the ANSI-standard name for this function, but if
X * your system was ANSI you'd be using jmemansi.c, right?
X */
X}
X
X
XGLOBAL void
Xjopen_backing_store (backing_store_ptr info, long total_bytes_needed)
X{
X char tracemsg[TEMP_NAME_LENGTH+40];
X
X select_file_name(info->temp_name);
X if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL)
X ERREXIT(methods, "Failed to create temporary file");
X info->read_backing_store = read_backing_store;
X info->write_backing_store = write_backing_store;
X info->close_backing_store = close_backing_store;
X /* hack to get around TRACEMS' inability to handle string parameters */
X sprintf(tracemsg, "Using temp file %s", info->temp_name);
X TRACEMS(methods, 1, tracemsg);
X}
X
X
X/*
X * These routines take care of any system-dependent initialization and
X * cleanup required. Keep in mind that jmem_term may be called more than
X * once.
X */
X
XGLOBAL void
Xjmem_init (external_methods_ptr emethods)
X{
X methods = emethods; /* save struct addr for error exit access */
X emethods->max_memory_to_use = DEFAULT_MAX_MEM;
X total_used = 0;
X next_file_num = 0;
X}
X
XGLOBAL void
Xjmem_term (void)
X{
X /* no work */
X}
END_OF_FILE
if test 7643 -ne `wc -c <'jmemname.c'`; then
echo shar: \"'jmemname.c'\" unpacked with wrong size!
fi
# end of 'jmemname.c'
fi
if test -f 'jrevdct.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jrevdct.c'\"
else
echo shar: Extracting \"'jrevdct.c'\" \(7547 characters\)
sed "s/^X//" >'jrevdct.c' <<'END_OF_FILE'
X/*
X * jrevdct.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains the basic inverse-DCT transformation subroutine.
X *
X * This implementation is based on Appendix A.2 of the book
X * "Discrete Cosine Transform---Algorithms, Advantages, Applications"
X * by K.R. Rao and P. Yip (Academic Press, Inc, London, 1990).
X * It uses scaled fixed-point arithmetic instead of floating point.
X */
X
X#include "jinclude.h"
X
X/*
X * This routine is specialized to the case DCTSIZE = 8.
X */
X
X#if DCTSIZE != 8
X Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
X#endif
X
X
X/* The poop on this scaling stuff is as follows:
X *
X * We have to do addition and subtraction of the integer inputs, which
X * is no problem, and multiplication by fractional constants, which is
X * a problem to do in integer arithmetic. We multiply all the constants
X * by DCT_SCALE and convert them to integer constants (thus retaining
X * LG2_DCT_SCALE bits of precision in the constants). After doing a
X * multiplication we have to divide the product by DCT_SCALE, with proper
X * rounding, to produce the correct output. The division can be implemented
X * cheaply as a right shift of LG2_DCT_SCALE bits. The DCT equations also
X * specify an additional division by 2 on the final outputs; this can be
X * folded into the right-shift by shifting one more bit (see UNFIXH).
X *
X * If you are planning to recode this in assembler, you might want to set
X * LG2_DCT_SCALE to 15. This loses a bit of precision, but then all the
X * multiplications are between 16-bit quantities (given 8-bit JSAMPLEs!)
X * so you could use a signed 16x16=>32 bit multiply instruction instead of
X * full 32x32 multiply. Unfortunately there's no way to describe such a
X * multiply portably in C, so we've gone for the extra bit of accuracy here.
X */
X
X#ifdef EIGHT_BIT_SAMPLES
X#define LG2_DCT_SCALE 16
X#else
X#define LG2_DCT_SCALE 15 /* lose a little precision to avoid overflow */
X#endif
X
X#define ONE ((INT32) 1)
X
X#define DCT_SCALE (ONE << LG2_DCT_SCALE)
X
X/* In some places we shift the inputs left by a couple more bits, */
X/* so that they can be added to fractional results without too much */
X/* loss of precision. */
X#define LG2_OVERSCALE 2
X#define OVERSCALE (ONE << LG2_OVERSCALE)
X#define OVERSHIFT(x) ((x) <<= LG2_OVERSCALE)
X
X/* Scale a fractional constant by DCT_SCALE */
X#define FIX(x) ((INT32) ((x) * DCT_SCALE + 0.5))
X
X/* Scale a fractional constant by DCT_SCALE/OVERSCALE */
X/* Such a constant can be multiplied with an overscaled input */
X/* to produce something that's scaled by DCT_SCALE */
X#define FIXO(x) ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5))
X
X/* Descale and correctly round a value that's scaled by DCT_SCALE */
X#define UNFIX(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
X
X/* Same with an additional division by 2, ie, correctly rounded UNFIX(x/2) */
X#define UNFIXH(x) RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
X
X/* Take a value scaled by DCT_SCALE and round to integer scaled by OVERSCALE */
X#define UNFIXO(x) RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)),\
X LG2_DCT_SCALE-LG2_OVERSCALE)
X
X/* Here are the constants we need */
X/* SIN_i_j is sine of i*pi/j, scaled by DCT_SCALE */
X/* COS_i_j is cosine of i*pi/j, scaled by DCT_SCALE */
X
X#define SIN_1_4 FIX(0.707106781)
X#define COS_1_4 SIN_1_4
X
X#define SIN_1_8 FIX(0.382683432)
X#define COS_1_8 FIX(0.923879533)
X#define SIN_3_8 COS_1_8
X#define COS_3_8 SIN_1_8
X
X#define SIN_1_16 FIX(0.195090322)
X#define COS_1_16 FIX(0.980785280)
X#define SIN_7_16 COS_1_16
X#define COS_7_16 SIN_1_16
X
X#define SIN_3_16 FIX(0.555570233)
X#define COS_3_16 FIX(0.831469612)
X#define SIN_5_16 COS_3_16
X#define COS_5_16 SIN_3_16
X
X/* OSIN_i_j is sine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
X/* OCOS_i_j is cosine of i*pi/j, scaled by DCT_SCALE/OVERSCALE */
X
X#define OSIN_1_4 FIXO(0.707106781)
X#define OCOS_1_4 OSIN_1_4
X
X#define OSIN_1_8 FIXO(0.382683432)
X#define OCOS_1_8 FIXO(0.923879533)
X#define OSIN_3_8 OCOS_1_8
X#define OCOS_3_8 OSIN_1_8
X
X#define OSIN_1_16 FIXO(0.195090322)
X#define OCOS_1_16 FIXO(0.980785280)
X#define OSIN_7_16 OCOS_1_16
X#define OCOS_7_16 OSIN_1_16
X
X#define OSIN_3_16 FIXO(0.555570233)
X#define OCOS_3_16 FIXO(0.831469612)
X#define OSIN_5_16 OCOS_3_16
X#define OCOS_5_16 OSIN_3_16
X
X
X/*
X * Perform the inverse DCT on one block of coefficients.
X *
X * A 2-D IDCT can be done by 1-D IDCT on each row
X * followed by 1-D IDCT on each column.
X */
X
XGLOBAL void
Xj_rev_dct (DCTBLOCK data)
X{
X int pass, rowctr;
X register DCTELEM *inptr, *outptr;
X DCTBLOCK workspace;
X
X /* Each iteration of the inner loop performs one 8-point 1-D IDCT.
X * It reads from a *row* of the input matrix and stores into a *column*
X * of the output matrix. In the first pass, we read from the data[] array
X * and store into the local workspace[]. In the second pass, we read from
X * the workspace[] array and store into data[], thus performing the
X * equivalent of a columnar IDCT pass with no variable array indexing.
X */
X
X inptr = data; /* initialize pointers for first pass */
X outptr = workspace;
X for (pass = 1; pass >= 0; pass--) {
X for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
X /* many tmps have nonoverlapping lifetime -- flashy register colourers
X * should be able to do this lot very well
X */
X INT32 in0, in1, in2, in3, in4, in5, in6, in7;
X INT32 tmp10, tmp11, tmp12, tmp13;
X INT32 tmp20, tmp21, tmp22, tmp23;
X INT32 tmp30, tmp31;
X INT32 tmp40, tmp41, tmp42, tmp43;
X INT32 tmp50, tmp51, tmp52, tmp53;
X SHIFT_TEMPS
X
X in0 = inptr[0];
X in1 = inptr[1];
X in2 = inptr[2];
X in3 = inptr[3];
X in4 = inptr[4];
X in5 = inptr[5];
X in6 = inptr[6];
X in7 = inptr[7];
X
X /* These values are scaled by DCT_SCALE */
X
X tmp10 = (in0 + in4) * COS_1_4;
X tmp11 = (in0 - in4) * COS_1_4;
X tmp12 = in2 * SIN_1_8 - in6 * COS_1_8;
X tmp13 = in6 * SIN_1_8 + in2 * COS_1_8;
X
X tmp20 = tmp10 + tmp13;
X tmp21 = tmp11 + tmp12;
X tmp22 = tmp11 - tmp12;
X tmp23 = tmp10 - tmp13;
X
X /* These values are scaled by OVERSCALE */
X
X tmp30 = UNFIXO((in3 + in5) * COS_1_4);
X tmp31 = UNFIXO((in3 - in5) * COS_1_4);
X
X OVERSHIFT(in1);
X OVERSHIFT(in7);
X
X tmp40 = in1 + tmp30;
X tmp41 = in7 + tmp31;
X tmp42 = in1 - tmp30;
X tmp43 = in7 - tmp31;
X
X /* And these are scaled by DCT_SCALE */
X
X tmp50 = tmp40 * OCOS_1_16 + tmp41 * OSIN_1_16;
X tmp51 = tmp40 * OSIN_1_16 - tmp41 * OCOS_1_16;
X tmp52 = tmp42 * OCOS_5_16 + tmp43 * OSIN_5_16;
X tmp53 = tmp42 * OSIN_5_16 - tmp43 * OCOS_5_16;
X
X outptr[ 0] = (DCTELEM) UNFIXH(tmp20 + tmp50);
X outptr[DCTSIZE ] = (DCTELEM) UNFIXH(tmp21 + tmp53);
X outptr[DCTSIZE*2] = (DCTELEM) UNFIXH(tmp22 + tmp52);
X outptr[DCTSIZE*3] = (DCTELEM) UNFIXH(tmp23 + tmp51);
X outptr[DCTSIZE*4] = (DCTELEM) UNFIXH(tmp23 - tmp51);
X outptr[DCTSIZE*5] = (DCTELEM) UNFIXH(tmp22 - tmp52);
X outptr[DCTSIZE*6] = (DCTELEM) UNFIXH(tmp21 - tmp53);
X outptr[DCTSIZE*7] = (DCTELEM) UNFIXH(tmp20 - tmp50);
X
X inptr += DCTSIZE; /* advance inptr to next row */
X outptr++; /* advance outptr to next column */
X }
X /* end of pass; in case it was pass 1, set up for pass 2 */
X inptr = workspace;
X outptr = data;
X }
X}
END_OF_FILE
if test 7547 -ne `wc -c <'jrevdct.c'`; then
echo shar: \"'jrevdct.c'\" unpacked with wrong size!
fi
# end of 'jrevdct.c'
fi
echo shar: End of archive 14 \(of 18\).
cp /dev/null ark14isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: djpeg.1 jccolor.c jdsample.c jwrrle.c makefile.ansi
# makefile.mms makefile.sas makefile.unix
# Wrapped by kent@sparky on Mon Mar 23 16:02:55 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 15 (of 18)."'
if test -f 'djpeg.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'djpeg.1'\"
else
echo shar: Extracting \"'djpeg.1'\" \(3099 characters\)
sed "s/^X//" >'djpeg.1' <<'END_OF_FILE'
X.TH DJPEG 1 "28 February 1992"
X.SH NAME
Xdjpeg \- decompress a JPEG file to an image file
X.SH SYNOPSIS
X.B djpeg
X[
X.B \-GPRTgD1bd
X]
X[
X.BI \-q " colors"
X]
X[
X.BI \-m " memory"
X]
X[
X.I filename
X]
X.LP
X.SH DESCRIPTION
X.LP
X.B djpeg
Xdecompresses the named JPEG file, or the standard input if no file is named,
Xand produces an image file on the standard output. PPM, GIF, Targa, or RLE
Xoutput format can be selected. (RLE is supported only if the URT library is
Xavailable.)
X.SH OPTIONS
X.TP
X.B \-G
XSelect GIF output format (implies
X.BR \-q ,
Xwith default of 256 colors).
X.TP
X.B \-P
XSelect PPM or PGM output format (this is the default). PGM is emitted if the
XJPEG file is gray-scale or if
X.B \-g
Xis specified.
X.TP
X.B \-R
XSelect RLE output format. Requires URT library.
X.TP
X.B \-T
XSelect Targa output format. Gray-scale format is emitted if the JPEG file is
Xgray-scale or if
X.B \-g
Xis specified; otherwise, colormapped format is emitted if
X.B \-q
Xis specified; otherwise, 24-bit full-color format is emitted.
X.TP
X.B \-g
XForce gray-scale output even if input is color.
X.TP
X.BI \-q " N"
XQuantize to N colors. This reduces the number of colors in the output image
Xso that it can be displayed on a colormapped display or stored in a
Xcolormapped file format. For example, if you have an 8-bit display, you'd
Xneed to quantize to 256 or fewer colors.
X.TP
X.B \-D
XDo not use dithering in color quantization. By default, Floyd-Steinberg
Xdithering is applied when quantizing colors, but on some images dithering may
Xresult in objectionable "graininess". If that happens, you can turn off
Xdithering with
X.BR \-D .
X.B \-D
Xis ignored unless you also say
X.B \-q
Xor
X.BR \-G .
X.TP
X.B \-1
XUse one-pass instead of two-pass color quantization. The one-pass method is
Xfaster and needs less memory, but it produces a lower-quality image.
X.B \-1
Xis ignored unless you also say
X.B \-q
Xor
X.BR \-G .
XAlso, the one-pass method is always used for gray-scale output (the two-pass
Xmethod is no improvement then).
X.TP
X.B \-b
XPerform cross-block smoothing. This is quite memory-intensive and only seems
Xto improve the image at low quality settings (\fB\-Q\fR 10 to 20 or so).
XAt normal
X.B \-Q
Xsettings it may make the image worse.
X.TP
X.B \-d
XEnable debug printout. More
X.BR \-d 's
Xgive more output. Also, version information is printed at startup.
X.TP
X.BI \-m " memory"
XSet limit for amount of memory to use in processing large images. Value is
Xin thousands of bytes, or millions of bytes if "M" is attached to the
Xnumber. For example,
X.B \-m 4m
Xselects 4000000 bytes. If more space is needed, temporary files will be used.
X.SH EXAMPLES
X.LP
XThis example decompresses the JPEG file foo.jpg, quantizes to 256 colors,
Xand saves the output in GIF format in foo.gif:
X.IP
X.B djpeg \-G
X.I foo.jpg
X.B >
X.I foo.gif
X.SH SEE ALSO
X.BR cjpeg (1)
X.br
X.BR ppm (5),
X.BR pgm (5)
X.br
XWallace, Gregory K. "The JPEG Still Picture Compression Standard",
XCommunications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
X.SH AUTHOR
XIndependent JPEG Group
X.SH BUGS
XArithmetic coding is not supported for legal reasons.
X.PP
XNot as fast as we'd like.
END_OF_FILE
if test 3099 -ne `wc -c <'djpeg.1'`; then
echo shar: \"'djpeg.1'\" unpacked with wrong size!
fi
# end of 'djpeg.1'
fi
if test -f 'jccolor.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jccolor.c'\"
else
echo shar: Extracting \"'jccolor.c'\" \(6864 characters\)
sed "s/^X//" >'jccolor.c' <<'END_OF_FILE'
X/*
X * jccolor.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains input colorspace conversion routines.
X * These routines are invoked via the methods get_sample_rows
X * and colorin_init/term.
X */
X
X#include "jinclude.h"
X
X
Xstatic JSAMPARRAY pixel_row; /* Workspace for a pixel row in input format */
X
X
X/*
X * Initialize for colorspace conversion.
X */
X
XMETHODDEF void
Xcolorin_init (compress_info_ptr cinfo)
X{
X /* Allocate a workspace for the result of get_input_row. */
X pixel_row = (*cinfo->emethods->alloc_small_sarray)
X (cinfo->image_width, (long) cinfo->input_components);
X}
X
X
X/*
X * Fetch some rows of pixels from get_input_row and convert to the
X * JPEG colorspace.
X */
X
X
X/*
X * This version handles RGB -> YCbCr conversion.
X * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
X * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
X * The conversion equations to be implemented are therefore
X * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
X * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B
X * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B
X * where Cb and Cr must be incremented by MAXJSAMPLE/2 to create a
X * nonnegative output value.
X * (These numbers are derived from TIFF Appendix O, draft of 4/10/91.)
X *
X * To avoid floating-point arithmetic, we represent the fractional constants
X * as integers scaled up by 2^14 (about 4 digits precision); we have to divide
X * the products by 2^14, with appropriate rounding, to get the correct answer.
X *
X * For even more speed, we could avoid any multiplications in the inner loop
X * by precalculating the constants times R,G,B for all possible values.
X * This is not currently implemented.
X */
X
X#define SCALEBITS 14
X#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
X#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
X
X
XMETHODDEF void
Xget_rgb_ycc_rows (compress_info_ptr cinfo,
X int rows_to_read, JSAMPIMAGE image_data)
X{
X register INT32 r, g, b;
X register JSAMPROW inptr0, inptr1, inptr2;
X register JSAMPROW outptr0, outptr1, outptr2;
X register long col;
X long width = cinfo->image_width;
X int row;
X
X for (row = 0; row < rows_to_read; row++) {
X /* Read one row from the source file */
X (*cinfo->methods->get_input_row) (cinfo, pixel_row);
X /* Convert colorspace */
X inptr0 = pixel_row[0];
X inptr1 = pixel_row[1];
X inptr2 = pixel_row[2];
X outptr0 = image_data[0][row];
X outptr1 = image_data[1][row];
X outptr2 = image_data[2][row];
X for (col = width; col > 0; col--) {
X r = GETJSAMPLE(*inptr0++);
X g = GETJSAMPLE(*inptr1++);
X b = GETJSAMPLE(*inptr2++);
X /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
X * must be too; we do not need an explicit range-limiting operation.
X * Hence the value being shifted is never negative, and we don't
X * need the general RIGHT_SHIFT macro.
X */
X /* Y */
X *outptr0++ = (JSAMPLE)
X (( FIX(0.29900)*r + FIX(0.58700)*g + FIX(0.11400)*b
X + ONE_HALF) >> SCALEBITS);
X /* Cb */
X *outptr1++ = (JSAMPLE)
X (((-FIX(0.16874))*r - FIX(0.33126)*g + FIX(0.50000)*b
X + ONE_HALF*(MAXJSAMPLE+1)) >> SCALEBITS);
X /* Cr */
X *outptr2++ = (JSAMPLE)
X (( FIX(0.50000)*r - FIX(0.41869)*g - FIX(0.08131)*b
X + ONE_HALF*(MAXJSAMPLE+1)) >> SCALEBITS);
X }
X }
X}
X
X
X/*
X * Fetch some rows of pixels from get_input_row and convert to the
X * JPEG colorspace.
X * This version handles grayscale (no conversion).
X */
X
XMETHODDEF void
Xget_grayscale_rows (compress_info_ptr cinfo,
X int rows_to_read, JSAMPIMAGE image_data)
X{
X int row;
X
X for (row = 0; row < rows_to_read; row++) {
X /* Read one row from the source file */
X (*cinfo->methods->get_input_row) (cinfo, pixel_row);
X /* Convert colorspace (gamma mapping needed here) */
X jcopy_sample_rows(pixel_row, 0, image_data[0], row,
X 1, cinfo->image_width);
X }
X}
X
X
X/*
X * Fetch some rows of pixels from get_input_row and convert to the
X * JPEG colorspace.
X * This version handles multi-component colorspaces without conversion.
X */
X
XMETHODDEF void
Xget_noconvert_rows (compress_info_ptr cinfo,
X int rows_to_read, JSAMPIMAGE image_data)
X{
X int row, ci;
X
X for (row = 0; row < rows_to_read; row++) {
X /* Read one row from the source file */
X (*cinfo->methods->get_input_row) (cinfo, pixel_row);
X /* Convert colorspace (gamma mapping needed here) */
X for (ci = 0; ci < cinfo->input_components; ci++) {
X jcopy_sample_rows(pixel_row, ci, image_data[ci], row,
X 1, cinfo->image_width);
X }
X }
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xcolorin_term (compress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for input colorspace conversion.
X */
X
XGLOBAL void
Xjselccolor (compress_info_ptr cinfo)
X{
X /* Make sure input_components agrees with in_color_space */
X switch (cinfo->in_color_space) {
X case CS_GRAYSCALE:
X if (cinfo->input_components != 1)
X ERREXIT(cinfo->emethods, "Bogus input colorspace");
X break;
X
X case CS_RGB:
X case CS_YCbCr:
X case CS_YIQ:
X if (cinfo->input_components != 3)
X ERREXIT(cinfo->emethods, "Bogus input colorspace");
X break;
X
X case CS_CMYK:
X if (cinfo->input_components != 4)
X ERREXIT(cinfo->emethods, "Bogus input colorspace");
X break;
X
X default:
X ERREXIT(cinfo->emethods, "Unsupported input colorspace");
X break;
X }
X
X /* Check num_components, set conversion method based on requested space */
X switch (cinfo->jpeg_color_space) {
X case CS_GRAYSCALE:
X if (cinfo->num_components != 1)
X ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
X if (cinfo->in_color_space == CS_GRAYSCALE)
X cinfo->methods->get_sample_rows = get_grayscale_rows;
X else
X ERREXIT(cinfo->emethods, "Unsupported color conversion request");
X break;
X
X case CS_YCbCr:
X if (cinfo->num_components != 3)
X ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
X if (cinfo->in_color_space == CS_RGB)
X cinfo->methods->get_sample_rows = get_rgb_ycc_rows;
X else if (cinfo->in_color_space == CS_YCbCr)
X cinfo->methods->get_sample_rows = get_noconvert_rows;
X else
X ERREXIT(cinfo->emethods, "Unsupported color conversion request");
X break;
X
X case CS_CMYK:
X if (cinfo->num_components != 4)
X ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
X if (cinfo->in_color_space == CS_CMYK)
X cinfo->methods->get_sample_rows = get_noconvert_rows;
X else
X ERREXIT(cinfo->emethods, "Unsupported color conversion request");
X break;
X
X default:
X ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace");
X break;
X }
X
X cinfo->methods->colorin_init = colorin_init;
X cinfo->methods->colorin_term = colorin_term;
X}
END_OF_FILE
if test 6864 -ne `wc -c <'jccolor.c'`; then
echo shar: \"'jccolor.c'\" unpacked with wrong size!
fi
# end of 'jccolor.c'
fi
if test -f 'jdsample.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdsample.c'\"
else
echo shar: Extracting \"'jdsample.c'\" \(6290 characters\)
sed "s/^X//" >'jdsample.c' <<'END_OF_FILE'
X/*
X * jdsample.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains un-subsampling routines.
X * These routines are invoked via the unsubsample and
X * unsubsample_init/term methods.
X */
X
X#include "jinclude.h"
X
X
X/*
X * Initialize for un-subsampling a scan.
X */
X
XMETHODDEF void
Xunsubsample_init (decompress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X/*
X * Un-subsample pixel values of a single component.
X * This version handles any integral sampling ratios.
X * This is not used for typical JPEG files, so it need not be fast.
X */
X
XMETHODDEF void
Xint_unsubsample (decompress_info_ptr cinfo, int which_component,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
X JSAMPARRAY output_data)
X{
X jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
X register JSAMPROW inptr, outptr;
X register JSAMPLE invalue;
X register short h_expand, h;
X short v_expand, v;
X int inrow, outrow;
X register long incol;
X
X#ifdef DEBUG /* for debugging pipeline controller */
X if (input_rows != compptr->v_samp_factor ||
X output_rows != cinfo->max_v_samp_factor ||
X (input_cols % compptr->h_samp_factor) != 0 ||
X (output_cols % cinfo->max_h_samp_factor) != 0 ||
X output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor)
X ERREXIT(cinfo->emethods, "Bogus unsubsample parameters");
X#endif
X
X h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
X v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
X
X outrow = 0;
X for (inrow = 0; inrow < input_rows; inrow++) {
X for (v = 0; v < v_expand; v++) {
X inptr = input_data[inrow];
X outptr = output_data[outrow++];
X for (incol = 0; incol < input_cols; incol++) {
X invalue = GETJSAMPLE(*inptr++);
X for (h = 0; h < h_expand; h++) {
X *outptr++ = invalue;
X }
X }
X }
X }
X}
X
X
X/*
X * Un-subsample pixel values of a single component.
X * This version handles the extremely common case of
X * horizontal expansion by 2 and any integral vertical expansion.
X */
X
XMETHODDEF void
Xh2_unsubsample (decompress_info_ptr cinfo, int which_component,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
X JSAMPARRAY output_data)
X{
X jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
X register JSAMPROW inptr, outptr;
X register JSAMPLE invalue;
X short v_expand, v;
X int inrow, outrow;
X register long incol;
X
X#ifdef DEBUG /* for debugging pipeline controller */
X if (input_rows != compptr->v_samp_factor ||
X output_rows != cinfo->max_v_samp_factor ||
X (input_cols % compptr->h_samp_factor) != 0 ||
X (output_cols % cinfo->max_h_samp_factor) != 0 ||
X output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor)
X ERREXIT(cinfo->emethods, "Bogus unsubsample parameters");
X#endif
X
X v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
X
X/* The subsampled image width will always be a multiple of DCTSIZE,
X * so we can unroll the inner loop.
X */
X
X outrow = 0;
X for (inrow = 0; inrow < input_rows; inrow++) {
X for (v = 0; v < v_expand; v++) {
X inptr = input_data[inrow];
X outptr = output_data[outrow++];
X#if DCTSIZE == 8
X for (incol = 0; incol < input_cols; incol += DCTSIZE) {
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X }
X#else /* nonstandard DCTSIZE */
X for (incol = 0; incol < input_cols; incol++) {
X invalue = GETJSAMPLE(*inptr++);
X *outptr++ = invalue;
X *outptr++ = invalue;
X }
X#endif
X }
X }
X}
X
X
X/*
X * Un-subsample pixel values of a single component.
X * This version handles the special case of a full-size component.
X */
X
XMETHODDEF void
Xfullsize_unsubsample (decompress_info_ptr cinfo, int which_component,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
X JSAMPARRAY output_data)
X{
X#ifdef DEBUG /* for debugging pipeline controller */
X if (input_cols != output_cols || input_rows != output_rows)
X ERREXIT(cinfo->emethods, "Pipeline controller messed up");
X#endif
X
X jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols);
X}
X
X
X
X/*
X * Clean up after a scan.
X */
X
XMETHODDEF void
Xunsubsample_term (decompress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X
X/*
X * The method selection routine for unsubsampling.
X * Note that we must select a routine for each component.
X */
X
XGLOBAL void
Xjselunsubsample (decompress_info_ptr cinfo)
X{
X short ci;
X jpeg_component_info * compptr;
X
X if (cinfo->CCIR601_sampling)
X ERREXIT(cinfo->emethods, "CCIR601 subsampling not implemented yet");
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
X compptr->v_samp_factor == cinfo->max_v_samp_factor)
X cinfo->methods->unsubsample[ci] = fullsize_unsubsample;
X else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
X (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
X cinfo->methods->unsubsample[ci] = h2_unsubsample;
X else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
X (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
X cinfo->methods->unsubsample[ci] = int_unsubsample;
X else
X ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
X }
X
X cinfo->methods->unsubsample_init = unsubsample_init;
X cinfo->methods->unsubsample_term = unsubsample_term;
X}
END_OF_FILE
if test 6290 -ne `wc -c <'jdsample.c'`; then
echo shar: \"'jdsample.c'\" unpacked with wrong size!
fi
# end of 'jdsample.c'
fi
if test -f 'jwrrle.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jwrrle.c'\"
else
echo shar: Extracting \"'jwrrle.c'\" \(6758 characters\)
sed "s/^X//" >'jwrrle.c' <<'END_OF_FILE'
X/*
X * jwrrle.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to write output images in RLE format.
X * The Utah Raster Toolkit library is required (version 3.0).
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume output to
X * an ordinary stdio stream.
X *
X * These routines are invoked via the methods put_pixel_rows, put_color_map,
X * and output_init/term.
X *
X * Based on code contributed by Mike Lijewski.
X */
X
X#include "jinclude.h"
X
X#ifdef RLE_SUPPORTED
X
X/* rle.h is provided by the Utah Raster Toolkit. */
X
X#include <rle.h>
X
X
X/*
X * output_term assumes that JSAMPLE has the same representation as rle_pixel,
X * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples.
X */
X
X#ifndef EIGHT_BIT_SAMPLES
X Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
X#endif
X
X
X/*
X * Since RLE stores scanlines bottom-to-top, we have to invert the image
X * from JPEG's top-to-bottom order. To do this, we save the outgoing data
X * in virtual array(s) during put_pixel_row calls, then actually emit the
X * RLE file during output_term. We use one virtual array if the output is
X * grayscale or colormapped, more if it is full color.
X */
X
X#define MAX_CHANS 4 /* allow up to four color components */
Xstatic big_sarray_ptr channels[MAX_CHANS]; /* Virtual arrays for saved data */
X
Xstatic long cur_output_row; /* next row# to write to virtual array(s) */
X
X
X/*
X * For now, if we emit an RLE color map then it is always 256 entries long,
X * though not all of the entries need be used.
X */
X
X#define CMAPBITS 8
X#define CMAPLENGTH (1<<(CMAPBITS))
X
Xstatic rle_map *output_colormap; /* RLE-style color map, or NULL if none */
Xstatic int number_colors; /* Number of colors actually used */
X
X
X/*
X * Write the file header.
X *
X * In this module it's easier to wait till output_term to actually write
X * anything; here we just request the big arrays we'll need.
X */
X
XMETHODDEF void
Xoutput_init (decompress_info_ptr cinfo)
X{
X short ci;
X
X if (cinfo->final_out_comps > MAX_CHANS)
X ERREXIT1(cinfo->emethods, "Cannot handle %d output channels for RLE",
X cinfo->final_out_comps);
X
X for (ci = 0; ci < cinfo->final_out_comps; ci++) {
X channels[ci] = (*cinfo->emethods->request_big_sarray)
X (cinfo->image_width, cinfo->image_height, 1L);
X }
X
X output_colormap = NULL; /* No output colormap as yet */
X number_colors = 0;
X cur_output_row = 0; /* Start filling virtual arrays at row 0 */
X
X cinfo->total_passes++; /* count file writing as separate pass */
X}
X
X
X/*
X * Write some pixel data.
X *
X * This routine just saves the data away in virtual arrays.
X */
X
XMETHODDEF void
Xput_pixel_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X JSAMPROW outputrow[1]; /* a pseudo JSAMPARRAY structure */
X int row;
X short ci;
X
X for (row = 0; row < num_rows; row++) {
X for (ci = 0; ci < cinfo->final_out_comps; ci++) {
X outputrow[0] = *((*cinfo->emethods->access_big_sarray)
X (channels[ci], cur_output_row, TRUE));
X jcopy_sample_rows(pixel_data[ci], row, outputrow, 0,
X 1, cinfo->image_width);
X }
X cur_output_row++;
X }
X}
X
X
X/*
X * Write the color map.
X *
X * For RLE output we just save the colormap for the output stage.
X */
X
XMETHODDEF void
Xput_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
X{
X size_t cmapsize;
X short ci;
X int i;
X
X if (num_colors > CMAPLENGTH)
X ERREXIT1(cinfo->emethods, "Cannot handle %d colormap entries for RLE",
X num_colors);
X
X /* Allocate storage for RLE-style cmap, zero any extra entries */
X cmapsize = cinfo->color_out_comps * CMAPLENGTH * SIZEOF(rle_map);
X output_colormap = (rle_map *) (*cinfo->emethods->alloc_small) (cmapsize);
X MEMZERO((void *) output_colormap, cmapsize);
X
X /* Save away data in RLE format --- note 8-bit left shift! */
X /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
X for (ci = 0; ci < cinfo->color_out_comps; ci++) {
X for (i = 0; i < num_colors; i++) {
X output_colormap[ci * CMAPLENGTH + i] = GETJSAMPLE(colormap[ci][i]) << 8;
X }
X }
X number_colors = num_colors;
X}
X
X
X/*
X * Finish up at the end of the file.
X *
X * Here is where we really output the RLE file.
X */
X
XMETHODDEF void
Xoutput_term (decompress_info_ptr cinfo)
X{
X rle_hdr header; /* Output file information */
X rle_pixel *output_rows[MAX_CHANS];
X char cmapcomment[80];
X short ci;
X long row;
X
X /* Initialize the header info */
X MEMZERO((void *) &header, SIZEOF(rle_hdr)); /* make sure all bits are 0 */
X header.rle_file = cinfo->output_file;
X header.xmin = 0;
X header.xmax = cinfo->image_width - 1;
X header.ymin = 0;
X header.ymax = cinfo->image_height - 1;
X header.alpha = 0;
X header.ncolors = cinfo->final_out_comps;
X for (ci = 0; ci < cinfo->final_out_comps; ci++) {
X RLE_SET_BIT(header, ci);
X }
X if (number_colors > 0) {
X header.ncmap = cinfo->color_out_comps;
X header.cmaplen = CMAPBITS;
X header.cmap = output_colormap;
X /* Add a comment to the output image with the true colormap length. */
X sprintf(cmapcomment, "color_map_length=%d", number_colors);
X rle_putcom(cmapcomment, &header);
X }
X /* Emit the RLE header and color map (if any) */
X rle_put_setup(&header);
X
X /* Now output the RLE data from our virtual array(s).
X * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
X * and (b) we are not on a machine where FAR pointers differ from regular.
X */
X for (row = cinfo->image_height-1; row >= 0; row--) {
X (*cinfo->methods->progress_monitor) (cinfo, cinfo->image_height-row-1,
X cinfo->image_height);
X for (ci = 0; ci < cinfo->final_out_comps; ci++) {
X output_rows[ci] = (rle_pixel *) *((*cinfo->emethods->access_big_sarray)
X (channels[ci], row, FALSE));
X }
X rle_putrow(output_rows, (int) cinfo->image_width, &header);
X }
X cinfo->completed_passes++;
X
X /* Emit file trailer */
X rle_puteof(&header);
X fflush(cinfo->output_file);
X if (ferror(cinfo->output_file))
X ERREXIT(cinfo->emethods, "Output file write error");
X
X /* Release memory */
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for RLE format output.
X * This should be called from d_ui_method_selection if RLE output is wanted.
X */
X
XGLOBAL void
Xjselwrle (decompress_info_ptr cinfo)
X{
X cinfo->methods->output_init = output_init;
X cinfo->methods->put_color_map = put_color_map;
X cinfo->methods->put_pixel_rows = put_pixel_rows;
X cinfo->methods->output_term = output_term;
X}
X
X#endif /* RLE_SUPPORTED */
END_OF_FILE
if test 6758 -ne `wc -c <'jwrrle.c'`; then
echo shar: \"'jwrrle.c'\" unpacked with wrong size!
fi
# end of 'jwrrle.c'
fi
if test -f 'makefile.ansi' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.ansi'\"
else
echo shar: Extracting \"'makefile.ansi'\" \(6360 characters\)
sed "s/^X//" >'makefile.ansi' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is suitable for Unix-like systems with ANSI-capable compilers.
X# If you have a non-ANSI compiler, makefile.unix is a better starting point.
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC= cc
X
X# You may need to adjust these cc options:
XCFLAGS= -O
X# In particular:
X# Add -DBSD if on a pure BSD system (see jinclude.h).
X# Add -DMEM_STATS to enable gathering of memory usage statistics.
X# You may also want to add -DTWO_FILE_COMMANDLINE or -D switches for other
X# symbols listed in jconfig.h, if you prefer not to change jconfig.h.
X
X# Link-time cc options:
XLDFLAGS=
X
X# To link any special libraries, add the necessary -l commands here.
X# In particular, on some versions of HP-UX (and probably other SysV-derived
X# systems) there is a faster alternate malloc(3) library that you can use
X# by adding "-lmalloc" to this line.
XLDLIBS=
X
X# miscellaneous OS-dependent stuff
X# linker
XLN= $(CC)
X# file deletion command
XRM= rm -f
X# library (.a) file creation command
XAR= ar rc
X# second step in .a creation (use "touch" if not needed)
XAR2= ranlib
X
X
X# source files (independently compilable files)
XSOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
X jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
X jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
X jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
X jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
X jwrppm.c jwrrle.c jwrtarga.c
X# virtual source files (not present in distribution file)
XVIRTSOURCES= jmemsys.c
X# system-dependent implementations of source files
XSYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
X jmemdosa.asm
X# files included by source files
XINCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
X# documentation, test, and support files
XDOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
XMAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
X makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
X makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
X makljpeg.cf makefile.mms makefile.vms makvms.opt
XOTHERFILES= ansi2knr.c ckconfig.c example.c
XTESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
XDISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
X $(OTHERFILES) $(TESTFILES)
X# objectfiles common to cjpeg and djpeg
XCOMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
X# compression objectfiles
XCLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
X jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
X jrdrle.o jrdtarga.o
XCOBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
X jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
X jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
XDOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.a
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X
X
Xall: cjpeg djpeg
X# By default, libjpeg.a is not built unless you explicitly request it.
X# You can add libjpeg.a to the line above if you want it built by default.
X
X
Xcjpeg: $(COBJECTS)
X $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
X
Xdjpeg: $(DOBJECTS)
X $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
X
X# libjpeg.a is useful if you are including the JPEG software in a larger
X# program; you'd include it in your link, rather than the individual modules.
Xlibjpeg.a: $(LIBOBJECTS)
X $(RM) libjpeg.a
X $(AR) libjpeg.a $(LIBOBJECTS)
X $(AR2) libjpeg.a
X
Xclean:
X $(RM) *.o cjpeg djpeg libjpeg.a core testout.*
X
Xdistribute:
X $(RM) jpegsrc.tar*
X tar cvf jpegsrc.tar $(DISTFILES)
X compress -v jpegsrc.tar
X
Xtest: cjpeg djpeg
X $(RM) testout.ppm testout.gif testout.jpg
X ./djpeg testorig.jpg >testout.ppm
X ./djpeg -G testorig.jpg >testout.gif
X ./cjpeg testimg.ppm >testout.jpg
X cmp testimg.ppm testout.ppm
X cmp testimg.gif testout.gif
X cmp testimg.jpg testout.jpg
X
X
Xjbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h
Xjcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h
Xjccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
Xjcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
Xjcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
Xjchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
Xjcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
Xjcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
Xjcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
Xjcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
Xjdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
Xjdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
Xjddeflts.o : jddeflts.c jinclude.h jconfig.h jpegdata.h
Xjdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
Xjdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
Xjdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
Xjdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
Xjdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
Xjerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
Xjquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
Xjquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
Xjfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
Xjrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
Xjutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
Xjmemmgr.o : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
Xjrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
Xjrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
Xjrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
Xjrdrle.o : jrdrle.c jinclude.h jconfig.h jpegdata.h
Xjrdtarga.o : jrdtarga.c jinclude.h jconfig.h jpegdata.h
Xjwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
Xjwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
Xjwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h
Xjwrrle.o : jwrrle.c jinclude.h jconfig.h jpegdata.h
Xjwrtarga.o : jwrtarga.c jinclude.h jconfig.h jpegdata.h
Xjmemsys.o : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
END_OF_FILE
if test 6360 -ne `wc -c <'makefile.ansi'`; then
echo shar: \"'makefile.ansi'\" unpacked with wrong size!
fi
# end of 'makefile.ansi'
fi
if test -f 'makefile.mms' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.mms'\"
else
echo shar: Extracting \"'makefile.mms'\" \(6695 characters\)
sed "s/^X//" >'makefile.mms' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for use with MMS on VAX/VMS systems.
X# Thanks to Rick Dyson (dy...@iowasp.physics.uiowa.edu) for his help.
X
X# Read SETUP instructions before saying "MMS" !!
X
XCFLAGS= $(CFLAGS) /NoDebug /Optimize /Define = (TWO_FILE_COMMANDLINE,HAVE_STDC,INCLUDES_ARE_ANSI)
XOPT= Sys$Disk:[]MAKVMS.OPT
X
X
X# source files (independently compilable files)
XSOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
X jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
X jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
X jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
X jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
X jwrppm.c jwrrle.c jwrtarga.c
X# virtual source files (not present in distribution file)
XVIRTSOURCES= jmemsys.c
X# system-dependent implementations of source files
XSYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
X jmemdosa.asm
X# files included by source files
XINCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
X# documentation, test, and support files
XDOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
XMAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
X makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
X makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
X makljpeg.cf makefile.mms makefile.vms makvms.opt
XOTHERFILES= ansi2knr.c ckconfig.c example.c
XTESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
XDISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
X $(OTHERFILES) $(TESTFILES)
X# objectfiles common to cjpeg and djpeg
XCOMOBJECTS= jutils.obj jerror.obj jmemmgr.obj jmemsys.obj
X# compression objectfiles
XCLIBOBJECTS= jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
X jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
X jwrjfif.obj jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj
XCOBJECTS= jcmain.obj $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj \
X jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj \
X jquant2.obj jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj \
X jwrrle.obj jwrtarga.obj
XDOBJECTS= jdmain.obj $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.olb
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X# objectfile lists with commas --- what a crock
XCOBJLIST= jcmain.obj,jcmaster.obj,jcdeflts.obj,jcarith.obj,jccolor.obj,\
X jcexpand.obj,jchuff.obj,jcmcu.obj,jcpipe.obj,jcsample.obj,\
X jfwddct.obj,jwrjfif.obj,jrdgif.obj,jrdppm.obj,jrdrle.obj,\
X jrdtarga.obj,jutils.obj,jerror.obj,jmemmgr.obj,jmemsys.obj
XDOBJLIST= jdmain.obj,jdmaster.obj,jddeflts.obj,jbsmooth.obj,jdarith.obj,\
X jdcolor.obj,jdhuff.obj,jdmcu.obj,jdpipe.obj,jdsample.obj,\
X jquant1.obj,jquant2.obj,jrevdct.obj,jrdjfif.obj,jwrgif.obj,\
X jwrppm.obj,jwrrle.obj,jwrtarga.obj,jutils.obj,jerror.obj,\
X jmemmgr.obj,jmemsys.obj
XLIBOBJLIST= jcmaster.obj,jcdeflts.obj,jcarith.obj,jccolor.obj,jcexpand.obj,\
X jchuff.obj,jcmcu.obj,jcpipe.obj,jcsample.obj,jfwddct.obj,\
X jwrjfif.obj,jrdgif.obj,jrdppm.obj,jrdrle.obj,jrdtarga.obj,\
X jdmaster.obj,jddeflts.obj,jbsmooth.obj,jdarith.obj,jdcolor.obj,\
X jdhuff.obj,jdmcu.obj,jdpipe.obj,jdsample.obj,jquant1.obj,\
X jquant2.obj,jrevdct.obj,jrdjfif.obj,jwrgif.obj,jwrppm.obj,\
X jwrrle.obj,jwrtarga.obj,jutils.obj,jerror.obj,jmemmgr.obj,\
X jmemsys.obj
X
X
X.first
X @ Define Sys Sys$Library
X
X# By default, libjpeg.olb is not built unless you explicitly request it.
X# You can add libjpeg.olb to the next line if you want it built by default.
XALL : cjpeg.exe djpeg.exe
X @ Continue
X
Xcjpeg.exe : $(COBJECTS)
X $(LINK) $(LFLAGS) /Executable = cjpeg.exe $(COBJLIST),$(OPT)/Option
X
Xdjpeg.exe : $(DOBJECTS)
X $(LINK) $(LFLAGS) /Executable = djpeg.exe $(DOBJLIST),$(OPT)/Option
X
X# libjpeg.olb is useful if you are including the JPEG software in a larger
X# program; you'd include it in your link, rather than the individual modules.
Xlibjpeg.olb : $(LIBOBJECTS)
X Library /Create libjpeg.olb $(LIBOBJLIST)
X
Xclean :
X @- Set Protection = Owner:RWED *.*;-1
X @- Set Protection = Owner:RWED *.OBJ
X - Purge /NoLog /NoConfirm *.*
X - Delete /NoLog /NoConfirm *.OBJ;
X
X
Xjbsmooth.obj : jbsmooth.c jinclude.h jconfig.h jpegdata.h
Xjcarith.obj : jcarith.c jinclude.h jconfig.h jpegdata.h
Xjccolor.obj : jccolor.c jinclude.h jconfig.h jpegdata.h
Xjcdeflts.obj : jcdeflts.c jinclude.h jconfig.h jpegdata.h
Xjcexpand.obj : jcexpand.c jinclude.h jconfig.h jpegdata.h
Xjchuff.obj : jchuff.c jinclude.h jconfig.h jpegdata.h
Xjcmain.obj : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjcmaster.obj : jcmaster.c jinclude.h jconfig.h jpegdata.h
Xjcmcu.obj : jcmcu.c jinclude.h jconfig.h jpegdata.h
Xjcpipe.obj : jcpipe.c jinclude.h jconfig.h jpegdata.h
Xjcsample.obj : jcsample.c jinclude.h jconfig.h jpegdata.h
Xjdarith.obj : jdarith.c jinclude.h jconfig.h jpegdata.h
Xjdcolor.obj : jdcolor.c jinclude.h jconfig.h jpegdata.h
Xjddeflts.obj : jddeflts.c jinclude.h jconfig.h jpegdata.h
Xjdhuff.obj : jdhuff.c jinclude.h jconfig.h jpegdata.h
Xjdmain.obj : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjdmaster.obj : jdmaster.c jinclude.h jconfig.h jpegdata.h
Xjdmcu.obj : jdmcu.c jinclude.h jconfig.h jpegdata.h
Xjdpipe.obj : jdpipe.c jinclude.h jconfig.h jpegdata.h
Xjdsample.obj : jdsample.c jinclude.h jconfig.h jpegdata.h
Xjerror.obj : jerror.c jinclude.h jconfig.h jpegdata.h
Xjquant1.obj : jquant1.c jinclude.h jconfig.h jpegdata.h
Xjquant2.obj : jquant2.c jinclude.h jconfig.h jpegdata.h
Xjfwddct.obj : jfwddct.c jinclude.h jconfig.h jpegdata.h
Xjrevdct.obj : jrevdct.c jinclude.h jconfig.h jpegdata.h
Xjutils.obj : jutils.c jinclude.h jconfig.h jpegdata.h
Xjmemmgr.obj : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
Xjrdjfif.obj : jrdjfif.c jinclude.h jconfig.h jpegdata.h
Xjrdgif.obj : jrdgif.c jinclude.h jconfig.h jpegdata.h
Xjrdppm.obj : jrdppm.c jinclude.h jconfig.h jpegdata.h
Xjrdrle.obj : jrdrle.c jinclude.h jconfig.h jpegdata.h
Xjrdtarga.obj : jrdtarga.c jinclude.h jconfig.h jpegdata.h
Xjwrjfif.obj : jwrjfif.c jinclude.h jconfig.h jpegdata.h
Xjwrgif.obj : jwrgif.c jinclude.h jconfig.h jpegdata.h
Xjwrppm.obj : jwrppm.c jinclude.h jconfig.h jpegdata.h
Xjwrrle.obj : jwrrle.c jinclude.h jconfig.h jpegdata.h
Xjwrtarga.obj : jwrtarga.c jinclude.h jconfig.h jpegdata.h
Xjmemsys.obj : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
END_OF_FILE
if test 6695 -ne `wc -c <'makefile.mms'`; then
echo shar: \"'makefile.mms'\" unpacked with wrong size!
fi
# end of 'makefile.mms'
fi
if test -f 'makefile.sas' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.sas'\"
else
echo shar: Extracting \"'makefile.sas'\" \(6349 characters\)
sed "s/^X//" >'makefile.sas' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for Amiga systems using SAS C 5.10b.
X# Use jmemname.c as the system-dependent memory manager.
X# Contributed by Ed Hanway (sisd!j...@uunet.uu.net).
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC= lc
X
X# Uncomment the following lines for generic 680x0 version
XARCHFLAGS=
XSUFFIX=
X
X# Uncomment the following lines for 68030-only version
X#ARCHFLAGS= -m3
X#SUFFIX=.030
X
X# You may need to adjust these cc options:
XCFLAGS= -v -b -rr -O -j104 $(ARCHFLAGS) -DHAVE_STDC -DINCLUDES_ARE_ANSI \
X -DAMIGA -DTWO_FILE_COMMANDLINE -DINCOMPLETE_TYPES_BROKEN \
X -DNO_MKTEMP -DNEED_SIGNAL_CATCHER
X# -j104 disables warnings for mismatched const qualifiers
X
X# Link-time cc options:
XLDFLAGS= SC SD ND BATCH
X
X# To link any special libraries, add the necessary commands here.
XLDLIBS= LIB LIB:lcr.lib
X
X# miscellaneous OS-dependent stuff
X# linker
XLN= blink
X# file deletion command
XRM= delete quiet
X# library (.lib) file creation command
XAR= oml
X
X
X# source files (independently compilable files)
XSOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
X jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
X jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
X jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
X jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
X jwrppm.c jwrrle.c jwrtarga.c
X# virtual source files (not present in distribution file)
XVIRTSOURCES= jmemsys.c
X# system-dependent implementations of source files
XSYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
X jmemdosa.asm
X# files included by source files
XINCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
X# documentation, test, and support files
XDOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
XMAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
X makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
X makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
X makljpeg.cf makefile.mms makefile.vms makvms.opt
XOTHERFILES= ansi2knr.c ckconfig.c example.c
XTESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
XDISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
X $(OTHERFILES) $(TESTFILES)
X# objectfiles common to cjpeg and djpeg
XCOMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
X# compression objectfiles
XCLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
X jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
X jrdrle.o jrdtarga.o
XCOBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
X jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
X jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
XDOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.lib
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X
X
Xall: cjpeg$(SUFFIX) djpeg$(SUFFIX)
X# By default, libjpeg.lib is not built unless you explicitly request it.
X# You can add libjpeg.lib to the line above if you want it built by default.
X
X
Xcjpeg$(SUFFIX): $(COBJECTS)
X $(LN) <WITH <
X$(LDFLAGS)
XTO cjpeg$(SUFFIX)
XFROM LIB:c.o $(COBJECTS)
X$(LDLIBS)
X<
X
Xdjpeg$(SUFFIX): $(DOBJECTS)
X $(LN) <WITH <
X$(LDFLAGS)
XTO djpeg$(SUFFIX)
XFROM LIB:c.o $(DOBJECTS)
X$(LDLIBS)
X<
X
X# libjpeg.lib is useful if you are including the JPEG software in a larger
X# program; you'd include it in your link, rather than the individual modules.
Xlibjpeg.lib: $(LIBOBJECTS)
X -$(RM) libjpeg.lib
X $(AR) libjpeg.lib r $(LIBOBJECTS)
X
Xclean:
X -$(RM) *.o cjpeg djpeg cjpeg.030 djpeg.030 libjpeg.lib core testout.*
X
Xdistribute:
X -$(RM) jpegsrc.tar*
X tar cvf jpegsrc.tar $(DISTFILES)
X compress -v jpegsrc.tar
X
Xtest: cjpeg djpeg
X -$(RM) testout.ppm testout.gif testout.jpg
X djpeg testorig.jpg testout.ppm
X djpeg -G testorig.jpg testout.gif
X cjpeg testimg.ppm testout.jpg
X cmp testimg.ppm testout.ppm
X cmp testimg.gif testout.gif
X cmp testimg.jpg testout.jpg
X
X
Xjbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h
Xjcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h
Xjccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
Xjcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
Xjcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
Xjchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
Xjcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
Xjcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
Xjcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
Xjcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
Xjdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
Xjdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
Xjddeflts.o : jddeflts.c jinclude.h jconfig.h jpegdata.h
Xjdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
Xjdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
Xjdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
Xjdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
Xjdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
Xjerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
Xjquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
Xjquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
Xjfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
Xjrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
Xjutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
Xjmemmgr.o : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
Xjrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
Xjrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
Xjrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
Xjrdrle.o : jrdrle.c jinclude.h jconfig.h jpegdata.h
Xjrdtarga.o : jrdtarga.c jinclude.h jconfig.h jpegdata.h
Xjwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
Xjwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
Xjwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h
Xjwrrle.o : jwrrle.c jinclude.h jconfig.h jpegdata.h
Xjwrtarga.o : jwrtarga.c jinclude.h jconfig.h jpegdata.h
Xjmemsys.o : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
END_OF_FILE
if test 6349 -ne `wc -c <'makefile.sas'`; then
echo shar: \"'makefile.sas'\" unpacked with wrong size!
fi
# end of 'makefile.sas'
fi
if test -f 'makefile.unix' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.unix'\"
else
echo shar: Extracting \"'makefile.unix'\" \(6796 characters\)
sed "s/^X//" >'makefile.unix' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is suitable for Unix-like systems with non-ANSI compilers.
X# If you have an ANSI compiler, makefile.ansi is a better starting point.
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC= cc
X
X# You may need to adjust these cc options:
XCFLAGS= -O
X# In particular:
X# Add -DBSD if on a pure BSD system (see jinclude.h).
X# Add -DVMS if on a VMS system (see ansi2knr.c).
X# Add -DMSDOS if on an MSDOS system (see ansi2knr.c).
X# Add -DMEM_STATS to enable gathering of memory usage statistics.
X# You may also want to add -DTWO_FILE_COMMANDLINE or -D switches for other
X# symbols listed in jconfig.h, if you prefer not to change jconfig.h.
X
X# Link-time cc options:
XLDFLAGS=
X
X# To link any special libraries, add the necessary -l commands here.
X# In particular, on some versions of HP-UX (and probably other SysV-derived
X# systems) there is a faster alternate malloc(3) library that you can use
X# by adding "-lmalloc" to this line.
XLDLIBS=
X
X# miscellaneous OS-dependent stuff
X# linker
XLN= $(CC)
X# file deletion command
XRM= rm -f
X# library (.a) file creation command
XAR= ar rc
X# second step in .a creation (use "touch" if not needed)
XAR2= ranlib
X
X
X# source files (independently compilable files)
XSOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c jchuff.c \
X jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c jdarith.c jdcolor.c \
X jddeflts.c jdhuff.c jdmain.c jdmaster.c jdmcu.c jdpipe.c jdsample.c \
X jerror.c jquant1.c jquant2.c jfwddct.c jrevdct.c jutils.c jmemmgr.c \
X jrdjfif.c jrdgif.c jrdppm.c jrdrle.c jrdtarga.c jwrjfif.c jwrgif.c \
X jwrppm.c jwrrle.c jwrtarga.c
X# virtual source files (not present in distribution file)
XVIRTSOURCES= jmemsys.c
X# system-dependent implementations of source files
XSYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h \
X jmemdosa.asm
X# files included by source files
XINCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
X# documentation, test, and support files
XDOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
XMAKEFILES= makefile.ansi makefile.unix makefile.manx makefile.sas \
X makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk makefile.bcc \
X makcjpeg.lst makdjpeg.lst makefile.pwc makcjpeg.cf makdjpeg.cf \
X makljpeg.cf makefile.mms makefile.vms makvms.opt
XOTHERFILES= ansi2knr.c ckconfig.c example.c
XTESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
XDISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) \
X $(OTHERFILES) $(TESTFILES)
X# objectfiles common to cjpeg and djpeg
XCOMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
X# compression objectfiles
XCLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
X jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
X jrdrle.o jrdtarga.o
XCOBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
X jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
X jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
XDOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.a
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X
X
Xall: ansi2knr cjpeg djpeg
X# By default, libjpeg.a is not built unless you explicitly request it.
X# You can add libjpeg.a to the line above if you want it built by default.
X
X
X# This rule causes ansi2knr to be invoked. If you use this makefile,
X# make sure PROTO is not defined by jconfig.h.
X
X.c.o:
X ./ansi2knr $*.c tmpansi.c
X $(CC) $(CFLAGS) -c tmpansi.c
X mv tmpansi.o $*.o
X $(RM) tmpansi.c
X
Xansi2knr: ansi2knr.c
X $(CC) $(CFLAGS) -o ansi2knr ansi2knr.c
X
X
Xcjpeg: ansi2knr $(COBJECTS)
X $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
X
Xdjpeg: ansi2knr $(DOBJECTS)
X $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
X
X# libjpeg.a is useful if you are including the JPEG software in a larger
X# program; you'd include it in your link, rather than the individual modules.
Xlibjpeg.a: ansi2knr $(LIBOBJECTS)
X $(RM) libjpeg.a
X $(AR) libjpeg.a $(LIBOBJECTS)
X $(AR2) libjpeg.a
X
Xclean:
X $(RM) *.o cjpeg djpeg libjpeg.a ansi2knr core tmpansi.* testout.*
X
Xdistribute:
X $(RM) jpegsrc.tar*
X tar cvf jpegsrc.tar $(DISTFILES)
X compress -v jpegsrc.tar
X
Xtest: cjpeg djpeg
X $(RM) testout.ppm testout.gif testout.jpg
X ./djpeg testorig.jpg >testout.ppm
X ./djpeg -G testorig.jpg >testout.gif
X ./cjpeg testimg.ppm >testout.jpg
X cmp testimg.ppm testout.ppm
X cmp testimg.gif testout.gif
X cmp testimg.jpg testout.jpg
X
X
Xjbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h
Xjcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h
Xjccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h
Xjcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h
Xjcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h
Xjchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h
Xjcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h
Xjcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h
Xjcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h
Xjcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h
Xjdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h
Xjdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h
Xjddeflts.o : jddeflts.c jinclude.h jconfig.h jpegdata.h
Xjdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h
Xjdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h
Xjdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h
Xjdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h
Xjdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h
Xjerror.o : jerror.c jinclude.h jconfig.h jpegdata.h
Xjquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h
Xjquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h
Xjfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h
Xjrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h
Xjutils.o : jutils.c jinclude.h jconfig.h jpegdata.h
Xjmemmgr.o : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
Xjrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h
Xjrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h
Xjrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h
Xjrdrle.o : jrdrle.c jinclude.h jconfig.h jpegdata.h
Xjrdtarga.o : jrdtarga.c jinclude.h jconfig.h jpegdata.h
Xjwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h
Xjwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h
Xjwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h
Xjwrrle.o : jwrrle.c jinclude.h jconfig.h jpegdata.h
Xjwrtarga.o : jwrtarga.c jinclude.h jconfig.h jpegdata.h
Xjmemsys.o : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
END_OF_FILE
if test 6796 -ne `wc -c <'makefile.unix'`; then
echo shar: \"'makefile.unix'\" unpacked with wrong size!
fi
# end of 'makefile.unix'
fi
echo shar: End of archive 15 \(of 18\).
cp /dev/null ark15isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jddeflts.c jdmcu.c jwrtarga.c makdjpeg.cf makefile.bcc
# makefile.manx makefile.mc5 testimg.jpg.u testorig.jpg.u
# Wrapped by kent@sparky on Mon Mar 23 16:02:56 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 16 (of 18)."'
if test -f 'jddeflts.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jddeflts.c'\"
else
echo shar: Extracting \"'jddeflts.c'\" \(6026 characters\)
sed "s/^X//" >'jddeflts.c' <<'END_OF_FILE'
X/*
X * jddeflts.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains optional default-setting code for the JPEG decompressor.
X * User interfaces do not have to use this file, but those that don't use it
X * must know more about the innards of the JPEG code.
X */
X
X#include "jinclude.h"
X
X
X/* Default do-nothing progress monitoring routine.
X * This can be overridden by a user interface that wishes to
X * provide progress monitoring; just set methods->progress_monitor
X * after j_d_defaults is done. The routine will be called periodically
X * during the decompression process.
X *
X * During any one pass, loopcounter increases from 0 up to (not including)
X * looplimit; the step size is not necessarily 1. Both the step size and
X * the limit may differ between passes. The expected total number of passes
X * is in cinfo->total_passes, and the number of passes already completed is
X * in cinfo->completed_passes. Thus the fraction of work completed may be
X * estimated as
X * completed_passes + (loopcounter/looplimit)
X * ------------------------------------------
X * total_passes
X * ignoring the fact that the passes may not be equal amounts of work.
X *
X * When decompressing, the total_passes figure is an estimate that may be
X * on the high side; completed_passes will jump by more than one if some
X * passes are skipped.
X */
X
XMETHODDEF void
Xprogress_monitor (decompress_info_ptr cinfo, long loopcounter, long looplimit)
X{
X /* do nothing */
X}
X
X
X/*
X * Reload the input buffer after it's been emptied, and return the next byte.
X * See the JGETC macro for calling conditions.
X *
X * This routine can be overridden by the system-dependent user interface,
X * in case the data source is not a stdio stream or some other special
X * condition applies. Note, however, that this capability only applies for
X * JFIF or similar serial-access JPEG file formats. The input file control
X * module for a random-access format such as TIFF/JPEG would most likely
X * override the read_jpeg_data method with its own routine.
X */
X
XMETHODDEF int
Xread_jpeg_data (decompress_info_ptr cinfo)
X{
X cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
X
X cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
X cinfo->next_input_byte,
X JPEG_BUF_SIZE);
X
X if (cinfo->bytes_in_buffer <= 0)
X ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
X
X return JGETC(cinfo);
X}
X
X
X
X/* Default parameter setup for decompression.
X *
X * User interfaces that don't choose to use this routine must do their
X * own setup of all these parameters. Alternately, you can call this
X * to establish defaults and then alter parameters selectively. This
X * is the recommended approach since, if we add any new parameters,
X * your code will still work (they'll be set to reasonable defaults).
X *
X * standard_buffering should be TRUE to cause an input buffer to be allocated
X * (the normal case); if FALSE, the user interface must provide a buffer.
X * This option is most useful in the case that the buffer must not be freed
X * at the end of an image. (For example, when reading a sequence of images
X * from a single file, the remaining data in the buffer represents the
X * start of the next image and mustn't be discarded.) To handle this,
X * allocate the input buffer yourself at startup, WITHOUT using alloc_small
X * (probably a direct call to malloc() instead). Then pass FALSE on each
X * call to j_d_defaults to ensure the buffer state is not modified.
X *
X * If the source of the JPEG data is not a stdio stream, override the
X * read_jpeg_data method with your own routine after calling j_d_defaults.
X * You can still use the standard buffer if it's appropriate.
X *
X * CAUTION: if you want to decompress multiple images per run, it's necessary
X * to call j_d_defaults before *each* call to jpeg_decompress, since subsidiary
X * structures like the quantization tables are automatically freed during
X * cleanup.
X */
X
XGLOBAL void
Xj_d_defaults (decompress_info_ptr cinfo, boolean standard_buffering)
X/* NB: the external methods must already be set up. */
X{
X short i;
X
X /* Initialize pointers as needed to mark stuff unallocated. */
X /* Outer application may fill in default tables for abbreviated files... */
X cinfo->comp_info = NULL;
X for (i = 0; i < NUM_QUANT_TBLS; i++)
X cinfo->quant_tbl_ptrs[i] = NULL;
X for (i = 0; i < NUM_HUFF_TBLS; i++) {
X cinfo->dc_huff_tbl_ptrs[i] = NULL;
X cinfo->ac_huff_tbl_ptrs[i] = NULL;
X }
X cinfo->colormap = NULL;
X
X /* Default to RGB output */
X /* UI can override by changing out_color_space */
X cinfo->out_color_space = CS_RGB;
X cinfo->jpeg_color_space = CS_UNKNOWN;
X /* Setting any other value in jpeg_color_space overrides heuristics in */
X /* jrdjfif.c. That might be useful when reading non-JFIF JPEG files, */
X /* but ordinarily the UI shouldn't change it. */
X
X /* Default to no gamma correction of output */
X cinfo->output_gamma = 1.0;
X
X /* Default to no color quantization */
X cinfo->quantize_colors = FALSE;
X /* but set reasonable default parameters for quantization, */
X /* so that turning on quantize_colors is sufficient to do something useful */
X cinfo->two_pass_quantize = TRUE;
X cinfo->use_dithering = TRUE;
X cinfo->desired_number_of_colors = 256;
X
X /* Default to no smoothing */
X cinfo->do_block_smoothing = FALSE;
X cinfo->do_pixel_smoothing = FALSE;
X
X /* Allocate memory for input buffer, unless outer application provides it. */
X if (standard_buffering) {
X cinfo->input_buffer = (char *) (*cinfo->emethods->alloc_small)
X ((size_t) (JPEG_BUF_SIZE + MIN_UNGET));
X cinfo->bytes_in_buffer = 0; /* initialize buffer to empty */
X }
X
X /* Install standard buffer-reloading method (outer code may override). */
X cinfo->methods->read_jpeg_data = read_jpeg_data;
X
X /* Install default do-nothing progress monitoring method. */
X cinfo->methods->progress_monitor = progress_monitor;
X}
END_OF_FILE
if test 6026 -ne `wc -c <'jddeflts.c'`; then
echo shar: \"'jddeflts.c'\" unpacked with wrong size!
fi
# end of 'jddeflts.c'
fi
if test -f 'jdmcu.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdmcu.c'\"
else
echo shar: Extracting \"'jdmcu.c'\" \(6106 characters\)
sed "s/^X//" >'jdmcu.c' <<'END_OF_FILE'
X/*
X * jdmcu.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains MCU disassembly routines and quantization descaling.
X * These routines are invoked via the disassemble_MCU, reverse_DCT, and
X * disassemble_init/term methods.
X */
X
X#include "jinclude.h"
X
X
X/*
X * Quantization descaling and zigzag reordering
X */
X
X
X/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
X
Xstatic const short ZAG[DCTSIZE2] = {
X 0, 1, 8, 16, 9, 2, 3, 10,
X 17, 24, 32, 25, 18, 11, 4, 5,
X 12, 19, 26, 33, 40, 48, 41, 34,
X 27, 20, 13, 6, 7, 14, 21, 28,
X 35, 42, 49, 56, 57, 50, 43, 36,
X 29, 22, 15, 23, 30, 37, 44, 51,
X 58, 59, 52, 45, 38, 31, 39, 46,
X 53, 60, 61, 54, 47, 55, 62, 63
X};
X
X
XLOCAL void
Xqdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl)
X{
X const short * zagptr = ZAG;
X short i;
X
X for (i = DCTSIZE2-1; i >= 0; i--) {
X (*outputptr)[*zagptr++] = (*input++) * (*quanttbl++);
X }
X}
X
X
X
X/*
X * Fetch one MCU row from entropy_decode, build coefficient array.
X * This version is used for noninterleaved (single-component) scans.
X */
X
XMETHODDEF void
Xdisassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
X JBLOCKIMAGE image_data)
X{
X JBLOCK MCU_data[1];
X long mcuindex;
X jpeg_component_info * compptr;
X QUANT_TBL_PTR quant_ptr;
X
X /* this is pretty easy since there is one component and one block per MCU */
X compptr = cinfo->cur_comp_info[0];
X quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
X for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
X /* Fetch the coefficient data */
X (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
X /* Descale, reorder, and distribute it into the image array */
X qdescale_zig(MCU_data[0], image_data[0][0] + mcuindex, quant_ptr);
X }
X}
X
X
X/*
X * Fetch one MCU row from entropy_decode, build coefficient array.
X * This version is used for interleaved (multi-component) scans.
X */
X
XMETHODDEF void
Xdisassemble_interleaved_MCU (decompress_info_ptr cinfo,
X JBLOCKIMAGE image_data)
X{
X JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
X long mcuindex;
X short blkn, ci, xpos, ypos;
X jpeg_component_info * compptr;
X QUANT_TBL_PTR quant_ptr;
X JBLOCKROW image_ptr;
X
X for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
X /* Fetch the coefficient data */
X (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
X /* Descale, reorder, and distribute it into the image array */
X blkn = 0;
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
X for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
X image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
X for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
X qdescale_zig(MCU_data[blkn], image_ptr, quant_ptr);
X image_ptr++;
X blkn++;
X }
X }
X }
X }
X}
X
X
X/*
X * Perform inverse DCT on each block in an MCU row's worth of data;
X * output the results into a sample array starting at row start_row.
X * NB: start_row can only be nonzero when dealing with a single-component
X * scan; otherwise we'd have to pass different offsets for different
X * components, since the heights of interleaved MCU rows can vary.
X * But the pipeline controller logic is such that this is not necessary.
X */
X
XMETHODDEF void
Xreverse_DCT (decompress_info_ptr cinfo,
X JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data, int start_row)
X{
X DCTBLOCK block;
X JBLOCKROW browptr;
X JSAMPARRAY srowptr;
X long blocksperrow, bi;
X short numrows, ri;
X short ci;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X /* calculate size of an MCU row in this component */
X blocksperrow = cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE;
X numrows = cinfo->cur_comp_info[ci]->MCU_height;
X /* iterate through all blocks in MCU row */
X for (ri = 0; ri < numrows; ri++) {
X browptr = coeff_data[ci][ri];
X srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
X for (bi = 0; bi < blocksperrow; bi++) {
X /* copy the data into a local DCTBLOCK. This allows for change of
X * representation (if DCTELEM != JCOEF). On 80x86 machines it also
X * brings the data back from FAR storage to NEAR storage.
X */
X { register JCOEFPTR elemptr = browptr[bi];
X register DCTELEM *localblkptr = block;
X register short elem = DCTSIZE2;
X
X while (--elem >= 0)
X *localblkptr++ = (DCTELEM) *elemptr++;
X }
X
X j_rev_dct(block); /* perform inverse DCT */
X
X /* output the data into the sample array.
X * Note change from signed to unsigned representation:
X * DCT calculation works with values +-CENTERJSAMPLE,
X * but sample arrays always hold 0..MAXJSAMPLE.
X * Have to do explicit range-limiting because of quantization errors
X * and so forth in the DCT/IDCT phase.
X */
X { register JSAMPROW elemptr;
X register DCTELEM *localblkptr = block;
X register short elemr, elemc;
X register DCTELEM temp;
X
X for (elemr = 0; elemr < DCTSIZE; elemr++) {
X elemptr = srowptr[elemr] + (bi * DCTSIZE);
X for (elemc = 0; elemc < DCTSIZE; elemc++) {
X temp = (*localblkptr++) + CENTERJSAMPLE;
X if (temp < 0) temp = 0;
X else if (temp > MAXJSAMPLE) temp = MAXJSAMPLE;
X *elemptr++ = (JSAMPLE) temp;
X }
X }
X }
X }
X }
X }
X}
X
X
X/*
X * Initialize for processing a scan.
X */
X
XMETHODDEF void
Xdisassemble_init (decompress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X/*
X * Clean up after a scan.
X */
X
XMETHODDEF void
Xdisassemble_term (decompress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X
X/*
X * The method selection routine for MCU disassembly.
X */
X
XGLOBAL void
Xjseldmcu (decompress_info_ptr cinfo)
X{
X if (cinfo->comps_in_scan == 1)
X cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
X else
X cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
X cinfo->methods->reverse_DCT = reverse_DCT;
X cinfo->methods->disassemble_init = disassemble_init;
X cinfo->methods->disassemble_term = disassemble_term;
X}
END_OF_FILE
if test 6106 -ne `wc -c <'jdmcu.c'`; then
echo shar: \"'jdmcu.c'\" unpacked with wrong size!
fi
# end of 'jdmcu.c'
fi
if test -f 'jwrtarga.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jwrtarga.c'\"
else
echo shar: Extracting \"'jwrtarga.c'\" \(5888 characters\)
sed "s/^X//" >'jwrtarga.c' <<'END_OF_FILE'
X/*
X * jwrtarga.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to write output images in Targa format.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume output to
X * an ordinary stdio stream.
X *
X * These routines are invoked via the methods put_pixel_rows, put_color_map,
X * and output_init/term.
X *
X * Based on code contributed by Lee Daniel Crocker.
X */
X
X#include "jinclude.h"
X
X#ifdef TARGA_SUPPORTED
X
X
X/*
X * To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
X * This is not yet implemented.
X */
X
X#ifndef EIGHT_BIT_SAMPLES
X Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
X#endif
X
X
XLOCAL void
Xwrite_header (decompress_info_ptr cinfo, int num_colors)
X/* Create and write a Targa header */
X{
X char targaheader[18];
X
X /* Set unused fields of header to 0 */
X MEMZERO((void *) targaheader, SIZEOF(targaheader));
X
X if (num_colors > 0) {
X targaheader[1] = 1; /* color map type 1 */
X targaheader[5] = (char) (num_colors & 0xFF);
X targaheader[6] = (char) (num_colors >> 8);
X targaheader[7] = 24; /* 24 bits per cmap entry */
X }
X
X targaheader[12] = (char) (cinfo->image_width & 0xFF);
X targaheader[13] = (char) (cinfo->image_width >> 8);
X targaheader[14] = (char) (cinfo->image_height & 0xFF);
X targaheader[15] = (char) (cinfo->image_height >> 8);
X targaheader[17] = 0x20; /* Top-down, non-interlaced */
X
X if (cinfo->out_color_space == CS_GRAYSCALE) {
X targaheader[2] = 3; /* image type = uncompressed gray-scale */
X targaheader[16] = 8; /* bits per pixel */
X } else { /* must be RGB */
X if (num_colors > 0) {
X targaheader[2] = 1; /* image type = colormapped RGB */
X targaheader[16] = 8;
X } else {
X targaheader[2] = 2; /* image type = uncompressed RGB */
X targaheader[16] = 24;
X }
X }
X
X if (JFWRITE(cinfo->output_file, targaheader, 18) != (size_t) 18)
X ERREXIT(cinfo->emethods, "Could not write Targa header");
X}
X
X
X/*
X * Write the file header.
X */
X
XMETHODDEF void
Xoutput_init (decompress_info_ptr cinfo)
X{
X if (cinfo->out_color_space == CS_GRAYSCALE) {
X /* Targa doesn't have a mapped grayscale format, so we will */
X /* demap quantized gray output. Never emit a colormap. */
X write_header(cinfo, 0);
X } else if (cinfo->out_color_space == CS_RGB) {
X /* For quantized output, defer writing header until put_color_map time. */
X if (! cinfo->quantize_colors)
X write_header(cinfo, 0);
X } else {
X ERREXIT(cinfo->emethods, "Targa output must be grayscale or RGB");
X }
X}
X
X
X/*
X * Write some pixel data.
X */
X
XMETHODDEF void
Xput_pixel_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X register FILE * outfile = cinfo->output_file;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X register long width = cinfo->image_width;
X register int row;
X
X if (cinfo->final_out_comps == 1) {
X /* here for grayscale or quantized color output */
X for (row = 0; row < num_rows; row++) {
X ptr0 = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(*ptr0), outfile);
X ptr0++;
X }
X }
X } else {
X /* here for unquantized color output */
X for (row = 0; row < num_rows; row++) {
X ptr0 = pixel_data[0][row];
X ptr1 = pixel_data[1][row];
X ptr2 = pixel_data[2][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(*ptr2), outfile); /* write in BGR order */
X ptr2++;
X putc(GETJSAMPLE(*ptr1), outfile);
X ptr1++;
X putc(GETJSAMPLE(*ptr0), outfile);
X ptr0++;
X }
X }
X }
X}
X
X
X/*
X * Write some demapped pixel data when color quantization is in effect.
X * For Targa, this is only applied to grayscale data.
X */
X
XMETHODDEF void
Xput_demapped_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X register FILE * outfile = cinfo->output_file;
X register JSAMPARRAY color_map = cinfo->colormap;
X register JSAMPROW ptr;
X register long col;
X long width = cinfo->image_width;
X int row;
X
X for (row = 0; row < num_rows; row++) {
X ptr = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(color_map[0][GETJSAMPLE(*ptr)]), outfile);
X ptr++;
X }
X }
X}
X
X
X/*
X * Write the color map.
X */
X
XMETHODDEF void
Xput_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
X{
X register FILE * outfile = cinfo->output_file;
X int i;
X
X if (cinfo->out_color_space == CS_RGB) {
X /* We only support 8-bit colormap indexes, so only 256 colors */
X if (num_colors > 256)
X ERREXIT(cinfo->emethods, "Too many colors for Targa output");
X /* Time to write the header */
X write_header(cinfo, num_colors);
X /* Write the colormap. Note Targa uses BGR byte order */
X for (i = 0; i < num_colors; i++) {
X putc(GETJSAMPLE(colormap[2][i]), outfile);
X putc(GETJSAMPLE(colormap[1][i]), outfile);
X putc(GETJSAMPLE(colormap[0][i]), outfile);
X }
X } else {
X cinfo->methods->put_pixel_rows = put_demapped_rows;
X }
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xoutput_term (decompress_info_ptr cinfo)
X{
X /* No work except to make sure we wrote the output file OK */
X fflush(cinfo->output_file);
X if (ferror(cinfo->output_file))
X ERREXIT(cinfo->emethods, "Output file write error");
X}
X
X
X/*
X * The method selection routine for Targa format output.
X * This should be called from d_ui_method_selection if Targa output is wanted.
X */
X
XGLOBAL void
Xjselwtarga (decompress_info_ptr cinfo)
X{
X cinfo->methods->output_init = output_init;
X cinfo->methods->put_color_map = put_color_map;
X cinfo->methods->put_pixel_rows = put_pixel_rows;
X cinfo->methods->output_term = output_term;
X}
X
X#endif /* TARGA_SUPPORTED */
END_OF_FILE
if test 5888 -ne `wc -c <'jwrtarga.c'`; then
echo shar: \"'jwrtarga.c'\" unpacked with wrong size!
fi
# end of 'jwrtarga.c'
fi
if test -f 'makdjpeg.cf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makdjpeg.cf'\"
else
echo shar: Extracting \"'makdjpeg.cf'\" \(300 characters\)
sed "s/^X//" >'makdjpeg.cf' <<'END_OF_FILE'
XL jdmain.mix jdmaster.mix jddeflts.mix jbsmooth.mix jdarith.mix jdcolor.mix
XL jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix
XL jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jwrrle.mix jwrtarga.mix
XL jutils.mix jerror.mix jmemmgr.mix jmemsys.mix jmemdosa.mix
Xfa;
Xb djpeg,8K,48K,
END_OF_FILE
if test 300 -ne `wc -c <'makdjpeg.cf'`; then
echo shar: \"'makdjpeg.cf'\" unpacked with wrong size!
fi
# end of 'makdjpeg.cf'
fi
if test -f 'makefile.bcc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.bcc'\"
else
echo shar: Extracting \"'makefile.bcc'\" \(6113 characters\)
sed "s/^X//" >'makefile.bcc' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is suitable for Borland C (Turbo C) on MS-DOS.
X# It is set up for Borland C++, revision 3.0 or later.
X# For older versions (pre-3.0), replace "-O2" with "-O -G -Z" in CFLAGS.
X# If you have an even older version of Turbo C, you may be able to make it
X# work by saying "CC= tcc" below. (Very early versions of Turbo C++,
X# like 1.01, are so buggy that you may as well forget it.)
X# Thanks to Tom Wright and Ge' Weijers for this file.
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC= bcc
X
X# You may need to adjust these cc options:
XCFLAGS= -DHAVE_STDC -DINCLUDES_ARE_ANSI \
X -ms -DMSDOS -DINCOMPLETE_TYPES_BROKEN -w-par -O2
X# -DHAVE_STDC -DINCLUDES_ARE_ANSI enable ANSI-C features (we DON'T want -A)
X# -ms selects small memory model for most efficient code
X# -DMSDOS enables DOS-specific code
X# -DINCOMPLETE_TYPES_BROKEN suppresses bogus warning about undefined structures
X# -w-par suppresses warnings about unused function parameters
X# -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z)
X
X# Link-time cc options:
XLDFLAGS= -ms
X# memory model option here must match CFLAGS!
XCOMOBJECTS= jutils.obj jerror.obj jmemmgr.obj jmemsys.obj jmemdosa.obj
X# compression objectfiles
XCLIBOBJECTS= jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
X jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
X jwrjfif.obj jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj
XCOBJECTS= jcmain.obj $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj \
X jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj \
X jquant2.obj jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj \
X jwrrle.obj jwrtarga.obj
XDOBJECTS= jdmain.obj $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.lib
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X
X
Xall: cjpeg.exe djpeg.exe
X
X
Xcjpeg.exe: $(COBJECTS)
X $(CC) $(LDFLAGS) -ecjpeg.exe @makcjpeg.lst
X
Xdjpeg.exe: $(DOBJECTS)
X $(CC) $(LDFLAGS) -edjpeg.exe @makdjpeg.lst
X
X.c.obj:
X $(CC) $(CFLAGS) -c $<
X
Xclean:
X del *.obj
X del cjpeg.exe
X del djpeg.exe
X del testout.*
X
Xtest:
X del testout.*
X djpeg testorig.jpg testout.ppm
X djpeg -G testorig.jpg testout.gif
X cjpeg testimg.ppm testout.jpg
X fc testimg.ppm testout.ppm
X fc testimg.gif testout.gif
X fc testimg.jpg testout.jpg
Xjmemdosa.obj : jmemdosa.asm
X tasm /mx jmemdosa.asm
END_OF_FILE
if test 6113 -ne `wc -c <'makefile.bcc'`; then
echo shar: \"'makefile.bcc'\" unpacked with wrong size!
fi
# end of 'makefile.bcc'
fi
if test -f 'makefile.manx' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.manx'\"
else
echo shar: Extracting \"'makefile.manx'\" \(5948 characters\)
sed "s/^X//" >'makefile.manx' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for Amiga systems using Manx Aztec C ver 5.x.
X# Use jmemname.c as the system-dependent memory manager.
X# Thanks to D.J. James (djj...@cup.portal.com) for this version.
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC= cc
X
X# You may need to adjust these cc options:
XCFLAGS= -MC -MD -sf -sn -sp -DAMIGA -DTWO_FILE_COMMANDLINE \
X -DNEED_SIGNAL_CATCHER -Dsignal_catcher=_abort
X
X# Link-time cc options:
XLDFLAGS=
X
X# To link any special libraries, add the necessary -l commands here.
XLDLIBS= -lml -lcl
X
X# miscellaneous OS-dependent stuff
X# linker
XLN= ln
X# file deletion command
XRM= delete quiet
X# library (.lib) file creation command
XAR= lb
Xall: cjpeg djpeg
X# By default, libjpeg.lib is not built unless you explicitly request it.
X# You can add libjpeg.lib to the line above if you want it built by default.
X
X
Xcjpeg: $(COBJECTS)
X $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
X
Xdjpeg: $(DOBJECTS)
X $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
X
X# libjpeg.lib is useful if you are including the JPEG software in a larger
X# program; you'd include it in your link, rather than the individual modules.
Xlibjpeg.lib: $(LIBOBJECTS)
X -$(RM) libjpeg.lib
X $(AR) libjpeg.lib $(LIBOBJECTS)
X
Xclean:
X -$(RM) *.o cjpeg djpeg libjpeg.lib core testout.*
if test 5948 -ne `wc -c <'makefile.manx'`; then
echo shar: \"'makefile.manx'\" unpacked with wrong size!
fi
# end of 'makefile.manx'
fi
if test -f 'makefile.mc5' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.mc5'\"
else
echo shar: Extracting \"'makefile.mc5'\" \(6015 characters\)
sed "s/^X//" >'makefile.mc5' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for Microsoft C for MS-DOS, version 5.x.
X
X# Read SETUP instructions before saying "make" !!
X
X# Microsoft's brain-damaged version of make uses nonstandard syntax (a blank
X# line is needed to terminate a command list) and it simply scans the rules
X# in order, rather than doing a true dependency-tree walk. Furthermore,
X# expanded command lines can't exceed 128 chars (this is a DOS bug, not
X# make's fault); so we can't just name all the objectfiles in the link steps.
X# Instead we shove each objectfile into a library as it is made, and link
X# from the library. The objectfiles are also kept separately as timestamps.
X
X# You may need to adjust these cc options:
XCFLAGS= /AS /I. /W3 /Oail /Gs # NB: /Gs turns off stack oflo checks
XLDFLAGS= /Fm /F 2000 # /F hhhh sets stack size (in hex)
X# In particular:
X# Add /DMSDOS if your compiler doesn't automatically #define MSDOS.
X# Add /DMEM_STATS to enable gathering of memory usage statistics.
X# You might also want to add /G2 if you have an 80286, etc.
XCOMOBJECTS= jutils.obj jerror.obj jmemmgr.obj jmemsys.obj jmemdosa.obj
X# compression objectfiles
XCLIBOBJECTS= jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
X jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
X jwrjfif.obj jrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj
XCOBJECTS= jcmain.obj $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj \
X jdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj \
X jquant2.obj jrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj \
X jwrrle.obj jwrtarga.obj
XDOBJECTS= jdmain.obj $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.lib
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X
X
X# inference rule used for all compilations except jcmain.c, jdmain.c
X# notice that objectfile is also inserted into libjpeg.lib
X.c.obj:
X cl $(CFLAGS) /c $*.c
X lib libjpeg -+$*.obj;
X
X# inference rule for assembly code
X.asm.obj:
X masm /mx $*;
X lib libjpeg -+$*.obj;
X
X
Xjbsmooth.obj : jbsmooth.c jinclude.h jconfig.h jpegdata.h
X
Xjcarith.obj : jcarith.c jinclude.h jconfig.h jpegdata.h
X
Xjccolor.obj : jccolor.c jinclude.h jconfig.h jpegdata.h
X
Xjcdeflts.obj : jcdeflts.c jinclude.h jconfig.h jpegdata.h
X
Xjcexpand.obj : jcexpand.c jinclude.h jconfig.h jpegdata.h
X
Xjchuff.obj : jchuff.c jinclude.h jconfig.h jpegdata.h
X
Xjcmain.obj : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
X cl $(CFLAGS) /c $*.c
X
Xjcmaster.obj : jcmaster.c jinclude.h jconfig.h jpegdata.h
X
Xjcmcu.obj : jcmcu.c jinclude.h jconfig.h jpegdata.h
X
Xjcpipe.obj : jcpipe.c jinclude.h jconfig.h jpegdata.h
X
Xjcsample.obj : jcsample.c jinclude.h jconfig.h jpegdata.h
X
Xjdarith.obj : jdarith.c jinclude.h jconfig.h jpegdata.h
X
Xjdcolor.obj : jdcolor.c jinclude.h jconfig.h jpegdata.h
X
Xjddeflts.obj : jddeflts.c jinclude.h jconfig.h jpegdata.h
X
Xjdhuff.obj : jdhuff.c jinclude.h jconfig.h jpegdata.h
X
Xjdmain.obj : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
X cl $(CFLAGS) /c $*.c
X
X
Xjmemdosa.obj : jmemdosa.asm
X
X
Xcjpeg.exe: $(COBJECTS)
X cl /Fecjpeg.exe jcmain.obj libjpeg.lib $(LDFLAGS)
X
Xdjpeg.exe: $(DOBJECTS)
X cl /Fedjpeg.exe jdmain.obj libjpeg.lib $(LDFLAGS)
END_OF_FILE
if test 6015 -ne `wc -c <'makefile.mc5'`; then
echo shar: \"'makefile.mc5'\" unpacked with wrong size!
fi
# end of 'makefile.mc5'
fi
if test -f 'testimg.jpg.u' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'testimg.jpg.u'\"
else
echo shar: Extracting \"'testimg.jpg.u'\" \(6072 characters\)
sed "s/^X//" >'testimg.jpg.u' <<'END_OF_FILE'
Xbegin 666 testimg.jpg
XM_]C_X 02D9)1@ ! 0 0 ! #_VP!# @&!@<&!0@'!P<)"0@*#!0-# L+
XM#!D2$P\4'1H?'AT:'!P@)"XG("(L(QP<*#<I+# Q-#0T'R<Y/3@R/"XS-#+_
XMVP!# 0D)"0P+#!@-#1@R(1PA,C(R,C(R,C(R,C(R,C(R,C(R,C(R,C(R,C(R
XM,C(R,C(R,C(R,C(R,C(R,C(R,C(R,C+_P 1" !] 'T# 2( A$! Q$!_\0
XM'P 04! 0$! 0$ $" P0%!@<("0H+_\0 M1 @$# P($ P4%
XM! 0 %] 0(# 01!1(A,4$&$U%A!R)Q%#*!D:$((T*QP152T? D,V)R@@D*
XM%A<8&1HE)B<H*2HT-38W.#DZ0T1%1D=(24I35%565UA96F-D969G:&EJ<W1U
XM=G=X>7J#A(6&AXB)BI*3E)66EYB9FJ*CI*6FIZBIJK*SM+6VM[BYNL+#Q,7&
XMQ\C)RM+3U-76U]C9VN'BX^3EYN?HZ>KQ\O/T]?;W^/GZ_\0 'P$ P$! 0$!
XM 0$! 0 $" P0%!@<("0H+_\0 M1$ @$"! 0#! <%! 0 0)W $"
XM Q$$!2$Q!A)!40=A<1,B,H$(%$*1H;'!"2,S4O 58G+1"A8D-.$E\1<8&1HF
XM)R@I*C4V-S@Y.D-$149'2$E*4U155E=865IC9&5F9VAI:G-T=79W>'EZ@H.$
XMA8:'B(F*DI.4E9:7F)F:HJ.DI::GJ*FJLK.TM;:WN+FZPL/$Q<;'R,G*TM/4
XMU=;7V-G:XN/DY>;GZ.GJ\O/T]?;W^/GZ_]H # ,! (1 Q$ /P"1I?N1QJ V
XM/E4= *E0) K%CESC+>IJ")1;Q%F8F1CR>] .[YWZYP!7%8^L+<;DG<^>?N@=
XM6J8W4<&WS&)F(.$49('T]*I-+Y &1F1CA5]#_D51N[Z.#]U+,!(_+E?O'V [
XM5I3I\S,IZ&Q_;5NJLN\H^.CC&3[5,;]HI52>+RE925F+9&?2O/KS48'N$1(Y
XM7E#@_,_!] /PK7OM8NI8H())XXIWXQC)'^?\]JZEA4T<TIV9V:3Q;0RN)!D
XM_,#G\..E)+J,$$'F/*/+'.X<]L]J\VGNIHI8U%PVY^3*&P3P3CCM]/S-5-$T
XM[4->NC,9Y(K2,@27!."/8>K<]*3PL8ZMZ$>TOT/6(KHW)3R&$N\95E.1CUSZ
XM5H6UF6Y)\S'<_=4^WK5+0]*AT_38+;:Z6Z+\L;'YVYZM_AVK<+*HPH '3 %<
XM<K7LMB)SZ(0*(CD#>_JU2#>_+<TW.2*DWJB%F8*H&23T%"1@VV/1 H]Z661+
XM:W>9^BC@>I]*YO6?&-O81JMC&+IV!_>9P@_QKE9KW7O$)(D=UB)X51M6JU-:
XM>'E/5Z(UKO789+IH$)GGE;#"/N?3/84GB7QB_@N+3[5(DDN;B-I94_N+D!?_
XM &;\JK,-.\$6":A>XN+QSB& -@D]_H/>O--7U"[U[5;C4;J15EF;..< =@/8
XM#BM*5-3=WL;32?NK8] P[GS6!SV7L*7<JIYCEAQQM[>]-W(!NF;YP/NYX%<W
XMJ6L>8;BVV$+&27D![=AQUHIP4M#MG+E6I<N=8N77R57$@8E)."?3M[&L!9#=
XMW#PPRL/E+2R]]H&3S_2F6EZ[EXR0 R_+_A1&$M9W;YC$VU7(ZE3G(KOA!15D
XM<<Y.3(["7R!+>X^9.(E/8D8!_"KEK=QF6>>X!DG*,Q;^XH'0>A[53U2W:RN&
XMPZF$ &/:PSM(R..O>M#0]/O]27SV\UH'_=QKGF0]>/;CDT^91W)M=:%O3](:
XM;4[:XN_,\LQ?P#^)AQ&OT!Y->H:1H\=A!$TD:)Y8_=PI]V,?U/O63H&DFWSY
XMLV^6-L'I@$^GX8K>N93$ @8DGK7%BI\TK+8R3:5D3,YW%B<XI(W9R/[I]:KL
XMQ!5>K'J,]!5^VM_ERYR3T'85S:!RNUQLLQB@DD2,R,BY"@XS^->9W>MZCK%T
XMW]H.R6ZN1]GBR%"]L]RP//->L"(E",9![5Y!XR5]*U222(;58_,O9@>U:46N
XM>QM3IQ<6^J.BT=5WFW= Y&"I(SU]/\]ZO:WX@T[PS;AKD>==-_J[5#@_5O05
XM@>&+MKFU<HYS$#M;/(4C(_J/PKSW4)FNM2GG+%M[DY/)JY4%.I=[%IM1L3:G
XMJ=YKFI27]Z^Z1SA0.%1>P ["JSD#'TJ5%&WT JJY+L374K+1"L='J>H)>WGE
XM1#8&W#?R<@#)P/PK&C=IHYH9"=\A5E &2V,_+^HK1@C0ZBDA^6)%,$&[^)R#
XM^F3_ "K-M)'A0-OV,[;>1D^_\ZT4%!61,JCDVV#H1<"( !P0N!V)JW:2J#,C
XMQ^:'7*_0*23]:I#_ $>^*3%@RM\S#L?6K:PO//;V%L5>1T$8;.0%^\6^G/Z&
XMFFDKB9<L=,B\0RV4^6$$2>7< MEF(/RJ/J"/RKU/1["*W4)L5'";0J]$7^Z/
XMZU0\->'XK.*+:@PJD1''//5S[GMZ"MP/#;337,KB.WB&W<W&37FUJKJ2TV&[
XM13BMQMO&L6H3;AA%"MN/?C''Y5%+.9'8QC&3QD=*Q]3U;[:P,-ZMI & P,L
XM>@R>P]JSY-;U#3[@HT<5U&O78WS"H;YMC6GAFM9;G86L>QP3R2<DFMB+ ]*
XMYO3M8@U"W$B*T;#@HXY!K;@D+0@BLMG8*L7U-.+&*\X^)FG[XQ(H'(KL+W7;
XM72H]T[,6[(@R37 >+/$$VNVK1Q1I BM@%W&[]*N%^9-"P\)*5^A@^ +AAJ3V
XMQ;_61L@Y[]1_(_G7/W*;+V9 ,!6('YU=\)2-;>)K3/>90?H3C^M2ZY"(=<O(
XMQP-VX?0G_$UZ+^,@RY#LB(Z9Z5 &$8 .>:EG;,@4<;:LV&G->^8P7(4@ XIJ
XMW4"UK2"U%E&%X1V?/KC"_P!*S9 )]/+])8Y3N&>26 Y_-3^==#K@@ETS>J@-
XM&2N".$+,2<GOUP![>U<JI(/!.3SS6TW9F4-43SW4=Q#'YL9$ZKCS5_CQP 1_
XM6NP\"Z*GS7-QRT@R>#Q'V4>[']!7*Z1IQU+5%1P5MH1OE(]/3ZD\5[3I5I'I
XM^G>==;(HXP997/ ''3\!@ 5R8BI9<O4T^%<QIH\=G:27,[B- ,DD8P/I7E7B
XM_5]1O[A65'ALU;$:]AGN?>NCNM7EUV\WX,=HI_=1^O\ M'W_ )59.G)- 8V0
XM,OH:XXM19TTJ#BN:>[_ \V_LN[DOXX&9Y6<C"J?F;IC'^>*ZO7/!MQX=O[>\
XMT^[8PR-ATD^;GW]1FMVVL+JTN UNQ4#(7(!(_&K]S]HGMB+QEE8 _,1C'Y5L
XMZMUH'(U43OH8MA."^57:3VKLXYTL-!EOIE)6-<A1_$>PKBU0QE6/4G)KMO(2
XM^\+&&10RY&0>AKG2N:8NRBO4\BO+G5M<UG9?-)&DC[1%">ASP,?ES^-96MV/
XM]BZM+:I(7C'*D]?QKT.>*>R<O;[$<*55]N2/Q-<5K%G,PDNKE_,F8C+'MS75
XM&I'1(A4Y;F9H3$:Y;2YY\Z/)_P"!BMKQ3%MUN[?@;6(_4'^M86FMLFA8\'SD
XM_P#0JZ7QP/*U*3 YE5&_3'^%;OXD<YQQ)Y<^M=_X2LTM='#R\M,V\?2N$M8Q
XM-/%$!DR2!<>U>H6ML%A6)%PL:A1BLZTK1L..]SD=*NFU:ZNH;QD:!.(5( 52
XM3P?<^YKG-2ADL=0FMYHV1T<\$8_*NKM+FPT.SD:98[F.Y@8%U<##'L![9K)L
XM+>]\37UK-+&TEM9(J2N!DL 20/<U:F[N3V)<4E9'7^!]#/EPAU^<XN)N._\
XM O\ 7\Z@\;>)/MVJQZ'9OBTMW'VAE/\ K)!_#]!_/Z5I:KKQ\,>$7EM0?[0O
XM7VJ^,>7[C/4@?J:\WTN-FC:9B2PF&3]0:PBN:]20XKFJ)=$=_9*$5,= *Z&T
XMD' /0USEB?W2]JV;:3 %<AZLXW1NX4KNXZ52O779MQQ1'.2,'IVJEJ,X6)B>
XM@'-*[.:$/>*-QMW#'>NRT-A)H$JYY49KAW5WC#@>]=CX2<202Q,1M*G-7%ZA
XMC(_N?0Q=0&[)[UQWB1UCL&SU)%=;>,/FYZ'%<!XMN@TL5L#_ +1JZ2YII%.7
XM+2,)7$=NC]"LJ_XUUOQ"5MUE<@<'Y"?H 1_,UR5SQIZ8ZEU;]*[/Q4OVSPE:
XM72] (Y"?7C%=C?O(XF<_X8M#-K:$C*0J6/UKTZUCV0AC_'S7%^"K4FQENB.9
XMFP#["NWW; %'05R8B5YV'T1YQ#H-SK[P+;1>39K&%BP.O7+,.F<]ZZKPL;;P
XM[IUXA9)+2W+2S7)_B; X'J3@ 5HZDSZ-:)I%NXEOI4$9*#_5KT&/<UY[K=\D
XMUU'I$$O^AQ2?O9%Z2R],_0=!^)[UNVZKMT,TKKUV_P REK.IW7B'49;RY+*O
XM_+&('*H/2K&BQ!K.<D<B9>/SK-ML--SP.1BM'1G\H7B'LP'X@-_A6D[<K2-:
XM:M),["U&V-1SBM2!L 9K)L9!+"K>U:43 C%>9U/6>J-")LC--NH1-&5/<52E
XMNTLU#2MM#' XH74[=U!$R$>QIF+B[W1 -(GN[H&.64.%P CD+^5=#I%A<:;8
XMO.\^2ZXV@8Q5'3M?L;6Y#9\PXQ@5:NO$MB;>2VB$C,!GIW/:J1C6=67NI:&5
XMJ$RPQ2.QPB@DGT%>774[7VH/.V<NW ]!VKK/&.HF*SCM%.))N6'HO_US7(0*
XM/-SV Y_*N[#PY8N1SUYW:@BQ=18@0#G@''X9_K75*_VSX=PJ<EEC:/IW# "N
XM:NUW+@=3D 8]!_\ 6KH?"W^D>%S!CE;KD>WWOZ42?NW\R9+5'0:!9BTTNUA"
XM[2%W,/<\UJL>:BMTVKCT %/)YZ5P7YG=CEH['->)]4.D^8GFK+K-TI,L@_Y8
XM(1T'H2/R&*X IC800#FIKN>2ZNYKB:4RR2.69VZL?6FE2/)'/)KTX0Y(V>YC
XM>[N$0Y+9X)S5RU;;<2X/WB&^O!_QK/#,NUNW0U,&.Y6'8421:9U&E7F8 ">1
XM6Y;RYZ$5PD5S);@R)SM;)'L:Z'2M6BGP"0/4'BN&K2:=T>C2JJ2L=0^V6,Y'
XM-4O)6-LA!^ ZU8@E23'S#!]ZT;>")QGC</UK*Q?M.0JV]Y;1J/\ 0XV<>L>:
XM2^NHH4ENYD2)0H^11C'I6N\<84\*N!7!>-+TAK6U0D!B97]\=!6L$YOE,)U5
XM:]CD[^]DU'4I;F0DEC\H]!V%-@1A(L?=G /O3(HB'YZFK%FHDU"WX_Y: G\Z
XM]"2LK(X8N[N795!FB/;S/YG_ K?\")_H=\A[2*?T(K%E3YTP,XR?UK?\"+M
XMDU('TB//ODUS3?[MFDMTSJU&,^F:,4V-U\L#(R.M&ZN-1(E+4\U\0Z+%IUT\
XMEE(6M1)Y;(?O1-Z'U!['V-9\H#7%JH/\.>!_GTKHH";^2WDE Q?2R6LR@<':
XMP <>AYS]17,H<WL0/.T$#\C7K2N8TWI8@'IGWJ2$X.T?A[4TJ%92/7%2%0)\
XM#BAEIDUNQ^U*I^ZW'-=38Z19B$.\09CSS7-.@66V8=2<?K78V0S"I_V0:Y*S
XM:2:.R@KNS+EO:VR >7"JX]":TX9$C0<<U2MU!4,>_:IQ_K O:N5MF[BC2@VW
XM3;608/4@FHM7\!V&LA95FE@G5<*<[E_$&K=DH0KBMF-S251Q=T<%>^R/&M;\
XM&ZQH699(?/MAG,T(R /<=16'ILBM?*=PRIS7T=&V>& (/!SWKS#XC>%[#1S#
XMK&GKY#S.!)$H^4D]QZ5V4\1[3W9;G/&7*TF<Q*P\W'H6!K=\)_N[+4)5.22B
XMC\F_^M7+-*7GDR.[?SKJO")W:/,QZM=E3] !2J*T6=70L[;F,[@V<]?K1_:$
X5\?!!)K4=0>,56>)-W2L42VGN?__9
X
Xend
END_OF_FILE
if test 6072 -ne `wc -c <'testimg.jpg.u'`; then
echo shar: \"'testimg.jpg.u'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'testimg.jpg'\"
cat testimg.jpg.u | uudecode
if [ -f testimg.jpg ]; then
rm testimg.jpg.u
fi
fi
# end of 'testimg.jpg.u'
fi
if test -f 'testorig.jpg.u' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'testorig.jpg.u'\"
else
echo shar: Extracting \"'testorig.jpg.u'\" \(6077 characters\)
sed "s/^X//" >'testorig.jpg.u' <<'END_OF_FILE'
Xbegin 666 testorig.jpg
XM_]C_X 02D9)1@ ! 0 0 ! #_VP!# @&!@<&!0@'!P<)"0@*#!0-# L+
XM#!D2$P\4'1H?'AT:'!P@)"XG("(L(QP<*#<I+# Q-#0T'R<Y/3@R/"XS-#+_
XMVP!# 0D)"0P+#!@-#1@R(1PA,C(R,C(R,C(R,C(R,C(R,C(R,C(R,C(R,C(R
XM,C(R,C(R,C(R,C(R,C(R,C(R,C(R,C+_P 1" !] 'T# 2( A$! Q$!_\0
XM'P 04! 0$! 0$ $" P0%!@<("0H+_\0 M1 @$# P($ P4%
XM! 0 %] 0(# 01!1(A,4$&$U%A!R)Q%#*!D:$((T*QP152T? D,V)R@@D*
XM%A<8&1HE)B<H*2HT-38W.#DZ0T1%1D=(24I35%565UA96F-D969G:&EJ<W1U
XM=G=X>7J#A(6&AXB)BI*3E)66EYB9FJ*CI*6FIZBIJK*SM+6VM[BYNL+#Q,7&
XMQ\C)RM+3U-76U]C9VN'BX^3EYN?HZ>KQ\O/T]?;W^/GZ_\0 'P$ P$! 0$!
XM 0$! 0 $" P0%!@<("0H+_\0 M1$ @$"! 0#! <%! 0 0)W $"
XM Q$$!2$Q!A)!40=A<1,B,H$(%$*1H;'!"2,S4O 58G+1"A8D-.$E\1<8&1HF
XM)R@I*C4V-S@Y.D-$149'2$E*4U155E=865IC9&5F9VAI:G-T=79W>'EZ@H.$
XMA8:'B(F*DI.4E9:7F)F:HJ.DI::GJ*FJLK.TM;:WN+FZPL/$Q<;'R,G*TM/4
XMU=;7V-G:XN/DY>;GZ.GJ\O/T]?;W^/GZ_]H # ,! (1 Q$ /P"1I?N1QJ V
XM/E4= *E0) K%CESC+>IJ")1;Q%F8F1CR>] .[YWZYP!7%8^L+<;DG<^>?N@=
XM6J8W4<&WS&)F(.$49('T]*I-+Y &1F1CA5]#_D51N[Z.#]U+,!(_+E?O'V [
XM5I3I\S,IZ&Q_;5NJLN\H^.CC&3[5,;]HI52>+RE925F+9&?2O/KS48'N$1(Y
XM7E#@_,_!] /PK7OM8NI8H())XXIWXQC)'^?\]JZEA4T<TIV9V:3Q;0RN)!D
XM_,#G\..E)+J,$$'F/*/+'.X<]L]J\VGNIHI8U%PVY^3*&P3P3CCM]/S-5-$T
XM[4->NC,9Y(K2,@27!."/8>K<]*3PL8ZMZ$>TOT/6(KHW)3R&$N\95E.1CUSZ
XM5H6UF6Y)\S'<_=4^WK5+0]*AT_38+;:Z6Z+\L;'YVYZM_AVK<+*HPH '3 %<
XM<K7LMB)SZ(0*(CD#>_JU2#>_+<TW.2*DWJB%F8*H&23T%"1@VV/1 H]Z661+
XM:W>9^BC@>I]*YO6?&-O81JMC&+IV!_>9P@_QKE9KW7O$)(D=UB)X51M6JU-:
XM>'E/5Z(UKO789+IH$)GGE;#"/N?3/84OB/Q@W@R*PM5A22YGC:65/[BY 7_V
XM;\JJ,-.\$6":A>XN+QSB& -@D]_H/>O--7U"YU[5;C4;P_O9FS@9PH[ >P'%
XM:4J:F[O8VFD_=6QZ!AW/FL#GLO84NY53S'+#CC;V]Z;N0#=,WS@?=SP*YO4M
XM8\PW%ML(6,DO(#V[#CK13@I:';.7*M2Y<ZQ<NODJN) Q*2<$^G;V-8"R&[N'
XMAAE8?*6EE[[0,GG^E,M+UW+QD@!E^7_"B,):SNWS&)MJN1U*G.17?""BK(XY
XMR<F1V$OD"6]Q\R<1*>Q(P#^%7+6[C,L\]P#).49BW]Q0.@]#VJGJENUE<-AU
XM,( ,>UAG:1D<=>]:&AZ??ZDOGMYK0/\ NXUSS(>O'MQR:?,H[DVNM"WI^D--
XMJ=M<7?F>68OX!_$PXC7Z \FO4-(T>.P@B:2-$\L?NX4^[&/ZGWK)T#23;Y\V
XM;?+&V#TP"?3\,5O7,IB 0,23UKBQ4^:5EL9)M*R)F<[BQ.<4D;LY']T^M5V8
XM@JO5CU&>@J_;6_RY<Y)Z#L*YM Y7:XV68Q022)&9&1<A0<9_&O,[O6]1UBZ;
XM^T'9+=7(^SQ9"A>V>Y8'GFO6!$2A&,@]J\@\9*^E:I))$-JL?F7LP/:M*+7/
XM8VITXN+?5'1:.J[S;N@<C!4D9Z^G^>]7M;\0:=X9MPUR/.NF_P!7:H<'ZMZ"
XML#PQ=M<VKE'.8@=K9Y"D9']1^%>>ZA,UUJ4\Y8MO<G)Y-7*@IU+O8M-J-B;4
XM]3O-<U*2_O7W2.<*!PJ+V '8579@I'TJ1%&WT JJ^78D5U*RT0K'1ZGJ"7MY
XMY40V!MPW\G( R<#\*QHW::.:&0G?(590!DMC/R_J*T8(T.HI(?EB13!!N_B<
XM@_ID_P JS;21X4#;]C.VWD9/O_.M%!05D3*HY-M@Z$7 B <$+@=B:MVDJ@S
XM(\?FAUROT"DD_6J0_P!'OBDQ8,K?,P['UJVL+SSV]A;%7D=!&&SD!?O%OIS^
XMAIII*XF7+'3(O$,ME/EA!$GEW +99B#\JCZ@C\J]3T>PBMU";%1PFT*O1%_N
XMC^M4/#7A^*SBBVH,*I$1QSSU<^Y[>@K<#PVTTUS*XCMXAMW-QDUYM:JZDM-A
XMNT4XK<;;QK%J$VX810K;CWXQQ^512SF1V,8QD\9'2L?4]6^VL##>K:0!@ ,#
XM+'H,GL/:L^36]0T^X*-'%=1KUV-\PJ&^;8UIX9K66YV%K'L<$\DG))K8BP /
XM2N;T[6(-0MQ(BM&PX*..0:VX)"T((K+9V"K%]33BQBO./B9I^^,2*!R*["]U
XMVUTJ/=.S%NR(,DUP'BSQ!-KMJT<4:0(K8!=QN_2KA?F30L/"2E?H8/@"X8:D
XM]L6_UD;(.>_4?R/YUS]RFR]F0# 5B!^=7?"4C6WB:TSWF4'Z$X_K4NN0B'7+
XMR,<#=N'T)_Q->B_C(,N0[(B.F>E0!A& #GFI9VS(%'&VK>G::U]YK 9"X .*
XM:MU L:T@M191A>$=GSZXPO\ 2LV0"?3R_26.4[AGDE@.?S4_G70ZX()=,WJH
XM#1DK@CA"S$G)[]< >WM7*J2#P3D\\UM-V9E#5$\]U'<0Q^;&1.JX\U?X\< $
XM?UKL/ NBI\US<<M(,G@\1]E'NQ_05RND:<=2U14<%;:$;Y2/3T^I/%>TZ5:1
XMZ?IWG76R*.,&65SP!QT_ 8 %<F(J67+U-/A7,::/'9VDES.XC0#))&,#Z5Y5
XMXOU?4;^X5E1X;-6Q&O89[GWKH[K5Y==O-^#':*?W4?K_ +1]_P"563IR30&-
XMD#+Z&N.+46=-*@XKFGN_P/-O[+NY+^.!F>5G(PJGYFZ8Q_GBNKUSP;<>';^W
XMO-/NV,,C8=)/FY]_49K=MK"ZM+@-;L5 R%R 2/QJ_<_:)[8B\996 /S$8Q^5
XM;.K=:!R-5$[Z&+83@OE5VD]J[..=+#09;Z925C7(4?Q'L*XM4,95CU)R:[;R
XM$OO"QAD4,N1D'H:YTKFF+LHKU/(KRYU;7-9V7S21I(^T10GH<\#'Y<_C65K=
XMC_8NK2VJ2%XQRI/7\:]#GBGLG+V^Q'"E5?;DC\37%:Q9S,)+JY?S)F(RQ[<U
XMU1J1T2(5.6YF:$Q&N6TN>?.CR?\ @8K:\4Q;=;NWX&UB/U!_K6%IK;)H6/!\
XMY/\ T*NE\<#RM2DP.951OTQ_A6[^)'.<<2>7/K7?>$[,6VCAWY:9M_X5PMK&
XM)IXH@,F20+CVKU&TM@L*Q(,+&H48K.O*T;#CO<Y#2KIM6NKJ&\9&@3B%2 %4
XMD\'W/N:YS4H9+'4)K>:-D='/!&/RKJ[2YL-#LY&F6.YCN8&!=7 PQ[ >V:R;
XM"WO?$U]:S2QM);62*DK@9+ $D#W-6IN[D]B7%)61U_@?0SY<(=?G.+B;CO\
XMP+_7\Z@\;>)/MVJQZ'9OBTMW'VAE/^LD'\/T'\_I6EJNO'PQX1>6U!_M"]?:
XMKXQY?N,]2!^IKS?2XV:-IF)+"89/U!K"*YKU)#BN:HET1W]DH14QT KH;20<
XM ]#7.6)_=+VK9MI, 5R'JSC=&[A2N[CI5*]==FW'%$<Y(P>G:J6HSA8F)Z <
XMTKLYH0]XHW&W<,=Z[+0V$F@2KGE1FN'=7>,.![UV/A)Q)!+$Q&TJ<U<7J&,C
XM^Y]#%U ;LGO7'>)'6.P;/4D5UMXP^;GH<5P'BVZ#2Q6P/^T:NDN::13ERTC"
XM5Q';H_0K*O\ C76_$)6W65R!P?D)^@!'\S7)7/&GICJ75OTKL_%2_;/"5I=+
XMT CD)]>,5V-^\CB9S_ABT,VMH2,I"I8_6O3K6/9"&/\ 'S7%^"K4FQENB.9F
XMP#["NWSM 4=!7)B)7G8KHCSB'0;G7W@6VB\FS6,+%@=>N68=,Y[UU7A8VWAW
XM3KQ"R26EN6EFN3_$V!P/4G K1U)GT:T32+=Q+?2H(R4'^K7H,>YKSW6[Y)K
XMJ/2()?\ 0XI/WLB])9>F?H.@_$]ZW;=5VZ&25UZ[?YE+6=3NO$.HRWER65?^
XM6,0.50>E6-%B#6<Y(Y$R\?G6;;8:;G@<C%:.C/Y0O$/9@/Q ;_"M)VY6D:TU
XM:29V%J-L:CG%:D#8 S638R"6%6]JTHF!&*\SJ>L]4:$39&:;=0B:,J>XJE+=
XMI9J&E;:&.!Q0NIV[J")D(]C3,7%WNB :1/=W0,<LH<+@!'(7\JZ'2+"XTVQ>
XM=Y\EUQM QBJ.G:_8VMR&SYAQC JU=>);$V\EM$)&8#/3N>U4C&LZLO=2T,K4
XM)EABD=CA%!)/H*\NNIVOM0>=LY=N!Z#M76>,=1,5G':*<23<L/1?_KFN0@4>
XM;GL!S^5=V'ARQ<CGKSNU!%BZBQ @'/ ./PS_ %KJE?[9\.X5.2RQM'T[A@!7
XM-7:[EP.IR ,>@_\ K5T/A;_2/"Y@QRMUR/;[W]*)/W;^9,EJCH- LQ::7:PA
XM=I"[F'N>:U6/-16Z;5QZ "GD\]*X+\SNQRT=CFO$^J'2?,3S5EUFZ4F60?\
XM+!".@]"1^0Q7 %,;"" <U-=SR75W-<32F621RS.W5CZTTJ1Y(YY->G"')&SW
XM,;W=PB');/!.:N6K;;B7!^\0WUX/^-9X9EVMVZ&I@QW*P["B2+3.HTJ\S 3
XMR*W+>7/0BN$BN9+<&1.=K9(]C70Z5JT4^ 2!Z@\5PU:33NCT:5525CJ'VRQG
XM(YJEY*QMD(/P'6K$$J28^88/O6C;P1.,\;A^M96+]IR%6WO+:-1_H<;./6/-
XM)?744*2W<R)$H4?(HQCTK7>.,*>%7 K@O&EZ0UK:H2 Q,K^^.@K6"<WRF$ZJ
XMM>QR=_>R:CJ4MS(22Q^4>@["FP(PD6/NS@'WID41#\]35BS42:A;\?\ +0$_
XMG7H25E9'#%W=R[*H,T1[>9_,_P"%;_@1/]#OD/:13^A%8LJ?.F!G&3^M;_@1
XM=LFI ^D1Y]\FN:;_ ';-);IG5J,9],T8IL;KY8&1D=:-U<:B1*6IYKXAT6+3
XMKIY+*0M:B3RV0_>B;T/J#V/L:SY0&N+50?X<\#_/I71P@WTEO)-MQ?3R6<R@
XM<$J1AQZ'G/U%<PAS?1 \[00/R->M*YC3>EB >F?>I(3@[1^'M3< ,I'KBI"H
XM$^!Q0RTR:W8_:E4_=;CFNIL=(LQ"'>(,QYYKFI(PDMJW=CC]:[&R&85/^R#7
XM)6;231V4%=V9<M[6V0#RX57'H36G#(D:#CFJ5N 5#'OVJ<?? [5RMLW<4:4&
XMVZ;:R#!ZD$U%J_@.PUD+*LTL$ZKA3G<OX@U:L@$*XK:CD-)5'%W1P5[[(\:U
XMOP;K&A9EDA\^V&<S0C( ]QU%8>FR*U\IW#*G-?1T1WC! (/!SWKS'XB^%K#2
XM!%K.GKY#RRA)(E'RDGN/2NRGB/:>[+<YXRY6DSEY6'FX]"P-;OA/]W9:A*IR
XM244?DW_UJY4S&2>3([M_.NK\(G=H\S'JUT0?H *516BSJZ%G;<QG<&SGK]:/
X6[0GCX()-:CH#QBJSQ)NZ5BB6T]S_V3'J
X
Xend
END_OF_FILE
if test 6077 -ne `wc -c <'testorig.jpg.u'`; then
echo shar: \"'testorig.jpg.u'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'testorig.jpg'\"
cat testorig.jpg.u | uudecode
if [ -f testorig.jpg ]; then
rm testorig.jpg.u
fi
fi
# end of 'testorig.jpg.u'
fi
echo shar: End of archive 16 \(of 18\).
cp /dev/null ark16isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: cjpeg.1 jcmaster.c jcmcu.c jdmaster.c jmemdos.h jmemsys.h
# jwrppm.c makcjpeg.cf makcjpeg.lst makdjpeg.lst makefile.mc6
# makefile.pwc
# Wrapped by kent@sparky on Mon Mar 23 16:02:57 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 17 (of 18)."'
if test -f 'cjpeg.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'cjpeg.1'\"
else
echo shar: Extracting \"'cjpeg.1'\" \(4126 characters\)
sed "s/^X//" >'cjpeg.1' <<'END_OF_FILE'
X.TH CJPEG 1 "28 February 1992"
X.SH NAME
Xcjpeg \- compress an image file to a JPEG file
X.SH SYNOPSIS
X.B cjpeg
X[
X.BI \-Q " quality"
X]
X[
X.B \-oTIad
X]
X[
X.BI \-m " memory"
X]
X[
X.I filename
X]
X.LP
X.SH DESCRIPTION
X.LP
X.B cjpeg
Xcompresses the named image file, or the standard input if no file is
Xnamed, and produces a JPEG/JFIF file on the standard output.
XThe currently supported image file formats are: PPM (PBMPLUS color
Xformat), PGM (PBMPLUS gray-scale format), GIF, Targa, and RLE (Utah Raster
XToolkit format). (RLE is supported only if the URT library is available.)
X.SH OPTIONS
X.TP
X.BI \-Q " quality"
XScale quantization tables to adjust image quality. Quality is 0 (worst) to
X100 (best); default is 75. (See below for more info.)
X.TP
X.B \-o
XPerform optimization of entropy encoding parameters. Without this, default
Xencoding parameters are used.
X.B \-o
Xusually makes the JPEG file a little smaller, but
X.B cjpeg
Xruns somewhat slower and needs much more memory. Image quality and speed of
Xdecompression are unaffected by
X.BR \-o .
X.TP
X.B \-T
XInput file is Targa format. Targa files that contain an "identification"
Xfield will not be automatically recognized by
X.BR cjpeg ;
Xfor such files you must specify
X.B \-T
Xto force
X.B cjpeg
Xto treat the input as Targa format.
X.TP
X.B \-I
XGenerate noninterleaved JPEG file (not yet supported).
X.TP
X.B \-a
XUse arithmetic coding rather than Huffman coding (not currently
Xsupported for legal reasons).
X.TP
X.B \-d
XEnable debug printout. More
X.BR \-d 's
Xgive more output. Also, version information is printed at startup.
X.TP
X.BI \-m " memory"
XSet limit for amount of memory to use in processing large images. Value is
Xin thousands of bytes, or millions of bytes if "M" is attached to the
Xnumber. For example,
X.B \-m 4m
Xselects 4000000 bytes. If more space is needed, temporary files will be used.
X.PP
XThe
X.B \-Q
Xswitch lets you trade off compressed file size against quality of the
Xreconstructed image: the higher the
X.B \-Q
Xsetting, the larger the JPEG file, and the closer the output image will be to
Xthe original input. Normally you want to use the lowest
X.B \-Q
Xsetting (smallest file) that decompresses into something visually
Xindistinguishable from the original image. For this purpose the
X.B \-Q
Xsetting should be between 50 and 95; the default of 75 is often about right.
XIf you see defects at
X.B \-Q
X75, then go up 5 or 10 counts at a time until you are happy with the output
Ximage. (The optimal setting will vary from one image to another.)
X.PP
X.B \-Q
X100 will generate a quantization table of all 1's, eliminating loss in the
Xquantization step (but there is still information loss in subsampling, as well
Xas roundoff error). This setting is mainly of interest for experimental
Xpurposes.
X.B \-Q
Xvalues above about 95 are
X.B not
Xrecommended for normal use; the compressed file size goes up dramatically for
Xhardly any gain in output image quality.
X.PP
XIn the other direction,
X.B \-Q
Xvalues below 50 will produce very small files of low image quality. Settings
Xaround 5 to 10 might be useful in preparing an index of a large image library,
Xfor example. Try
X.B \-Q
X2 (or so) for some amusing Cubist effects. (Note:
X.B \-Q
Xvalues below about 25 generate 2-byte quantization tables, which are
Xconsidered optional in the JPEG standard.
X.B cjpeg
Xemits a warning message when you give such a
X.B \-Q
Xvalue, because some commercial JPEG programs may be unable to decode the
Xresulting file.)
X.SH EXAMPLES
X.LP
XThis example compresses the PPM file foo.ppm with a quality factor of
X60 and saves the output as foo.jpg:
X.IP
X.B cjpeg \-Q
X.I 60 foo.ppm
X.B >
X.I foo.jpg
X.SH SEE ALSO
X.BR djpeg (1)
X.br
X.BR ppm (5),
X.BR pgm (5)
X.br
XWallace, Gregory K. "The JPEG Still Picture Compression Standard",
XCommunications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
X.SH AUTHOR
XIndependent JPEG Group
X.SH BUGS
XArithmetic coding and interleaved output not yet supported.
X.PP
XNot all variants of Targa file format are supported.
X.PP
XThe
X.B -T
Xswitch is not a bug, it's a feature. (It would be a bug if the Targa format
Xdesigners had not been clueless.)
X.PP
XNot as fast as we'd like.
END_OF_FILE
if test 4126 -ne `wc -c <'cjpeg.1'`; then
echo shar: \"'cjpeg.1'\" unpacked with wrong size!
fi
# end of 'cjpeg.1'
fi
if test -f 'jcmaster.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcmaster.c'\"
else
echo shar: Extracting \"'jcmaster.c'\" \(4201 characters\)
sed "s/^X//" >'jcmaster.c' <<'END_OF_FILE'
X/*
X * jcmaster.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains the main control for the JPEG compressor.
X * The system-dependent (user interface) code should call jpeg_compress()
X * after doing appropriate setup of the compress_info_struct parameter.
X */
X
X#include "jinclude.h"
X
X
XMETHODDEF void
Xc_per_scan_method_selection (compress_info_ptr cinfo)
X/* Central point for per-scan method selection */
X{
X /* Edge expansion */
X jselexpand(cinfo);
X /* Subsampling of pixels */
X jselsubsample(cinfo);
X /* MCU extraction */
X jselcmcu(cinfo);
X}
X
X
XLOCAL void
Xc_initial_method_selection (compress_info_ptr cinfo)
X/* Central point for initial method selection */
X{
X /* Input image reading method selection is already done. */
X /* So is output file header formatting (both are done by user interface). */
X
X /* Gamma and color space conversion */
X jselccolor(cinfo);
X /* Entropy encoding: either Huffman or arithmetic coding. */
X#ifdef ARITH_CODING_SUPPORTED
X jselcarithmetic(cinfo);
X#else
X cinfo->arith_code = FALSE; /* force Huffman mode */
X#endif
X jselchuffman(cinfo);
X /* Pipeline control */
X jselcpipeline(cinfo);
X /* Overall control (that's me!) */
X cinfo->methods->c_per_scan_method_selection = c_per_scan_method_selection;
X}
X
X
XLOCAL void
Xinitial_setup (compress_info_ptr cinfo)
X/* Do computations that are needed before initial method selection */
X{
X short ci;
X jpeg_component_info *compptr;
X
X /* Compute maximum sampling factors; check factor validity */
X cinfo->max_h_samp_factor = 1;
X cinfo->max_v_samp_factor = 1;
X for (ci = 0; ci < cinfo->num_components; ci++) {
X compptr = &cinfo->comp_info[ci];
X if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
X compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
X ERREXIT(cinfo->emethods, "Bogus sampling factors");
X cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
X compptr->h_samp_factor);
X cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
X compptr->v_samp_factor);
X
X }
X
X /* Compute logical subsampled dimensions of components */
X for (ci = 0; ci < cinfo->num_components; ci++) {
X compptr = &cinfo->comp_info[ci];
X compptr->true_comp_width = (cinfo->image_width * compptr->h_samp_factor
X + cinfo->max_h_samp_factor - 1)
X / cinfo->max_h_samp_factor;
X compptr->true_comp_height = (cinfo->image_height * compptr->v_samp_factor
X + cinfo->max_v_samp_factor - 1)
X / cinfo->max_v_samp_factor;
X }
X}
X
X
X/*
X * This is the main entry point to the JPEG compressor.
X */
X
X
XGLOBAL void
Xjpeg_compress (compress_info_ptr cinfo)
X{
X /* Init pass counts to 0 --- total_passes is adjusted in method selection */
X cinfo->total_passes = 0;
X cinfo->completed_passes = 0;
X
X /* Read the input file header: determine image size & component count.
X * NOTE: the user interface must have initialized the input_init method
X * pointer (eg, by calling jselrppm) before calling me.
X * The other file reading methods (get_input_row etc.) were probably
X * set at the same time, but could be set up by input_init itself,
X * or by c_ui_method_selection.
X */
X (*cinfo->methods->input_init) (cinfo);
X
X /* Give UI a chance to adjust compression parameters and select */
X /* output file format based on results of input_init. */
X (*cinfo->methods->c_ui_method_selection) (cinfo);
X
X /* Now select methods for compression steps. */
X initial_setup(cinfo);
X c_initial_method_selection(cinfo);
X
X /* Initialize the output file & other modules as needed */
X /* (entropy_encoder is inited by pipeline controller) */
X
X (*cinfo->methods->colorin_init) (cinfo);
X (*cinfo->methods->write_file_header) (cinfo);
X
X /* And let the pipeline controller do the rest. */
X (*cinfo->methods->c_pipeline_controller) (cinfo);
X
X /* Finish output file, release working storage, etc */
X (*cinfo->methods->write_file_trailer) (cinfo);
X (*cinfo->methods->colorin_term) (cinfo);
X (*cinfo->methods->input_term) (cinfo);
X
X (*cinfo->emethods->free_all) ();
X
X /* My, that was easy, wasn't it? */
X}
END_OF_FILE
if test 4201 -ne `wc -c <'jcmaster.c'`; then
echo shar: \"'jcmaster.c'\" unpacked with wrong size!
fi
# end of 'jcmaster.c'
fi
if test -f 'jcmcu.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcmcu.c'\"
else
echo shar: Extracting \"'jcmcu.c'\" \(5804 characters\)
sed "s/^X//" >'jcmcu.c' <<'END_OF_FILE'
X/*
X * jcmcu.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains MCU extraction routines and quantization scaling.
X * These routines are invoked via the extract_MCUs and
X * extract_init/term methods.
X */
X
X#include "jinclude.h"
X
X
X/*
X * If this file is compiled with -DDCT_ERR_STATS, it will reverse-DCT each
X * block and sum the total errors across the whole picture. This provides
X * a convenient method of using real picture data to test the roundoff error
X * of a DCT algorithm. DCT_ERR_STATS should *not* be defined for a production
X * compression program, since compression is much slower with it defined.
X * Also note that jrevdct.o must be linked into the compressor when this
X * switch is defined.
X */
X
X#ifdef DCT_ERR_STATS
Xstatic int dcterrorsum; /* these hold the error statistics */
Xstatic int dcterrormax;
Xstatic int dctcoefcount; /* This will probably overflow on a 16-bit-int machine */
X#endif
X
X
X/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
X
Xstatic const short ZAG[DCTSIZE2] = {
X 0, 1, 8, 16, 9, 2, 3, 10,
X 17, 24, 32, 25, 18, 11, 4, 5,
X 12, 19, 26, 33, 40, 48, 41, 34,
X 27, 20, 13, 6, 7, 14, 21, 28,
X 35, 42, 49, 56, 57, 50, 43, 36,
X 29, 22, 15, 23, 30, 37, 44, 51,
X 58, 59, 52, 45, 38, 31, 39, 46,
X 53, 60, 61, 54, 47, 55, 62, 63
X};
X
X
XLOCAL void
Xextract_block (JSAMPARRAY input_data, int start_row, long start_col,
X JBLOCK output_data, QUANT_TBL_PTR quanttbl)
X/* Extract one 8x8 block from the specified location in the sample array; */
X/* perform forward DCT, quantization scaling, and zigzag reordering on it. */
X{
X /* This routine is heavily used, so it's worth coding it tightly. */
X DCTBLOCK block;
X#ifdef DCT_ERR_STATS
X DCTBLOCK svblock; /* saves input data for comparison */
X#endif
X
X { register JSAMPROW elemptr;
X register DCTELEM *localblkptr = block;
X#if DCTSIZE != 8
X register short elemc;
X#endif
X register short elemr;
X
X for (elemr = DCTSIZE; elemr > 0; elemr--) {
X elemptr = input_data[start_row++] + start_col;
X#if DCTSIZE == 8 /* unroll the inner loop */
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X#else
X for (elemc = DCTSIZE; elemc > 0; elemc--) {
X *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
X }
X#endif
X }
X }
X
X#ifdef DCT_ERR_STATS
X memcpy((void *) svblock, (void *) block, SIZEOF(DCTBLOCK));
X#endif
X
X j_fwd_dct(block);
X
X { register JCOEF temp;
X register short i;
X
X for (i = 0; i < DCTSIZE2; i++) {
X temp = (JCOEF) block[ZAG[i]];
X /* divide by *quanttbl, ensuring proper rounding */
X if (temp < 0) {
X temp = -temp;
X temp += *quanttbl>>1;
X temp /= *quanttbl;
X temp = -temp;
X } else {
X temp += *quanttbl>>1;
X temp /= *quanttbl;
X }
X *output_data++ = temp;
X quanttbl++;
X }
X }
X
X#ifdef DCT_ERR_STATS
X j_rev_dct(block);
X
X { register int diff;
X register short i;
X
X for (i = 0; i < DCTSIZE2; i++) {
X diff = block[i] - svblock[i];
X if (diff < 0) diff = -diff;
X dcterrorsum += diff;
X if (dcterrormax < diff) dcterrormax = diff;
X }
X dctcoefcount += DCTSIZE2;
X }
X#endif
X}
X
X
X/*
X * Extract samples in MCU order, process & hand off to output_method.
X * The input is always exactly N MCU rows worth of data.
X */
X
XMETHODDEF void
Xextract_MCUs (compress_info_ptr cinfo,
X JSAMPIMAGE image_data,
X int num_mcu_rows,
X MCU_output_method_ptr output_method)
X{
X JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
X int mcurow;
X long mcuindex;
X short blkn, ci, xpos, ypos;
X jpeg_component_info * compptr;
X QUANT_TBL_PTR quant_ptr;
X
X for (mcurow = 0; mcurow < num_mcu_rows; mcurow++) {
X for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
X /* Extract data from the image array, DCT it, and quantize it */
X blkn = 0;
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
X for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
X for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
X extract_block(image_data[ci],
X (mcurow * compptr->MCU_height + ypos)*DCTSIZE,
X (mcuindex * compptr->MCU_width + xpos)*DCTSIZE,
X MCU_data[blkn], quant_ptr);
X blkn++;
X }
X }
X }
X /* Send the MCU whereever the pipeline controller wants it to go */
X (*output_method) (cinfo, MCU_data);
X }
X }
X}
X
X
X/*
X * Initialize for processing a scan.
X */
X
XMETHODDEF void
Xextract_init (compress_info_ptr cinfo)
X{
X /* no work for now */
X#ifdef DCT_ERR_STATS
X dcterrorsum = dcterrormax = dctcoefcount = 0;
X#endif
X}
X
X
X/*
X * Clean up after a scan.
X */
X
XMETHODDEF void
Xextract_term (compress_info_ptr cinfo)
X{
X /* no work for now */
X#ifdef DCT_ERR_STATS
X TRACEMS3(cinfo->emethods, 0, "DCT roundoff errors = %d/%d, max = %d",
X dcterrorsum, dctcoefcount, dcterrormax);
X#endif
X}
X
X
X
X/*
X * The method selection routine for MCU extraction.
X */
X
XGLOBAL void
Xjselcmcu (compress_info_ptr cinfo)
X{
X /* just one implementation for now */
X cinfo->methods->extract_init = extract_init;
X cinfo->methods->extract_MCUs = extract_MCUs;
X cinfo->methods->extract_term = extract_term;
X}
END_OF_FILE
if test 5804 -ne `wc -c <'jcmcu.c'`; then
echo shar: \"'jcmcu.c'\" unpacked with wrong size!
fi
# end of 'jcmcu.c'
fi
if test -f 'jdmaster.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdmaster.c'\"
else
echo shar: Extracting \"'jdmaster.c'\" \(5627 characters\)
sed "s/^X//" >'jdmaster.c' <<'END_OF_FILE'
X/*
X * jdmaster.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains the main control for the JPEG decompressor.
X * The system-dependent (user interface) code should call jpeg_decompress()
X * after doing appropriate setup of the decompress_info_struct parameter.
X */
X
X#include "jinclude.h"
X
X
XMETHODDEF void
Xd_per_scan_method_selection (decompress_info_ptr cinfo)
X/* Central point for per-scan method selection */
X{
X /* MCU disassembly */
X jseldmcu(cinfo);
X /* Un-subsampling of pixels */
X jselunsubsample(cinfo);
X}
X
X
XLOCAL void
Xd_initial_method_selection (decompress_info_ptr cinfo)
X/* Central point for initial method selection (after reading file header) */
X{
X /* JPEG file scanning method selection is already done. */
X /* So is output file format selection (both are done by user interface). */
X
X /* Entropy decoding: either Huffman or arithmetic coding. */
X#ifdef ARITH_CODING_SUPPORTED
X jseldarithmetic(cinfo);
X#else
X if (cinfo->arith_code) {
X ERREXIT(cinfo->emethods, "Arithmetic coding not supported");
X }
X#endif
X jseldhuffman(cinfo);
X /* Cross-block smoothing */
X#ifdef BLOCK_SMOOTHING_SUPPORTED
X jselbsmooth(cinfo);
X#else
X cinfo->do_block_smoothing = FALSE;
X#endif
X /* Gamma and color space conversion */
X jseldcolor(cinfo);
X
X /* Color quantization selection rules */
X#ifdef QUANT_1PASS_SUPPORTED
X#ifdef QUANT_2PASS_SUPPORTED
X /* We have both, check for conditions in which 1-pass should be used */
X if (cinfo->num_components != 3 || cinfo->jpeg_color_space != CS_YCbCr)
X cinfo->two_pass_quantize = FALSE; /* 2-pass only handles YCbCr input */
X if (cinfo->out_color_space == CS_GRAYSCALE)
X cinfo->two_pass_quantize = FALSE; /* Should use 1-pass for grayscale out */
X#else /* not QUANT_2PASS_SUPPORTED */
X cinfo->two_pass_quantize = FALSE; /* only have 1-pass */
X#endif
X#else /* not QUANT_1PASS_SUPPORTED */
X#ifdef QUANT_2PASS_SUPPORTED
X cinfo->two_pass_quantize = TRUE; /* only have 2-pass */
X#else /* not QUANT_2PASS_SUPPORTED */
X if (cinfo->quantize_colors) {
X ERREXIT(cinfo->emethods, "Color quantization was not compiled");
X }
X#endif
X#endif
X
X#ifdef QUANT_1PASS_SUPPORTED
X jsel1quantize(cinfo);
X#endif
X#ifdef QUANT_2PASS_SUPPORTED
X jsel2quantize(cinfo);
X#endif
X
X /* Pipeline control */
X jseldpipeline(cinfo);
X /* Overall control (that's me!) */
X cinfo->methods->d_per_scan_method_selection = d_per_scan_method_selection;
X}
X
X
XLOCAL void
Xinitial_setup (decompress_info_ptr cinfo)
X/* Do computations that are needed before initial method selection */
X{
X short ci;
X jpeg_component_info *compptr;
X
X /* Compute maximum sampling factors; check factor validity */
X cinfo->max_h_samp_factor = 1;
X cinfo->max_v_samp_factor = 1;
X for (ci = 0; ci < cinfo->num_components; ci++) {
X compptr = &cinfo->comp_info[ci];
X if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
X compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
X ERREXIT(cinfo->emethods, "Bogus sampling factors");
X cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
X compptr->h_samp_factor);
X cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
X compptr->v_samp_factor);
X
X }
X
X /* Compute logical subsampled dimensions of components */
X for (ci = 0; ci < cinfo->num_components; ci++) {
X compptr = &cinfo->comp_info[ci];
X compptr->true_comp_width = (cinfo->image_width * compptr->h_samp_factor
X + cinfo->max_h_samp_factor - 1)
X / cinfo->max_h_samp_factor;
X compptr->true_comp_height = (cinfo->image_height * compptr->v_samp_factor
X + cinfo->max_v_samp_factor - 1)
X / cinfo->max_v_samp_factor;
X }
X}
X
X
X/*
X * This is the main entry point to the JPEG decompressor.
X */
X
X
XGLOBAL void
Xjpeg_decompress (decompress_info_ptr cinfo)
X{
X /* Init pass counts to 0 --- total_passes is adjusted in method selection */
X cinfo->total_passes = 0;
X cinfo->completed_passes = 0;
X
X /* Read the JPEG file header markers; everything up through the first SOS
X * marker is read now. NOTE: the user interface must have initialized the
X * read_file_header method pointer (eg, by calling jselrjfif or jselrtiff).
X * The other file reading methods (read_scan_header etc.) were probably
X * set at the same time, but could be set up by read_file_header itself.
X */
X (*cinfo->methods->read_file_header) (cinfo);
X if (! ((*cinfo->methods->read_scan_header) (cinfo)))
X ERREXIT(cinfo->emethods, "Empty JPEG file");
X
X /* Give UI a chance to adjust decompression parameters and select */
X /* output file format based on info from file header. */
X (*cinfo->methods->d_ui_method_selection) (cinfo);
X
X /* Now select methods for decompression steps. */
X initial_setup(cinfo);
X d_initial_method_selection(cinfo);
X
X /* Initialize the output file & other modules as needed */
X /* (modules needing per-scan init are called by pipeline controller) */
X
X (*cinfo->methods->output_init) (cinfo);
X (*cinfo->methods->colorout_init) (cinfo);
X if (cinfo->quantize_colors)
X (*cinfo->methods->color_quant_init) (cinfo);
X
X /* And let the pipeline controller do the rest. */
X (*cinfo->methods->d_pipeline_controller) (cinfo);
X
X /* Finish output file, release working storage, etc */
X if (cinfo->quantize_colors)
X (*cinfo->methods->color_quant_term) (cinfo);
X (*cinfo->methods->colorout_term) (cinfo);
X (*cinfo->methods->output_term) (cinfo);
X (*cinfo->methods->read_file_trailer) (cinfo);
X
X (*cinfo->emethods->free_all) ();
X
X /* My, that was easy, wasn't it? */
X}
END_OF_FILE
if test 5627 -ne `wc -c <'jdmaster.c'`; then
echo shar: \"'jdmaster.c'\" unpacked with wrong size!
fi
# end of 'jdmaster.c'
fi
if test -f 'jmemdos.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemdos.h'\"
else
echo shar: Extracting \"'jmemdos.h'\" \(5657 characters\)
sed "s/^X//" >'jmemdos.h' <<'END_OF_FILE'
X/*
X * jmemdos.h (jmemsys.h)
X *
X * Copyright (C) 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This include file defines the interface between the system-independent
X * and system-dependent portions of the JPEG memory manager. (The system-
X * independent portion is jmemmgr.c; there are several different versions
X * of the system-dependent portion, and of this file for that matter.)
X *
X * This version is suitable for MS-DOS (80x86) implementations.
X */
X
X
X/*
X * These two functions are used to allocate and release small chunks of
X * memory (typically the total amount requested through jget_small is
X * no more than 20Kb or so). Behavior should be the same as for the
X * standard library functions malloc and free; in particular, jget_small
X * returns NULL on failure. On most systems, these ARE malloc and free.
X * On an 80x86 machine using small-data memory model, these manage near heap.
X */
X
XEXTERN void * jget_small PP((size_t sizeofobject));
XEXTERN void jfree_small PP((void * object));
X
X/*
X * These two functions are used to allocate and release large chunks of
X * memory (up to the total free space designated by jmem_available).
X * The interface is the same as above, except that on an 80x86 machine,
X * far pointers are used. On other systems these ARE the same as above.
X */
X
X#ifdef NEED_FAR_POINTERS /* typically not needed except on 80x86 */
XEXTERN void FAR * jget_large PP((size_t sizeofobject));
XEXTERN void jfree_large PP((void FAR * object));
X#else
X#define jget_large(sizeofobject) jget_small(sizeofobject)
X#define jfree_large(object) jfree_small(object)
X#endif
X
X/*
X * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
X * be requested in a single call on jget_large (and jget_small for that
X * matter, but that case should never come into play). This macro is needed
X * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
X * On machines with flat address spaces, any large constant may be used here.
X */
X
X#define MAX_ALLOC_CHUNK 65400L
X
X/*
X * This routine computes the total space available for allocation by
X * jget_large. If more space than this is needed, backing store will be used.
X * NOTE: any memory already allocated must not be counted.
X *
X * There is a minimum space requirement, corresponding to the minimum
X * feasible buffer sizes; jmemmgr.c will request that much space even if
X * jmem_available returns zero. The maximum space needed, enough to hold
X * all working storage in memory, is also passed in case it is useful.
X *
X * It is OK for jmem_available to underestimate the space available (that'll
X * just lead to more backing-store access than is really necessary).
X * However, an overestimate will lead to failure. Hence it's wise to subtract
X * a slop factor from the true available space, especially if jget_small space
X * comes from the same pool. 5% should be enough.
X *
X * On machines with lots of virtual memory, any large constant may be returned.
X * Conversely, zero may be returned to always use the minimum amount of memory.
X */
X
XEXTERN long jmem_available PP((long min_bytes_needed, long max_bytes_needed));
X
X
X/*
X * This structure holds whatever state is needed to access a single
X * backing-store object. The read/write/close method pointers are called
X * by jmemmgr.c to manipulate the backing-store object; all other fields
X * are private to the system-dependent backing store routines.
X */
X
X#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
X
Xtypedef unsigned short XMSH; /* type of extended-memory handles */
Xtypedef unsigned short EMSH; /* type of expanded-memory handles */
X
Xtypedef union {
X short file_handle; /* DOS file handle if it's a temp file */
X XMSH xms_handle; /* handle if it's a chunk of XMS */
X EMSH ems_handle; /* handle if it's a chunk of EMS */
X } handle_union;
X
Xtypedef struct backing_store_struct * backing_store_ptr;
X
Xtypedef struct backing_store_struct {
X /* Methods for reading/writing/closing this backing-store object */
X METHOD(void, read_backing_store, (backing_store_ptr info,
X void FAR * buffer_address,
X long file_offset, long byte_count));
X METHOD(void, write_backing_store, (backing_store_ptr info,
X void FAR * buffer_address,
X long file_offset, long byte_count));
X METHOD(void, close_backing_store, (backing_store_ptr info));
X /* Private fields for system-dependent backing-store management */
X /* For the MS-DOS environment, we need: */
X handle_union handle; /* reference to backing-store storage object */
X char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
X } backing_store_info;
X
X/*
X * Initial opening of a backing-store object. This must fill in the
X * read/write/close pointers in the object. The read/write routines
X * may take an error exit if the specified maximum file size is exceeded.
X * (If jmem_available always returns a large value, this routine can just
X * take an error exit.)
X */
X
XEXTERN void jopen_backing_store PP((backing_store_ptr info,
X long total_bytes_needed));
X
X
X/*
X * These routines take care of any system-dependent initialization and
X * cleanup required. The system methods struct address should be saved
X * by jmem_init in case an error exit must be taken. jmem_term may assume
X * that all requested memory has been freed and that all opened backing-
X * store objects have been closed.
X * NB: jmem_term may be called more than once, and must behave reasonably
X * if that happens.
X */
X
XEXTERN void jmem_init PP((external_methods_ptr emethods));
XEXTERN void jmem_term PP((void));
END_OF_FILE
if test 5657 -ne `wc -c <'jmemdos.h'`; then
echo shar: \"'jmemdos.h'\" unpacked with wrong size!
fi
# end of 'jmemdos.h'
fi
if test -f 'jmemsys.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jmemsys.h'\"
else
echo shar: Extracting \"'jmemsys.h'\" \(5401 characters\)
sed "s/^X//" >'jmemsys.h' <<'END_OF_FILE'
X/*
X * jmemsys.h
X *
X * Copyright (C) 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This include file defines the interface between the system-independent
X * and system-dependent portions of the JPEG memory manager. (The system-
X * independent portion is jmemmgr.c; there are several different versions
X * of the system-dependent portion, and of this file for that matter.)
X *
X * This is a "generic" skeleton that may need to be modified for particular
X * systems. It should be usable as-is on the majority of non-MSDOS machines.
X */
X
X
X/*
X * These two functions are used to allocate and release small chunks of
X * memory (typically the total amount requested through jget_small is
X * no more than 20Kb or so). Behavior should be the same as for the
X * standard library functions malloc and free; in particular, jget_small
X * returns NULL on failure. On most systems, these ARE malloc and free.
X * On an 80x86 machine using small-data memory model, these manage near heap.
X */
X
XEXTERN void * jget_small PP((size_t sizeofobject));
XEXTERN void jfree_small PP((void * object));
X
X/*
X * These two functions are used to allocate and release large chunks of
X * memory (up to the total free space designated by jmem_available).
X * The interface is the same as above, except that on an 80x86 machine,
X * far pointers are used. On other systems these ARE the same as above.
X */
X
X#ifdef NEED_FAR_POINTERS /* typically not needed except on 80x86 */
XEXTERN void FAR * jget_large PP((size_t sizeofobject));
XEXTERN void jfree_large PP((void FAR * object));
X#else
X#define jget_large(sizeofobject) jget_small(sizeofobject)
X#define jfree_large(object) jfree_small(object)
X#endif
X
X/*
X * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
X * be requested in a single call on jget_large (and jget_small for that
X * matter, but that case should never come into play). This macro is needed
X * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
X * On machines with flat address spaces, any large constant may be used here.
X */
X
X#define MAX_ALLOC_CHUNK 1000000000L
X
X/*
X * This routine computes the total space available for allocation by
X * jget_large. If more space than this is needed, backing store will be used.
X * NOTE: any memory already allocated must not be counted.
X *
X * There is a minimum space requirement, corresponding to the minimum
X * feasible buffer sizes; jmemmgr.c will request that much space even if
X * jmem_available returns zero. The maximum space needed, enough to hold
X * all working storage in memory, is also passed in case it is useful.
X *
X * It is OK for jmem_available to underestimate the space available (that'll
X * just lead to more backing-store access than is really necessary).
X * However, an overestimate will lead to failure. Hence it's wise to subtract
X * a slop factor from the true available space, especially if jget_small space
X * comes from the same pool. 5% should be enough.
X *
X * On machines with lots of virtual memory, any large constant may be returned.
X * Conversely, zero may be returned to always use the minimum amount of memory.
X */
X
XEXTERN long jmem_available PP((long min_bytes_needed, long max_bytes_needed));
X
X
X/*
X * This structure holds whatever state is needed to access a single
X * backing-store object. The read/write/close method pointers are called
X * by jmemmgr.c to manipulate the backing-store object; all other fields
X * are private to the system-dependent backing store routines.
X */
X
X#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
X
Xtypedef struct backing_store_struct * backing_store_ptr;
X
Xtypedef struct backing_store_struct {
X /* Methods for reading/writing/closing this backing-store object */
X METHOD(void, read_backing_store, (backing_store_ptr info,
X void FAR * buffer_address,
X long file_offset, long byte_count));
X METHOD(void, write_backing_store, (backing_store_ptr info,
X void FAR * buffer_address,
X long file_offset, long byte_count));
X METHOD(void, close_backing_store, (backing_store_ptr info));
X /* Private fields for system-dependent backing-store management */
X /* For a typical implementation with temp files, we might need: */
X FILE * temp_file; /* stdio reference to temp file */
X char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
X } backing_store_info;
X
X/*
X * Initial opening of a backing-store object. This must fill in the
X * read/write/close pointers in the object. The read/write routines
X * may take an error exit if the specified maximum file size is exceeded.
X * (If jmem_available always returns a large value, this routine can just
X * take an error exit.)
X */
X
XEXTERN void jopen_backing_store PP((backing_store_ptr info,
X long total_bytes_needed));
X
X
X/*
X * These routines take care of any system-dependent initialization and
X * cleanup required. The system methods struct address should be saved
X * by jmem_init in case an error exit must be taken. jmem_term may assume
X * that all requested memory has been freed and that all opened backing-
X * store objects have been closed.
X * NB: jmem_term may be called more than once, and must behave reasonably
X * if that happens.
X */
X
XEXTERN void jmem_init PP((external_methods_ptr emethods));
XEXTERN void jmem_term PP((void));
END_OF_FILE
if test 5401 -ne `wc -c <'jmemsys.h'`; then
echo shar: \"'jmemsys.h'\" unpacked with wrong size!
fi
# end of 'jmemsys.h'
fi
if test -f 'jwrppm.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jwrppm.c'\"
else
echo shar: Extracting \"'jwrppm.c'\" \(4269 characters\)
sed "s/^X//" >'jwrppm.c' <<'END_OF_FILE'
X/*
X * jwrppm.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to write output images in PPM format.
X * The PBMPLUS library is required (well, it will be in the real version).
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume output to
X * an ordinary stdio stream.
X *
X * These routines are invoked via the methods put_pixel_rows, put_color_map,
X * and output_init/term.
X */
X
X#include "jinclude.h"
X
X#ifdef PPM_SUPPORTED
X
X
X/*
X * Haven't yet got around to making this work with text-format output,
X * hence cannot handle pixels wider than 8 bits.
X */
X
X#ifndef EIGHT_BIT_SAMPLES
X Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
X#endif
X
X
X/*
X * Write the file header.
X */
X
XMETHODDEF void
Xoutput_init (decompress_info_ptr cinfo)
X{
X if (cinfo->out_color_space == CS_GRAYSCALE) {
X /* emit header for raw PGM format */
X fprintf(cinfo->output_file, "P5\n%ld %ld\n%d\n",
X cinfo->image_width, cinfo->image_height, 255);
X } else if (cinfo->out_color_space == CS_RGB) {
X /* emit header for raw PPM format */
X fprintf(cinfo->output_file, "P6\n%ld %ld\n%d\n",
X cinfo->image_width, cinfo->image_height, 255);
X } else {
X ERREXIT(cinfo->emethods, "PPM output must be grayscale or RGB");
X }
X}
X
X
X/*
X * Write some pixel data.
X */
X
XMETHODDEF void
Xput_pixel_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X register FILE * outfile = cinfo->output_file;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X register long width = cinfo->image_width;
X register int row;
X
X if (cinfo->out_color_space == CS_GRAYSCALE) {
X for (row = 0; row < num_rows; row++) {
X ptr0 = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(*ptr0), outfile);
X ptr0++;
X }
X }
X } else {
X for (row = 0; row < num_rows; row++) {
X ptr0 = pixel_data[0][row];
X ptr1 = pixel_data[1][row];
X ptr2 = pixel_data[2][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(*ptr0), outfile);
X ptr0++;
X putc(GETJSAMPLE(*ptr1), outfile);
X ptr1++;
X putc(GETJSAMPLE(*ptr2), outfile);
X ptr2++;
X }
X }
X }
X}
X
X
X/*
X * Write some pixel data when color quantization is in effect.
X */
X
XMETHODDEF void
Xput_demapped_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X register FILE * outfile = cinfo->output_file;
X register JSAMPARRAY color_map = cinfo->colormap;
X register JSAMPROW ptr;
X register long col;
X long width = cinfo->image_width;
X int row;
X
X if (cinfo->out_color_space == CS_GRAYSCALE) {
X for (row = 0; row < num_rows; row++) {
X ptr = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(color_map[0][GETJSAMPLE(*ptr)]), outfile);
X ptr++;
X }
X }
X } else {
X for (row = 0; row < num_rows; row++) {
X ptr = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X register int pixval = GETJSAMPLE(*ptr);
X
X putc(GETJSAMPLE(color_map[0][pixval]), outfile);
X putc(GETJSAMPLE(color_map[1][pixval]), outfile);
X putc(GETJSAMPLE(color_map[2][pixval]), outfile);
X ptr++;
X }
X }
X }
X}
X
X
X/*
X * Write the color map.
X * For PPM output, we just demap the output data!
X */
X
XMETHODDEF void
Xput_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
X{
X cinfo->methods->put_pixel_rows = put_demapped_rows;
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xoutput_term (decompress_info_ptr cinfo)
X{
X /* No work except to make sure we wrote the output file OK */
X fflush(cinfo->output_file);
X if (ferror(cinfo->output_file))
X ERREXIT(cinfo->emethods, "Output file write error");
X}
X
X
X/*
X * The method selection routine for PPM format output.
X * This should be called from d_ui_method_selection if PPM output is wanted.
X */
X
XGLOBAL void
Xjselwppm (decompress_info_ptr cinfo)
X{
X cinfo->methods->output_init = output_init;
X cinfo->methods->put_color_map = put_color_map;
X cinfo->methods->put_pixel_rows = put_pixel_rows;
X cinfo->methods->output_term = output_term;
X}
X
X#endif /* PPM_SUPPORTED */
END_OF_FILE
if test 4269 -ne `wc -c <'jwrppm.c'`; then
echo shar: \"'jwrppm.c'\" unpacked with wrong size!
fi
# end of 'jwrppm.c'
fi
if test -f 'makcjpeg.cf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makcjpeg.cf'\"
else
echo shar: Extracting \"'makcjpeg.cf'\" \(276 characters\)
sed "s/^X//" >'makcjpeg.cf' <<'END_OF_FILE'
XL jcmain.mix jcmaster.mix jcdeflts.mix jcarith.mix jccolor.mix jcexpand.mix
XL jchuff.mix jcmcu.mix jcpipe.mix jcsample.mix jfwddct.mix jwrjfif.mix
XL jrdgif.mix jrdppm.mix jrdrle.mix jrdtarga.mix jutils.mix jerror.mix
XL jmemmgr.mix jmemsys.mix jmemdosa.mix
Xfa;
Xb cjpeg,8K,48K,
END_OF_FILE
if test 276 -ne `wc -c <'makcjpeg.cf'`; then
echo shar: \"'makcjpeg.cf'\" unpacked with wrong size!
fi
# end of 'makcjpeg.cf'
fi
if test -f 'makcjpeg.lst' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makcjpeg.lst'\"
else
echo shar: Extracting \"'makcjpeg.lst'\" \(248 characters\)
sed "s/^X//" >'makcjpeg.lst' <<'END_OF_FILE'
Xjcmain.obj jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj
Xjchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj jwrjfif.obj
Xjrdgif.obj jrdppm.obj jrdrle.obj jrdtarga.obj jutils.obj jerror.obj
Xjmemmgr.obj jmemsys.obj jmemdosa.obj
END_OF_FILE
if test 248 -ne `wc -c <'makcjpeg.lst'`; then
echo shar: \"'makcjpeg.lst'\" unpacked with wrong size!
fi
# end of 'makcjpeg.lst'
fi
if test -f 'makdjpeg.lst' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makdjpeg.lst'\"
else
echo shar: Extracting \"'makdjpeg.lst'\" \(272 characters\)
sed "s/^X//" >'makdjpeg.lst' <<'END_OF_FILE'
Xjdmain.obj jdmaster.obj jddeflts.obj jbsmooth.obj jdarith.obj jdcolor.obj
Xjdhuff.obj jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj jquant2.obj
Xjrevdct.obj jrdjfif.obj jwrgif.obj jwrppm.obj jwrrle.obj jwrtarga.obj
Xjutils.obj jerror.obj jmemmgr.obj jmemsys.obj jmemdosa.obj
END_OF_FILE
if test 272 -ne `wc -c <'makdjpeg.lst'`; then
echo shar: \"'makdjpeg.lst'\" unpacked with wrong size!
fi
# end of 'makdjpeg.lst'
fi
if test -f 'makefile.mc6' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.mc6'\"
else
echo shar: Extracting \"'makefile.mc6'\" \(5933 characters\)
sed "s/^X//" >'makefile.mc6' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for Microsoft C for MS-DOS, version 6.x (use NMAKE).
X# Thanks to Alan Wright and Chris Turner of Olivetti Research Ltd.
X
X# Read SETUP instructions before saying "make" !!
X
X# compiler flags. -D gives a #define to the sources:
X# -O default optimisation
X# -W3 warning level 3
X# -Za ANSI conformance, defines __STDC__ but undefines far
X# and near, so we DON'T use it.
X# -DHAVE_STDC indicate we do have all the ANSI language features
X# -DINCLUDES_ARE_ANSI and all the ANSI include files.
X# -DMSDOS we are on an MSDOS machine
X# -DMEM_STATS enable memory usage statistics (optional)
X# -c compile, don't link (implicit in inference rules)
X# You might also want to add -G2 if you have an 80286, etc.
X
XCFLAGS = -c -O -W3 -DHAVE_STDC -DINCLUDES_ARE_ANSI -DMSDOS
X# default rules in nmake will use cflags and compile the list below
Xjmemdosa.obj : jmemdosa.asm
X masm /mx $*;
X
X
X# use linker response files because file list > 128 chars
X
Xcjpeg.exe: $(COBJECTS)
X link /STACK:8192 @makcjpeg.lnk
X
Xdjpeg.exe: $(DOBJECTS)
X link /STACK:8192 @makdjpeg.lnk
X
Xtest:
X del testout.*
X djpeg testorig.jpg testout.ppm
X djpeg -G testorig.jpg testout.gif
X cjpeg testimg.ppm testout.jpg
X fc testimg.ppm testout.ppm
X fc testimg.gif testout.gif
X fc testimg.jpg testout.jpg
END_OF_FILE
if test 5933 -ne `wc -c <'makefile.mc6'`; then
echo shar: \"'makefile.mc6'\" unpacked with wrong size!
fi
# end of 'makefile.mc6'
fi
if test -f 'makefile.pwc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.pwc'\"
else
echo shar: Extracting \"'makefile.pwc'\" \(5907 characters\)
sed "s/^X//" >'makefile.pwc' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for Mix Software's Power C, v2.1.1
X# and Dan Grayson's pd make 2.14 under MS-DOS.
X# This file assumes that you have Microsoft's MASM or a compatible assembler
X# to handle the jmemdosa.asm file. If not, you will need to use jmemname.c
X# and go to a large-data memory model.
X# Thanks to Bob Hardy for this version.
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC=pc
X
X# You may need to adjust these cc options:
XMODEL=m
XCFLAGS= -dMSDOS -m$(MODEL)
X# In particular:
X# Add -dMEM_STATS to enable gathering of memory usage statistics.
X
X# Link-time cc options:
XLDFLAGS=
XLDLIBS=
X
X# miscellaneous OS-dependent stuff
X# linker
XLN=pcl
X# file deletion command
XRM=del
X# library (.mix) file creation command
XAR=merge
X
X
X# source files (independently compilable files)
XSOURCES= 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
X# virtual source files (not present in distribution file)
XVIRTSOURCES= jmemsys.c
X# system-dependent implementations of source files
XSYSDEPFILES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemdos.h jmemdosa.asm
X# files included by source files
XINCLUDES= jinclude.h jconfig.h jpegdata.h jversion.h jmemsys.h egetopt.c
X# documentation, test, and support files
XDOCS= README SETUP USAGE CHANGELOG cjpeg.1 djpeg.1 architecture codingrules
XMAKEFILES= 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
XOTHERFILES= ansi2knr.c ckconfig.c example.c
XTESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg
XDISTFILES= $(DOCS) $(MAKEFILES) $(SOURCES) $(SYSDEPFILES) $(INCLUDES) $(OTHERFILES) $(TESTFILES)
X# objectfiles common to cjpeg and djpeg
XCOMOBJECTS= jutils.mix jerror.mix jmemmgr.mix jmemsys.mix jmemdosa.mix
X# compression objectfiles
XCLIBOBJECTS= 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
XCOBJECTS= jcmain.mix $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= 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
XDOBJECTS= jdmain.mix $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.mix
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X
X
Xall: cjpeg.exe djpeg.exe
X# By default, libjpeg.mix is not built unless you explicitly request it.
X# You can add libjpeg.mix to the line above if you want it built by default.
X
X
Xcjpeg.exe: $(COBJECTS)
X $(LN) $(LDFLAGS) @makcjpeg.cf
X
Xdjpeg.exe: $(DOBJECTS)
X $(LN) $(LDFLAGS) @makdjpeg.cf
X
X# libjpeg.mix is useful if you are including the JPEG software in a larger
X# program; you'd include it in your link, rather than the individual modules.
Xlibjpeg.mix: $(LIBOBJECTS)
X @$(RM) libjpeg.mix
X $(AR) libjpeg.mix @makljpeg.cf
X
Xclean:
X $(RM) *.mix cjpeg.exe djpeg.exe testout.*
X
Xtest:
X @$(RM) testout.*
X +djpeg testorig.jpg testout.ppm
X +djpeg -G testorig.jpg testout.gif
X +cjpeg testimg.ppm testout.jpg
X fc testimg.ppm testout.ppm
X fc testimg.gif testout.gif
X fc testimg.jpg testout.jpg
X
X
Xjbsmooth.mix : jbsmooth.c jinclude.h jconfig.h jpegdata.h
Xjcarith.mix : jcarith.c jinclude.h jconfig.h jpegdata.h
Xjccolor.mix : jccolor.c jinclude.h jconfig.h jpegdata.h
Xjcdeflts.mix : jcdeflts.c jinclude.h jconfig.h jpegdata.h
Xjcexpand.mix : jcexpand.c jinclude.h jconfig.h jpegdata.h
Xjchuff.mix : jchuff.c jinclude.h jconfig.h jpegdata.h
Xjcmain.mix : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjcmaster.mix : jcmaster.c jinclude.h jconfig.h jpegdata.h
Xjcmcu.mix : jcmcu.c jinclude.h jconfig.h jpegdata.h
Xjcpipe.mix : jcpipe.c jinclude.h jconfig.h jpegdata.h
Xjcsample.mix : jcsample.c jinclude.h jconfig.h jpegdata.h
Xjdarith.mix : jdarith.c jinclude.h jconfig.h jpegdata.h
Xjdcolor.mix : jdcolor.c jinclude.h jconfig.h jpegdata.h
Xjddeflts.mix : jddeflts.c jinclude.h jconfig.h jpegdata.h
Xjdhuff.mix : jdhuff.c jinclude.h jconfig.h jpegdata.h
Xjdmain.mix : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
Xjdmaster.mix : jdmaster.c jinclude.h jconfig.h jpegdata.h
Xjdmcu.mix : jdmcu.c jinclude.h jconfig.h jpegdata.h
Xjdpipe.mix : jdpipe.c jinclude.h jconfig.h jpegdata.h
Xjdsample.mix : jdsample.c jinclude.h jconfig.h jpegdata.h
Xjerror.mix : jerror.c jinclude.h jconfig.h jpegdata.h
Xjquant1.mix : jquant1.c jinclude.h jconfig.h jpegdata.h
Xjquant2.mix : jquant2.c jinclude.h jconfig.h jpegdata.h
Xjfwddct.mix : jfwddct.c jinclude.h jconfig.h jpegdata.h
Xjrevdct.mix : jrevdct.c jinclude.h jconfig.h jpegdata.h
Xjutils.mix : jutils.c jinclude.h jconfig.h jpegdata.h
Xjmemmgr.mix : jmemmgr.c jinclude.h jconfig.h jpegdata.h jmemsys.h
Xjrdjfif.mix : jrdjfif.c jinclude.h jconfig.h jpegdata.h
Xjrdgif.mix : jrdgif.c jinclude.h jconfig.h jpegdata.h
Xjrdppm.mix : jrdppm.c jinclude.h jconfig.h jpegdata.h
Xjrdrle.mix : jrdrle.c jinclude.h jconfig.h jpegdata.h
Xjrdtarga.mix : jrdtarga.c jinclude.h jconfig.h jpegdata.h
Xjwrjfif.mix : jwrjfif.c jinclude.h jconfig.h jpegdata.h
Xjwrgif.mix : jwrgif.c jinclude.h jconfig.h jpegdata.h
Xjwrppm.mix : jwrppm.c jinclude.h jconfig.h jpegdata.h
Xjwrrle.mix : jwrrle.c jinclude.h jconfig.h jpegdata.h
Xjwrtarga.mix : jwrtarga.c jinclude.h jconfig.h jpegdata.h
Xjmemsys.mix : jmemsys.c jinclude.h jconfig.h jpegdata.h jmemsys.h
Xjmemdosa.mix : jmemdosa.asm
X masm /mx jmemdosa;
X mix jmemdosa.obj
END_OF_FILE
if test 5907 -ne `wc -c <'makefile.pwc'`; then
echo shar: \"'makefile.pwc'\" unpacked with wrong size!
fi
# end of 'makefile.pwc'
fi
echo shar: End of archive 17 \(of 18\).
cp /dev/null ark17isdone
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: CHANGELOG codingrules jcexpand.c jcsample.c jutils.c
# Wrapped by kent@sparky on Mon Mar 23 16:02:58 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 18 (of 18)."'
if test -f 'CHANGELOG' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CHANGELOG'\"
else
echo shar: Extracting \"'CHANGELOG'\" \(2869 characters\)
sed "s/^X//" >'CHANGELOG' <<'END_OF_FILE'
XCHANGELOG for Independent JPEG Group's JPEG software
X
XVersion 3 17-Mar-92
X--------------------
X
XMemory manager is finally capable of swapping to temp files. There are
Xseparate versions of jmemsys.c for no temp files (same behavior as older
Xversions), simple temp files with or without tmpfile(), and a DOS-specific
Xversion (including special code for EMS and XMS). This is probably much more
Xsystem-dependent than any of the older code; some bugs may surface here.
X
XHooks added for user interface to install progress monitoring routine
X(percent-done bar, etc). See comments with dummy progress_monitor
Xroutines in jcdeflts.c, jddeflts.c.
X
XTwo-pass color quantization (finally!). This is now the default method when
Xquantizing; say '-1' to djpeg for quick-and-ugly 1-pass method. There is
Xa test file for checking 2-pass quantization and GIF output.
X
XFixed bug in jcopy_block_row that broke cjpeg -o option and djpeg -b option
Xon MSDOS machines.
X
XMiscellaneous small speedups; notably, DCT computation rearranged so that
XGCC "inline" feature is no longer needed for good code quality.
X
XFile config.c renamed ckconfig.c to avoid name conflict with /etc/config
Xon Unix systems.
X
XAdded example.c to document usage of JPEG subroutines better.
X
XMemory manager now knows how to release all storage during error exit ---
Xavoids memory leak when using JPEG as subroutines. This implies a couple
Xsmall changes to the subroutine interface: the old free_defaults subroutines
Xare no longer needed, but if you have a replacement error_exit method then it
Xmust call the new free_all method. Also, jselvirtmem renamed to jselmemmgr.
X
XCode for reading Targa files with 32-bit pixels was incorrect.
X
XColorspace conversion slightly faster and more accurate; because of
Xthis, old "test" files will no longer match bit-for-bit.
X
X
XVersion 2 13-Dec-91
X--------------------
X
XDocumentation improved a little --- there are man pages now.
XInstallation instructions moved from README to a separate file SETUP.
X
XNew program config.c is provided to help you get the configuration options
Xright. This should make installation a lot more foolproof.
X
XSense of djpeg -D switch reversed: dithering is now ON by default.
X
XRLE image file support added (thanks to Mike Lijewski).
X
XTarga image file support added (thanks to Lee Crocker).
X
XPPM input now accepts all PPM and PGM files.
X
XBug fix: on machines where 'int' is 16 bits, high-Q-setting JPEG files
Xwere not decoded correctly.
X
XNumerous changes to improve portability. There should be few or no compiler
Xwarnings now.
X
XMakefiles cleaned up; defaults now appropriate for production use rather than
Xdebugging.
X
XSubroutine interface cleaned up. If you wrote code based on version 1's
Xjcmain/jdmain, you'll need to change it, but it should get a little shorter
Xand simpler.
X
X
XVersion 1 7-Oct-91
X--------------------
X
XInitial public release.
END_OF_FILE
if test 2869 -ne `wc -c <'CHANGELOG'`; then
echo shar: \"'CHANGELOG'\" unpacked with wrong size!
fi
# end of 'CHANGELOG'
fi
if test -f 'codingrules' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'codingrules'\"
else
echo shar: Extracting \"'codingrules'\" \(3948 characters\)
sed "s/^X//" >'codingrules' <<'END_OF_FILE'
X
X JPEG SYSTEM CODING RULES 27-SEP-91
X
XSince numerous people will be contributing code and bug fixes, it's important
Xto establish a common coding style. The goal of using similar coding styles
Xis much more important than the details of just what that style is.
X
XI suggest we follow the recommendations of "Recommended C Style and Coding
XStandards" revision 6.1 (Cannon et al. as modified by Spencer, Keppel and
XBrader). I have placed a copy of this document in the jpeg FTP archive (see
Xjpeg/doc/cstyle.ms.tbl.Z, or cstyle.txt.Z for those without nroff/tbl).
X
XUnless someone has a real strong objection, let's do block comments thusly:
X
X/*
X * Block comments in this style.
X */
X
Xand indent statements in K&R style, e.g.,
X
X if (test) {
X then-part;
X } else {
X else-part;
X }
X
XI suggest that multi-word names be written in the style multi_word_name
Xrather than multiWordName, but I am open to argument on this.
X
X
XI would like to use function prototypes everywhere, and rely on automatic
Xsource code transformation to feed non-ANSI C compilers. The best tool
XI have so far found for this is 'ansi2knr.c', which is part of Ghostscript.
Xansi2knr is not very bright, so it imposes a format requirement on function
Xdeclarations: the function name MUST BEGIN IN COLUMN 1. Thus all functions
Xshould be written in the following style:
X
Xstatic int *
Xfunction_name (int a, char *b)
X{
X code...
X}
X
Xansi2knr won't help with method declarations (function pointers in structs).
XI suggest we use a macro to declare method pointers, something like this:
X
X#ifdef PROTO
X#define METHOD(type,methodname,arglist) type (*methodname) arglist
X#else
X#define METHOD(type,methodname,arglist) type (*methodname) ()
X#endif
X
Xwhich is used like this:
X
Xstruct function_pointers {
X METHOD(void, init_entropy_encoder, (functptrs fptrs, jparms *jp));
X METHOD(void, term_entropy_encoder, (void));
X};
X
XNote the set of parentheses surrounding the parameter list.
X
XA similar solution is used for external function declarations (see the PP
Xmacro in jpegdata.h).
X
XIf the code is to work on non-ANSI compilers, you cannot rely on a prototype
Xdeclaration to coerce actual parameters into the right types. Therefore, use
Xexplicit casts on actual parameters whenever the actual parameter type is not
Xidentical to the formal parameter. Beware of implicit conversions to "int".
X
XIt seems there are some non-ANSI compilers in which the sizeof() operator
Xis defined to return int, while size_t is defined as long. Needless to say,
Xthis is brain-damaged. Always use the SIZEOF() macro in place of sizeof(),
Xso that the result is guaranteed to be of type size_t.
X
X
XWe can expect that the JPEG compressor and decompressor will be incorporated
Xinto larger programs. Therefore, the following rules are important:
X
X1. Avoid direct use of any file I/O, "malloc", error report printouts, etc;
Xpass these through the common routines provided.
X
X2. Assume that the JPEG code may be invoked more than once per program run;
Xtherefore, do not rely on static initialization of variables, and be careful
Xto release all allocated storage at the end of processing.
X
X3. Minimize global namespace pollution. Functions should be declared static
Xwherever possible. (Note that our method-based calling conventions help this
Xa lot: in many modules only the method-selector function will ever need to be
Xcalled directly, so only that function need be externally visible.) All
Xglobal function names should begin with "j", and should be unique in the first
Xsix characters for portability reasons.
XDon't use global variables at all; anything that must be used in another
Xmodule should be put into parameters (there'll be some large structs passed
Xaround for this purpose).
X
X4. Source file names should also begin with "j"; remember to keep them to
Xeight characters (plus ".c" or ".h", etc) to make life easy for MS-DOSers.
XDo not put code for both compression and decompression into the same source
Xfile.
END_OF_FILE
if test 3948 -ne `wc -c <'codingrules'`; then
echo shar: \"'codingrules'\" unpacked with wrong size!
fi
# end of 'codingrules'
fi
if test -f 'jcexpand.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcexpand.c'\"
else
echo shar: Extracting \"'jcexpand.c'\" \(1947 characters\)
sed "s/^X//" >'jcexpand.c' <<'END_OF_FILE'
X/*
X * jcexpand.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains image edge-expansion routines.
X * These routines are invoked via the edge_expand method.
X */
X
X#include "jinclude.h"
X
X
X/*
X * Expand an image so that it is a multiple of the MCU dimensions.
X * This is to be accomplished by duplicating the rightmost column
X * and/or bottommost row of pixels. The image has not yet been
X * subsampled, so all components have the same dimensions.
X */
X
XMETHODDEF void
Xedge_expand (compress_info_ptr cinfo,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPIMAGE image_data)
X{
X /* Expand horizontally */
X if (input_cols < output_cols) {
X register JSAMPROW ptr;
X register JSAMPLE pixval;
X register long count;
X register int row;
X short ci;
X long numcols = output_cols - input_cols;
X
X for (ci = 0; ci < cinfo->num_components; ci++) {
X for (row = 0; row < input_rows; row++) {
X ptr = image_data[ci][row] + (input_cols-1);
X pixval = GETJSAMPLE(*ptr++);
X for (count = numcols; count > 0; count--)
X *ptr++ = pixval;
X }
X }
X }
X
X /* Expand vertically */
X /* This happens only once at the bottom of the image, */
X /* so it needn't be super-efficient */
X if (input_rows < output_rows) {
X register int row;
X short ci;
X JSAMPARRAY this_component;
X
X for (ci = 0; ci < cinfo->num_components; ci++) {
X this_component = image_data[ci];
X for (row = input_rows; row < output_rows; row++) {
X jcopy_sample_rows(this_component, input_rows-1, this_component, row,
X 1, output_cols);
X }
X }
X }
X}
X
X
X/*
X * The method selection routine for edge expansion.
X */
X
XGLOBAL void
Xjselexpand (compress_info_ptr cinfo)
X{
X /* just one implementation for now */
X cinfo->methods->edge_expand = edge_expand;
X}
END_OF_FILE
if test 1947 -ne `wc -c <'jcexpand.c'`; then
echo shar: \"'jcexpand.c'\" unpacked with wrong size!
fi
# end of 'jcexpand.c'
fi
if test -f 'jcsample.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcsample.c'\"
else
echo shar: Extracting \"'jcsample.c'\" \(3761 characters\)
sed "s/^X//" >'jcsample.c' <<'END_OF_FILE'
X/*
X * jcsample.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains subsampling routines.
X * These routines are invoked via the subsample and
X * subsample_init/term methods.
X */
X
X#include "jinclude.h"
X
X
X/*
X * Initialize for subsampling a scan.
X */
X
XMETHODDEF void
Xsubsample_init (compress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X/*
X * Subsample pixel values of a single component.
X * This version only handles integral sampling ratios.
X */
X
XMETHODDEF void
Xsubsample (compress_info_ptr cinfo, int which_component,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
X JSAMPARRAY output_data)
X{
X jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
X int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
X long outcol;
X JSAMPROW inptr, outptr;
X INT32 outvalue;
X
X /* TEMP FOR DEBUGGING PIPELINE CONTROLLER */
X if (output_rows != compptr->v_samp_factor ||
X input_rows != cinfo->max_v_samp_factor ||
X (output_cols % compptr->h_samp_factor) != 0 ||
X (input_cols % cinfo->max_h_samp_factor) != 0 ||
X input_cols*compptr->h_samp_factor != output_cols*cinfo->max_h_samp_factor)
X ERREXIT(cinfo->emethods, "Bogus subsample parameters");
X
X h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
X v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
X numpix = h_expand * v_expand;
X numpix2 = numpix/2;
X
X inrow = 0;
X for (outrow = 0; outrow < output_rows; outrow++) {
X outptr = output_data[outrow];
X for (outcol = 0; outcol < output_cols; outcol++) {
X outvalue = 0;
X for (v = 0; v < v_expand; v++) {
X inptr = input_data[inrow+v] + (outcol*h_expand);
X for (h = 0; h < h_expand; h++) {
X outvalue += (INT32) GETJSAMPLE(*inptr++);
X }
X }
X *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
X }
X inrow += v_expand;
X }
X}
X
X
X/*
X * Subsample pixel values of a single component.
X * This version handles the special case of a full-size component.
X */
X
XMETHODDEF void
Xfullsize_subsample (compress_info_ptr cinfo, int which_component,
X long input_cols, int input_rows,
X long output_cols, int output_rows,
X JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
X JSAMPARRAY output_data)
X{
X if (input_cols != output_cols || input_rows != output_rows) /* DEBUG */
X ERREXIT(cinfo->emethods, "Pipeline controller messed up");
X
X jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols);
X}
X
X
X/*
X * Clean up after a scan.
X */
X
XMETHODDEF void
Xsubsample_term (compress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X
X/*
X * The method selection routine for subsampling.
X * Note that we must select a routine for each component.
X */
X
XGLOBAL void
Xjselsubsample (compress_info_ptr cinfo)
X{
X short ci;
X jpeg_component_info * compptr;
X
X if (cinfo->CCIR601_sampling)
X ERREXIT(cinfo->emethods, "CCIR601 subsampling not implemented yet");
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
X compptr->v_samp_factor == cinfo->max_v_samp_factor)
X cinfo->methods->subsample[ci] = fullsize_subsample;
X else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
X (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
X cinfo->methods->subsample[ci] = subsample;
X else
X ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
X }
X
X cinfo->methods->subsample_init = subsample_init;
X cinfo->methods->subsample_term = subsample_term;
X}
END_OF_FILE
if test 3761 -ne `wc -c <'jcsample.c'`; then
echo shar: \"'jcsample.c'\" unpacked with wrong size!
fi
# end of 'jcsample.c'
fi
if test -f 'jutils.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jutils.c'\"
else
echo shar: Extracting \"'jutils.c'\" \(2942 characters\)
sed "s/^X//" >'jutils.c' <<'END_OF_FILE'
X/*
X * jutils.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains miscellaneous utility routines needed for both
X * compression and decompression.
X * Note we prefix all global names with "j" to minimize conflicts with
X * a surrounding application.
X */
X
X#include "jinclude.h"
X
X
XGLOBAL long
Xjround_up (long a, long b)
X/* Compute a rounded up to next multiple of b; a >= 0, b > 0 */
X{
X a += b-1;
X return a - (a % b);
X}
X
X
XGLOBAL void
Xjcopy_sample_rows (JSAMPARRAY input_array, int source_row,
X JSAMPARRAY output_array, int dest_row,
X int num_rows, long num_cols)
X/* Copy some rows of samples from one place to another.
X * num_rows rows are copied from input_array[source_row++]
X * to output_array[dest_row++]; these areas should not overlap.
X * The source and destination arrays must be at least as wide as num_cols.
X */
X{
X /* On normal machines we can use memcpy(). This won't work on 80x86 because
X * the sample arrays are FAR and we're assuming a small-pointer memory model.
X */
X register JSAMPROW inptr, outptr;
X#ifdef NEED_FAR_POINTERS
X register long count;
X#else
X register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
X#endif
X register int row;
X
X input_array += source_row;
X output_array += dest_row;
X
X for (row = num_rows; row > 0; row--) {
X inptr = *input_array++;
X outptr = *output_array++;
X#ifdef NEED_FAR_POINTERS
X for (count = num_cols; count > 0; count--)
X *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
X#else
X memcpy((void *) outptr, (void *) inptr, count);
X#endif
X }
X}
X
X
XGLOBAL void
Xjcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, long num_blocks)
X/* Copy a row of coefficient blocks from one place to another. */
X{
X /* On normal machines we can use memcpy(). This won't work on 80x86 because
X * the block arrays are FAR and we're assuming a small-pointer memory model.
X */
X#ifdef NEED_FAR_POINTERS
X register JCOEFPTR inptr, outptr;
X register long count;
X
X inptr = (JCOEFPTR) input_row;
X outptr = (JCOEFPTR) output_row;
X for (count = num_blocks * DCTSIZE2; count > 0; count--) {
X *outptr++ = *inptr++;
X }
X#else
X memcpy((void *) output_row, (void *) input_row,
X (size_t) (num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))));
X#endif
X}
X
X
XGLOBAL void
Xjzero_far (void FAR * target, size_t bytestozero)
X/* Zero out a chunk of FAR memory. */
X/* This might be sample-array data, block-array data, or alloc_medium data. */
X{
X /* On normal machines we can use MEMZERO(). This won't work on 80x86
X * because we're assuming a small-pointer memory model.
X */
X#ifdef NEED_FAR_POINTERS
X register char FAR * ptr = (char FAR *) target;
X register size_t count;
X
X for (count = bytestozero; count > 0; count--) {
X *ptr++ = 0;
X }
X#else
X MEMZERO((void *) target, bytestozero);
X#endif
X}
END_OF_FILE
if test 2942 -ne `wc -c <'jutils.c'`; then
echo shar: \"'jutils.c'\" unpacked with wrong size!
fi
# end of 'jutils.c'
fi
echo shar: End of archive 18 \(of 18\).
cp /dev/null ark18isdone
[ Reposted due to a propagation problem. -Kent+ ]
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jchuff.c jcmain.c jrdgif.c makljpeg.cf
# Wrapped by kent@sparky on Mon Mar 23 16:02:49 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 11 (of 18)."'
if test -f 'jchuff.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jchuff.c'\"
else
echo shar: Extracting \"'jchuff.c'\" \(20071 characters\)
sed "s/^X//" >'jchuff.c' <<'END_OF_FILE'
X/*
X * jchuff.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains Huffman entropy encoding routines.
X * These routines are invoked via the methods entropy_encode,
X * entropy_encoder_init/term, and entropy_optimize.
X */
X
X#include "jinclude.h"
X
X
X/* Static variables to avoid passing 'round extra parameters */
X
Xstatic compress_info_ptr cinfo;
X
Xstatic INT32 huff_put_buffer; /* current bit-accumulation buffer */
Xstatic int huff_put_bits; /* # of bits now in it */
X
Xstatic char * output_buffer; /* output buffer */
Xstatic int bytes_in_buffer;
X
X
X
XLOCAL void
Xfix_huff_tbl (HUFF_TBL * htbl)
X/* Compute derived values for a Huffman table */
X{
X int p, i, l, lastp, si;
X char huffsize[257];
X UINT16 huffcode[257];
X UINT16 code;
X
X /* Figure C.1: make table of Huffman code length for each symbol */
X /* Note that this is in code-length order. */
X
X p = 0;
X for (l = 1; l <= 16; l++) {
X for (i = 1; i <= (int) htbl->bits[l]; i++)
X huffsize[p++] = (char) l;
X }
X huffsize[p] = 0;
X lastp = p;
X
X /* Figure C.2: generate the codes themselves */
X /* Note that this is in code-length order. */
X
X code = 0;
X si = huffsize[0];
X p = 0;
X while (huffsize[p]) {
X while (((int) huffsize[p]) == si) {
X huffcode[p++] = code;
X code++;
X }
X code <<= 1;
X si++;
X }
X
X /* Figure C.3: generate encoding tables */
X /* These are code and size indexed by symbol value */
X
X /* Set any codeless symbols to have code length 0;
X * this allows emit_bits to detect any attempt to emit such symbols.
X */
X MEMZERO((void *) htbl->ehufsi, SIZEOF(htbl->ehufsi));
X
X for (p = 0; p < lastp; p++) {
X htbl->ehufco[htbl->huffval[p]] = huffcode[p];
X htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
X }
X
X /* We don't bother to fill in the decoding tables mincode[], maxcode[], */
X /* and valptr[], since they are not used for encoding. */
X}
X
X
X/* Outputting bytes to the file */
X
XLOCAL void
Xflush_bytes (void)
X{
X if (bytes_in_buffer)
X (*cinfo->methods->entropy_output) (cinfo, output_buffer, bytes_in_buffer);
X bytes_in_buffer = 0;
X}
X
X
X#define emit_byte(val) \
X MAKESTMT( if (bytes_in_buffer >= JPEG_BUF_SIZE) \
X flush_bytes(); \
X output_buffer[bytes_in_buffer++] = (char) (val); )
X
X
X
X/* Outputting bits to the file */
X
X/* Only the right 24 bits of huff_put_buffer are used; the valid bits are
X * left-justified in this part. At most 16 bits can be passed to emit_bits
X * in one call, and we never retain more than 7 bits in huff_put_buffer
X * between calls, so 24 bits are sufficient.
X */
X
XLOCAL void
Xemit_bits (UINT16 code, int size)
X{
X}
X
X
XLOCAL void
Xflush_bits (void)
X{
X emit_bits((UINT16) 0x7F, 7); /* fill any partial byte with ones */
X huff_put_buffer = 0; /* and reset bit-buffer to empty */
X huff_put_bits = 0;
X}
X
X
X
X/* Encode a single block's worth of coefficients */
X/* Note that the DC coefficient has already been converted to a difference */
X
XLOCAL void
Xencode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
X{
X register int temp, temp2;
X register int nbits;
X register int k, r, i;
X
X /* Encode the DC coefficient difference per section F.1.2.1 */
X
X temp = temp2 = block[0];
X
X if (temp < 0) {
X temp = -temp; /* temp is abs value of input */
X /* For a negative input, want temp2 = bitwise complement of abs(input) */
X /* This code assumes we are on a two's complement machine */
X temp2--;
X }
X
X /* Find the number of bits needed for the magnitude of the coefficient */
X nbits = 0;
X while (temp) {
X nbits++;
X temp >>= 1;
X }
X
X /* Emit the Huffman-coded symbol for the number of bits */
X emit_bits(dctbl->ehufco[nbits], dctbl->ehufsi[nbits]);
X
X /* Emit that number of bits of the value, if positive, */
X /* or the complement of its magnitude, if negative. */
X if (nbits) /* emit_bits rejects calls with size 0 */
X emit_bits((UINT16) temp2, nbits);
X
X /* Encode the AC coefficients per section F.1.2.2 */
X
X r = 0; /* r = run length of zeros */
X
X for (k = 1; k < DCTSIZE2; k++) {
X if ((temp = block[k]) == 0) {
X r++;
X } else {
X /* if run length > 15, must emit special run-length-16 codes (0xF0) */
X while (r > 15) {
X emit_bits(actbl->ehufco[0xF0], actbl->ehufsi[0xF0]);
X r -= 16;
X }
X
X temp2 = temp;
X if (temp < 0) {
X temp = -temp; /* temp is abs value of input */
X /* This code assumes we are on a two's complement machine */
X temp2--;
X }
X
X /* Find the number of bits needed for the magnitude of the coefficient */
X nbits = 1; /* there must be at least one 1 bit */
X while (temp >>= 1)
X nbits++;
X
X /* Emit Huffman symbol for run length / number of bits */
X i = (r << 4) + nbits;
X emit_bits(actbl->ehufco[i], actbl->ehufsi[i]);
X
X /* Emit that number of bits of the value, if positive, */
X /* or the complement of its magnitude, if negative. */
X emit_bits((UINT16) temp2, nbits);
X
X r = 0;
X }
X }
X
X /* If the last coef(s) were zero, emit an end-of-block code */
X if (r > 0)
X emit_bits(actbl->ehufco[0], actbl->ehufsi[0]);
X}
X
X
X
X/*
X * Initialize for a Huffman-compressed scan.
X * This is invoked after writing the SOS marker.
X * The pipeline controller must establish the entropy_output method pointer
X * before calling this routine.
X */
X
XMETHODDEF void
Xhuff_init (compress_info_ptr xinfo)
X{
X short ci;
X jpeg_component_info * compptr;
X
X /* Initialize static variables */
X cinfo = xinfo;
X huff_put_buffer = 0;
X huff_put_bits = 0;
X
X /* Initialize the output buffer */
X output_buffer = (char *) (*cinfo->emethods->alloc_small)
X ((size_t) JPEG_BUF_SIZE);
X bytes_in_buffer = 0;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X /* Make sure requested tables are present */
X if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
X ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
X /* Compute derived values for Huffman tables */
X /* We may do this more than once for same table, but it's not a big deal */
X fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
X fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
X /* Initialize DC predictions to 0 */
X cinfo->last_dc_val[ci] = 0;
X }
X
X /* Initialize restart stuff */
X cinfo->restarts_to_go = cinfo->restart_interval;
X cinfo->next_restart_num = 0;
X}
X
X
X/*
X * Emit a restart marker & resynchronize predictions.
X */
X
XLOCAL void
Xemit_restart (compress_info_ptr cinfo)
X{
X short ci;
X
X flush_bits();
X
X emit_byte(0xFF);
X emit_byte(RST0 + cinfo->next_restart_num);
X
X /* Re-initialize DC predictions to 0 */
X for (ci = 0; ci < cinfo->comps_in_scan; ci++)
X cinfo->last_dc_val[ci] = 0;
X
X /* Update restart state */
X cinfo->restarts_to_go = cinfo->restart_interval;
X cinfo->next_restart_num++;
X cinfo->next_restart_num &= 7;
X}
X
X
X/*
X * Encode and output one MCU's worth of Huffman-compressed coefficients.
X */
X
XMETHODDEF void
Xhuff_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
X{
X short blkn, ci;
X jpeg_component_info * compptr;
X JCOEF temp;
X
X /* Account for restart interval, emit restart marker if needed */
X if (cinfo->restart_interval) {
X if (cinfo->restarts_to_go == 0)
X emit_restart(cinfo);
X cinfo->restarts_to_go--;
X }
X
X for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
X ci = cinfo->MCU_membership[blkn];
X compptr = cinfo->cur_comp_info[ci];
X /* Convert DC value to difference, update last_dc_val */
X temp = MCU_data[blkn][0];
X MCU_data[blkn][0] -= cinfo->last_dc_val[ci];
X cinfo->last_dc_val[ci] = temp;
X encode_one_block(MCU_data[blkn],
X cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no],
X cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
X }
X}
X
X
X/*
X * Finish up at the end of a Huffman-compressed scan.
X */
X
XMETHODDEF void
Xhuff_term (compress_info_ptr cinfo)
X{
X /* Flush out the last data */
X flush_bits();
X flush_bytes();
X /* Release the I/O buffer */
X (*cinfo->emethods->free_small) ((void *) output_buffer);
X}
X
X
X
X
X/*
X * Huffman coding optimization.
X *
X /* This algorithm is explained in section K.2 of the JPEG standard */
X
X MEMZERO((void *) bits, SIZEOF(bits));
X MEMZERO((void *) codesize, SIZEOF(codesize));
X for (i = 0; i < 257; i++)
X others[i] = -1; /* init links to empty */
X
X freq[256] = 1; /* make sure there is a nonzero count */
X /* including the pseudo-symbol 256 in the Huffman procedure guarantees
X * that no real symbol is given code-value of all ones, because 256
X * will be placed in the largest codeword category.
X */
X
X /* Huffman's basic algorithm to assign optimal code lengths to symbols */
X
X for (;;) {
X /* Find the smallest nonzero frequency, set c1 = its symbol */
X /* In case of ties, take the larger symbol number */
X c1 = -1;
X v = 1000000000L;
X for (i = 0; i <= 256; i++) {
X if (freq[i] && freq[i] <= v) {
X v = freq[i];
X c1 = i;
X }
X }
X
X /* Find the next smallest nonzero frequency, set c2 = its symbol */
X /* In case of ties, take the larger symbol number */
X c2 = -1;
X v = 1000000000L;
X for (i = 0; i <= 256; i++) {
X if (freq[i] && freq[i] <= v && i != c1) {
X v = freq[i];
X c2 = i;
X }
X }
X
X /* Done if we've merged everything into one frequency */
X if (c2 < 0)
X break;
X
X /* Else merge the two counts/trees */
X freq[c1] += freq[c2];
X freq[c2] = 0;
X
X /* Increment the codesize of everything in c1's tree branch */
X codesize[c1]++;
X while (others[c1] >= 0) {
X c1 = others[c1];
X codesize[c1]++;
X }
X
X others[c1] = c2; /* chain c2 onto c1's tree branch */
X
X /* Increment the codesize of everything in c2's tree branch */
X codesize[c2]++;
X while (others[c2] >= 0) {
X c2 = others[c2];
X codesize[c2]++;
X }
X }
X
X /* Now count the number of symbols of each code length */
X for (i = 0; i <= 256; i++) {
X if (codesize[i]) {
X /* The JPEG standard seems to think that this can't happen, */
X /* but I'm paranoid... */
X if (codesize[i] > MAX_CLEN)
X ERREXIT(cinfo->emethods, "Huffman code size table overflow");
X
X bits[codesize[i]]++;
X }
X }
X
X /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
X * Huffman procedure assigned any such lengths, we must adjust the coding.
X * Here is what the JPEG spec says about how this next bit works:
X * Since symbols are paired for the longest Huffman code, the symbols are
X * removed from this length category two at a time. The prefix for the pair
X * (which is one bit shorter) is allocated to one of the pair; then,
X * skipping the BITS entry for that prefix length, a code word from the next
X * shortest nonzero BITS entry is converted into a prefix for two code words
X * one bit longer.
X */
X
X for (i = MAX_CLEN; i > 16; i--) {
X while (bits[i] > 0) {
X j = i - 2; /* find length of new prefix to be used */
X while (bits[j] == 0)
X j--;
X
X bits[i] -= 2; /* remove two symbols */
X bits[i-1]++; /* one goes in this length */
X bits[j+1] += 2; /* two new symbols in this length */
X bits[j]--; /* symbol of this length is now a prefix */
X }
X }
X
X /* Remove the count for the pseudo-symbol 256 from the largest codelength */
X while (bits[i] == 0) /* find largest codelength still in use */
X i--;
X bits[i]--;
X
X /* Return final symbol counts (only for lengths 0..16) */
X memcpy((void *) htbl->bits, (void *) bits, SIZEOF(htbl->bits));
X
X /* Return a list of the symbols sorted by code length */
X /* It's not real clear to me why we don't need to consider the codelength
X * changes made above, but the JPEG spec seems to think this works.
X */
X p = 0;
X for (i = 1; i <= MAX_CLEN; i++) {
X for (j = 0; j <= 255; j++) {
X if (codesize[j] == i) {
X htbl->huffval[p] = (UINT8) j;
X p++;
X }
X }
X }
X}
X
X
X r = 0; /* r = run length of zeros */
X
X for (k = 1; k < DCTSIZE2; k++) {
X if ((temp = block[k]) == 0) {
X r++;
X } else {
X /* if run length > 15, must emit special run-length-16 codes (0xF0) */
X while (r > 15) {
X ac_counts[0xF0]++;
X r -= 16;
X }
X
X /* Find the number of bits needed for the magnitude of the coefficient */
X if (temp < 0) temp = -temp;
X
X for (nbits = 0; temp; nbits++)
X temp >>= 1;
X
X /* Count Huffman symbol for run length / number of bits */
X ac_counts[(r << 4) + nbits]++;
X
X r = 0;
X }
X }
X
X /* If the last coef(s) were zero, emit an end-of-block code */
X if (r > 0)
X ac_counts[0]++;
X}
X
X
X
X/*
X * Trial-encode one MCU's worth of Huffman-compressed coefficients.
X */
X
XLOCAL void
Xhtest_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
X{
X short blkn, ci;
X jpeg_component_info * compptr;
X
X /* Take care of restart intervals if needed */
X if (cinfo->restart_interval) {
X if (cinfo->restarts_to_go == 0) {
X /* Re-initialize DC predictions to 0 */
X for (ci = 0; ci < cinfo->comps_in_scan; ci++)
X cinfo->last_dc_val[ci] = 0;
X /* Update restart state */
X cinfo->restarts_to_go = cinfo->restart_interval;
X }
X cinfo->restarts_to_go--;
X }
X
X for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
X ci = cinfo->MCU_membership[blkn];
X compptr = cinfo->cur_comp_info[ci];
X /* NB: unlike the real entropy encoder, we may not change the input data */
X htest_one_block(MCU_data[blkn],
X (JCOEF) (MCU_data[blkn][0] - cinfo->last_dc_val[ci]),
X dc_count_ptrs[compptr->dc_tbl_no],
X ac_count_ptrs[compptr->ac_tbl_no]);
X cinfo->last_dc_val[ci] = MCU_data[blkn][0];
X }
X}
X
X
X
X/*
X * Find the best coding parameters for a Huffman-coded scan.
X * When called, the scan data has already been converted to a sequence of
X * MCU groups of quantized coefficients, which are stored in a "big" array.
X * The source_method knows how to iterate through that array.
X * On return, the MCU data is unmodified, but the Huffman tables referenced
X * by the scan components may have been altered.
X */
X
XMETHODDEF void
Xhuff_optimize (compress_info_ptr cinfo, MCU_output_caller_ptr source_method)
X/* Optimize Huffman-coding parameters (Huffman symbol table) */
X{
X int i, tbl;
X HUFF_TBL **htblptr;
X
X /* Allocate and zero the count tables */
X /* Note that gen_huff_coding expects 257 entries in each table! */
X
X for (i = 0; i < NUM_HUFF_TBLS; i++) {
X dc_count_ptrs[i] = NULL;
X ac_count_ptrs[i] = NULL;
X }
X
X for (i = 0; i < cinfo->comps_in_scan; i++) {
X /* Create DC table */
X tbl = cinfo->cur_comp_info[i]->dc_tbl_no;
X if (dc_count_ptrs[tbl] == NULL) {
X dc_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
X (257 * SIZEOF(long));
X MEMZERO((void *) dc_count_ptrs[tbl], 257 * SIZEOF(long));
X }
X /* Create AC table */
X tbl = cinfo->cur_comp_info[i]->ac_tbl_no;
X if (ac_count_ptrs[tbl] == NULL) {
X ac_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
X (257 * SIZEOF(long));
X MEMZERO((void *) ac_count_ptrs[tbl], 257 * SIZEOF(long));
X }
X }
X
X /* Initialize DC predictions to 0 */
X for (i = 0; i < cinfo->comps_in_scan; i++) {
X cinfo->last_dc_val[i] = 0;
X }
X /* Initialize restart stuff */
X cinfo->restarts_to_go = cinfo->restart_interval;
X
X }
X }
X}
X
X
X#endif /* ENTROPY_OPT_SUPPORTED */
X
X
X/*
X * The method selection routine for Huffman entropy encoding.
X */
X
XGLOBAL void
Xjselchuffman (compress_info_ptr cinfo)
X{
X if (! cinfo->arith_code) {
X cinfo->methods->entropy_encoder_init = huff_init;
X cinfo->methods->entropy_encode = huff_encode;
X cinfo->methods->entropy_encoder_term = huff_term;
X#ifdef ENTROPY_OPT_SUPPORTED
X cinfo->methods->entropy_optimize = huff_optimize;
X /* The standard Huffman tables are only valid for 8-bit data precision.
X * If the precision is higher, force optimization on so that usable
X * tables will be computed. This test can be removed if default tables
X * are supplied that are valid for the desired precision.
X */
X if (cinfo->data_precision > 8)
X cinfo->optimize_coding = TRUE;
X if (cinfo->optimize_coding)
X cinfo->total_passes++; /* one pass needed for entropy optimization */
X#endif
X }
X}
END_OF_FILE
if test 20071 -ne `wc -c <'jchuff.c'`; then
echo shar: \"'jchuff.c'\" unpacked with wrong size!
fi
# end of 'jchuff.c'
fi
if test -f 'jcmain.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jcmain.c'\"
else
echo shar: Extracting \"'jcmain.c'\" \(9991 characters\)
sed "s/^X//" >'jcmain.c' <<'END_OF_FILE'
X/*
X * jcmain.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains a trivial test user interface for the JPEG compressor.
X * It should work on any system with Unix- or MS-DOS-style command lines.
X *
X * Two different command line styles are permitted, depending on the
X * compile-time switch TWO_FILE_COMMANDLINE:
X * cjpeg [options] inputfile outputfile
X * cjpeg [options] [inputfile]
X * In the second style, output is always to standard output, which you'd
X * normally redirect to a file or pipe to some other program. Input is
X * either from a named file or from standard input (typically redirected).
X * The second style is convenient on Unix but is unhelpful on systems that
X * don't support pipes. Also, you MUST use the first style if your system
X * doesn't do binary I/O to stdin/stdout.
X */
X
X#include "jinclude.h"
X#ifdef INCLUDES_ARE_ANSI
X#include <stdlib.h> /* to declare exit() */
X#endif
X#ifdef NEED_SIGNAL_CATCHER
X#include <signal.h> /* to declare signal() */
X#endif
X
X#ifdef THINK_C
X#include <console.h> /* command-line reader for Macintosh */
X#endif
X
X#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
X#define READ_BINARY "r"
X#define WRITE_BINARY "w"
X#else
X#define READ_BINARY "rb"
X#define WRITE_BINARY "wb"
X#endif
X
X#ifndef EXIT_FAILURE /* define exit() codes if not provided */
X#define EXIT_FAILURE 1
X#endif
X#ifndef EXIT_SUCCESS
X#ifdef VMS
X#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
X#else
X#define EXIT_SUCCESS 0
X#endif
X#endif
X
X
X#include "jversion.h" /* for version message */
X
X
X/*
X * PD version of getopt(3).
X */
X
X#include "egetopt.c"
X
X
X/*
X * This routine determines what format the input file is,
X * and selects the appropriate input-reading module.
X *
X * To determine which family of input formats the file belongs to,
X * we may look only at the first byte of the file, since C does not
X * guarantee that more than one character can be pushed back with ungetc.
X * Looking at additional bytes would require one of these approaches:
X * 1) assume we can fseek() the input file (fails for piped input);
X * 2) assume we can push back more than one character (works in
X * some C implementations, but unportable);
X * 3) provide our own buffering as is done in djpeg (breaks input readers
X * that want to use stdio directly, such as the RLE library);
X * or 4) don't put back the data, and modify the input_init methods to assume
X * they start reading after the start of file (also breaks RLE library).
X * #1 is attractive for MS-DOS but is untenable on Unix.
X *
X * The most portable solution for file types that can't be identified by their
X * first byte is to make the user tell us what they are. This is also the
X * only approach for "raw" file types that contain only arbitrary values.
X * We presently apply this method for Targa files. Most of the time Targa
X * files start with 0x00, so we recognize that case. Potentially, however,
X * a Targa file could start with any byte value (byte 0 is the length of the
X * seldom-used ID field), so we accept a -T switch to force Targa input mode.
X */
X
Xstatic boolean is_targa; /* records user -T switch */
X
X
XLOCAL void
Xselect_file_type (compress_info_ptr cinfo)
X{
X int c;
X
X if (is_targa) {
X#ifdef TARGA_SUPPORTED
X jselrtarga(cinfo);
X#else
X ERREXIT(cinfo->emethods, "Targa support was not compiled");
X#endif
X return;
X }
X
X if ((c = getc(cinfo->input_file)) == EOF)
X ERREXIT(cinfo->emethods, "Empty input file");
X
X switch (c) {
X#ifdef GIF_SUPPORTED
X case 'G':
X jselrgif(cinfo);
X break;
X#endif
X#ifdef PPM_SUPPORTED
X case 'P':
X jselrppm(cinfo);
X break;
X#endif
X#ifdef RLE_SUPPORTED
X case 'R':
X jselrrle(cinfo);
X break;
X#endif
X#ifdef TARGA_SUPPORTED
X case 0x00:
X jselrtarga(cinfo);
X break;
X#endif
X default:
X#ifdef TARGA_SUPPORTED
X ERREXIT(cinfo->emethods, "Unrecognized input file format --- did you forget -T ?");
X#else
X ERREXIT(cinfo->emethods, "Unrecognized input file format");
X#endif
X break;
X }
X
X if (ungetc(c, cinfo->input_file) == EOF)
X ERREXIT(cinfo->emethods, "ungetc failed");
X}
X
X
X/*
X * This routine gets control after the input file header has been read.
X * It must determine what output JPEG file format is to be written,
X * and make any other compression parameter changes that are desirable.
X */
X
XMETHODDEF void
Xc_ui_method_selection (compress_info_ptr cinfo)
X{
X /* If the input is gray scale, generate a monochrome JPEG file. */
X if (cinfo->in_color_space == CS_GRAYSCALE)
X j_monochrome_default(cinfo);
X /* For now, always select JFIF output format. */
X#ifdef JFIF_SUPPORTED
X jselwjfif(cinfo);
X#else
X You shoulda defined JFIF_SUPPORTED. /* deliberate syntax error */
X#endif
X}
X
X
X/*
X * Signal catcher to ensure that temporary files are removed before aborting.
X * NB: for Amiga Manx C this is actually a global routine named _abort();
X * see -Dsignal_catcher=_abort in CFLAGS. Talk about bogus...
X */
X
X#ifdef NEED_SIGNAL_CATCHER
X
Xstatic external_methods_ptr emethods; /* for access to free_all */
X
XGLOBAL void
Xsignal_catcher (int signum)
X{
X emethods->trace_level = 0; /* turn off trace output */
X (*emethods->free_all) (); /* clean up memory allocation & temp files */
X exit(EXIT_FAILURE);
X}
X
X#endif
X
X
XLOCAL void
Xusage (char * progname)
X/* complain about bad command line */
X{
X fprintf(stderr, "usage: %s ", progname);
X fprintf(stderr, "[-Q quality 0..100] [-o] [-T] [-I] [-a] [-d] [-m mem]");
X#ifdef TWO_FILE_COMMANDLINE
X fprintf(stderr, " inputfile outputfile\n");
X#else
X fprintf(stderr, " [inputfile]\n");
X#endif
X exit(EXIT_FAILURE);
X}
X
X
X/*
X * The main program.
X */
X
XGLOBAL int
Xmain (int argc, char **argv)
X{
X struct compress_info_struct cinfo;
X struct compress_methods_struct c_methods;
X struct external_methods_struct e_methods;
X int c;
X
X /* On Mac, fetch a command line. */
X#ifdef THINK_C
X argc = ccommand(&argv);
X#endif
X
X /* Initialize the system-dependent method pointers. */
X cinfo.methods = &c_methods;
X cinfo.emethods = &e_methods;
X jselerror(&e_methods); /* error/trace message routines */
X jselmemmgr(&e_methods); /* memory allocation routines */
X c_methods.c_ui_method_selection = c_ui_method_selection;
X
X /* Now OK to enable signal catcher. */
X#ifdef NEED_SIGNAL_CATCHER
X emethods = &e_methods;
X signal(SIGINT, signal_catcher);
X#ifdef SIGTERM /* not all systems have SIGTERM */
X signal(SIGTERM, signal_catcher);
X#endif
X#endif
X
X /* Set up default JPEG parameters. */
X j_c_defaults(&cinfo, 75, FALSE); /* default quality level = 75 */
X is_targa = FALSE;
X
X /* Scan command line options, adjust parameters */
X
X while ((c = egetopt(argc, argv, "IQ:Taom:d")) != EOF)
X switch (c) {
X case 'I': /* Create noninterleaved file. */
X#ifdef MULTISCAN_FILES_SUPPORTED
X cinfo.interleave = FALSE;
X#else
X fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n",
X argv[0]);
X exit(EXIT_FAILURE);
X#endif
X break;
X case 'Q': /* Quality factor. */
X { int val;
X if (optarg == NULL)
X usage(argv[0]);
X if (sscanf(optarg, "%d", &val) != 1)
X usage(argv[0]);
X /* Note: for now, we make force_baseline FALSE.
X * This means non-baseline JPEG files can be created with low Q values.
X * To ensure only baseline files are generated, pass TRUE instead.
X */
X j_set_quality(&cinfo, val, FALSE);
X }
X break;
X case 'T': /* Input file is Targa format. */
X is_targa = TRUE;
X break;
X case 'a': /* Use arithmetic coding. */
X#ifdef ARITH_CODING_SUPPORTED
X cinfo.arith_code = TRUE;
X#else
X fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
X argv[0]);
X exit(EXIT_FAILURE);
X#endif
X break;
X case 'o': /* Enable entropy parm optimization. */
X#ifdef ENTROPY_OPT_SUPPORTED
X cinfo.optimize_coding = TRUE;
X#else
X fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
X argv[0]);
X exit(EXIT_FAILURE);
X#endif
X break;
X case 'm': /* Maximum memory in Kb (or Mb with 'm'). */
X { long lval;
X char ch = 'x';
X
X if (optarg == NULL)
X usage(argv[0]);
X if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
X usage(argv[0]);
X if (ch == 'm' || ch == 'M')
X lval *= 1000L;
X e_methods.max_memory_to_use = lval * 1000L;
X }
X break;
X case 'd': /* Debugging. */
X e_methods.trace_level++;
X break;
X case '?':
X default:
X usage(argv[0]);
X break;
X }
X
X /* If -d appeared, print version identification */
X if (e_methods.trace_level > 0)
X fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n",
X JVERSION, JCOPYRIGHT);
X
X /* Select the input and output files */
X
X#ifdef TWO_FILE_COMMANDLINE
X
X if (optind != argc-2) {
X fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
X usage(argv[0]);
X }
X if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
X exit(EXIT_FAILURE);
X }
X if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
X exit(EXIT_FAILURE);
X }
X
X#else /* not TWO_FILE_COMMANDLINE -- use Unix style */
X
X cinfo.input_file = stdin; /* default input file */
X cinfo.output_file = stdout; /* always the output file */
X
X if (optind < argc-1) {
X fprintf(stderr, "%s: only one input file\n", argv[0]);
X usage(argv[0]);
X }
X if (optind < argc) {
X if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
X fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
X exit(EXIT_FAILURE);
X }
X }
X
X#endif /* TWO_FILE_COMMANDLINE */
X
X /* Figure out the input file format, and set up to read it. */
X select_file_type(&cinfo);
X
X /* Do it to it! */
X jpeg_compress(&cinfo);
X
X /* All done. */
X exit(EXIT_SUCCESS);
X return 0; /* suppress no-return-value warnings */
X}
END_OF_FILE
if test 9991 -ne `wc -c <'jcmain.c'`; then
echo shar: \"'jcmain.c'\" unpacked with wrong size!
fi
# end of 'jcmain.c'
fi
if test -f 'jrdgif.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jrdgif.c'\"
else
echo shar: Extracting \"'jrdgif.c'\" \(19830 characters\)
sed "s/^X//" >'jrdgif.c' <<'END_OF_FILE'
X/*
X * jrdgif.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to read input images in GIF format.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume input from
X * an ordinary stdio stream. They further assume that reading begins
X * at the start of the file; input_init may need work if the
X * user interface has already read some data (e.g., to determine that
X * the file is indeed GIF format).
X *
X * These routines are invoked via the methods get_input_row
X * and input_init/term.
X */
X
X/*
X * This code is loosely based on giftoppm from the PBMPLUS distribution
X * of Feb. 1991. That file contains the following copyright notice:
X * +-------------------------------------------------------------------+
X * | Copyright 1990, David Koblas. |
X * | Permission to use, copy, modify, and distribute this software |
X * | and its documentation for any purpose and without fee is hereby |
X * | granted, provided that the above copyright notice appear in all |
X * | copies and that both that copyright notice and this permission |
X * | notice appear in supporting documentation. This software is |
X * | provided "as is" without express or implied warranty. |
X * +-------------------------------------------------------------------+
X *
X * We are also required to state that
X * "The Graphics Interchange Format(c) is the Copyright property of
X * CompuServe Incorporated. GIF(sm) is a Service Mark property of
X * CompuServe Incorporated."
X */
X
X#include "jinclude.h"
X
X *
X * The stack represents the not-yet-used expansion of the last LZW symbol.
X * In the worst case, a symbol could expand to as many bytes as there are
X * LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
X * (This is conservative since that number includes the raw-byte symbols.)
X *
X * The tables are allocated from FAR heap space since they would use up
X * rather a lot of the near data space in a PC.
X */
X
Xstatic UINT16 FAR *symbol_head; /* => table of prefix symbols */
Xstatic UINT8 FAR *symbol_tail; /* => table of suffix bytes */
Xstatic UINT8 FAR *symbol_stack; /* stack for symbol expansions */
Xstatic UINT8 FAR *sp; /* stack pointer */
X
X/* Static state for interlaced image processing */
X
Xstatic boolean is_interlaced; /* TRUE if have interlaced image */
Xstatic big_sarray_ptr interlaced_image; /* full image in interlaced order */
Xstatic long cur_row_number; /* need to know actual row number */
Xstatic long pass2_offset; /* # of pixel rows in pass 1 */
Xstatic long pass3_offset; /* # of pixel rows in passes 1&2 */
Xstatic long pass4_offset; /* # of pixel rows in passes 1,2,3 */
X
X
X/* Forward declarations */
XMETHODDEF void load_interlaced_image PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
XMETHODDEF void get_interlaced_row PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
X
X
X
XLOCAL int
XReadByte (compress_info_ptr cinfo)
X/* Read next byte from GIF file */
X{
X register FILE * infile = cinfo->input_file;
X int c;
X
X if ((c = getc(infile)) == EOF)
X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
X return c;
X}
X
X
XLOCAL int
XGetDataBlock (compress_info_ptr cinfo, char *buf)
X/* Read a GIF data block, which has a leading count byte */
X/* A zero-length block marks the end of a data block sequence */
X{
X int count;
X
X count = ReadByte(cinfo);
X if (count > 0) {
X if (! ReadOK(cinfo->input_file, buf, count))
X ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
X }
X return count;
X}
X
X
XLOCAL void
XSkipDataBlocks (compress_info_ptr cinfo)
X/* Skip a series of data blocks, until a block terminator is found */
X{
X char buf[256];
X
X while (GetDataBlock(cinfo, buf) > 0)
X /* skip */;
X}
X
X
XLOCAL void
XReInitLZW (void)
X/* (Re)initialize LZW state; shared code for startup and Clear processing */
X{
X code_size = input_code_size+1;
X limit_code = clear_code << 1; /* 2^code_size */
X max_code = clear_code + 2; /* first unused code value */
X sp = symbol_stack; /* init stack to empty */
X}
X
X
XLOCAL void
XInitLZWCode (void)
X/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
X{
X /* GetCode initialization */
X last_byte = 2; /* make safe to "recopy last two bytes" */
X last_bit = 0; /* nothing in the buffer */
X cur_bit = 0; /* force buffer load on first call */
X out_of_blocks = FALSE;
X
X /* LZWReadByte initialization */
X clear_code = 1 << input_code_size; /* compute special code values */
X end_code = clear_code + 1; /* note that these do not change */
X first_time = TRUE;
X ReInitLZW();
X}
X
X
XLOCAL int
X}
X
X
XLOCAL int
XLZWReadByte (compress_info_ptr cinfo)
X/* Read an LZW-compressed byte */
X{
X static int oldcode; /* previous LZW symbol */
X static int firstcode; /* first byte of oldcode's expansion */
X register int code; /* current working code */
X int incode; /* saves actual input code */
X
X /* First time, just eat the expected Clear code(s) and return next code, */
X /* which is assumed to be a raw byte. */
X if (first_time) {
X first_time = FALSE;
X do {
X code = GetCode(cinfo);
X } while (code == clear_code);
X firstcode = oldcode = code; /* make firstcode, oldcode valid! */
X return code;
X }
X
X /* If any codes are stacked from a previously read symbol, return them */
X if (sp > symbol_stack)
X return (int) *(--sp);
X
X code = GetCode(cinfo);
X
X if (code == clear_code) {
X /* Reinit static state, swallow any extra Clear codes, and return */
X ReInitLZW();
X do {
X code = GetCode(cinfo);
X } while (code == clear_code);
X firstcode = oldcode = code; /* gotta reinit these too */
X return code;
X }
X
X if (code == end_code) {
X /* Skip the rest of the image, unless GetCode already read terminator */
X if (! out_of_blocks)
X SkipDataBlocks(cinfo);
X return -1;
X }
X
X limit_code <<= 1; /* keep equal to 2^code_size */
X }
X }
X
X oldcode = incode; /* save last input symbol for future use */
X return firstcode; /* return first byte of symbol's expansion */
X}
X
X
XLOCAL void
XReadColorMap (compress_info_ptr cinfo, int cmaplen, JSAMPARRAY cmap)
X/* Read a GIF colormap */
X{
X int i;
X
X for (i = 0; i < cmaplen; i++) {
X cmap[CM_RED][i] = (JSAMPLE) ReadByte(cinfo);
X cmap[CM_GREEN][i] = (JSAMPLE) ReadByte(cinfo);
X cmap[CM_BLUE][i] = (JSAMPLE) ReadByte(cinfo);
X }
X}
X
X
XLOCAL void
XDoExtension (compress_info_ptr cinfo)
X/* Process an extension block */
X/* Currently we ignore 'em all */
X{
X int extlabel;
X
X /* Read extension label byte */
X extlabel = ReadByte(cinfo);
X TRACEMS1(cinfo->emethods, 1, "Ignoring GIF extension block of type 0x%02x",
X extlabel);
X /* Skip the data block(s) associated with the extension */
X SkipDataBlocks(cinfo);
X}
X
X
X/*
X * Read the file header; return image size and component count.
X */
X
XMETHODDEF void
Xinput_init (compress_info_ptr cinfo)
X{
X char hdrbuf[10]; /* workspace for reading control blocks */
X UINT16 width, height; /* image dimensions */
X int colormaplen, aspectRatio;
X int c;
X
X */
X for (;;) {
X c = ReadByte(cinfo);
X
X if (c == ';') /* GIF terminator?? */
X ERREXIT(cinfo->emethods, "Too few images in GIF file");
X
X if (c == '!') { /* Extension */
X DoExtension(cinfo);
X continue;
X }
X
X break;
X }
X
X /* Prepare to read selected image: first initialize LZW decompressor */
X symbol_head = (UINT16 FAR *) (*cinfo->emethods->alloc_medium)
X (LZW_TABLE_SIZE * SIZEOF(UINT16));
X symbol_tail = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
X (LZW_TABLE_SIZE * SIZEOF(UINT8));
X symbol_stack = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
X (LZW_TABLE_SIZE * SIZEOF(UINT8));
X InitLZWCode();
X
X /*
X * If image is interlaced, we read it into a full-size sample array,
X * decompressing as we go; then get_input_row selects rows from the
X * sample array in the proper order.
X */
X if (is_interlaced) {
X /* We request the big array now, but can't access it until the pipeline
X * controller causes all the big arrays to be allocated. Hence, the
X * actual work of reading the image is postponed until the first call
X * of get_input_row.
X */
X interlaced_image = (*cinfo->emethods->request_big_sarray)
X ((long) width, (long) height, 1L);
X cinfo->methods->get_input_row = load_interlaced_image;
X cinfo->total_passes++; /* count file reading as separate pass */
X }
X
X /* Return info about the image. */
X cinfo->input_components = NUMCOLORS;
X cinfo->in_color_space = CS_RGB;
X cinfo->image_width = width;
X cinfo->image_height = height;
X cinfo->data_precision = 8; /* always, even if 12-bit JSAMPLEs */
X}
X
X
X/*
X * Read one row of pixels.
X * This version is used for noninterlaced GIF images:
X * we read directly from the GIF file.
X */
X
XMETHODDEF void
Xget_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X register int c;
X
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X if ((c = LZWReadByte(cinfo)) < 0)
X ERREXIT(cinfo->emethods, "Premature end of GIF image");
X *ptr0++ = colormap[CM_RED][c];
X *ptr1++ = colormap[CM_GREEN][c];
X *ptr2++ = colormap[CM_BLUE][c];
X }
X}
X
X
X/*
X * Read one row of pixels.
X * This version is used for the first call on get_input_row when
X * reading an interlaced GIF file: we read the whole image into memory.
X */
X
XMETHODDEF void
Xload_interlaced_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X JSAMPARRAY image_ptr;
X register JSAMPROW sptr;
X register long col;
X register int c;
X long row;
X
X /* Read the interlaced image into the big array we've created. */
X for (row = 0; row < cinfo->image_height; row++) {
X (*cinfo->methods->progress_monitor) (cinfo, row, cinfo->image_height);
X image_ptr = (*cinfo->emethods->access_big_sarray)
X (interlaced_image, row, TRUE);
X sptr = image_ptr[0];
X for (col = cinfo->image_width; col > 0; col--) {
X if ((c = LZWReadByte(cinfo)) < 0)
X ERREXIT(cinfo->emethods, "Premature end of GIF image");
X *sptr++ = (JSAMPLE) c;
X }
X }
X cinfo->completed_passes++;
X
X /* Replace method pointer so subsequent calls don't come here. */
X cinfo->methods->get_input_row = get_interlaced_row;
X /* Initialize for get_interlaced_row, and perform first call on it. */
X cur_row_number = 0;
X pass2_offset = (cinfo->image_height + 7L) / 8L;
X pass3_offset = pass2_offset + (cinfo->image_height + 3L) / 8L;
X pass4_offset = pass3_offset + (cinfo->image_height + 1L) / 4L;
X
X get_interlaced_row(cinfo, pixel_row);
X}
X
X
X/*
X * Read one row of pixels.
X * This version is used for interlaced GIF images:
X * we read from the big in-memory image.
X */
X
XMETHODDEF void
Xget_interlaced_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
X{
X JSAMPARRAY image_ptr;
X register JSAMPROW sptr, ptr0, ptr1, ptr2;
X register long col;
X register int c;
X long irow;
X
X /* Figure out which row of interlaced image is needed, and access it. */
X switch ((int) (cur_row_number & 7L)) {
X case 0: /* first-pass row */
X irow = cur_row_number >> 3;
X break;
X case 4: /* second-pass row */
X irow = (cur_row_number >> 3) + pass2_offset;
X break;
X case 2: /* third-pass row */
X case 6:
X irow = (cur_row_number >> 2) + pass3_offset;
X break;
X default: /* fourth-pass row */
X irow = (cur_row_number >> 1) + pass4_offset;
X break;
X }
X image_ptr = (*cinfo->emethods->access_big_sarray)
X (interlaced_image, irow, FALSE);
X /* Scan the row, expand colormap, and output */
X sptr = image_ptr[0];
X ptr0 = pixel_row[0];
X ptr1 = pixel_row[1];
X ptr2 = pixel_row[2];
X for (col = cinfo->image_width; col > 0; col--) {
X c = GETJSAMPLE(*sptr++);
X *ptr0++ = colormap[CM_RED][c];
X *ptr1++ = colormap[CM_GREEN][c];
X *ptr2++ = colormap[CM_BLUE][c];
X }
X cur_row_number++; /* for next time */
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xinput_term (compress_info_ptr cinfo)
X{
X /* no work (we let free_all release the workspace) */
X}
X
X
X/*
X * The method selection routine for GIF format input.
X * Note that this must be called by the user interface before calling
X * jpeg_compress. If multiple input formats are supported, the
X * user interface is responsible for discovering the file format and
X * calling the appropriate method selection routine.
X */
X
XGLOBAL void
Xjselrgif (compress_info_ptr cinfo)
X{
X cinfo->methods->input_init = input_init;
X cinfo->methods->get_input_row = get_input_row; /* assume uninterlaced */
X cinfo->methods->input_term = input_term;
X}
X
X#endif /* GIF_SUPPORTED */
END_OF_FILE
if test 19830 -ne `wc -c <'jrdgif.c'`; then
echo shar: \"'jrdgif.c'\" unpacked with wrong size!
fi
# end of 'jrdgif.c'
fi
if test -f 'makljpeg.cf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makljpeg.cf'\"
else
echo shar: Extracting \"'makljpeg.cf'\" \(439 characters\)
sed "s/^X//" >'makljpeg.cf' <<'END_OF_FILE'
Xjcmaster.mix,jcdeflts.mix,jcarith.mix,jccolor.mix,jcexpand.mix,jchuff.mix
Xjcmcu.mix,jcpipe.mix,jcsample.mix,jfwddct.mix,jwrjfif.mix,jrdgif.mix
Xjrdppm.mix,jrdrle.mix,jrdtarga.mix,jdmaster.mix,jddeflts.mix,jbsmooth.mix
Xjdarith.mix,jdcolor.mix,jdhuff.mix,jdmcu.mix,jdpipe.mix,jdsample.mix
Xjquant1.mix,jquant2.mix,jrevdct.mix,jrdjfif.mix,jwrgif.mix,jwrppm.mix
Xjwrrle.mix,jwrtarga.mix,jutils.mix,jerror.mix,jmemmgr.mix,jmemsys.mix
Xjmemdosa.mix
END_OF_FILE
if test 439 -ne `wc -c <'makljpeg.cf'`; then
echo shar: \"'makljpeg.cf'\" unpacked with wrong size!
fi
# end of 'makljpeg.cf'
fi
echo shar: End of archive 11 \(of 18\).
cp /dev/null ark11isdone
[ Reposted due to a propagation problem. -Kent+ ]
#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: jddeflts.c jdmcu.c jwrtarga.c makdjpeg.cf makefile.bcc
# makefile.manx makefile.mc5 testimg.jpg.u testorig.jpg.u
# Wrapped by kent@sparky on Mon Mar 23 16:02:56 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 16 (of 18)."'
if test -f 'jddeflts.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jddeflts.c'\"
else
echo shar: Extracting \"'jddeflts.c'\" \(6026 characters\)
sed "s/^X//" >'jddeflts.c' <<'END_OF_FILE'
X/*
X * jddeflts.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains optional default-setting code for the JPEG decompressor.
X * User interfaces do not have to use this file, but those that don't use it
X * must know more about the innards of the JPEG code.
X */
X
X#include "jinclude.h"
X
X
X/* Default do-nothing progress monitoring routine.
X * This can be overridden by a user interface that wishes to
X * provide progress monitoring; just set methods->progress_monitor
X * after j_d_defaults is done. The routine will be called periodically
X * during the decompression process.
X *
X * During any one pass, loopcounter increases from 0 up to (not including)
X * looplimit; the step size is not necessarily 1. Both the step size and
X * the limit may differ between passes. The expected total number of passes
X * is in cinfo->total_passes, and the number of passes already completed is
X * in cinfo->completed_passes. Thus the fraction of work completed may be
X * estimated as
X * completed_passes + (loopcounter/looplimit)
X * ------------------------------------------
X * total_passes
X * ignoring the fact that the passes may not be equal amounts of work.
X *
X * When decompressing, the total_passes figure is an estimate that may be
X * on the high side; completed_passes will jump by more than one if some
X * passes are skipped.
X */
X
XMETHODDEF void
Xprogress_monitor (decompress_info_ptr cinfo, long loopcounter, long looplimit)
X{
X /* do nothing */
X}
X
X
X/*
X * Reload the input buffer after it's been emptied, and return the next byte.
X * See the JGETC macro for calling conditions.
X *
X * This routine can be overridden by the system-dependent user interface,
X * in case the data source is not a stdio stream or some other special
X * condition applies. Note, however, that this capability only applies for
X * JFIF or similar serial-access JPEG file formats. The input file control
X * module for a random-access format such as TIFF/JPEG would most likely
X * override the read_jpeg_data method with its own routine.
X */
X
XMETHODDEF int
Xread_jpeg_data (decompress_info_ptr cinfo)
X{
X cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
X
X cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
X cinfo->next_input_byte,
X JPEG_BUF_SIZE);
X
X if (cinfo->bytes_in_buffer <= 0)
X ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
X
X return JGETC(cinfo);
X}
X
X
X
X */
X
XGLOBAL void
Xj_d_defaults (decompress_info_ptr cinfo, boolean standard_buffering)
X/* NB: the external methods must already be set up. */
X{
X short i;
X
X /* Initialize pointers as needed to mark stuff unallocated. */
X /* Outer application may fill in default tables for abbreviated files... */
X cinfo->comp_info = NULL;
X for (i = 0; i < NUM_QUANT_TBLS; i++)
X cinfo->quant_tbl_ptrs[i] = NULL;
X for (i = 0; i < NUM_HUFF_TBLS; i++) {
X cinfo->dc_huff_tbl_ptrs[i] = NULL;
X cinfo->ac_huff_tbl_ptrs[i] = NULL;
X }
X cinfo->colormap = NULL;
X
X /* Default to RGB output */
X /* UI can override by changing out_color_space */
X cinfo->out_color_space = CS_RGB;
X cinfo->jpeg_color_space = CS_UNKNOWN;
X /* Setting any other value in jpeg_color_space overrides heuristics in */
X /* jrdjfif.c. That might be useful when reading non-JFIF JPEG files, */
X /* but ordinarily the UI shouldn't change it. */
X
X /* Default to no gamma correction of output */
X cinfo->output_gamma = 1.0;
X
X /* Default to no color quantization */
X cinfo->quantize_colors = FALSE;
X /* but set reasonable default parameters for quantization, */
X /* so that turning on quantize_colors is sufficient to do something useful */
X cinfo->two_pass_quantize = TRUE;
X cinfo->use_dithering = TRUE;
X cinfo->desired_number_of_colors = 256;
X
X /* Default to no smoothing */
X cinfo->do_block_smoothing = FALSE;
X cinfo->do_pixel_smoothing = FALSE;
X
X /* Allocate memory for input buffer, unless outer application provides it. */
X if (standard_buffering) {
X cinfo->input_buffer = (char *) (*cinfo->emethods->alloc_small)
X ((size_t) (JPEG_BUF_SIZE + MIN_UNGET));
X cinfo->bytes_in_buffer = 0; /* initialize buffer to empty */
X }
X
X /* Install standard buffer-reloading method (outer code may override). */
X cinfo->methods->read_jpeg_data = read_jpeg_data;
X
X /* Install default do-nothing progress monitoring method. */
X cinfo->methods->progress_monitor = progress_monitor;
X}
END_OF_FILE
if test 6026 -ne `wc -c <'jddeflts.c'`; then
echo shar: \"'jddeflts.c'\" unpacked with wrong size!
fi
# end of 'jddeflts.c'
fi
if test -f 'jdmcu.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jdmcu.c'\"
else
echo shar: Extracting \"'jdmcu.c'\" \(6106 characters\)
sed "s/^X//" >'jdmcu.c' <<'END_OF_FILE'
X/*
X * jdmcu.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains MCU disassembly routines and quantization descaling.
X * These routines are invoked via the disassemble_MCU, reverse_DCT, and
X * disassemble_init/term methods.
X */
X
X#include "jinclude.h"
X
X
X/*
X * Quantization descaling and zigzag reordering
X */
X
X
X/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
X
Xstatic const short ZAG[DCTSIZE2] = {
X 0, 1, 8, 16, 9, 2, 3, 10,
X 17, 24, 32, 25, 18, 11, 4, 5,
X 12, 19, 26, 33, 40, 48, 41, 34,
X 27, 20, 13, 6, 7, 14, 21, 28,
X 35, 42, 49, 56, 57, 50, 43, 36,
X 29, 22, 15, 23, 30, 37, 44, 51,
X 58, 59, 52, 45, 38, 31, 39, 46,
X 53, 60, 61, 54, 47, 55, 62, 63
X};
X
X
XLOCAL void
Xqdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl)
X{
X const short * zagptr = ZAG;
X short i;
X
X for (i = DCTSIZE2-1; i >= 0; i--) {
X (*outputptr)[*zagptr++] = (*input++) * (*quanttbl++);
X }
X}
X
X
X
X/*
X * Fetch one MCU row from entropy_decode, build coefficient array.
X * This version is used for noninterleaved (single-component) scans.
X */
X
XMETHODDEF void
Xdisassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
X JBLOCKIMAGE image_data)
X{
X JBLOCK MCU_data[1];
X long mcuindex;
X jpeg_component_info * compptr;
X QUANT_TBL_PTR quant_ptr;
X
X /* this is pretty easy since there is one component and one block per MCU */
X compptr = cinfo->cur_comp_info[0];
X quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
X for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
X /* Fetch the coefficient data */
X (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
X /* Descale, reorder, and distribute it into the image array */
X qdescale_zig(MCU_data[0], image_data[0][0] + mcuindex, quant_ptr);
X }
X}
X
X
X/*
X * Fetch one MCU row from entropy_decode, build coefficient array.
X * This version is used for interleaved (multi-component) scans.
X */
X
XMETHODDEF void
Xdisassemble_interleaved_MCU (decompress_info_ptr cinfo,
X JBLOCKIMAGE image_data)
X{
X JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
X long mcuindex;
X short blkn, ci, xpos, ypos;
X jpeg_component_info * compptr;
X QUANT_TBL_PTR quant_ptr;
X JBLOCKROW image_ptr;
X
X for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
X /* Fetch the coefficient data */
X (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
X /* Descale, reorder, and distribute it into the image array */
X blkn = 0;
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X compptr = cinfo->cur_comp_info[ci];
X quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
X for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
X image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
X for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
X qdescale_zig(MCU_data[blkn], image_ptr, quant_ptr);
X image_ptr++;
X blkn++;
X }
X }
X }
X }
X}
X
X
X/*
X * Perform inverse DCT on each block in an MCU row's worth of data;
X * output the results into a sample array starting at row start_row.
X * NB: start_row can only be nonzero when dealing with a single-component
X * scan; otherwise we'd have to pass different offsets for different
X * components, since the heights of interleaved MCU rows can vary.
X * But the pipeline controller logic is such that this is not necessary.
X */
X
XMETHODDEF void
Xreverse_DCT (decompress_info_ptr cinfo,
X JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data, int start_row)
X{
X DCTBLOCK block;
X JBLOCKROW browptr;
X JSAMPARRAY srowptr;
X long blocksperrow, bi;
X short numrows, ri;
X short ci;
X
X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
X /* calculate size of an MCU row in this component */
X blocksperrow = cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE;
X numrows = cinfo->cur_comp_info[ci]->MCU_height;
X /* iterate through all blocks in MCU row */
X for (ri = 0; ri < numrows; ri++) {
X browptr = coeff_data[ci][ri];
X srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
X for (bi = 0; bi < blocksperrow; bi++) {
X /* copy the data into a local DCTBLOCK. This allows for change of
X * representation (if DCTELEM != JCOEF). On 80x86 machines it also
X * brings the data back from FAR storage to NEAR storage.
X */
X { register JCOEFPTR elemptr = browptr[bi];
X register DCTELEM *localblkptr = block;
X register short elem = DCTSIZE2;
X
X while (--elem >= 0)
X *localblkptr++ = (DCTELEM) *elemptr++;
X }
X
X j_rev_dct(block); /* perform inverse DCT */
X
X /* output the data into the sample array.
X * Note change from signed to unsigned representation:
X * DCT calculation works with values +-CENTERJSAMPLE,
X * but sample arrays always hold 0..MAXJSAMPLE.
X * Have to do explicit range-limiting because of quantization errors
X * and so forth in the DCT/IDCT phase.
X */
X { register JSAMPROW elemptr;
X register DCTELEM *localblkptr = block;
X register short elemr, elemc;
X register DCTELEM temp;
X
X for (elemr = 0; elemr < DCTSIZE; elemr++) {
X elemptr = srowptr[elemr] + (bi * DCTSIZE);
X for (elemc = 0; elemc < DCTSIZE; elemc++) {
X temp = (*localblkptr++) + CENTERJSAMPLE;
X if (temp < 0) temp = 0;
X else if (temp > MAXJSAMPLE) temp = MAXJSAMPLE;
X *elemptr++ = (JSAMPLE) temp;
X }
X }
X }
X }
X }
X }
X}
X
X
X/*
X * Initialize for processing a scan.
X */
X
XMETHODDEF void
Xdisassemble_init (decompress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X/*
X * Clean up after a scan.
X */
X
XMETHODDEF void
Xdisassemble_term (decompress_info_ptr cinfo)
X{
X /* no work for now */
X}
X
X
X
X/*
X * The method selection routine for MCU disassembly.
X */
X
XGLOBAL void
Xjseldmcu (decompress_info_ptr cinfo)
X{
X if (cinfo->comps_in_scan == 1)
X cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
X else
X cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
X cinfo->methods->reverse_DCT = reverse_DCT;
X cinfo->methods->disassemble_init = disassemble_init;
X cinfo->methods->disassemble_term = disassemble_term;
X}
END_OF_FILE
if test 6106 -ne `wc -c <'jdmcu.c'`; then
echo shar: \"'jdmcu.c'\" unpacked with wrong size!
fi
# end of 'jdmcu.c'
fi
if test -f 'jwrtarga.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'jwrtarga.c'\"
else
echo shar: Extracting \"'jwrtarga.c'\" \(5888 characters\)
sed "s/^X//" >'jwrtarga.c' <<'END_OF_FILE'
X/*
X * jwrtarga.c
X *
X * Copyright (C) 1991, 1992, Thomas G. Lane.
X * This file is part of the Independent JPEG Group's software.
X * For conditions of distribution and use, see the accompanying README file.
X *
X * This file contains routines to write output images in Targa format.
X *
X * These routines may need modification for non-Unix environments or
X * specialized applications. As they stand, they assume output to
X * an ordinary stdio stream.
X *
X * These routines are invoked via the methods put_pixel_rows, put_color_map,
X * and output_init/term.
X *
X * Based on code contributed by Lee Daniel Crocker.
X */
X
X#include "jinclude.h"
X
X#ifdef TARGA_SUPPORTED
X
X
X/*
X * To support 12-bit JPEG data, we'd have to scale output down to 8 bits.
X * This is not yet implemented.
X */
X
X#ifndef EIGHT_BIT_SAMPLES
X Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
X#endif
X
X
XLOCAL void
Xwrite_header (decompress_info_ptr cinfo, int num_colors)
X/* Create and write a Targa header */
X{
X char targaheader[18];
X
X /* Set unused fields of header to 0 */
X MEMZERO((void *) targaheader, SIZEOF(targaheader));
X
X if (num_colors > 0) {
X targaheader[1] = 1; /* color map type 1 */
X targaheader[5] = (char) (num_colors & 0xFF);
X targaheader[6] = (char) (num_colors >> 8);
X targaheader[7] = 24; /* 24 bits per cmap entry */
X }
X
X targaheader[12] = (char) (cinfo->image_width & 0xFF);
X targaheader[13] = (char) (cinfo->image_width >> 8);
X targaheader[14] = (char) (cinfo->image_height & 0xFF);
X targaheader[15] = (char) (cinfo->image_height >> 8);
X targaheader[17] = 0x20; /* Top-down, non-interlaced */
X
X if (cinfo->out_color_space == CS_GRAYSCALE) {
X targaheader[2] = 3; /* image type = uncompressed gray-scale */
X targaheader[16] = 8; /* bits per pixel */
X } else { /* must be RGB */
X if (num_colors > 0) {
X targaheader[2] = 1; /* image type = colormapped RGB */
X targaheader[16] = 8;
X } else {
X targaheader[2] = 2; /* image type = uncompressed RGB */
X targaheader[16] = 24;
X }
X }
X
X if (JFWRITE(cinfo->output_file, targaheader, 18) != (size_t) 18)
X ERREXIT(cinfo->emethods, "Could not write Targa header");
X}
X
X
X/*
X * Write the file header.
X */
X
XMETHODDEF void
Xoutput_init (decompress_info_ptr cinfo)
X{
X if (cinfo->out_color_space == CS_GRAYSCALE) {
X /* Targa doesn't have a mapped grayscale format, so we will */
X /* demap quantized gray output. Never emit a colormap. */
X write_header(cinfo, 0);
X } else if (cinfo->out_color_space == CS_RGB) {
X /* For quantized output, defer writing header until put_color_map time. */
X if (! cinfo->quantize_colors)
X write_header(cinfo, 0);
X } else {
X ERREXIT(cinfo->emethods, "Targa output must be grayscale or RGB");
X }
X}
X
X
X/*
X * Write some pixel data.
X */
X
XMETHODDEF void
Xput_pixel_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X register FILE * outfile = cinfo->output_file;
X register JSAMPROW ptr0, ptr1, ptr2;
X register long col;
X register long width = cinfo->image_width;
X register int row;
X
X if (cinfo->final_out_comps == 1) {
X /* here for grayscale or quantized color output */
X for (row = 0; row < num_rows; row++) {
X ptr0 = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(*ptr0), outfile);
X ptr0++;
X }
X }
X } else {
X /* here for unquantized color output */
X for (row = 0; row < num_rows; row++) {
X ptr0 = pixel_data[0][row];
X ptr1 = pixel_data[1][row];
X ptr2 = pixel_data[2][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(*ptr2), outfile); /* write in BGR order */
X ptr2++;
X putc(GETJSAMPLE(*ptr1), outfile);
X ptr1++;
X putc(GETJSAMPLE(*ptr0), outfile);
X ptr0++;
X }
X }
X }
X}
X
X
X/*
X * Write some demapped pixel data when color quantization is in effect.
X * For Targa, this is only applied to grayscale data.
X */
X
XMETHODDEF void
Xput_demapped_rows (decompress_info_ptr cinfo, int num_rows,
X JSAMPIMAGE pixel_data)
X{
X register FILE * outfile = cinfo->output_file;
X register JSAMPARRAY color_map = cinfo->colormap;
X register JSAMPROW ptr;
X register long col;
X long width = cinfo->image_width;
X int row;
X
X for (row = 0; row < num_rows; row++) {
X ptr = pixel_data[0][row];
X for (col = width; col > 0; col--) {
X putc(GETJSAMPLE(color_map[0][GETJSAMPLE(*ptr)]), outfile);
X ptr++;
X }
X }
X}
X
X
X/*
X * Write the color map.
X */
X
XMETHODDEF void
Xput_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
X{
X register FILE * outfile = cinfo->output_file;
X int i;
X
X if (cinfo->out_color_space == CS_RGB) {
X /* We only support 8-bit colormap indexes, so only 256 colors */
X if (num_colors > 256)
X ERREXIT(cinfo->emethods, "Too many colors for Targa output");
X /* Time to write the header */
X write_header(cinfo, num_colors);
X /* Write the colormap. Note Targa uses BGR byte order */
X for (i = 0; i < num_colors; i++) {
X putc(GETJSAMPLE(colormap[2][i]), outfile);
X putc(GETJSAMPLE(colormap[1][i]), outfile);
X putc(GETJSAMPLE(colormap[0][i]), outfile);
X }
X } else {
X cinfo->methods->put_pixel_rows = put_demapped_rows;
X }
X}
X
X
X/*
X * Finish up at the end of the file.
X */
X
XMETHODDEF void
Xoutput_term (decompress_info_ptr cinfo)
X{
X /* No work except to make sure we wrote the output file OK */
X fflush(cinfo->output_file);
X if (ferror(cinfo->output_file))
X ERREXIT(cinfo->emethods, "Output file write error");
X}
X
X
X/*
X * The method selection routine for Targa format output.
X * This should be called from d_ui_method_selection if Targa output is wanted.
X */
X
XGLOBAL void
Xjselwtarga (decompress_info_ptr cinfo)
X{
X cinfo->methods->output_init = output_init;
X cinfo->methods->put_color_map = put_color_map;
X cinfo->methods->put_pixel_rows = put_pixel_rows;
X cinfo->methods->output_term = output_term;
X}
X
X#endif /* TARGA_SUPPORTED */
END_OF_FILE
if test 5888 -ne `wc -c <'jwrtarga.c'`; then
echo shar: \"'jwrtarga.c'\" unpacked with wrong size!
fi
# end of 'jwrtarga.c'
fi
if test -f 'makdjpeg.cf' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makdjpeg.cf'\"
else
echo shar: Extracting \"'makdjpeg.cf'\" \(300 characters\)
sed "s/^X//" >'makdjpeg.cf' <<'END_OF_FILE'
XL jdmain.mix jdmaster.mix jddeflts.mix jbsmooth.mix jdarith.mix jdcolor.mix
XL jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix
XL jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jwrrle.mix jwrtarga.mix
XL jutils.mix jerror.mix jmemmgr.mix jmemsys.mix jmemdosa.mix
Xfa;
Xb djpeg,8K,48K,
END_OF_FILE
if test 300 -ne `wc -c <'makdjpeg.cf'`; then
echo shar: \"'makdjpeg.cf'\" unpacked with wrong size!
fi
# end of 'makdjpeg.cf'
fi
if test -f 'makefile.bcc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.bcc'\"
else
echo shar: Extracting \"'makefile.bcc'\" \(6113 characters\)
sed "s/^X//" >'makefile.bcc' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is suitable for Borland C (Turbo C) on MS-DOS.
X# It is set up for Borland C++, revision 3.0 or later.
X# For older versions (pre-3.0), replace "-O2" with "-O -G -Z" in CFLAGS.
X# If you have an even older version of Turbo C, you may be able to make it
X# work by saying "CC= tcc" below. (Very early versions of Turbo C++,
X# like 1.01, are so buggy that you may as well forget it.)
X# Thanks to Tom Wright and Ge' Weijers for this file.
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC= bcc
X
X# You may need to adjust these cc options:
XCFLAGS= -DHAVE_STDC -DINCLUDES_ARE_ANSI \
X -ms -DMSDOS -DINCOMPLETE_TYPES_BROKEN -w-par -O2
X# -DHAVE_STDC -DINCLUDES_ARE_ANSI enable ANSI-C features (we DON'T want -A)
X# -ms selects small memory model for most efficient code
X# -DMSDOS enables DOS-specific code
X# -DINCOMPLETE_TYPES_BROKEN suppresses bogus warning about undefined structures
X# -w-par suppresses warnings about unused function parameters
X# -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z)
X
X# Link-time cc options:
XLDFLAGS= -ms
X# memory model option here must match CFLAGS!
X
Xcjpeg.exe: $(COBJECTS)
X $(CC) $(LDFLAGS) -ecjpeg.exe @makcjpeg.lst
X
Xdjpeg.exe: $(DOBJECTS)
X $(CC) $(LDFLAGS) -edjpeg.exe @makdjpeg.lst
X
X.c.obj:
X $(CC) $(CFLAGS) -c $<
X
Xclean:
X del *.obj
X del cjpeg.exe
X del djpeg.exe
X del testout.*
X
Xtest:
X del testout.*
X djpeg testorig.jpg testout.ppm
X djpeg -G testorig.jpg testout.gif
X cjpeg testimg.ppm testout.jpg
X fc testimg.ppm testout.ppm
X fc testimg.gif testout.gif
X fc testimg.jpg testout.jpg
X
Xjmemdosa.obj : jmemdosa.asm
X tasm /mx jmemdosa.asm
END_OF_FILE
if test 6113 -ne `wc -c <'makefile.bcc'`; then
echo shar: \"'makefile.bcc'\" unpacked with wrong size!
fi
# end of 'makefile.bcc'
fi
if test -f 'makefile.manx' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.manx'\"
else
echo shar: Extracting \"'makefile.manx'\" \(5948 characters\)
sed "s/^X//" >'makefile.manx' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for Amiga systems using Manx Aztec C ver 5.x.
X# Use jmemname.c as the system-dependent memory manager.
X# Thanks to D.J. James (djj...@cup.portal.com) for this version.
X
X# Read SETUP instructions before saying "make" !!
X
X# The name of your C compiler:
XCC= cc
X
X# You may need to adjust these cc options:
XCFLAGS= -MC -MD -sf -sn -sp -DAMIGA -DTWO_FILE_COMMANDLINE \
X -DNEED_SIGNAL_CATCHER -Dsignal_catcher=_abort
X
X# Link-time cc options:
XLDFLAGS=
X
X# To link any special libraries, add the necessary -l commands here.
XLDLIBS= -lml -lcl
X
X# miscellaneous OS-dependent stuff
X# linker
XLN= ln
X# file deletion command
XRM= delete quiet
X# library (.lib) file creation command
XAR= lb
XCOMOBJECTS= jutils.o jerror.o jmemmgr.o jmemsys.o
X# compression objectfiles
XCLIBOBJECTS= jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o jchuff.o \
X jcmcu.o jcpipe.o jcsample.o jfwddct.o jwrjfif.o jrdgif.o jrdppm.o \
X jrdrle.o jrdtarga.o
XCOBJECTS= jcmain.o $(CLIBOBJECTS) $(COMOBJECTS)
X# decompression objectfiles
XDLIBOBJECTS= jdmaster.o jddeflts.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
X jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o jrdjfif.o \
X jwrgif.o jwrppm.o jwrrle.o jwrtarga.o
XDOBJECTS= jdmain.o $(DLIBOBJECTS) $(COMOBJECTS)
X# These objectfiles are included in libjpeg.lib
XLIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
X
X
Xall: cjpeg djpeg
X# By default, libjpeg.lib is not built unless you explicitly request it.
X# You can add libjpeg.lib to the line above if you want it built by default.
X
X
Xcjpeg: $(COBJECTS)
X $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
X
Xdjpeg: $(DOBJECTS)
X $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
X
X# libjpeg.lib is useful if you are including the JPEG software in a larger
X# program; you'd include it in your link, rather than the individual modules.
Xlibjpeg.lib: $(LIBOBJECTS)
X -$(RM) libjpeg.lib
X $(AR) libjpeg.lib $(LIBOBJECTS)
X
Xclean:
X -$(RM) *.o cjpeg djpeg libjpeg.lib core testout.*
X
Xdistribute:
X -$(RM) jpegsrc.tar*
X tar cvf jpegsrc.tar $(DISTFILES)
X compress -v jpegsrc.tar
X
Xtest: cjpeg djpeg
X -$(RM) testout.ppm testout.gif testout.jpg
X djpeg testorig.jpg testout.ppm
X djpeg -G testorig.jpg testout.gif
X cjpeg testimg.ppm testout.jpg
echo shar: \"'makefile.manx'\" unpacked with wrong size!
fi
# end of 'makefile.manx'
fi
if test -f 'makefile.mc5' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.mc5'\"
else
echo shar: Extracting \"'makefile.mc5'\" \(6015 characters\)
sed "s/^X//" >'makefile.mc5' <<'END_OF_FILE'
X# Makefile for Independent JPEG Group's software
X
X# This makefile is for Microsoft C for MS-DOS, version 5.x.
X
X# Read SETUP instructions before saying "make" !!
X
X# Microsoft's brain-damaged version of make uses nonstandard syntax (a blank
X# line is needed to terminate a command list) and it simply scans the rules
X# in order, rather than doing a true dependency-tree walk. Furthermore,
X# expanded command lines can't exceed 128 chars (this is a DOS bug, not
X# make's fault); so we can't just name all the objectfiles in the link steps.
X# Instead we shove each objectfile into a library as it is made, and link
X# from the library. The objectfiles are also kept separately as timestamps.
X
X# You may need to adjust these cc options:
XCFLAGS= /AS /I. /W3 /Oail /Gs # NB: /Gs turns off stack oflo checks
XLDFLAGS= /Fm /F 2000 # /F hhhh sets stack size (in hex)
X# In particular:
X# Add /DMSDOS if your compiler doesn't automatically #define MSDOS.
X# Add /DMEM_STATS to enable gathering of memory usage statistics.
X# You might also want to add /G2 if you have an 80286, etc.
X
X# inference rule used for all compilations except jcmain.c, jdmain.c
X# notice that objectfile is also inserted into libjpeg.lib
X.c.obj:
X cl $(CFLAGS) /c $*.c
X lib libjpeg -+$*.obj;
X
X# inference rule for assembly code
X.asm.obj:
X masm /mx $*;
X lib libjpeg -+$*.obj;
X
X
Xjbsmooth.obj : jbsmooth.c jinclude.h jconfig.h jpegdata.h
X
Xjcarith.obj : jcarith.c jinclude.h jconfig.h jpegdata.h
X
Xjccolor.obj : jccolor.c jinclude.h jconfig.h jpegdata.h
X
Xjcdeflts.obj : jcdeflts.c jinclude.h jconfig.h jpegdata.h
X
Xjcexpand.obj : jcexpand.c jinclude.h jconfig.h jpegdata.h
X
Xjchuff.obj : jchuff.c jinclude.h jconfig.h jpegdata.h
X
Xjcmain.obj : jcmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
X cl $(CFLAGS) /c $*.c
X
Xjcmaster.obj : jcmaster.c jinclude.h jconfig.h jpegdata.h
X
Xjcmcu.obj : jcmcu.c jinclude.h jconfig.h jpegdata.h
X
Xjcpipe.obj : jcpipe.c jinclude.h jconfig.h jpegdata.h
X
Xjcsample.obj : jcsample.c jinclude.h jconfig.h jpegdata.h
X
Xjdarith.obj : jdarith.c jinclude.h jconfig.h jpegdata.h
X
Xjdcolor.obj : jdcolor.c jinclude.h jconfig.h jpegdata.h
X
Xjddeflts.obj : jddeflts.c jinclude.h jconfig.h jpegdata.h
X
Xjdhuff.obj : jdhuff.c jinclude.h jconfig.h jpegdata.h
X
Xjdmain.obj : jdmain.c jinclude.h jconfig.h jpegdata.h jversion.h egetopt.c
X cl $(CFLAGS) /c $*.c
X
X
Xcjpeg.exe: $(COBJECTS)
X cl /Fecjpeg.exe jcmain.obj libjpeg.lib $(LDFLAGS)
X
Xdjpeg.exe: $(DOBJECTS)
X cl /Fedjpeg.exe jdmain.obj libjpeg.lib $(LDFLAGS)
END_OF_FILE
if test 6015 -ne `wc -c <'makefile.mc5'`; then
echo shar: \"'makefile.mc5'\" unpacked with wrong size!
fi
fi
echo shar: End of archive 16 \(of 18\).
cp /dev/null ark16isdone