]> granicus.if.org Git - libjpeg-turbo/commitdiff
The Independent JPEG Group's JPEG software v1 jpeg-1
authorThomas G. Lane <tgl@netcom.com>
Mon, 7 Oct 1991 00:00:00 +0000 (00:00 +0000)
committerDRC <information@libjpeg-turbo.org>
Wed, 29 Jul 2015 20:18:11 +0000 (15:18 -0500)
53 files changed:
README [new file with mode: 0644]
ansi2knr.c [new file with mode: 0644]
architecture [new file with mode: 0644]
codingrules [new file with mode: 0644]
egetopt.c [new file with mode: 0644]
jbsmooth.c [new file with mode: 0644]
jcarith.c [new file with mode: 0644]
jccolor.c [new file with mode: 0644]
jcdeflts.c [new file with mode: 0644]
jcexpand.c [new file with mode: 0644]
jchuff.c [new file with mode: 0644]
jcmain.c [new file with mode: 0644]
jcmaster.c [new file with mode: 0644]
jcmcu.c [new file with mode: 0644]
jconfig.h [new file with mode: 0644]
jcpipe.c [new file with mode: 0644]
jcsample.c [new file with mode: 0644]
jdarith.c [new file with mode: 0644]
jdcolor.c [new file with mode: 0644]
jdhuff.c [new file with mode: 0644]
jdmain.c [new file with mode: 0644]
jdmaster.c [new file with mode: 0644]
jdmcu.c [new file with mode: 0644]
jdpipe.c [new file with mode: 0644]
jdsample.c [new file with mode: 0644]
jerror.c [new file with mode: 0644]
jfwddct.c [new file with mode: 0644]
jinclude.h [new file with mode: 0644]
jpegdata.h [new file with mode: 0644]
jquant1.c [new file with mode: 0644]
jquant2.c [new file with mode: 0644]
jrdgif.c [new file with mode: 0644]
jrdjfif.c [new file with mode: 0644]
jrdppm.c [new file with mode: 0644]
jrevdct.c [new file with mode: 0644]
jutils.c [new file with mode: 0644]
jvirtmem.c [new file with mode: 0644]
jwrgif.c [new file with mode: 0644]
jwrjfif.c [new file with mode: 0644]
jwrppm.c [new file with mode: 0644]
makcjpeg.cf [new file with mode: 0644]
makcjpeg.lnk [new file with mode: 0644]
makdjpeg.cf [new file with mode: 0644]
makdjpeg.lnk [new file with mode: 0644]
makefile.amiga [new file with mode: 0644]
makefile.mc5 [new file with mode: 0644]
makefile.mc6 [new file with mode: 0644]
makefile.pwc [new file with mode: 0644]
makefile.unix [new file with mode: 0644]
makljpeg.cf [new file with mode: 0644]
testimg.jpg [new file with mode: 0644]
testimg.ppm [new file with mode: 0644]
testorig.jpg [new file with mode: 0644]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..9a2a1bb
--- /dev/null
+++ b/README
@@ -0,0 +1,391 @@
+The Independent JPEG Group's JPEG software
+==========================================
+
+README for release of  7-Oct-91
+===============================
+
+This distribution contains the first public release of the Independent JPEG
+Group's free JPEG software.  You are welcome to redistribute this software and
+to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
+
+This software is still undergoing revision.  Updated versions may be obtained
+by anonymous FTP to uunet.uu.net; look under directory /graphics/jpeg.  This
+particular version will be archived as jpegsrc.v1.tar.Z.  If you don't have
+access to Internet FTP, UUNET's archives are also available via UUCP; contact
+postmaster@uunet.uu.net for information on retrieving files that way.
+
+Please report any problems with this software to jpeg-info@uunet.uu.net.
+
+If you intend to become a serious user of this software, please contact
+jpeg-info@uunet to be added to our electronic mailing list.  Then you'll be
+notified of updates and have a chance to participate in discussions, etc.
+
+This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, and other
+members of the independent JPEG group.
+
+
+DISCLAIMER
+==========
+
+THIS SOFTWARE IS NOT COMPLETE NOR FULLY DEBUGGED.  It is not guaranteed to be
+useful for anything, nor to be compatible with subsequent releases, nor to be
+an accurate implementation of the JPEG standard.  (See LEGAL ISSUES for even
+more disclaimers.)
+
+
+WHAT'S HERE
+===========
+
+This distribution contains 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 necessarily identical to the input image.  Hence
+you should not use JPEG if you have to have identical output bits.  However,
+on typical images of real-world scenes, very good compression levels can be
+obtained with hardly any visible change, and amazingly high compression levels
+can be obtained if you can tolerate a low-quality image.  For more details,
+see the references, or just experiment with various compression settings.
+
+The software implements JPEG baseline and extended-sequential compression
+processes.  Provision is made for supporting all variants of these processes,
+although some uncommon parameter settings aren't implemented yet.  For legal
+reasons, we are not distributing code for the arithmetic-coding process; see
+LEGAL ISSUES.  At present we have made no provision for supporting the
+progressive or lossless processes defined in the standard.
+
+The present software is still largely in the prototype stage.  It does not
+support all possible variants of the JPEG standard, and some functions have
+rather slow and/or crude implementations.  However, it is useful already.
+
+The emphasis in designing this software has been on achieving portability and
+flexibility, while also making it fast enough to be useful.  We have not yet
+undertaken serious performance measurement or tuning; we intend to do so in
+the future.
+
+
+This software can be used on several levels:
+
+* As canned software for JPEG compression and decompression.  Just edit the
+  Makefile and configuration files as needed (see SETUP), compile and go.
+  Members of the independent JPEG group will improve the out-of-the-box
+  functionality as time goes on.
+
+* As the basis for other JPEG programs.  For example, you could incorporate
+  the decompressor into a general image viewing package by replacing the
+  output module with write-to-screen functions.  For an implementation on
+  specific hardware, you might want to replace some of the inner loops with
+  assembly code.  For a non-command-line-driven system, you might want a
+  different user interface.  (Members of the group will be producing Macintosh
+  and Amiga versions with appropriate user interfaces, for example.)
+
+* As a toolkit for experimentation with JPEG and JPEG-like algorithms.  Most
+  of the individual decisions you might want to mess with are packaged up into
+  separate modules.  For example, the details of color-space conversion and
+  subsampling techniques are each localized in one compressor and one
+  decompressor module.  You'd probably also want to extend the user interface
+  to give you more detailed control over the JPEG compression parameters.
+
+In particular, we welcome the use of this software as the basis for commercial
+products; no royalty is required.
+
+
+SETUP
+=====
+
+The installation process is not very automatic; you will need at least some
+familiarity with C programming and program build procedures for your system.
+(Volunteers to work on improving this situation are welcome.  Also, we will
+probably start distributing pre-built binaries for popular systems at some
+point.)
+
+First, select a makefile and copy it to "Makefile".  "makefile.unix"
+is appropriate for most Unix and Unix-like systems.  Special makefiles are
+included for various PC compilers.  If you don't see a makefile for your
+system, we recommend starting from makefile.unix.
+
+Look over the Makefile and adjust options as needed.  In particular, you'll
+need to change the CC= and CFLAGS= definitions if you don't have gcc
+(makefile.unix only).  If you have a function-prototype-less compiler, be sure
+to uncomment the .c.o rule and say "make ansi2knr".  This will cause the
+source files to be preprocessed to change our ANSI-style function definitions
+to old-style definitions.  (Thanks to Peter Deutsch of Aladdin Enterprises for
+ansi2knr.)
+
+Also look over jconfig.h and adjust #defines as necessary.  If you have an
+ANSI-compliant C compiler (gcc for instance), no changes should be necessary
+except perhaps for RIGHT_SHIFT_IS_UNSIGNED and TWO_FILE_COMMANDLINE.  For
+older compilers other mods may be needed, depending on what ANSI features are
+supported.  If you prefer, you can usually leave jconfig.h unmodified and add
+-D switches to the Makefile's CFLAGS= definition.
+
+Then say "make".
+
+If you have trouble with missing system include files or inclusion of the
+wrong ones, you can fix it in jinclude.h.  In particular, if you are using
+gcc on a machine with non-ANSI system include files, you are likely to find
+that jinclude.h tries to include the wrong files (because gcc defines
+__STDC__).  There's no good automatic solution to this, so you'll just have
+to hand-edit jinclude.h.
+
+As a quick test of functionality we've included three sample files:
+       testorig.jpg    same as blkint.jpg from JPEG validation floppy.
+       testimg.ppm     output of djpeg testorig.jpg
+       testimg.jpg     output of cjpeg testimg.ppm
+The two .jpg files aren't identical due to different parameter choices (and
+wouldn't be anyway, since JPEG is lossy).  However, if you can generate
+duplicates of testimg.ppm and testimg.jpg then you probably have a working
+port.  "make test" will perform the necessary comparisons (by generating
+testout.ppm and testout.jpg and comparing these to testimg.*).  NOTE: this
+is far from an exhaustive test of the JPEG software; some modules, such as
+color quantization and GIF I/O, are not exercised at all.  It's just a quick
+test to give you some confidence that you haven't missed something major.
+
+If you need to make a smaller version of the JPEG software, some optional
+functions can be removed at compile time.  See the xxx_SUPPORTED #defines
+in jconfig.h.  (Not a lot is actually removed right now, but as more optional
+stuff gets added, this mechanism will start to make a difference.)
+
+If you want to incorporate the JPEG code as subroutines in a larger program,
+we recommend that you make libjpeg.a.  Then use the .h files and libjpeg.a as
+your interface to the JPEG functions.  Your surrounding program will have to
+provide functionality similar to what's in jcmain.c or jdmain.c, and you may
+want to replace jerror.c and possibly other modules depending on your needs.
+See the "architecture" file for more info.  If it seems to you that the system
+structure doesn't accommodate what you want to do, please contact the authors.
+
+Special notes for Macintosh Think C users: If you have version 5.0 you should
+be able to just turn on __STDC__ through the compiler switch that enables
+that.  With version 4.0 you must manually edit jconfig.h to define PROTO,
+HAVE_UNSIGNED_CHAR, HAVE_UNSIGNED_SHORT, and const.  (It seems to be safe to
+just define __STDC__ to take care of the first three.)  When setting up
+project files, use the COBJECTS and DOBJECTS lists in makefile.unix as a guide
+to which files need to be included, and add the ANSI and Unix C libraries in a
+separate segment.  You may need to divide the JPEG files into more than one
+segment; you can do this pretty much as you please.
+
+
+USAGE
+=====
+
+The user interface is pretty minimal at this point.  We haven't bothered to
+generate manual-page files since the switches badly need redesign.  At the
+moment, things work like this:
+
+There are two programs, cjpeg to compress an image file into JPEG format,
+and djpeg to decompress.
+
+On Unix systems, you say:
+       cjpeg [switches] [imagefile] >jpegfile
+       djpeg [switches] [jpegfile]  >imagefile
+The programs read the specified input file, or standard input if none is
+named.  They always write to standard output (with trace/error messages to
+standard error).  These conventions are handy for piping images between
+programs.
+
+On PC, Macintosh, and Amiga systems, you say:
+       cjpeg [switches] imagefile jpegfile
+       djpeg [switches] jpegfile  imagefile
+i.e., both input and output files are named on the command line.  This style
+is a little more foolproof, and it loses no functionality if you don't have
+pipes.  You can get this style on Unix too, if you prefer, by defining
+TWO_FILE_COMMANDLINE in jconfig.h or in the Makefile.  You MUST use this style
+on any system that doesn't cope well with binary data fed through
+stdin/stdout.
+
+Currently supported image file formats include raw-format PPM, raw-format PGM
+(for monochrome images), and GIF.  cjpeg recognizes the input image format
+automatically, but you have to tell djpeg which format to generate.
+
+The only JPEG file format currently supported is a raw JPEG data stream.
+Unless modified, the programs use the JFIF conventions for variables left
+unspecified by the JPEG standard.  (In particular, cjpeg generates a JFIF APP0
+marker.)  Support for the JPEG-in-TIFF format will probably be added at some
+future date.
+
+The command line switches for cjpeg are:
+
+       -I              Generate noninterleaved JPEG file (not yet supported).
+
+       -Q quality      Scale quantization tables to adjust quality.
+                       Quality is 0 (worst) to 100 (best); default is 75.
+                       (See below for more info.)
+
+       -a              Use arithmetic coding rather than Huffman coding.
+                       (Not currently supported, see LEGAL ISSUES.)
+
+       -o              Perform optimization of entropy encoding parameters.
+                       Without this, default Huffman or arithmetic
+                       parameters are used.  -o makes the JPEG file a tad
+                       smaller, but compression uses much more memory.
+                       Image quality is unaffected by -o.
+
+       -d              Enable debug printout.  More -d's give more printout.
+
+Typically you'd use -Q settings of 50 or 75 or so.  -Q 100 will generate a
+quantization table of all 1's, meaning no quantization loss; then any
+differences between input and output images are due to subsampling or to
+roundoff error in the DCT or colorspace-conversion steps.  -Q values below 50
+may be useful for making real small, low-quality images.  Try -Q 2 (or so) for
+some amusing Cubist effects.  (Note that -Q values below about 25 generate
+2-byte quantization tables, which are not decodable by pure baseline JPEG
+decoders.  cjpeg emits a warning message when you give such a -Q value.)
+
+The command line switches for djpeg are:
+
+       -G              Select GIF output format (implies -q, with default
+                       of 256 colors).
+
+       -b              Perform cross-block smoothing.  This is quite
+                       memory-intensive and only seems to improve the image
+                       at very low quality settings (-Q 10 to 20 or so).
+
+       -g              Force gray-scale output even if input is color.
+
+       -q N            Quantize to N colors.
+
+       -D              Use Floyd-Steinberg dithering in color quantization.
+
+       -2              Use two-pass color quantization (not yet supported).
+
+       -d              Enable debug printout.  More -d's give more printout.
+
+Color quantization currently uses a rather shoddy algorithm (although it's not
+so horrible when dithered).  Because of this, the GIF output mode is not
+recommended in the current release, except for gray-scale output.  You can get
+better results by applying ppmquant to the unquantized (PPM) output of djpeg,
+then converting to GIF with ppmtogif.  We expect to provide a considerably
+better quantization algorithm in a future release.
+
+Note that djpeg *can* read noninterleaved JPEG files even though cjpeg can't
+yet generate them.  For most applications this is a nonissue, since hardly
+anybody seems to be using noninterleaved format.
+
+On a non-virtual-memory machine, you may run out of memory if you use -I or -o
+in cjpeg, or -q ... -2 in djpeg, or try to read an interlaced GIF file.  This
+will be addressed eventually by replacing jvirtmem.c with something that uses
+temporary files for large images (see TO DO).
+
+
+REFERENCES
+==========
+
+The best and most readily available introduction to the JPEG compression
+algorithm is Wallace's article in the April '91 CACM:
+       Wallace, Gregory K.  "The JPEG Still Picture Compression Standard",
+       Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
+(Adjacent articles in that issue discuss MPEG motion picture compression,
+applications of JPEG, and related topics.)  We highly recommend reading that
+article before looking at any of the JPEG software.
+
+For more detail about the JPEG standard you pretty much have to go to the
+draft standard, which is not nearly as intelligible as Wallace's article.
+The current version is ISO/IEC Committee Draft CD 10918-1 dated 1991-03-15.
+The standard is not presently available electronically; you must order a paper
+copy through ISO.
+
+The JPEG standard does not specify all details of an interchangeable file
+format.  For the omitted details we follow the "JFIF" conventions, revision
+1.01.  A copy of the JFIF spec is available from:
+       Literature Department
+       C-Cube Microsystems, Inc.
+       399A West Trimble Road
+       San Jose, CA  95131
+       (408) 944-6300
+Requests can also be e-mailed to info@c3.pla.ca.us (this address good after
+10/10/91).  The same source can supply copies of the draft JPEG-in-TIFF specs.
+
+If you want to understand this implementation, start by reading the
+"architecture" documentation file.  Please read "codingrules" if you want to
+contribute any code.
+
+
+SUPPORTING SOFTWARE
+===================
+
+You will probably want Jef Poskanzer's PBMPLUS image software; this provides
+many useful operations on PPM-format image files.  In particular, it can
+convert PPM images to and from a wide range of other formats.  You can FTP
+this free software from export.lcs.mit.edu (contrib/pbmplus*.tar.Z) or
+ftp.ee.lbl.gov (pbmplus*.tar.Z).
+
+If you are using X Windows you might want to use the xv or xloadimage viewers
+to save yourself the trouble of converting PPM to some other format.
+Both of these can be found in the contrib directory at export.lcs.mit.edu.
+
+
+LEGAL ISSUES
+============
+
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose.  This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+Permission is NOT granted for the use of any author's name or author's company
+name in advertising or publicity relating to this software or products derived
+from it.  This software may be referred to only as "the Independent JPEG
+Group's software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it.  (See the file
+ansi2knr.c for full details.)  However, since ansi2knr.c is not needed as part
+of any product generated from the JPEG code, this does not limit you more than
+the foregoing paragraphs do.
+
+
+It appears that the arithmetic coding option of the JPEG spec is covered by
+patents held by IBM, and possibly also patents of AT&T and Mitsubishi.  Hence
+arithmetic coding cannot legally be used without obtaining one or more
+licenses.  For this reason, support for arithmetic coding has been removed
+from the free JPEG software.  (Since arithmetic coding provides only a
+marginal gain over the unpatented Huffman mode, it is unlikely that very many
+people will choose to use it.  If you do obtain such a license, contact
+jpeg-info@uunet.uu.net for a copy of our arithmetic coding modules.)  So far
+as we are aware, there are no patent restrictions on the remaining code.
+
+
+TO DO
+=====
+
+Many of the modules need fleshing out to provide more complete
+implementations, or to provide faster paths for common cases.  The greatest
+needs are for (a) decent color quantization, and (b) a memory manager
+implementation that can work in limited memory by swapping "big" images to
+temporary files.  I (Tom Lane) am going to work on color quantization next.
+Volunteers to write a PC memory manager, or to work on any other modules, are
+welcome.
+
+We'd appreciate it if people would compile and check out the code on as wide a
+variety of systems as possible, and report any portability problems
+encountered (with solutions, if possible).  Checks of file compatibility with
+other JPEG implementations would also be of interest.  Finally, we would
+appreciate code profiles showing where the most time is spent, especially on
+unusual systems.
+
+Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
diff --git a/ansi2knr.c b/ansi2knr.c
new file mode 100644 (file)
index 0000000..77d3d81
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * Received from Peter Deutsch (ghost@aladdin.com)
+ * Fri, 26 Apr 91 10:10:10 PDT
+ */
+
+/* Copyright (C) 1989, 1991 Aladdin Enterprises.  All rights reserved.
+   Distributed by Free Software Foundation, Inc.
+
+This file is part of Ghostscript.
+
+Ghostscript is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
+to anyone for the consequences of using it or for whether it serves any
+particular purpose or works at all, unless he says so in writing.  Refer
+to the Ghostscript General Public License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+Ghostscript, but only under the conditions described in the Ghostscript
+General Public License.  A copy of this license is supposed to have been
+given to you along with Ghostscript so you can know your rights and
+responsibilities.  It should be in a file named COPYING.  Among other
+things, the copyright notice and this notice must be preserved on all
+copies.  */
+
+/*
+---------- Here is the GhostScript file COPYING, referred to above ----------
+----- These terms do NOT apply to the JPEG software itself; see README ------
+
+                   GHOSTSCRIPT GENERAL PUBLIC LICENSE
+                   (Clarified 11 Feb 1988)
+
+ Copyright (C) 1988 Richard M. Stallman
+ Everyone is permitted to copy and distribute verbatim copies of this
+ license, but changing it is not allowed.  You can also use this wording
+ to make the terms for other programs.
+
+  The license agreements of most software companies keep you at the
+mercy of those companies.  By contrast, our general public license is
+intended to give everyone the right to share Ghostscript.  To make sure
+that you get the rights we want you to have, we need to make
+restrictions that forbid anyone to deny you these rights or to ask you
+to surrender the rights.  Hence this license agreement.
+
+  Specifically, we want to make sure that you have the right to give
+away copies of Ghostscript, that you receive source code or else can get
+it if you want it, that you can change Ghostscript or use pieces of it
+in new free programs, and that you know you can do these things.
+
+  To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights.  For example, if you distribute
+copies of Ghostscript, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must tell them their rights.
+
+  Also, for our own protection, we must make certain that everyone finds
+out that there is no warranty for Ghostscript.  If Ghostscript is
+modified by someone else and passed on, we want its recipients to know
+that what they have is not what we distributed, so that any problems
+introduced by others will not reflect on our reputation.
+
+  Therefore we (Richard M. Stallman and the Free Software Foundation,
+Inc.) make the following terms which say what you must do to be allowed
+to distribute or change Ghostscript.
+
+
+                       COPYING POLICIES
+
+  1. You may copy and distribute verbatim copies of Ghostscript source
+code as you receive it, in any medium, provided that you conspicuously
+and appropriately publish on each copy a valid copyright and license
+notice "Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
+Distributed by Free Software Foundation, Inc." (or with whatever year is
+appropriate); keep intact the notices on all files that refer to this
+License Agreement and to the absence of any warranty; and give any other
+recipients of the Ghostscript program a copy of this License Agreement
+along with the program.  You may charge a distribution fee for the
+physical act of transferring a copy.
+
+  2. You may modify your copy or copies of Ghostscript or any portion of
+it, and copy and distribute such modifications under the terms of
+Paragraph 1 above, provided that you also do the following:
+
+    a) cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change; and
+
+    b) cause the whole of any work that you distribute or publish,
+    that in whole or in part contains or is a derivative of Ghostscript
+    or any part thereof, to be licensed at no charge to all third
+    parties on terms identical to those contained in this License
+    Agreement (except that you may choose to grant more extensive
+    warranty protection to some or all third parties, at your option).
+
+    c) You may charge a distribution fee for the physical act of
+    transferring a copy, and you may at your option offer warranty
+    protection in exchange for a fee.
+
+Mere aggregation of another unrelated program with this program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other program under the scope of these terms.
+
+  3. You may copy and distribute Ghostscript (or a portion or derivative
+of it, under Paragraph 2) in object code or executable form under the
+terms of Paragraphs 1 and 2 above provided that you also do one of the
+following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal
+    shipping charge) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+For an executable file, complete source code means all the source code for
+all modules it contains; but, as a special exception, it need not include
+source code for modules which are standard libraries that accompany the
+operating system on which the executable file runs.
+
+  4. You may not copy, sublicense, distribute or transfer Ghostscript
+except as expressly provided under this License Agreement.  Any attempt
+otherwise to copy, sublicense, distribute or transfer Ghostscript is
+void and your rights to use the program under this License agreement
+shall be automatically terminated.  However, parties who have received
+computer software programs from you with this License Agreement will not
+have their licenses terminated so long as such parties remain in full
+compliance.
+
+  5. If you wish to incorporate parts of Ghostscript into other free
+programs whose distribution conditions are different, write to the Free
+Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not
+yet worked out a simple rule that can be stated here, but we will often
+permit this.  We will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the
+sharing and reuse of software.
+
+Your comments and suggestions about our licensing policies and our
+software are welcome!  Please contact the Free Software Foundation,
+Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
+
+                      NO WARRANTY
+
+  BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
+NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
+WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
+M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
+PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE
+ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
+YOU.  SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
+STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
+ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
+GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
+ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
+PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
+HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
+BY ANY OTHER PARTY.
+-------------------- End of file COPYING ------------------------------
+*/
+
+
+/* ansi2knr.c */
+/* Convert ANSI function declarations to K&R syntax */
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef BSD
+#  include <strings.h>
+#  define strchr index
+#else
+#  ifdef VMS
+       extern char *strcat(), *strchr(), *strcpy(), *strupr();
+       extern int strcmp(), strlen(), strncmp();
+#  else
+#    include <string.h>
+#  endif
+#endif
+
+#ifdef MSDOS
+#  include <malloc.h>
+#else
+#  ifdef VMS
+     extern char *malloc();
+     extern void free();
+#  else
+#    ifdef BSD
+       extern char *malloc();
+#    else
+#      include <malloc.h>
+#    endif
+#  endif
+#endif
+
+/* Usage:
+       ansi2knr input_file output_file
+ * If no output_file is supplied, output goes to stdout.
+ * There are no error messages.
+ *
+ * ansi2knr recognizes functions by seeing a non-keyword identifier
+ * at the left margin, followed by a left parenthesis,
+ * with a right parenthesis as the last character on the line.
+ * It will recognize a multi-line header if the last character
+ * on each line but the last is a left parenthesis or comma.
+ * These algorithms ignore whitespace and comments, except that
+ * the function name must be the first thing on the line.
+ * The following constructs will confuse it:
+       - Any other construct that starts at the left margin and
+           follows the above syntax (such as a macro or function call).
+       - Macros that tinker with the syntax of the function header.
+ */
+
+/* Scanning macros */
+#define isidchar(ch) (isalnum(ch) || (ch) == '_')
+#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
+
+main(argc, argv)
+    int argc;
+    char *argv[];
+{      FILE *in, *out;
+#define bufsize 500                    /* arbitrary size */
+       char buf[bufsize];
+       char *line;
+       switch ( argc )
+          {
+       default:
+               printf("Usage: ansi2knr input_file [output_file]\n");
+               exit(0);
+       case 2:
+               out = stdout; break;
+       case 3:
+               out = fopen(argv[2], "w");
+               if ( out == NULL )
+                  {    fprintf(stderr, "Cannot open %s\n", argv[2]);
+                       exit(1);
+                  }
+          }
+       in = fopen(argv[1], "r");
+       if ( in == NULL )
+          {    fprintf(stderr, "Cannot open %s\n", argv[1]);
+               exit(1);
+          }
+       fprintf(out, "#line 1 \"%s\"\n", argv[1]);
+       line = buf;
+       while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
+          {    switch ( test1(buf) )
+                  {
+               case 1:                 /* a function */
+                       convert1(buf, out);
+                       break;
+               case -1:                /* maybe the start of a function */
+                       line = buf + strlen(buf);
+                       continue;
+               default:                /* not a function */
+                       fputs(buf, out);
+                       break;
+                  }
+               line = buf;
+          }
+       if ( line != buf ) fputs(buf, out);
+       fclose(out);
+       fclose(in);
+       return 0;
+}
+
+/* Skip over space and comments, in either direction. */
+char *
+skipspace(p, dir)
+    register char *p;
+    register int dir;                  /* 1 for forward, -1 for backward */
+{      for ( ; ; )
+          {    while ( isspace(*p) ) p += dir;
+               if ( !(*p == '/' && p[dir] == '*') ) break;
+               p += dir;  p += dir;
+               while ( !(*p == '*' && p[dir] == '/') )
+                  {    if ( *p == 0 ) return p;        /* multi-line comment?? */
+                       p += dir;
+                  }
+               p += dir;  p += dir;
+          }
+       return p;
+}
+
+/*
+ * Write blanks over part of a string.
+ */
+void
+writeblanks(start, end)
+    char *start;
+    char *end;
+{      char *p;
+       for ( p = start; p < end; p++ ) *p = ' ';
+}
+
+/*
+ * Test whether the string in buf is a function definition.
+ * The string may contain and/or end with a newline.
+ * Return as follows:
+ *     0 - definitely not a function definition;
+ *     1 - definitely a function definition;
+ *     -1 - may be the beginning of a function definition,
+ *             append another line and look again.
+ */
+test1(buf)
+    char *buf;
+{      register char *p = buf;
+       char *bend;
+       char *endfn;
+       int contin;
+       if ( !isidfirstchar(*p) )
+               return 0;               /* no name at left margin */
+       bend = skipspace(buf + strlen(buf) - 1, -1);
+       switch ( *bend )
+          {
+       case ')': contin = 1; break;
+       case '(':
+       case ',': contin = -1; break;
+       default: return 0;              /* not a function */
+          }
+       while ( isidchar(*p) ) p++;
+       endfn = p;
+       p = skipspace(p, 1);
+       if ( *p++ != '(' )
+               return 0;               /* not a function */
+       p = skipspace(p, 1);
+       if ( *p == ')' )
+               return 0;               /* no parameters */
+       /* Check that the apparent function name isn't a keyword. */
+       /* We only need to check for keywords that could be followed */
+       /* by a left parenthesis (which, unfortunately, is most of them). */
+          {    static char *words[] =
+                  {    "asm", "auto", "case", "char", "const", "double",
+                       "extern", "float", "for", "if", "int", "long",
+                       "register", "return", "short", "signed", "sizeof",
+                       "static", "switch", "typedef", "unsigned",
+                       "void", "volatile", "while", 0
+                  };
+               char **key = words;
+               char *kp;
+               int len = endfn - buf;
+               while ( (kp = *key) != 0 )
+                  {    if ( strlen(kp) == len && !strncmp(kp, buf, len) )
+                               return 0;       /* name is a keyword */
+                       key++;
+                  }
+          }
+       return contin;
+}
+
+convert1(buf, out)
+    char *buf;
+    FILE *out;
+{      char *endfn = strchr(buf, '(') + 1;
+       register char *p;
+       char **breaks;
+       unsigned num_breaks = 2;        /* for testing */
+       char **btop;
+       char **bp;
+       char **ap;
+top:   p = endfn;
+       breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
+       if ( breaks == 0 )
+          {    /* Couldn't allocate break table, give up */
+               fprintf(stderr, "Unable to allocate break table!\n");
+               fputs(buf, out);
+               return -1;
+          }
+       btop = breaks + num_breaks * 2 - 2;
+       bp = breaks;
+       /* Parse the argument list */
+       do
+          {    int level = 0;
+               char *end = NULL;
+               if ( bp >= btop )
+                  {    /* Filled up break table. */
+                       /* Allocate a bigger one and start over. */
+                       free((char *)breaks);
+                       num_breaks <<= 1;
+                       goto top;
+                  }
+               *bp++ = p;
+               /* Find the end of the argument */
+               for ( ; end == NULL; p++ )
+                  {    switch(*p)
+                          {
+                       case ',': if ( !level ) end = p; break;
+                       case '(': level++; break;
+                       case ')': if ( --level < 0 ) end = p; break;
+                       case '/': p = skipspace(p, 1) - 1; break;
+                       default: ;
+                          }
+                  }
+               p--;                    /* back up over terminator */
+               /* Find the name being declared. */
+               /* This is complicated because of procedure and */
+               /* array modifiers. */
+               for ( ; ; )
+                  {    p = skipspace(p - 1, -1);
+                       switch ( *p )
+                          {
+                       case ']':       /* skip array dimension(s) */
+                       case ')':       /* skip procedure args OR name */
+                          {    int level = 1;
+                               while ( level )
+                                switch ( *--p )
+                                  {
+                               case ']': case ')': level++; break;
+                               case '[': case '(': level--; break;
+                               case '/': p = skipspace(p, -1) + 1; break;
+                               default: ;
+                                  }
+                          }
+                               if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
+                                  {    /* We found the name being declared */
+                                       while ( !isidfirstchar(*p) )
+                                               p = skipspace(p, 1) + 1;
+                                       goto found;
+                                  }
+                               break;
+                       default: goto found;
+                          }
+                  }
+found:         if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
+                  {    p++;
+                       if ( bp == breaks + 1 ) /* sole argument */
+                               writeblanks(breaks[0], p);
+                       else
+                               writeblanks(bp[-1] - 1, p);
+                       bp--;
+                  }
+               else
+                  {    while ( isidchar(*p) ) p--;
+                       *bp++ = p+1;
+                  }
+               p = end;
+          }
+       while ( *p++ == ',' );
+       *bp = p;
+       /* Make a special check for 'void' arglist */
+       if ( bp == breaks+2 )
+          {    p = skipspace(breaks[0], 1);
+               if ( !strncmp(p, "void", 4) )
+                  {    p = skipspace(p+4, 1);
+                       if ( p == breaks[2] - 1 )
+                          {    bp = breaks;    /* yup, pretend arglist is empty */
+                               writeblanks(breaks[0], p + 1);
+                          }
+                  }
+          }
+       /* Put out the function name */
+       p = buf;
+       while ( p != endfn ) putc(*p, out), p++;
+       /* Put out the declaration */
+       for ( ap = breaks+1; ap < bp; ap += 2 )
+          {    p = *ap;
+               while ( isidchar(*p) ) putc(*p, out), p++;
+               if ( ap < bp - 1 ) fputs(", ", out);
+          }
+       fputs(")  ", out);
+       /* Put out the argument declarations */
+       for ( ap = breaks+2; ap <= bp; ap += 2 ) (*ap)[-1] = ';';
+       fputs(breaks[0], out);
+       free((char *)breaks);
+       return 0;
+}
diff --git a/architecture b/architecture
new file mode 100644 (file)
index 0000000..78587cd
--- /dev/null
@@ -0,0 +1,1106 @@
+
+       JPEG SYSTEM ARCHITECTURE                3-OCT-91
+
+
+This file provides an overview of the "architecture" of the portable JPEG
+software; that is, the functions of the various modules in the system and the
+interfaces between modules.  For more precise details about any data structure
+or calling convention, see the header files.
+
+Important note: when I say "module" I don't mean "a C function", which is what
+some people seem to think the term means.  A separate C source file is closer
+to the mark.  Also, it is frequently the case that several different modules
+present a common interface to callers; the term "object" or "method" refers to
+this common interface (see "Poor man's object-oriented programming", below).
+
+JPEG-specific terminology follows the JPEG R9 draft:
+  A "component" means a color channel, e.g., Red or Luminance.
+  A "sample" is a pixel component value (i.e., one number in the image data).
+  A "coefficient" is a frequency coefficient (a DCT transform output number).
+  The term "block" refers to an 8x8 group of samples or coefficients.
+  "MCU" (minimum coded unit) is the same as "MDU" of the R8 draft; i.e., an
+       interleaved set of blocks of size determined by the sampling factors,
+       or a single block in a noninterleaved scan.
+
+
+*** System requirements ***
+
+We must support compression and decompression of both Huffman and
+arithmetic-coded JPEG files.  Any set of compression parameters allowed by the
+JPEG spec should be readable for decompression.  (We can be more restrictive
+about what formats we can generate.)  (Note: for legal reasons no arithmetic
+coding implementation is currently included in the publicly available sources.
+However, the architecture still supports it.)
+
+We need to be able to handle both raw JPEG files (more specifically, the JFIF
+format) and JPEG-in-TIFF (C-cubed's format, and perhaps Kodak's).  Even if we
+don't implement TIFF ourselves, other people will want to use our code for
+that.  This means that generation and scanning of the file header has to be
+separated out.
+
+Perhaps we should be prepared to support the JPEG lossless mode (also referred
+to in the spec as spatial DPCM coding).  A lot of people seem to believe they
+need this... whether they really do is debatable, but the customer is always
+right.  On the other hand, there will not be much sharable code between the
+lossless and lossy modes!  At best, a lossless program could be derived from
+parts of the lossy version.  For now we will only worry about the lossy mode.
+
+I see no real value in supporting the JPEG progressive modes (note that
+spectral selection and successive approximation are two different progressive
+modes).  These are only of interest when painting the decompressed image in
+real-time, which nobody is going to do with a pure software implementation.
+
+There is some value in supporting the hierarchical mode, which allows for
+successive frames of higher resolution.  This could be of use for including
+"thumbnail" representations.  Also, Storm's JPEG++ files probably use the
+hierarchical mode (I haven't looked).  However, this appears to add a lot more
+complexity than it is worth.
+
+A variety of uncompressed image file formats and user interfaces must be
+supported.  These aspects therefore have to be kept separate from the rest of
+the system.  A particularly important issue is whether color quantization of
+the output is needed (i.e., whether a colormap is used).  We should be able to
+support both adaptive quantization (which requires two or more passes over the
+image) and nonadaptive (quantization to a prespecified colormap, which can be
+done in one pass).
+
+Memory usage is an important concern, since we will port this code to 80x86
+and other limited-memory machines.  For large intermediate structures, we
+should be able to use either virtual memory or temporary files.
+
+It should be possible to build programs that handle compression only,
+decompression only, or both, without much duplicate or unused code in any
+version.  (In particular, a decompression-only version should have no extra
+baggage.)
+
+
+*** Compression overview ***
+
+The *logical* steps needed in (non-lossless) JPEG compression are:
+
+1. Conversion from incoming image format to a standardized internal form
+   (either RGB or greyscale).
+
+2. Color space conversion (e.g., RGB to YCbCr).  This is a null step for
+   greyscale (unless we support mapping color inputs to greyscale, which
+   would most easily be done here).  Gamma adjustment may also be needed here.
+
+3. Subsampling (reduction of number of samples in some color components).
+   This step operates independently on each color component.
+
+4. MCU extraction (creation of a single sequence of 8x8 sample blocks).
+   This step and the following ones are performed once for each scan
+   in the output JPEG file, i.e., once if making an interleaved file and more
+   than once for a noninterleaved file.
+   Note: both this step and the previous one must deal with edge conditions
+   for pictures that aren't a multiple of the MCU dimensions.  Alternately,
+   we could expand the picture to a multiple of an MCU before doing these
+   two steps.  (The latter seems better and has been adopted below.)
+
+5. DCT transformation of each 8x8 block.
+
+6. Quantization scaling and zigzag reordering of the elements in each 8x8
+   block.
+
+7. Huffman or arithmetic encoding of the transformed block sequence.
+
+8. Output of the JPEG file with whatever headers/markers are wanted.
+
+Of course, the actual implementation will combine some of these logical steps
+for efficiency.  The trick is to keep these logical functions as separate as
+possible without losing too much performance.
+
+In addition to these logical pipeline steps, we need various modules that
+aren't part of the data pipeline.  These are:
+
+A. Overall control (sequencing of other steps & management of data passing).
+
+B. User interface; this will determine the input and output files, and supply
+   values for some compression parameters.  Note that this module is highly
+   platform-dependent.
+
+C. Compression parameter selection: some parameters should be chosen
+   automatically rather than requiring the user to find a good value.
+   The prototype only does this for the back-end (Huffman or arithmetic)
+   parameters, but further in the future, more might be done.  A
+   straightforward approach to selection is to try several values; this
+   requires being able to repeatedly apply some portion of the pipeline and
+   inspect the results (without actually outputting them).  Probably only
+   entropy encoding parameters can reasonably be done this way; optimizing
+   earlier steps would require too much data to be reprocessed (not to mention
+   the problem of interactions between parameters for different steps).
+   What other facilities do we need to support automatic parameter selection?
+
+D. A memory management module to deal with small-memory machines.  This must
+   create the illusion of virtual memory for certain large data structures
+   (e.g., the subsampled image or the transformed coefficients).
+   The interface to this must be defined to minimize the overhead incurred,
+   especially on virtual-memory machines where the module won't do much.
+
+In many cases we can arrange things so that a data stream is produced in
+segments by one module and consumed by another without the need to hold it all
+in (virtual) memory.  This is obviously not possible for any data that must be
+scanned more than once, so it won't work everywhere.
+
+The major variable at this level of detail is whether the JPEG file is to be
+interleaved or not; that affects the order of processing so fundamentally that
+the central control module must know about it.  Some of the other modules may
+need to know it too.  It would simplify life if we didn't need to support
+noninterleaved images, but that is not reasonable.
+
+Many of these steps operate independently on each color component; the
+knowledge of how many components there are, and how they are interleaved,
+ought to be confined to the central control module.  (Color space conversion
+and MCU extraction probably have to know it too.)
+
+
+*** Decompression overview ***
+
+Decompression is roughly the inverse process from compression, but there are
+some additional steps needed to produce a good output image.
+
+The *logical* steps needed in (non-lossless) JPEG decompression are:
+
+1. Scanning of the JPEG file, decoding of headers/markers etc.
+
+2. Huffman or arithmetic decoding of the coefficient sequence.
+
+3. Quantization descaling and zigzag reordering of the elements in each 8x8
+   block.
+
+4. MCU disassembly (conversion of a possibly interleaved sequence of 8x8
+   blocks back to separate components in pixel map order).
+
+5. (Optional)  Cross-block smoothing per JPEG section 13.10 or a similar
+   algorithm.  (Steps 5-8 operate independently on each component.)
+
+6. Inverse DCT transformation of each 8x8 block.
+
+7. De-subsampling.  At this point a pixel image of the original dimensions
+   has been recreated.
+
+8. Post-subsampling smoothing.  This can be combined with de-subsampling,
+   by using a convolution-like calculation to generate each output pixel
+   directly from one or more input pixels.
+
+9. Cropping to the original pixel dimensions (throwing away duplicated
+   pixels at the edges).  It is most convenient to do this now, as the
+   preceding steps are simplified by not having to worry about odd picture
+   sizes.
+
+10. Color space reconversion (e.g., YCbCr to RGB).  This is a null step for
+    greyscale.  (Note that if we support mapping color JPEG to greyscale,
+    it could be done as part of this step.)  Gamma adjustment may also be
+    needed here.
+
+11. Color quantization (only if a colormapped output format is requested).
+    NOTE: it might be better to do this on the internal color space instead of
+    RGB?  If so, it would need to be performed one step earlier.
+
+12. Writing of the desired image format.
+
+As before, some of these will be combined into single steps.  When dealing
+with a noninterleaved JPEG file, steps 2-9 will be performed once for each
+scan; the resulting data will need to be buffered up so that step 10 can
+process all the color components together.
+
+The same auxiliary modules are needed as before, except for compression
+parameter selection.  Note that rerunning a pipeline stage should never be
+needed during decompression.  This may allow a simpler control module.  The
+user interface might also be simpler since it need not supply any compression
+parameters.
+
+As before, not all of these steps require the whole image to be stored.
+Actually, two-pass color quantization is the only step that logically requires
+this; everything else could be done a few raster lines at a time (at least for
+interleaved images).  We might want to make color quantization be a separate
+program because of this fact.
+
+Again, many of the steps should be able to work on one color component in
+ignorance of the other components.
+
+
+*** Implications of noninterleaved formats ***
+
+Much of the work can be done in a single pass if an interleaved JPEG file
+format is used.  With a noninterleaved JPEG file, separating or recombining
+the components will force use of virtual memory (on a small-memory machine,
+we probably would want one temp file per color component).
+
+If any of the image formats we read or write are noninterleaved, the opposite
+condition might apply: processing a noninterleaved JPEG file would be more
+efficient.  Offhand, though, I can't think of any popular image formats that
+work that way; besides the win would only come if the same color space were
+used in JPEG and non-JPEG files.  It's not worth the complexity to make the
+system design accommodate that case efficiently.
+
+An argument against interleaving is that it makes the decompressor need more
+memory for cross-block smoothing (since the minimum processable chunk of the
+image gets bigger).  With images more than 1000 pixels across, 80x86 machines
+are likely to have difficulty in handling this feature.
+
+Another argument against interleaving is that the noninterleaved format allows
+a wider range of sampling factors, since the limit of ten blocks per MCU no
+longer applies.  We could get around this by blithely ignoring the spec's
+limit of ten blocks, but that seems like a bad idea (especially since it makes
+the above problem worse).
+
+The upshot is that we need to support both interleaved and noninterleaved JPEG
+formats, since for any given machine and picture size one may be much more
+efficient than the other.  However, the non-JPEG format we convert to or from
+will be assumed to be an interleaved format (i.e., it produces or stores all
+the components of a pixel together).
+
+I do not think it is necessary for the compressor to be able to output
+partially-interleaved formats (multiple scans, some of which interleave a
+subset of the components).  However, the decompressor must be able to read
+such files to conform to the spec.
+
+
+*** Data formats ***
+
+Pipeline steps that work on pixel sample values will use the following data
+structure:
+
+    typedef something JSAMPLE;         a pixel component value, 0..MAXJSAMPLE
+    typedef JSAMPLE *JSAMPROW;         ptr to a row of samples
+    typedef JSAMPROW *JSAMPARRAY;      ptr to a list of rows
+    typedef JSAMPARRAY *JSAMPIMAGE;    ptr to a list of color-component arrays
+
+The basic element type JSAMPLE will be one of unsigned char, (signed) char, or
+unsigned short.  Unsigned short will be used if samples wider than 8 bits are
+to be supported (this is a compile-time option).  Otherwise, unsigned char is
+used if possible.  If the compiler only supports signed chars, then it is
+necessary to mask off the value when reading.  Thus, all reads of sample
+values should be coded as "GETJSAMPLE(value)", where the macro will be defined
+as "((value)&0xFF)" on signed-char machines and "(value)" elsewhere.
+
+With these conventions, JSAMPLE values can be assumed to be >= 0.  This should
+simplify correct rounding during subsampling, etc.  The JPEG draft's
+specification that sample values run from -128..127 will be accommodated by
+subtracting 128 just as the sample value is copied into the source array for
+the DCT step (this will be an array of signed shorts or longs).  Similarly,
+during decompression the output of the IDCT step will be immediately shifted
+back to 0..255.  (NB: different values are required when 12-bit samples are in
+use.  The code should be written in terms of MAXJSAMPLE and CENTERJSAMPLE,
+which will be #defined as 255 and 128 respectively in an 8-bit implementation,
+and as 4095 and 2048 in a 12-bit implementation.)
+
+On compilers that don't support "unsigned short", signed short can be used for
+a 12-bit implementation.  To support lossless coding (which allows up to
+16-bit data precision) masking with 0xFFFF in GETJSAMPLE might be necessary.
+(But if "int" is 16 bits then using "unsigned int" is the best solution.)
+
+Notice that we use a pointer per row, rather than a two-dimensional JSAMPLE
+array.  This choice costs only a small amount of memory and has several
+benefits:
+
+* Code using the data structure doesn't need to know the allocated width of
+the rows.  This will simplify edge expansion/compression, since we can work
+in an array that's wider than the logical picture width.
+
+* The rows forming a component array may be allocated at different times
+without extra copying.  This will simplify working a few scanlines at a time,
+especially in smoothing steps that need access to the previous and next rows.
+
+* Indexing doesn't require multiplication; this is a performance win on many
+machines.
+
+Note that each color component is stored in a separate array; we don't use the
+traditional structure in which the components of a pixel are stored together.
+This simplifies coding of steps that work on each component independently,
+because they don't need to know how many components there are.  Furthermore,
+we can read or write each component to a temp file independently, which is
+helpful when dealing with noninterleaved JPEG files.
+
+A specific sample value will be accessed by code such as
+       GETJSAMPLE(image[colorcomponent][row][col])
+where col is measured from the image left edge, but row is measured from the
+first sample row currently in memory.  Either of the first two indexings can
+be precomputed by copying the relevant pointer.
+
+
+Pipeline steps that work on frequency-coefficient values will use the
+following data structure:
+
+    typedef short JCOEF;               a 16-bit signed integer
+    typedef JCOEF JBLOCK[64];          an 8x8 block of coefficients
+    typedef JBLOCK *JBLOCKROW;         ptr to one horizontal row of 8x8 blocks
+    typedef JBLOCKROW *JBLOCKARRAY;    ptr to a list of such rows
+    typedef JBLOCKARRAY *JBLOCKIMAGE;  ptr to a list of color component arrays
+
+The underlying type is always a 16-bit signed integer (this is "short" on all
+machines of interest, but let's use the typedef name anyway).  These are
+grouped into 8x8 blocks (we should use #defines DCTSIZE and DCTSIZE2 rather
+than "8" and "64").  The contents of a block may be either in "natural" or
+zigzagged order, and may be true values or divided by the quantization
+coefficients, depending on where the block is in the pipeline.
+
+Notice that the allocation unit is now a row of 8x8 blocks, corresponding to
+eight rows of samples.  Otherwise the structure is much the same as for
+samples, and for the same reasons.
+
+On machines where malloc() can't handle a request bigger than 64Kb, this data
+structure limits us to rows of less than 512 JBLOCKs, which would be a picture
+width of 4000 pixels.  This seems an acceptable restriction.
+
+
+On 80x86 machines, the bottom-level pointer types (JSAMPROW and JBLOCKROW)
+must be declared as "far" pointers, but the upper levels can be "near"
+(implying that the pointer lists are allocated in the DS segment).
+To simplify sharing code, we'll have a #define symbol FAR, which expands to
+the "far" keyword when compiling on 80x86 machines and to nothing elsewhere.
+
+
+The data arrays used as input and output of the DCT transform subroutine will
+be declared using a separate typedef; they could be arrays of "short", "int"
+or "long" independently of the above choices.  This would depend on what is
+needed to make the compiler generate correct and efficient multiply/add code
+in the DCT inner loops.  No significant speed or memory penalty will be paid
+to have a different representation than is used in the main image storage
+arrays, since some additional value-by-value processing is done at the time of
+creation or extraction of the DCT data anyway (e.g., add/subtract 128).
+
+
+*** Poor man's object-oriented programming ***
+
+It should be pretty clear by now that we have a lot of quasi-independent
+steps, many of which have several possible behaviors.  To avoid cluttering the
+code with lots of switch statements, we'll use a simple form of object-style
+programming to separate out the different possibilities.
+
+For example, Huffman and arithmetic coding will be implemented as two separate
+modules that present the same external interface; at runtime, the calling code
+will access the proper module indirectly through an "object".
+
+We can get the limited features we need while staying within portable C.  The
+basic tool is a function pointer.  An "object" is just a struct containing one
+or more function pointer fields, each of which corresponds to a method name in
+real object-oriented languages.  During initialization we fill in the function
+pointers with references to whichever module we have determined we need to use
+in this run.  Then invocation of the module is done by indirecting through a
+function pointer; on most architectures this is no more expensive (and
+possibly cheaper) than a switch, which would be the only other way of making
+the required run-time choice.  The really significant benefit, of course, is
+keeping the source code clean and well structured.
+
+For example, the interface for entropy decoding (Huffman or arithmetic
+decoding) might look like this:
+
+       struct function_ptr_struct {
+               ...
+               /* Entropy decoding methods */
+               void (*prepare_for_scan) ();
+               void (*get_next_mcu) ();
+               ...
+               };
+
+       typedef struct function_ptr_struct * function_ptrs;
+
+The struct pointer is what will actually be passed around.  A call site might
+look like this:
+
+       some_function (function_ptrs fptrs)
+           {
+               ...
+               (*fptrs->get_next_mcu) (...);
+               ...
+           }
+
+(It might be worth inventing some specialized macros to hide the rather ugly
+syntax for method definition and call.)  Note that the caller doesn't know how
+many different get_next_mcu procedures there are, what their real names are,
+nor how to choose which one to call.
+
+An important benefit of this scheme is that it is easy to provide multiple
+versions of any method, each tuned to a particular case.  While a lot of
+precalculation might be done to select an optimal implementation of a method,
+the cost per invocation is constant.  For example, the MCU extraction step
+might have a "generic" method, plus one or more "hardwired" methods for the
+most popular sampling factors; the hardwired methods would be faster because
+they'd use straight-line code instead of for-loops.  The cost to determine
+which method to use is paid only once, at startup, and the selection criteria
+are hidden from the callers of the method.
+
+This plan differs a little bit from usual object-oriented structures, in that
+only one instance of each object class will exist during execution.  The
+reason for having the class structure is that on different runs we may create
+different instances (choose to execute different modules).
+
+To minimize the number of object pointers that have to be passed around, it
+will be easiest to have just a few big structs containing all the method
+pointers.  We'll actually use two such structs, one for "globally" defined
+methods (applicable to the whole file or to all components of the current
+scan) and one for methods applicable to a single component.  There'll be one
+copy of the second kind of struct for each component of the current scan.
+This is necessary so that preselection of an optimal method can be done based
+on component-specific information (like sampling ratios...)
+
+Because of this choice, it's best not to think of an "object" as a specific
+data structure.  Rather, an "object" is just a group of related methods.
+There would typically be one or more C modules (source files) providing
+concrete implementations of those methods.  You can think of the term
+"method" as denoting the common interface presented by some set of functions,
+and "object" as denoting a group of common method interfaces, or the total
+shared interface behavior of a group of modules.
+
+
+*** Data chunk sizes ***
+
+To make the cost of this object-oriented style really minimal, we should make
+sure that each method call does a fair amount of computation.  To do that we
+should pass large chunks of data around; for example, the colorspace
+conversion method should process much more than one pixel per call.
+
+For many steps, the most natural unit of data seems to be an "MCU row".
+This consists of one complete horizontal strip of the image, as high as an
+MCU.  In a noninterleaved scan, an MCU row is always eight samples high (when
+looking at samples) or one 8x8 block high (when looking at coefficients).  In
+an interleaved scan, an MCU row consists of all the data for one horizontal
+row of MCUs; this may be from one to four blocks high (eight to thirty-two
+samples) depending on the sampling factors.  The height and width of an MCU
+row may be different in each component.  (Note that the height and width of an
+MCU row changes at the subsampling and de-subsampling steps.  An unsubsampled
+image has the same size in each component.  The preceding statements apply to
+the subsampled dimensions.)
+
+For example, consider a 1024-pixel-wide image using (2h:2v)(1h:1v)(1h:1v)
+subsampling.  In the noninterleaved case, an MCU row of Y would contain 8x1024
+samples or the same number of frequency coefficients, so it would occupy
+8K bytes (samples) or 16K bytes (coefficients).  An MCU row of Cb or Cr would
+contain 8x512 samples and occupy half as much space.  In the interleaved case,
+an MCU row would contain 16x1024 Y samples, 8x512 Cb and 8x512 Cr samples, so
+a total of 24K (samples) or 48K (coefficients) would be needed.  This is a
+reasonable amount of data to expect to retain in memory at one time.  (Bear in
+mind that we'll usually need to have several MCU rows resident in memory at
+once, at the inputs and outputs to various pipeline steps.)
+
+The worst case is probably (2h:4v)(1h:1v)(1h:1v) interleaving (this uses 10
+blocks per MCU, which is the maximum allowed by the spec).  An MCU will then
+contain 32 sample rows worth of Y, so it would occupy 40K or 80K bytes for a
+1024-pixel-wide image.  The most memory-intensive step is probably cross-block
+smoothing, for which we'd need 3 MCU rows of coefficients as input and another
+one as output; that would be 320K of working storage.  Anything much larger
+would not fit in an 80x86 machine.  (To decompress wider pictures on an 80x86,
+we'll have to skip cross-block smoothing or else use temporary files.)
+
+This unit is thus a reasonable-sized chunk for passing through the pipeline.
+Of course, its major advantage is that it is a natural chunk size for the MCU
+assembly and disassembly steps to work with.
+
+For the entropy (Huffman or arithmetic) encoding/decoding steps, the most
+convenient chunk is a single MCU: one 8x8 block if not interleaved, three to
+ten such blocks if interleaved.  The advantage of this is that when handling
+interleaved data, the blocks have the same sequence of component membership on
+each call.  (For example, Y,Y,Y,Y,Cb,Cr when using (2h:2v)(1h:1v)(1h:1v)
+subsampling.)  The code needs to know component membership so that it can
+apply the right set of compression coefficients to each block.  A prebuilt
+array describing this membership can be used during each call.  This chunk
+size also makes it easy to handle restart intervals: just count off one MCU
+per call and reinitialize when the count reaches zero (restart intervals are
+specified in numbers of MCU).
+
+For similar reasons, one MCU is also the best chunk size for the frequency
+coefficient quantization and dequantization steps.
+
+For subsampling and desubsampling, the best chunk size is to have each call
+transform Vk sample rows from or to Vmax sample rows (Vk = this component's
+vertical sampling factor, Vmax = largest vertical sampling factor).  There are
+eight such chunks in each MCU row.  Using a whole MCU row as the chunk size
+would reduce function call overhead a fraction, but would imply more buffering
+to provide context for cross-pixel smoothing.
+
+
+*** Compression object structure ***
+
+I propose the following set of objects for the compressor.  Here an "object"
+is the common interface for one or more modules having comparable functions.
+
+Most of these objects can be justified as information-hiding modules.
+I've indicated what information is private to each object/module.
+
+Note that in all cases, the caller of a method is expected to have allocated
+any storage needed for it to return its result.  (Typically this storage can
+be re-used in successive calls, so malloc'ing and free'ing once per call is
+not reasonable.)  Also, much of the context required (compression parameters,
+image size, etc) will be passed around in large common data structures, which
+aren't described here; see the header files.  Notice that any object that
+might need to allocate working storage receives an "init" and a "term" call;
+"term" should be careful to free all allocated storage so that the JPEG system
+can be used multiple times during a program run.  (For the same reason,
+depending on static initialization of variables is a no-no.)
+
+1. Input file conversion to standardized form.  This provides these methods:
+       input_init: read the file header, report image size & component count.
+       get_input_row: read one pixel row, return it in our standard format.
+       input_term: finish up at the end.
+   In implementations that support multiple input formats, input_init could
+   set up an appropriate get_input_row method depending on the format it
+   finds.  Note that in most applications, the selection and opening of the
+   input file will be under the control of the user interface module; and
+   indeed the user interface may have already read the input header, so that
+   all that input_init may have to do is return previously saved values.  The
+   behind-the-scenes interaction between this object and the user interface is
+   not specified by this architecture.
+   (Hides format of input image and mechanism used to read it.  This code is
+   likely to vary considerably from one implementation to another.  Note that
+   the color space and number of color components of the source are not hidden;
+   but they are used only by the next object.)
+
+2. Gamma and color space conversion.  This provides three methods:
+       colorin_init: initialization.
+       get_sample_rows: read, convert, and return a specified number of pixel
+                        rows (not more than remain in the picture).
+       colorin_term: finish up at the end.
+   The most efficient approach seems to be for this object to call
+   get_input_row directly, rather than being passed the input data; that way,
+   any intermediate storage required can be local to this object.
+   (get_sample_rows might tell get_input_row to read directly into its own
+   output area and then convert in place; or it may do something different.
+   For example, conversion in place wouldn't work if it is changing the number
+   of color components.)  The output of this step is in the standardized
+   sample array format shown previously.
+   (Hides all knowledge of color space semantics and conversion.  Remaining
+   modules only need to know the number of JPEG components.)
+
+3. Edge expansion: needs only a single method.
+       edge_expand: Given an NxM sample array, expand to a desired size (a
+                    multiple of the MCU dimensions) by duplicating the last
+                    row or column.  Repeat for each component.
+   Expansion will occur in place, so the caller must have pre-allocated enough
+   storage.  (I'm assuming that it is easier and faster to do this expansion
+   than it is to worry about boundary conditions in the next two steps.
+   Notice that vertical expansion will occur only once, at the bottom of the
+   picture, so only horizontal expansion by a few pixels is speed-critical.)
+   (This doesn't really hide any information, so maybe it could be a simple
+   subroutine instead of a method.  Depends on whether we want to be able to
+   use alternative, optimized methods.)
+
+4. Subsampling: this will be applied to one component at a time.
+       subsample_init: initialize (precalculate convolution factors, for
+                       example).  This will be called once per scan.
+       subsample: Given a sample array, reduce it to a smaller number of
+                  samples using specified sampling factors.
+       subsample_term: clean up at the end of a scan.
+   If the current component has vertical sampling factor Vk and the largest
+   sampling factor is Vmax, then the input is always Vmax sample rows (whose
+   width is a multiple of Hmax) and the output is always Vk sample rows.
+   Vmax additional rows above and below the nominal input rows are also passed
+   for use by partial-pixel-averaging sampling methods.  (Is this necessary?)
+   At the top and bottom of the image, these extra rows are copies of the
+   first or last actual input row.
+   (This hides whether and how cross-pixel averaging occurs.)
+
+5. MCU extraction (creation of a single sequence of 8x8 sample blocks).
+       extract_init: initialize as needed.  This will be called once per scan.
+       extract_MCUs: convert a sample array to a sequence of MCUs.
+       extract_term: clean up at the end of a scan.
+   Given one or more MCU rows worth of image data, extract sample blocks in the
+   appropriate order; pass these off to subsequent steps one MCU at a time.
+   The input must be a multiple of the MCU dimensions.  It will probably be
+   most convenient for the DCT transform, frequency quantization, and zigzag
+   reordering of each block to be done as simple subroutines of this step.
+   Once a transformed MCU has been completed, it'll be passed off to a
+   method call, which will be passed as a parameter to extract_MCUs.
+   That routine might either encode and output the MCU immediately, or buffer
+   it up for later output if we want to do global optimization of the entropy
+   encoding coefficients.  Note: when outputting a noninterleaved file this
+   object will be called separately for each component.  Direct output could
+   be done for the first component, but the others would have to be buffered.
+   (Again, an object mainly on the grounds that multiple instantiations might
+   be useful.)
+
+6. DCT transformation of each 8x8 block.  This probably doesn't have to be a
+   full-fledged method, but just a plain subroutine that will be called by MCU
+   extraction.  One 8x8 block will be processed per call.
+
+7. Quantization scaling and zigzag reordering of the elements in each 8x8
+   block.  (This can probably be a plain subroutine called once per block by
+   MCU extraction; hard to see a need for multiple instantiations here.)
+
+8. Entropy encoding (Huffman or arithmetic).
+       entropy_encoder_init: prepare for one scan.
+       entropy_encode: accepts an MCU's worth of quantized coefficients,
+                       encodes and outputs them.
+       entropy_encoder_term: finish up at end of a scan (dump any buffered
+                             bytes, for example).
+   The data output by this module will be sent to the entropy_output method
+   provided by the pipeline controller.  (It will probably be worth using
+   buffering to pass multiple bytes per call of the output method.)  The
+   output method could be just write_jpeg_data, but might also be a dummy
+   routine that counts output bytes (for use during cut-and-try coefficient
+   optimization).
+   (This hides which entropy encoding method is in use.)
+
+9. JPEG file header construction.  This will provide these methods:
+       write_file_header: output the initial header.
+       write_scan_header: output scan header (called once per component
+                          if noninterleaved mode).
+       write_jpeg_data: the actual data output method for the preceding step.
+       write_scan_trailer: finish up after one scan.
+       write_file_trailer: finish up at end of file.
+   Note that compressed data is passed to the write_jpeg_data method, in case
+   a simple fwrite isn't appropriate for some reason.
+   (This hides which variant JPEG file format is being written.  Also, the
+   actual mechanism for writing the file is private to this object and the
+   user interface.)
+
+10. Pipeline control.  This object will provide the "main loop" that invokes
+    all the pipeline objects.  Note that we will need several different main
+    loops depending on the situation (interleaved output or not, global
+    optimization of encoding parameters or not, etc).  This object will do
+    most of the memory allocation, since it will provide the working buffers
+    that are the inputs and outputs of the pipeline steps.
+    (An object mostly to support multiple instantiations; however, overall
+    memory management and sequencing of operations are known only here.)
+
+11. Overall control.  This module will provide at least two routines:
+       jpeg_compress: the main entry point to the compressor.
+       per_scan_method_selection: called by pipeline controllers for
+                                  secondary method selection passes.
+    jpeg_compress is invoked from the user interface after the UI has selected
+    the input and output files and obtained values for all compression
+    parameters that aren't dynamically determined.  jpeg_compress performs
+    basic initialization (e.g., calculating the size of MCUs), does the
+    "global" method selection pass, and finally calls the selected pipeline
+    control object.  (Per-scan method selections will be invoked by the
+    pipeline controller.)
+    Note that jpeg_compress can't be a method since it is invoked prior to
+    method selection.
+
+12. User interface; this is the architecture's term for "the rest of the
+    application program", i.e., that which invokes the JPEG compressor.  In a
+    standalone JPEG compression program the UI need be little more than a C
+    main() routine and argument parsing code; but we can expect that the JPEG
+    compressor may be incorporated into complex graphics applications, wherein
+    the UI is much more complex.  Much of the UI will need to be written
+    afresh for each non-Unix-like platform the compressor is ported to.
+    The UI is expected to supply input and output files and values for all
+    non-automatically-chosen compression parameters.  (Hence defaults are
+    determined by the UI; we should probably provide helpful routines to fill
+    in recommended defaults.)  The UI must also supply error handling
+    routines and some mechanism for trace messages.
+    (This module hides the user interface provided --- command line,
+    interactive, etc.  Except for error/message handling, the UI calls the
+    portable JPEG code, not the other way around.)
+
+13. (Optional) Compression parameter selection control.
+       entropy_optimize: given an array of MCUs ready to be fed to entropy
+                         encoding, find optimal encoding parameters.
+    The actual optimization algorithm ought to be separated out as an object,
+    even though a special pipeline control method will be needed.  (The
+    pipeline controller only has to understand that the output of extract_MCUs
+    must be built up as a virtual array rather than fed directly to entropy
+    encoding and output.  This pipeline behavior may also be useful for future
+    implementation of hierarchical modes, etc.)
+    To minimize the amount of control logic in the optimization module, the
+    pipeline control doesn't actually hand over big-array pointers, but rather
+    an "iterator": a function which knows how to scan the stored image.
+    (This hides the details of the parameter optimization algorithm.)
+
+    The present design doesn't allow for multiple passes at earlier points
+    in the pipeline, but allowing that would only require providing some
+    new pipeline control methods; nothing else need change.
+
+14. A memory management object.  This will provide methods to allocate "small"
+    things and "big" things.  Small things have to fit in memory and you get
+    back direct pointers (this could be handled by direct calls to malloc, but
+    it's cleaner not to assume malloc is the right routine).  "Big" things
+    mean buffered images for multiple passes, noninterleaved output, etc.
+    In this case the memory management object will give you room for a few MCU
+    rows and you have to ask for access to the next few; dumping and reloading
+    in a temporary file will go on behind the scenes.  (All big objects are
+    image arrays containing either samples or coefficients, and will be
+    scanned top-to-bottom some number of times, so we can apply this access
+    model easily.)  On a platform with virtual memory, the memory manager can
+    treat small and big things alike: just malloc up enough virtual memory for
+    the whole image, and let the operating system worry about swapping the
+    image to disk.
+
+    Most of the actual calls on the memory manager will be made from pipeline
+    control objects; changing any data item from "small" to "big" status would
+    require a new pipeline control object, since it will contain the logic to
+    ask for a new chunk of a big thing.  Thus, one way in which pipeline
+    controllers will vary is in which structures they treat as big.
+
+    The memory manager will need to be told roughly how much space is going to
+    be requested overall, so that it can figure out how big a buffer is safe
+    to allocate for a "big" object.  (If it happens that you are dealing with
+    a small image, you'd like to decide to keep it all in memory!)  The most
+    flexible way of doing this is to divide allocation of "big" objects into
+    two steps.  First, there will be one or more "request" calls that indicate
+    the desired object sizes; then an "instantiate" call causes the memory
+    manager to actually construct the objects.  The instantiation must occur
+    before the contents of any big object can be accessed.
+
+    For 80x86 CPUs, we would like the code to be compilable under small or
+    medium model, meaning that pointers are 16 bits unless explicitly declared
+    FAR.  Hence space allocated by the "small" allocator must fit into the
+    64Kb default data segment, along with stack space and global/static data.
+    For normal JPEG operations we seem to need only about 32Kb of such space,
+    so we are within the target (and have a reasonable slop for the needs of
+    a surrounding application program).  However, some color quantization
+    algorithms need 64Kb or more of all-in-memory space in order to create
+    color histograms.  For this purpose, we will also support "medium" size
+    things.  These are semantically the same as "small" things but are
+    referenced through FAR pointers.
+
+    The following methods will be needed:
+       alloc_small:    allocate an object of given size; use for any random
+                       data that's not an image array.
+       free_small:     release same.
+       alloc_medium:   like alloc_small, but returns a FAR pointer.
+       free_medium:    release same.
+       alloc_small_sarray: construct an all-in-memory image sample array.
+       free_small_sarray:  release same.
+       alloc_small_barray,
+       free_small_barray:  ditto for block (coefficient) arrays.
+       request_big_sarray:  request a virtual image sample array.  The size
+                            of the in-memory buffer will be determined by the
+                            memory manager, but it will always be a multiple
+                            of the passed-in MCU height.
+       request_big_barray:  ditto for block (coefficient) arrays.
+       alloc_big_arrays:  instantiate all the big arrays previously requested.
+                          This call will also pass some info about future
+                          memory demands, so that the memory manager can
+                          figure out how much space to leave unallocated.
+       access_big_sarray: obtain access to a specified portion of a virtual
+                          image sample array.
+       access_big_barray: ditto for block (coefficient) arrays.
+       free_big_sarray:   release a virtual sample array.
+       free_big_barray:   ditto for block (coefficient) arrays.
+
+    alloc_big_arrays will be called by the pipeline controller, which does
+    most of the memory allocation anyway.  The only reason for having separate
+    request calls is to allow some of the other modules to get big arrays.
+    The pipeline controller is required to give an upper bound on total future
+    small-array requests, so that this space can be discounted.  (A fairly
+    conservative estimate will be adequate.)  Future small-object requests
+    aren't counted; the memory manager has to use a slop factor for those.
+    10K or so seems to be sufficient.  (In an 80x86, small objects aren't an
+    issue anyway, since they don't compete for far-heap space.  "Medium"-size
+    objects will have to be counted separately.)
+
+    The distinction between sample and coefficient array routines is annoying,
+    but it has to be maintained for machines in which "char *" is represented
+    differently from "int *"... on byte-addressable machines some of these
+    methods could point to the same code.
+
+    The array routines will operate on only 2-D arrays (one component at a
+    time), since different components may require different-size arrays.
+
+    (This object hides the knowledge of whether virtual memory is available,
+    as well as the actual interface to OS and library support routines.)
+
+Note that any given implementation will presumably contain only one
+instantiation of input file header reading, overall control, user interface,
+and memory management.  Thus these could be called as simple subroutines,
+without bothering with an object indirection.  This is essential for overall
+control (which has to initialize the object structure); I'm undecided whether
+to impose objectness on the other three.
+
+
+*** Decompression object structure ***
+
+I propose the following set of objects for decompression.  The general
+comments at the top of the compression object section also apply here.
+
+1. JPEG file scanning.  This will provide these methods:
+       read_file_header: read the file header, determine which variant
+                         JPEG format is in use, read everything through SOF.
+       read_scan_header: read scan header (up through SOS).  This is called
+                         after read_file_header and again after each scan;
+                         it returns TRUE if it finds SOS, FALSE if EOI.
+       read_jpeg_data: fetch data for entropy decoder.
+       read_scan_trailer: finish up after one scan, prepare for another call
+                          of read_scan_header (may be a no-op).
+       read_file_trailer: finish up at end of file (probably a no-op).
+   The entropy decoder must deal with restart markers, but all other JPEG
+   marker types will be handled in this object; useful data from the markers
+   will be extracted into data structures available to subsequent routines.
+   Note that on exit from read_file_header, only the SOF-marker data should be
+   assumed valid (image size, component IDs, sampling factors); other data
+   such as Huffman tables may not appear until after the SOF.  The overall
+   image size and colorspace can be determined after read_file_header, but not
+   whether or how the data is interleaved.  (This hides which variant JPEG
+   file format is being read.  In particular, for JPEG-in-TIFF the read_header
+   routines might not be scanning standard JPEG markers at all; they could
+   extract the data from TIFF tags.  The user interface will already have
+   opened the input file and possibly read part of the header before
+   read_file_header is called.)
+
+   NOTE: for JFIF/raw-JPEG file format, the read_jpeg_data routine is actually
+   supplied by the user interface; the jrdjfif module uses read_jpeg_data
+   internally to scan the input stream.  This makes it possible for the user
+   interface module to single-handedly implement special applications like
+   reading from a non-stdio source.  For JPEG-in-TIFF format, the need for
+   random access will make it impossible for this to work; hence the TIFF
+   header module will probably override the UI read_jpeg_data routine.
+   Non-stdio input from a TIFF file will require extensive surgery to the TIFF
+   header module, if indeed it is practical at all.
+
+2. Entropy (Huffman or arithmetic) decoding of the coefficient sequence.
+       entropy_decoder_init: prepare for one scan.
+       entropy_decode: decodes and returns an MCU's worth of quantized
+                       coefficients per call.
+       entropy_decoder_term: finish up after a scan (may be a no-op).
+   This will read raw data by calling the read_jpeg_data method (I don't see
+   any reason to provide a further level of indirection).
+   (This hides which entropy encoding method is in use.)
+
+3. Quantization descaling and zigzag reordering of the elements in each 8x8
+   block.  (This can probably be a plain subroutine called once per block;
+   hard to see a need for multiple instantiations here.)
+
+4. MCU disassembly (conversion of a possibly interleaved sequence of 8x8
+   blocks back to separate components in pixel map order).
+       disassemble_init: initialize.  This will be called once per scan.
+       disassemble_MCU:  Given an MCU's worth of dequantized blocks,
+                         distribute them into the proper locations in a
+                         coefficient image array.
+       disassemble_term: clean up at the end of a scan.
+   Probably this should be called once per MCU row and should call the
+   preceding two objects repeatedly to obtain the row's data.  The output is
+   always a multiple of an MCU's dimensions.
+   (An object on the grounds that multiple instantiations might be useful.)
+
+5. Cross-block smoothing per JPEG section 13.10 or a similar algorithm.
+       smooth_coefficients: Given three block rows' worth of a single
+                            component, emit a smoothed equivalent of the
+                            middle row.  The "above" and "below" pointers
+                            may be NULL if at top/bottom of image.
+   The pipeline controller will do the necessary buffering to provide the
+   above/below context.  Smoothing will be optional since a good deal of
+   extra memory is needed to buffer the additional block rows.
+   (This object hides the details of the smoothing algorithm.)
+
+6. Inverse DCT transformation of each 8x8 block.  (This can be a plain
+   subroutine processing one block per call.)
+
+7. De-subsampling and smoothing: this will be applied to one component at a
+   time.  Note that cross-pixel smoothing, which was a separate step in the
+   prototype code, will now be performed simultaneously with expansion.
+       unsubsample_init: initialize (precalculate convolution factors, for
+                         example).  This will be called once per scan.
+       unsubsample: Given a sample array, enlarge it by specified sampling
+                    factors.
+       unsubsample_term: clean up at the end of a scan.
+   If the current component has vertical sampling factor Vk and the largest
+   sampling factor is Vmax, then the input is always Vk sample rows (whose
+   width is a multiple of Hk) and the output is always Vmax sample rows.
+   Vk additional rows above and below the nominal input rows are also passed
+   for use in cross-pixel smoothing.  At the top and bottom of the image,
+   these extra rows are copies of the first or last actual input row.
+   (This hides whether and how cross-pixel smoothing occurs.)
+
+8. Cropping to the original pixel dimensions (throwing away duplicated
+   pixels at the edges).  This won't be a separate object, just an
+   adjustment of the nominal image size in the pipeline controller.
+
+9. Color space reconversion and gamma adjustment.
+       colorout_init: initialization.  This will be passed the component
+                      data from read_file_header, and will determine the
+                      number of output components.
+       color_convert: convert a specified number of pixel rows.  Input and
+                      output are image arrays of same size but possibly
+                      different numbers of components.
+       colorout_term: cleanup (probably a no-op except for memory dealloc).
+   In practice will always be given an MCU row's worth of pixel rows, except
+   at the bottom where a smaller number of rows may be left over.  Note that
+   this object works on all the components at once.
+   (Hides all knowledge of color space semantics and conversion.  Remaining
+   modules only need to know the number of JPEG and output components.)
+
+10. Color quantization (used only if a colormapped output format is requested).
+    We use two different strategies depending on whether one-pass (on-the-fly)
+    or two-pass quantization is requested.  Note that the two-pass interface
+    is actually designed to let the quantizer make any number of passes.
+       color_quant_init: initialization, allocate working memory.  In 1-pass
+                         quantization, should call put_color_map.
+       color_quantize: convert a specified number of pixel rows.  Input
+                       and output are image arrays of same size, but input
+                       is N coefficients and output is only one.  (Used only
+                       in 1-pass quantization.)
+       color_quant_prescan: prescan a specified number of pixel rows in
+                            2-pass quantization.
+       color_quant_doit: perform multi-pass color quantization.  Input is a
+                         "big" sample image, output is via put_color_map and
+                         put_pixel_rows.  (Used only in 2-pass quantization.)
+       color_quant_term: cleanup (probably a no-op except for memory dealloc).
+    For one-pass quantization the image is simply processed by color_quantize,
+    a few rows at a time.  For two-pass quantization, the pipeline controller
+    accumulates the output of color_convert into a "big" sample image.  The
+    color_quant_prescan method is invoked during this process so that the
+    quantizer can accumulate statistics.  At the end of the image,
+    color_quant_doit is called; it must rescan the "big" image and pass
+    converted data to the output module.  Additional scans of the image could
+    be made before the output pass is done (in fact, prescan could be a no-op).
+    As with entropy parameter optimization, the pipeline controller actually
+    passes an iterator function rather than direct access to the big image.
+    NOTE: it might be better to do this on the internal color space instead of
+    RGB?  If so, it would need to be performed one step earlier.
+    (Hides color quantization algorithm.)
+
+11. Writing of the desired image format.
+       output_init: produce the file header given data from read_file_header.
+       put_color_map: output colormap, if any (called by color quantizer).
+       put_pixel_rows: output image data in desired format.
+       output_term: finish up at the end.
+    Note that whether colormapping is needed will be determined by the user
+    interface object prior to method selection.  In implementations that
+    support multiple output formats, the actual output format will also be
+    determined by the user interface.
+    (Hides format of output image and mechanism used to write it.  Note that
+    several other objects know the color model used by the output format.  The
+    actual mechanism for writing the file is private to this object and the
+    user interface.)
+
+12. Pipeline control.  This object will provide the "main loop" that invokes
+    all the pipeline objects.  Note that we will need several different main
+    loops depending on the situation (interleaved input or not, whether to
+    apply cross-block smoothing or not, etc).  We may want to divvy up the
+    pipeline controllers into two levels, one that retains control over the
+    whole file and one that is invoked per scan.
+    This object will do most of the memory allocation, since it will provide
+    the working buffers that are the inputs and outputs of the pipeline steps.
+    (An object mostly to support multiple instantiations; however, overall
+    memory management and sequencing of operations are known only here.)
+
+13. Overall control.  This module will provide at least two routines:
+       jpeg_decompress: the main entry point to the decompressor.
+       per_scan_method_selection: called by pipeline controllers for
+                                  secondary method selection passes.
+    jpeg_decompress is invoked from the user interface after the UI has
+    selected the input and output files and obtained values for all
+    user-specified options (e.g., output file format, whether to do block
+    smoothing).  jpeg_decompress calls read_file_header, performs basic
+    initialization (e.g., calculating the size of MCUs), does the "global"
+    method selection pass, and finally calls the selected pipeline control
+    object.  (Per-scan method selections will be invoked by the pipeline
+    controller.)
+    Note that jpeg_decompress can't be a method since it is invoked prior to
+    method selection.
+
+14. User interface; this is the architecture's term for "the rest of the
+    application program", i.e., that which invokes the JPEG decompressor.
+    The UI is expected to supply input and output files and values for all
+    operational parameters.  The UI must also supply error handling routines.
+    At the moment I can't think of any nonfatal errors the JPEG code is likely
+    to report, so a single report-this-error-and-exit method should be
+    sufficient.
+    (This module hides the user interface provided --- command line,
+    interactive, etc.  Except for error handling, the UI calls the portable
+    JPEG code, not the other way around.)
+
+15. A memory management object.  This will be identical to the memory
+    management for compression (and will be the same code, in combined
+    programs).  See above for details.
+
+
+*** Initial method selection ***
+
+The main ugliness in this design is the portion of startup that will select
+which of several instantiations should be used for each of the objects.  (For
+example, Huffman or arithmetic for entropy encoding; one of several pipeline
+controllers depending on interleaving, the size of the image, etc.)  It's not
+really desirable to have a single chunk of code that knows the names of all
+the possible instantiations and the conditions under which to select each one.
+
+The best approach seems to be to provide a selector function for each object
+(group of related method calls).  This function knows about each possible
+instantiation of its object and how to choose the right one; but it doesn't
+know about any other objects.
+
+Note that there will be several rounds of method selection: at initial startup,
+after overall compression parameters are determined (after the file header is
+read, if decompressing), and one in preparation for each scan (this occurs
+more than once if the file is noninterleaved).  Each object method will need
+to be clearly identified as to which round sets it up.
+
+
+*** Implications of DNL marker ***
+
+Some JPEG files may use a DNL marker to postpone definition of the image
+height (this would be useful for a fax-like scanner's output, for instance).
+In these files the SOF marker claims the image height is 0, and you only
+find out the true image height at the end of the first scan.
+
+We could handle these files as follows:
+1. Upon seeing zero image height, replace it by 65535 (the maximum allowed).
+2. When the DNL is found, update the image height in the global image
+   descriptor.
+This implies that pipeline control objects must avoid making copies of the
+image height, and must re-test for termination after each MCU row.  This is
+no big deal.
+
+In situations where image-size data structures are allocated, this approach
+will result in very inefficient use of virtual memory or
+much-larger-than-necessary temporary files.  This seems acceptable for
+something that probably won't be a mainstream usage.  People might have to
+forgo use of memory-hogging options (such as two-pass color quantization or
+noninterleaved JPEG files) if they want efficient conversion of such files.
+(One could improve efficiency by demanding a user-supplied upper bound for the
+height, less than 65536; in most cases it could be much less.)
+
+Alternately, we could insist that DNL-using files be preprocessed by a
+separate program that reads ahead to the DNL, then goes back and fixes the SOF
+marker.  This is a much simpler solution and is probably far more efficient.
+Even if one wants piped input, buffering the first scan of the JPEG file
+needs a lot smaller temp file than is implied by the maximum-height method.
+For this approach we'd simply treat DNL as a no-op in the decompressor (at
+most, check that it matches the SOF image height).
+
+We will not worry about making the compressor capable of outputting DNL.  Note
+that something similar to the first scheme above could be applied if anyone
+ever wants to make that work.
+
+
+*** Notes for MS-DOS implementors ***
+
+The standalone cjpeg and djpeg applications can be compiled in "small" memory
+model, at least at the moment; as the code grows we may be forced to switch to
+"medium" model.  (Small = both code and data pointers are near by default;
+medium = far code pointers, near data pointers.)  Medium model will slow down
+calls through method pointers, but I don't think this will amount to any
+significant speed penalty.
+
+When integrating the JPEG code into a larger application, it's a good idea to
+stay with a small-data-space model if possible.  An 8K stack is much more than
+sufficient for the JPEG code, and its static data requirements are less than
+1K.  When executed, it will typically malloc about 10K worth of near heap
+space (and lots of far heap, but that doesn't count in this calculation).
+This figure will vary depending on image size and other factors, but figuring
+20K should be more than sufficient.  Thus you have about 35K available for
+other modules' static data and near heap requirements before you need to go to
+a larger memory model.  The C library's static data will account for several K
+of this, but that still leaves a good deal for your needs.  (If you are tight
+on space, you could reduce JPEG_BUF_SIZE from 4K to 1K to save 3K of near heap
+space.)
+
+As the code is improved, we will endeavor to hold the near data requirements
+to the range given above.  This does imply that certain data structures will
+be allocated as FAR although they would fit in near space if we assumed the
+JPEG code is stand-alone.  (The LZW tables in jrdgif/jwrgif are examples.)
+To make an optimal implementation, you might want to move these structures
+back to near heap if you know there is sufficient space.
+
+
+*** Potential optimizations ***
+
+For colormapped input formats it might be worthwhile to merge the input file
+reading and the colorspace conversion steps; in other words, do the colorspace
+conversion by hacking up the colormap before inputting the image body, rather
+than doing the conversion on each pixel independently.  Not clear if this is
+worth the uglification involved.  In the above design for the compressor, only
+the colorspace conversion step ever sees the output of get_input_row, so this
+sort of thing could be done via private agreement between those two modules.
+
+Level shift from 0..255 to -128..127 may be done either during colorspace
+conversion, or at the moment of converting an 8x8 sample block into the format
+used by the DCT step (which will be signed short or long int).  This could be
+selectable by a compile-time flag, so that the intermediate steps can work on
+either signed or unsigned chars as samples, whichever is most easily handled
+by the platform.  However, making sure that rounding is done right will be a
+lot easier if we can assume positive values.  At the moment I think that
+benefit is worth the overhead of "& 0xFF" when reading out sample values on
+signed-char-only machines.
diff --git a/codingrules b/codingrules
new file mode 100644 (file)
index 0000000..fd6f700
--- /dev/null
@@ -0,0 +1,99 @@
+
+       JPEG SYSTEM CODING RULES                27-SEP-91
+
+Since numerous people will be contributing code and bug fixes, it's important
+to establish a common coding style.  The goal of using similar coding styles
+is much more important than the details of just what that style is.
+
+I suggest we follow the recommendations of "Recommended C Style and Coding
+Standards" revision 6.1 (Cannon et al. as modified by Spencer, Keppel and
+Brader).  I have placed a copy of this document in the jpeg FTP archive (see
+jpeg/doc/cstyle.ms.tbl.Z, or cstyle.txt.Z for those without nroff/tbl).
+
+Unless someone has a real strong objection, let's do block comments thusly:
+
+/*
+ *  Block comments in this style.
+ */
+
+and indent statements in K&R style, e.g.,
+
+       if (test) {
+           then-part;
+       } else {
+           else-part;
+       }
+
+I suggest that multi-word names be written in the style multi_word_name
+rather than multiWordName, but I am open to argument on this.
+
+
+I would like to use function prototypes everywhere, and rely on automatic
+source code transformation to feed non-ANSI C compilers.  The best tool
+I have so far found for this is 'ansi2knr.c', which is part of Ghostscript.
+ansi2knr is not very bright, so it imposes a format requirement on function
+declarations: the function name MUST BEGIN IN COLUMN 1.  Thus all functions
+should be written in the following style:
+
+static int *
+function_name (int a, char *b)
+{
+    code...
+}
+
+ansi2knr won't help with method declarations (function pointers in structs).
+I suggest we use a macro to declare method pointers, something like this:
+
+#ifdef PROTO
+#define METHOD(type,methodname,arglist)  type (*methodname) arglist
+#else
+#define METHOD(type,methodname,arglist)  type (*methodname) ()
+#endif
+
+which is used like this:
+
+struct function_pointers {
+       METHOD(void, init_entropy_encoder, (functptrs fptrs, jparms *jp));
+       METHOD(void, term_entropy_encoder, (void));
+};
+
+Note the set of parentheses surrounding the parameter list.
+
+A similar solution is used for external function declarations (see the PP
+macro in jpegdata.h).
+
+If the code is to work on non-ANSI compilers, you cannot rely on a prototype
+declaration to coerce actual parameters into the right types.  Therefore, use
+explicit casts on actual parameters whenever the actual parameter type is not
+identical to the formal parameter.  Beware of implicit conversions to "int".
+
+It seems there are some non-ANSI compilers in which the sizeof() operator
+is defined to return int, while size_t is defined as long.  Needless to say,
+this is brain-damaged.  Always use the SIZEOF() macro in place of sizeof(),
+so that the result is guaranteed to be of type size_t.
+
+
+We can expect that the JPEG compressor and decompressor will be incorporated
+into larger programs.  Therefore, the following rules are important:
+
+1. Avoid direct use of any file I/O, "malloc", error report printouts, etc;
+pass these through the common routines provided.
+
+2. Assume that the JPEG code may be invoked more than once per program run;
+therefore, do not rely on static initialization of variables, and be careful
+to release all allocated storage at the end of processing.
+
+3. Minimize global namespace pollution.  Functions should be declared static
+wherever possible.  (Note that our method-based calling conventions help this
+a lot: in many modules only the method-selector function will ever need to be
+called directly, so only that function need be externally visible.)  All
+global function names should begin with "j", and should be unique in the first
+six characters for portability reasons.
+Don't use global variables at all; anything that must be used in another
+module should be put into parameters (there'll be some large structs passed
+around for this purpose).
+
+4. Source file names should also begin with "j"; remember to keep them to
+eight characters (plus ".c" or ".h", etc) to make life easy for MS-DOSers.
+Do not put code for both compression and decompression into the same source
+file.
diff --git a/egetopt.c b/egetopt.c
new file mode 100644 (file)
index 0000000..8183d35
--- /dev/null
+++ b/egetopt.c
@@ -0,0 +1,276 @@
+/*
+ * egetopt.c -- Extended 'getopt'.
+ *
+ * A while back, a public-domain version of getopt() was posted to the
+ * net.  A bit later, a gentleman by the name of Keith Bostic made some
+ * enhancements and reposted it.
+ *
+ * In recent weeks (i.e., early-to-mid 1988) there's been some
+ * heated discussion in comp.lang.c about the merits and drawbacks
+ * of getopt(), especially with regard to its handling of '?'.
+ *
+ * In light of this, I have taken Mr. Bostic's public-domain getopt()
+ * and have made some changes that I hope will be considered to be
+ * improvements.  I call this routine 'egetopt' ("Extended getopt").
+ * The default behavior of this routine is the same as that of getopt(),
+ * but it has some optional features that make it more useful.  These
+ * options are controlled by the settings of some global variables.
+ * By not setting any of these extra global variables, you will have
+ * the same functionality as getopt(), which should satisfy those
+ * purists who believe getopt() is perfect and can never be improved.
+ * If, on the other hand, you are someone who isn't satisfied with the
+ * status quo, egetopt() may very well give you the added capabilities
+ * you want.
+ *
+ * Look at the enclosed README file for a description of egetopt()'s
+ * new features.
+ *
+ * The code was originally posted to the net as getopt.c by ...
+ *
+ *     Keith Bostic
+ *     ARPA: keith@seismo 
+ *     UUCP: seismo!keith
+ *
+ * Current version: added enhancements and comments, reformatted code.
+ *
+ *     Lloyd Zusman
+ *     Master Byte Software
+ *     Los Gatos, California
+ *     Internet:       ljz@fx.com
+ *     UUCP:           ...!ames!fxgrp!ljz
+ *
+ *     May, 1988
+ */
+
+/*
+ * If you want, include stdio.h or something where EOF and NULL are defined.
+ * However, egetopt() is written so as not to need stdio.h, which should
+ * make it significantly smaller on some systems.
+ */
+
+#ifndef EOF
+# define EOF           (-1)
+#endif /* ! EOF */
+
+#ifndef NULL
+# define NULL          (char *)0
+#endif /* ! NULL */
+
+/*
+ * None of these constants are referenced in the executable portion of
+ * the code ... their sole purpose is to initialize global variables.
+ */
+#define BADCH          (int)'?'
+#define NEEDSEP                (int)':'
+#define MAYBESEP       (int)'\0'
+#define ERRFD          2
+#define EMSG           ""
+#define START          "-"
+
+/*
+ * Here are all the pertinent global variables.
+ */
+int opterr = 1;                /* if true, output error message */
+int optind = 1;                /* index into parent argv vector */
+int optopt;            /* character checked for validity */
+int optbad = BADCH;    /* character returned on error */
+int optchar = 0;       /* character that begins returned option */
+int optneed = NEEDSEP; /* flag for mandatory argument */
+int optmaybe = MAYBESEP;/* flag for optional argument */
+int opterrfd = ERRFD;  /* file descriptor for error text */
+char *optarg;          /* argument associated with option */
+char *optstart = START;        /* list of characters that start options */
+
+
+/*
+ * Macros.
+ */
+
+/*
+ * Conditionally print out an error message and return (depends on the
+ * setting of 'opterr' and 'opterrfd').  Note that this version of
+ * TELL() doesn't require the existence of stdio.h.
+ */
+#define TELL(S)        { \
+       if (opterr && opterrfd >= 0) { \
+               char option = optopt; \
+               write(opterrfd, *nargv, strlen(*nargv)); \
+               write(opterrfd, (S), strlen(S)); \
+               write(opterrfd, &option, 1); \
+               write(opterrfd, "\n", 1); \
+       } \
+       return (optbad); \
+}
+
+/*
+ * This works similarly to index() and strchr().  I include it so that you
+ * don't need to be concerned as to which one your system has.
+ */
+static char *
+_sindex(string, ch)
+char *string;
+int ch;
+{
+       if (string != NULL) {
+               for (; *string != '\0'; ++string) {
+                       if (*string == (char)ch) {
+                               return (string);
+                       }
+               }
+       }
+
+       return (NULL);
+}
+
+/*
+ * Here it is:
+ */
+int
+egetopt(nargc, nargv, ostr)
+int nargc;
+char **nargv;
+char *ostr;
+{
+       static char *place = EMSG;      /* option letter processing */
+       register char *oli;             /* option letter list index */
+       register char *osi = NULL;      /* option start list index */
+
+       if (nargv == (char **)NULL) {
+               return (EOF);
+       }
+
+       if (nargc <= optind || nargv[optind] == NULL) {
+               return (EOF);
+       }
+
+       if (place == NULL) {
+               place = EMSG;
+       }
+
+       /*
+        * Update scanning pointer.
+        */
+       if (*place == '\0') {
+               place = nargv[optind];
+               if (place == NULL) {
+                       return (EOF);
+               }
+               osi = _sindex(optstart, *place);
+               if (osi != NULL) {
+                       optchar = (int)*osi;
+               }
+               if (optind >= nargc || osi == NULL || *++place == '\0') {
+                       return (EOF);
+               }
+
+               /*
+                * Two adjacent, identical flag characters were found.
+                * This takes care of "--", for example.
+                */
+               if (*place == place[-1]) {
+                       ++optind;
+                       return (EOF);
+               }
+       }
+
+       /*
+        * If the option is a separator or the option isn't in the list,
+        * we've got an error.
+        */
+       optopt = (int)*place++;
+       oli = _sindex(ostr, optopt);
+       if (optopt == optneed || optopt == optmaybe || oli == NULL) {
+               /*
+                * If we're at the end of the current argument, bump the
+                * argument index.
+                */
+               if (*place == '\0') {
+                       ++optind;
+               }
+               TELL(": illegal option -- ");   /* byebye */
+       }
+
+       /*
+        * If there is no argument indicator, then we don't even try to
+        * return an argument.
+        */
+       ++oli;
+       if (*oli == '\0' || (*oli != optneed && *oli != optmaybe)) {
+               /*
+                * If we're at the end of the current argument, bump the
+                * argument index.
+                */
+               if (*place == '\0') {
+                       ++optind;
+               }
+               optarg = NULL;
+       }
+       /*
+        * If we're here, there's an argument indicator.  It's handled
+        * differently depending on whether it's a mandatory or an
+        * optional argument.
+        */
+       else {
+               /*
+                * If there's no white space, use the rest of the
+                * string as the argument.  In this case, it doesn't
+                * matter if the argument is mandatory or optional.
+                */
+               if (*place != '\0') {
+                       optarg = place;
+               }
+               /*
+                * If we're here, there's whitespace after the option.
+                *
+                * Is it a mandatory argument?  If so, return the
+                * next command-line argument if there is one.
+                */
+               else if (*oli == optneed) {
+                       /*
+                        * If we're at the end of the argument list, there
+                        * isn't an argument and hence we have an error.
+                        * Otherwise, make 'optarg' point to the argument.
+                        */
+                       if (nargc <= ++optind) {
+                               place = EMSG;
+                               TELL(": option requires an argument -- ");
+                       }
+                       else {
+                               optarg = nargv[optind];
+                       }
+               }
+               /*
+                * If we're here it must have been an optional argument.
+                */
+               else {
+                       if (nargc <= ++optind) {
+                               place = EMSG;
+                               optarg = NULL;
+                       }
+                       else {
+                               optarg = nargv[optind];
+                               if (optarg == NULL) {
+                                       place = EMSG;
+                               }
+                               /*
+                                * If the next item begins with a flag
+                                * character, we treat it like a new
+                                * argument.  This is accomplished by
+                                * decrementing 'optind' and returning
+                                * a null argument.
+                                */
+                               else if (_sindex(optstart, *optarg) != NULL) {
+                                       --optind;
+                                       optarg = NULL;
+                               }
+                       }
+               }
+               place = EMSG;
+               ++optind;
+       }
+
+       /*
+        * Return option letter.
+        */
+       return (optopt);
+}
diff --git a/jbsmooth.c b/jbsmooth.c
new file mode 100644 (file)
index 0000000..ad2138d
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * jbsmooth.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains cross-block smoothing routines.
+ * These routines are invoked via the smooth_coefficients method.
+ */
+
+#include "jinclude.h"
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+
+
+/*
+ * Cross-block coefficient smoothing.
+ */
+
+METHODDEF void
+smooth_coefficients (decompress_info_ptr cinfo,
+                    jpeg_component_info *compptr,
+                    JBLOCKROW above,
+                    JBLOCKROW currow,
+                    JBLOCKROW below,
+                    JBLOCKROW output)
+{
+  QUANT_TBL_PTR Qptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
+  long blocks_in_row = compptr->subsampled_width / DCTSIZE;
+  long col;
+
+  /* First, copy the block row as-is.
+   * This takes care of the first & last blocks in the row, the top/bottom
+   * special cases, and the higher-order coefficients in each block.
+   */
+  jcopy_block_row(currow, output, blocks_in_row);
+
+  /* Now apply the smoothing calculation, but not to any blocks on the
+   * edges of the image.
+   */
+
+  if (above != NULL && below != NULL) {
+    for (col = 1; col < blocks_in_row-1; col++) {
+
+      /* See section 13.10 of JPEG-8-R8, or K.8 of JPEG-9-R6.
+       *
+       * As I understand it, this produces approximations
+       * for the low frequency AC components, based on the
+       * DC values of the block and its eight neighboring blocks.
+       * (Thus it can't be used for blocks on the image edges.)
+       */
+
+      /* The layout of these variables corresponds to
+       * the text in 13.10
+       */
+      
+      JCOEF DC1, DC2, DC3;
+      JCOEF DC4, DC5, DC6;
+      JCOEF DC7, DC8, DC9;
+      
+      long       AC01, AC02;
+      long AC10, AC11;
+      long AC20;
+      
+      DC1 = above [col-1][0];
+      DC2 = above [col  ][0];
+      DC3 = above [col+1][0];
+      DC4 = currow[col-1][0];
+      DC5 = currow[col  ][0];
+      DC6 = currow[col+1][0];
+      DC7 = below [col-1][0];
+      DC8 = below [col  ][0];
+      DC9 = below [col+1][0];
+      
+#define DIVIDE_256(x)  x = ( (x) < 0 ? -((128-(x))/256) : ((x)+128)/256 )
+      
+      AC01 = (36 * (DC4 - DC6));
+      DIVIDE_256(AC01);
+      AC10 = (36 * (DC2 - DC8));
+      DIVIDE_256(AC10);
+      AC20 = (9 * (DC2 + DC8 - 2*DC5));
+      DIVIDE_256(AC20);
+      AC11 = (5 * ((DC1 - DC3) - (DC7 - DC9)));
+      DIVIDE_256(AC11);
+      AC02 = (9 * (DC4 + DC6 - 2*DC5));
+      DIVIDE_256(AC02);
+      
+      /* I think that this checks to see if the quantisation
+       * on the transmitting side would have produced this
+       * answer. If so, then we use our (hopefully better)
+       * estimate.
+       */
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+#define COND_ASSIGN(_ac,_n,_z)   if ((ABS(output[col][_n] - (_ac))<<1) <= Qptr[_z]) output[col][_n] = (_ac)
+
+      COND_ASSIGN(AC01,  1, 1);
+      COND_ASSIGN(AC02,  2, 5);
+      COND_ASSIGN(AC10,  8, 2);
+      COND_ASSIGN(AC11,  9, 4);
+      COND_ASSIGN(AC20, 16, 3);
+    }
+  }
+}
+
+
+/*
+ * The method selection routine for cross-block smoothing.
+ */
+
+GLOBAL void
+jselbsmooth (decompress_info_ptr cinfo)
+{
+  /* just one implementation for now */
+  cinfo->methods->smooth_coefficients = smooth_coefficients;
+}
+
+#endif /* BLOCK_SMOOTHING_SUPPORTED */
diff --git a/jcarith.c b/jcarith.c
new file mode 100644 (file)
index 0000000..1949459
--- /dev/null
+++ b/jcarith.c
@@ -0,0 +1,42 @@
+/*
+ * jcarith.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains arithmetic entropy encoding routines.
+ * These routines are invoked via the methods entropy_encode,
+ * entropy_encoder_init/term, and entropy_optimize.
+ */
+
+#include "jinclude.h"
+
+#ifdef ARITH_CODING_SUPPORTED
+
+
+/*
+ * The arithmetic coding option of the JPEG standard specifies Q-coding,
+ * which is covered by patents held by IBM (and possibly AT&T and Mitsubishi).
+ * At this time it does not appear to be legal for the Independent JPEG
+ * Group to distribute software that implements arithmetic coding.
+ * We have therefore removed arithmetic coding support from the
+ * distributed source code.
+ *
+ * We're not happy about it either.
+ */
+
+
+/*
+ * The method selection routine for arithmetic entropy encoding.
+ */
+
+GLOBAL void
+jselcarithmetic (compress_info_ptr cinfo)
+{
+  if (cinfo->arith_code) {
+    ERREXIT(cinfo->emethods, "Sorry, there are legal restrictions on arithmetic coding");
+  }
+}
+
+#endif /* ARITH_CODING_SUPPORTED */
diff --git a/jccolor.c b/jccolor.c
new file mode 100644 (file)
index 0000000..7fd198c
--- /dev/null
+++ b/jccolor.c
@@ -0,0 +1,203 @@
+/*
+ * jccolor.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains input colorspace conversion routines.
+ * These routines are invoked via the methods get_sample_rows
+ * and colorin_init/term.
+ */
+
+#include "jinclude.h"
+
+
+static JSAMPARRAY pixel_row;   /* Workspace for a pixel row in input format */
+
+
+/*
+ * Initialize for colorspace conversion.
+ */
+
+METHODDEF void
+colorin_init (compress_info_ptr cinfo)
+{
+  /* Allocate a workspace for the result of get_input_row. */
+  pixel_row = (*cinfo->emethods->alloc_small_sarray)
+               (cinfo->image_width, (long) cinfo->input_components);
+}
+
+
+/*
+ * Fetch some rows of pixels from get_input_row and convert to the
+ * JPEG colorspace.
+ * This version handles RGB -> YCbCr conversion.
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ */
+
+METHODDEF void
+get_rgb_ycc_rows (compress_info_ptr cinfo,
+                 int rows_to_read, JSAMPIMAGE image_data)
+{
+  register INT32 r, g, b;
+  register JSAMPROW inptr0, inptr1, inptr2;
+  register JSAMPROW outptr0, outptr1, outptr2;
+  register long col;
+  long width = cinfo->image_width;
+  int row;
+
+  for (row = 0; row < rows_to_read; row++) {
+    /* Read one row from the source file */
+    (*cinfo->methods->get_input_row) (cinfo, pixel_row);
+    /* Convert colorspace */
+    inptr0 = pixel_row[0];
+    inptr1 = pixel_row[1];
+    inptr2 = pixel_row[2];
+    outptr0 = image_data[0][row];
+    outptr1 = image_data[1][row];
+    outptr2 = image_data[2][row];
+    for (col = width; col > 0; col--) {
+      r = GETJSAMPLE(*inptr0++);
+      g = GETJSAMPLE(*inptr1++);
+      b = GETJSAMPLE(*inptr2++);
+      /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+       * must be too; do not need an explicit range-limiting operation.
+       */
+      /* Y */
+      *outptr0++ = (   306*r +  601*g +  117*b + (INT32) 512) >> 10;
+      /* Cb */
+      *outptr1++ = ((-173)*r -  339*g +  512*b + (INT32) 512*(MAXJSAMPLE+1)) >> 10;
+      /* Cr */
+      *outptr2++ = (   512*r -  429*g -   83*b + (INT32) 512*(MAXJSAMPLE+1)) >> 10;
+    }
+  }
+}
+
+
+/*
+ * Fetch some rows of pixels from get_input_row and convert to the
+ * JPEG colorspace.
+ * This version handles grayscale (no conversion).
+ */
+
+METHODDEF void
+get_grayscale_rows (compress_info_ptr cinfo,
+                   int rows_to_read, JSAMPIMAGE image_data)
+{
+  int row;
+
+  for (row = 0; row < rows_to_read; row++) {
+    /* Read one row from the source file */
+    (*cinfo->methods->get_input_row) (cinfo, pixel_row);
+    /* Convert colorspace (gamma mapping needed here) */
+    jcopy_sample_rows(pixel_row, 0, image_data[0], row,
+                     1, cinfo->image_width);
+  }
+}
+
+
+/*
+ * Fetch some rows of pixels from get_input_row and convert to the
+ * JPEG colorspace.
+ * This version handles multi-component colorspaces without conversion.
+ */
+
+METHODDEF void
+get_noconvert_rows (compress_info_ptr cinfo,
+                   int rows_to_read, JSAMPIMAGE image_data)
+{
+  int row, ci;
+
+  for (row = 0; row < rows_to_read; row++) {
+    /* Read one row from the source file */
+    (*cinfo->methods->get_input_row) (cinfo, pixel_row);
+    /* Convert colorspace (gamma mapping needed here) */
+    for (ci = 0; ci < cinfo->input_components; ci++) {
+      jcopy_sample_rows(pixel_row, ci, image_data[ci], row,
+                       1, cinfo->image_width);
+    }
+  }
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+colorin_term (compress_info_ptr cinfo)
+{
+  /* Release the workspace. */
+  (*cinfo->emethods->free_small_sarray)
+               (pixel_row, (long) cinfo->input_components);
+}
+
+
+/*
+ * The method selection routine for input colorspace conversion.
+ */
+
+GLOBAL void
+jselccolor (compress_info_ptr cinfo)
+{
+  /* Make sure input_components agrees with in_color_space */
+  switch (cinfo->in_color_space) {
+  case CS_GRAYSCALE:
+    if (cinfo->input_components != 1)
+      ERREXIT(cinfo->emethods, "Bogus input colorspace");
+    break;
+
+  case CS_RGB:
+    if (cinfo->input_components != 3)
+      ERREXIT(cinfo->emethods, "Bogus input colorspace");
+    break;
+
+  case CS_CMYK:
+    if (cinfo->input_components != 4)
+      ERREXIT(cinfo->emethods, "Bogus input colorspace");
+    break;
+
+  default:
+    ERREXIT(cinfo->emethods, "Unsupported input colorspace");
+    break;
+  }
+
+  /* Check num_components, set conversion method based on requested space */
+  switch (cinfo->jpeg_color_space) {
+  case CS_GRAYSCALE:
+    if (cinfo->num_components != 1)
+      ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
+    if (cinfo->in_color_space == CS_GRAYSCALE)
+      cinfo->methods->get_sample_rows = get_grayscale_rows;
+    else
+      ERREXIT(cinfo->emethods, "Unsupported color conversion request");
+    break;
+
+  case CS_YCbCr:
+    if (cinfo->num_components != 3)
+      ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
+    if (cinfo->in_color_space == CS_RGB)
+      cinfo->methods->get_sample_rows = get_rgb_ycc_rows;
+    else
+      ERREXIT(cinfo->emethods, "Unsupported color conversion request");
+    break;
+
+  case CS_CMYK:
+    if (cinfo->num_components != 4)
+      ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
+    if (cinfo->in_color_space == CS_CMYK)
+      cinfo->methods->get_sample_rows = get_noconvert_rows;
+    else
+      ERREXIT(cinfo->emethods, "Unsupported color conversion request");
+    break;
+
+  default:
+    ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace");
+    break;
+  }
+
+  cinfo->methods->colorin_init = colorin_init;
+  cinfo->methods->colorin_term = colorin_term;
+}
diff --git a/jcdeflts.c b/jcdeflts.c
new file mode 100644 (file)
index 0000000..cd1624a
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ * jcdeflts.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains optional default-setting code for the JPEG compressor.
+ */
+
+#include "jinclude.h"
+
+
+LOCAL void
+add_huff_table (compress_info_ptr cinfo,
+               HUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
+/* Define a Huffman table */
+{
+  if (*htblptr == NULL)
+    *htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
+  
+  memcpy((void *) (*htblptr)->bits, (void *) bits,
+        SIZEOF((*htblptr)->bits));
+  memcpy((void *) (*htblptr)->huffval, (void *) val,
+        SIZEOF((*htblptr)->huffval));
+
+  /* Initialize sent_table FALSE so table will be written to JPEG file.
+   * In an application where we are writing non-interchange JPEG files,
+   * it might be desirable to save space by leaving default Huffman tables
+   * out of the file.  To do that, just initialize sent_table = TRUE...
+   */
+
+  (*htblptr)->sent_table = FALSE;
+}
+
+
+LOCAL void
+std_huff_tables (compress_info_ptr cinfo)
+/* Set up the standard Huffman tables (cf. JPEG-8-R8 section 13.3) */
+{
+  static const UINT8 dc_luminance_bits[17] =
+    { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+  static const UINT8 dc_luminance_val[] =
+    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+  
+  static const UINT8 dc_chrominance_bits[17] =
+    { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+  static const UINT8 dc_chrominance_val[] =
+    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+  
+  static const UINT8 ac_luminance_bits[17] =
+    { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
+  static const UINT8 ac_luminance_val[] =
+    { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+      0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+      0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+      0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+      0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+      0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+      0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+      0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+      0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+      0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+      0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+      0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+      0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+      0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+      0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+      0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+      0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+      0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+      0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+      0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+      0xf9, 0xfa };
+  
+  static const UINT8 ac_chrominance_bits[17] =
+    { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
+  static const UINT8 ac_chrominance_val[] =
+    { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+      0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+      0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+      0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+      0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+      0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+      0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+      0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+      0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+      0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+      0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+      0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+      0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+      0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+      0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+      0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+      0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+      0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+      0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+      0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+      0xf9, 0xfa };
+  
+  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
+                dc_luminance_bits, dc_luminance_val);
+  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
+                ac_luminance_bits, ac_luminance_val);
+  add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
+                dc_chrominance_bits, dc_chrominance_val);
+  add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
+                ac_chrominance_bits, ac_chrominance_val);
+}
+
+
+/* This is the sample quantization table given in JPEG-8-R8 sec 13.1,
+ * but expressed in zigzag order (as are all of our quant. tables).
+ * The spec says that the values given produce "good" quality, and
+ * when divided by 2, "very good" quality.  (These two settings are
+ * selected by quality=50 and quality=75 in j_set_quality, below.)
+ */
+
+
+static const QUANT_VAL std_luminance_quant_tbl[DCTSIZE2] = {
+  16,  11,  12,  14,  12,  10,  16,  14,
+  13,  14,  18,  17,  16,  19,  24,  40,
+  26,  24,  22,  22,  24,  49,  35,  37,
+  29,  40,  58,  51,  61,  60,  57,  51,
+  56,  55,  64,  72,  92,  78,  64,  68,
+  87,  69,  55,  56,  80, 109,  81,  87,
+  95,  98, 103, 104, 103,  62,  77, 113,
+ 121, 112, 100, 120,  92, 101, 103,  99
+};
+
+static const QUANT_VAL std_chrominance_quant_tbl[DCTSIZE2] = {
+  17,  18,  18,  24,  21,  24,  47,  26,
+  26,  47,  99,  66,  56,  66,  99,  99,
+  99,  99,  99,  99,  99,  99,  99,  99,
+  99,  99,  99,  99,  99,  99,  99,  99,
+  99,  99,  99,  99,  99,  99,  99,  99,
+  99,  99,  99,  99,  99,  99,  99,  99,
+  99,  99,  99,  99,  99,  99,  99,  99,
+  99,  99,  99,  99,  99,  99,  99,  99
+};
+
+
+LOCAL void
+add_quant_table (compress_info_ptr cinfo, int which_tbl,
+                const QUANT_VAL *basic_table, int scale_factor,
+                boolean force_baseline)
+/* Define a quantization table equal to the basic_table times */
+/* a scale factor (given as a percentage) */
+{
+  QUANT_TBL_PTR * qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
+  int i;
+  long temp;
+
+  if (*qtblptr == NULL)
+    *qtblptr = (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
+
+  for (i = 0; i < DCTSIZE2; i++) {
+    temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
+    /* limit the values to the valid range */
+    if (temp <= 0L) temp = 1L;
+#ifdef EIGHT_BIT_SAMPLES
+    if (temp > 32767L) temp = 32767L; /* QUANT_VALs are 'short' */
+#else
+    if (temp > 65535L) temp = 65535L; /* QUANT_VALs are 'UINT16' */
+#endif
+    if (force_baseline && temp > 255L)
+      temp = 255L;             /* limit to baseline range if requested */
+    (*qtblptr)[i] = (QUANT_VAL) temp;
+  }
+}
+
+
+GLOBAL void
+j_set_quality (compress_info_ptr cinfo, int quality, boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting. */
+/* The 'quality' factor should be 0 (terrible) to 100 (very good). */
+/* Quality 50 corresponds to the JPEG basic tables given above; */
+/* quality 100 results in no quantization scaling at all. */
+/* If force_baseline is TRUE, quantization table entries are limited */
+/* to 0..255 for JPEG baseline compatibility; this is only an issue */
+/* for quality settings below 24. */
+{
+  /* Safety limit on quality factor.  Convert 0 to 1 to avoid zero divide. */
+  if (quality <= 0) quality = 1;
+  if (quality > 100) quality = 100;
+
+  /* Convert quality rating to a percentage scaling of the basic tables.
+   * The basic table is used as-is (scaling 100) for a quality of 50.
+   * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
+   * note that at Q=100 the scaling is 0, which will cause add_quant_table
+   * to make all the table entries 1 (hence, no quantization loss).
+   * Qualities 1..50 are converted to scaling percentage 5000/Q.
+   */
+  if (quality < 50)
+    quality = 5000 / quality;
+  else
+    quality = 200 - quality*2;
+
+  /* Set up two quantization tables using the specified quality scaling */
+  add_quant_table(cinfo, 0, std_luminance_quant_tbl, quality, force_baseline);
+  add_quant_table(cinfo, 1, std_chrominance_quant_tbl, quality, force_baseline);
+}
+
+
+
+/* Default parameter setup for compression.
+ *
+ * User interfaces that don't choose to use this routine must do their
+ * own setup of all these parameters.  Alternately, you can call this
+ * to establish defaults and then alter parameters selectively.
+ *
+ * See above for the meaning of the 'quality' parameter.  Typically,
+ * the application's default quality setting will be passed to this
+ * routine.  A later call on j_set_quality() can be used to change to
+ * a user-specified quality setting.
+ *
+ * This sets up for a color image; to output a grayscale image,
+ * do this first and call j_monochrome_default() afterwards.
+ * (The latter can be called within c_ui_method_selection, so the
+ * choice can depend on the input file header.)
+ * Note that if you want a JPEG colorspace other than GRAYSCALE or YCbCr,
+ * you should also change the component ID codes, and you should NOT emit
+ * a JFIF header (set write_JFIF_header = FALSE).
+ *
+ * CAUTION: if you want to compress multiple images per run, it's safest
+ * to call j_default_compression before *each* call to jpeg_compress (and
+ * j_free_defaults afterwards).  If this isn't practical, you'll have to
+ * be careful to reset any individual parameters that may change during
+ * the compression run.  The main thing you need to worry about as this
+ * is written is that the sent_table boolean in each Huffman table must
+ * be reset to FALSE before each compression; otherwise, Huffman tables
+ * won't get emitted for the second and subsequent images.
+ */
+
+GLOBAL void
+j_default_compression (compress_info_ptr cinfo, int quality)
+/* NB: the external methods must already be set up. */
+{
+  short i;
+  jpeg_component_info * compptr;
+
+  /* Initialize pointers as needed to mark stuff unallocated. */
+  cinfo->comp_info = NULL;
+  for (i = 0; i < NUM_QUANT_TBLS; i++)
+    cinfo->quant_tbl_ptrs[i] = NULL;
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    cinfo->dc_huff_tbl_ptrs[i] = NULL;
+    cinfo->ac_huff_tbl_ptrs[i] = NULL;
+  }
+
+  cinfo->data_precision = 8;   /* default; can be overridden by input_init */
+  cinfo->density_unit = 0;     /* Pixel size is unknown by default */
+  cinfo->X_density = 1;                /* Pixel aspect ratio is square by default */
+  cinfo->Y_density = 1;
+
+  cinfo->input_gamma = 1.0;    /* no gamma correction by default */
+
+  /* Prepare three color components; first is luminance which is also usable */
+  /* for grayscale.  The others are assumed to be UV or similar chrominance. */
+  cinfo->write_JFIF_header = TRUE;
+  cinfo->jpeg_color_space = CS_YCbCr;
+  cinfo->num_components = 3;
+  cinfo->comp_info = (*cinfo->emethods->alloc_small)
+                       (4 * SIZEOF(jpeg_component_info));
+  /* Note: we allocate a 4-entry comp_info array so that user interface can
+   * easily change over to CMYK color space if desired.
+   */
+
+  compptr = &cinfo->comp_info[0];
+  compptr->component_index = 0;
+  compptr->component_id = 1;   /* JFIF specifies IDs 1,2,3 */
+  compptr->h_samp_factor = 2;  /* default to 2x2 subsamples of chrominance */
+  compptr->v_samp_factor = 2;
+  compptr->quant_tbl_no = 0;   /* use tables 0 for luminance */
+  compptr->dc_tbl_no = 0;
+  compptr->ac_tbl_no = 0;
+
+  compptr = &cinfo->comp_info[1];
+  compptr->component_index = 1;
+  compptr->component_id = 2;
+  compptr->h_samp_factor = 1;
+  compptr->v_samp_factor = 1;
+  compptr->quant_tbl_no = 1;   /* use tables 1 for chrominance */
+  compptr->dc_tbl_no = 1;
+  compptr->ac_tbl_no = 1;
+
+  compptr = &cinfo->comp_info[2];
+  compptr->component_index = 2;
+  compptr->component_id = 3;
+  compptr->h_samp_factor = 1;
+  compptr->v_samp_factor = 1;
+  compptr->quant_tbl_no = 1;   /* use tables 1 for chrominance */
+  compptr->dc_tbl_no = 1;
+  compptr->ac_tbl_no = 1;
+
+  /* Set up two quantization tables using the specified quality scaling */
+  /* Baseline compatibility is forced (a nonissue for reasonable defaults) */
+  j_set_quality(cinfo, quality, TRUE);
+
+  /* Set up two Huffman tables in case user interface wants Huffman coding */
+  std_huff_tables(cinfo);
+
+  /* Initialize default arithmetic coding conditioning */
+  for (i = 0; i < NUM_ARITH_TBLS; i++) {
+    cinfo->arith_dc_L[i] = 0;
+    cinfo->arith_dc_U[i] = 1;
+    cinfo->arith_ac_K[i] = 5;
+  }
+
+  /* Use Huffman coding, not arithmetic coding, by default */
+  cinfo->arith_code = FALSE;
+
+  /* Color images are interleaved by default */
+  cinfo->interleave = TRUE;
+
+  /* By default, don't do extra passes to optimize entropy coding */
+  cinfo->optimize_coding = FALSE;
+
+  /* By default, use the simpler non-cosited sampling alignment */
+  cinfo->CCIR601_sampling = FALSE;
+
+  /* No restart markers */
+  cinfo->restart_interval = 0;
+}
+
+
+
+GLOBAL void
+j_monochrome_default (compress_info_ptr cinfo)
+/* Change the j_default_compression() values to emit a monochrome JPEG file. */
+{
+  jpeg_component_info * compptr;
+
+  cinfo->jpeg_color_space = CS_GRAYSCALE;
+  cinfo->num_components = 1;
+  /* Set single component to 1x1 subsampling */
+  compptr = &cinfo->comp_info[0];
+  compptr->h_samp_factor = 1;
+  compptr->v_samp_factor = 1;
+}
+
+
+
+/* This routine releases storage allocated by j_default_compression.
+ * Note that freeing the method pointer structs and the compress_info_struct
+ * itself are the responsibility of the user interface.
+ */
+
+GLOBAL void
+j_free_defaults (compress_info_ptr cinfo)
+{
+  short i;
+
+#define FREE(ptr)  if ((ptr) != NULL) \
+                       (*cinfo->emethods->free_small) ((void *) ptr)
+
+  FREE(cinfo->comp_info);
+  for (i = 0; i < NUM_QUANT_TBLS; i++)
+    FREE(cinfo->quant_tbl_ptrs[i]);
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    FREE(cinfo->dc_huff_tbl_ptrs[i]);
+    FREE(cinfo->ac_huff_tbl_ptrs[i]);
+  }
+}
diff --git a/jcexpand.c b/jcexpand.c
new file mode 100644 (file)
index 0000000..94878bd
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * jcexpand.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains image edge-expansion routines.
+ * These routines are invoked via the edge_expand method.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * Expand an image so that it is a multiple of the MCU dimensions.
+ * This is to be accomplished by duplicating the rightmost column
+ * and/or bottommost row of pixels.  The image has not yet been
+ * subsampled, so all components have the same dimensions.
+ */
+
+METHODDEF void
+edge_expand (compress_info_ptr cinfo,
+            long input_cols, int input_rows,
+            long output_cols, int output_rows,
+            JSAMPIMAGE image_data)
+{
+  /* Expand horizontally */
+  if (input_cols < output_cols) {
+    register JSAMPROW ptr;
+    register JSAMPLE pixval;
+    register long count;
+    register int row;
+    short ci;
+    long numcols = output_cols - input_cols;
+
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      for (row = 0; row < input_rows; row++) {
+       ptr = image_data[ci][row] + (input_cols-1);
+       pixval = GETJSAMPLE(*ptr++);
+       for (count = numcols; count > 0; count--)
+         *ptr++ = pixval;
+      }
+    }
+  }
+
+  /* Expand vertically */
+  /* This happens only once at the bottom of the image, */
+  /* so it needn't be super-efficient */
+  if (input_rows < output_rows) {
+    register int row;
+    short ci;
+    JSAMPARRAY this_component;
+
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      this_component = image_data[ci];
+      for (row = input_rows; row < output_rows; row++) {
+       jcopy_sample_rows(this_component, input_rows-1, this_component, row,
+                         1, output_cols);
+      }
+    }
+  }
+}
+
+
+/*
+ * The method selection routine for edge expansion.
+ */
+
+GLOBAL void
+jselexpand (compress_info_ptr cinfo)
+{
+  /* just one implementation for now */
+  cinfo->methods->edge_expand = edge_expand;
+}
diff --git a/jchuff.c b/jchuff.c
new file mode 100644 (file)
index 0000000..531bc75
--- /dev/null
+++ b/jchuff.c
@@ -0,0 +1,689 @@
+/*
+ * jchuff.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy encoding routines.
+ * These routines are invoked via the methods entropy_encode,
+ * entropy_encoder_init/term, and entropy_optimize.
+ */
+
+#include "jinclude.h"
+
+
+/* Static variables to avoid passing 'round extra parameters */
+
+static compress_info_ptr cinfo;
+
+static INT32 huff_put_buffer;  /* current bit-accumulation buffer */
+static int huff_put_bits;      /* # of bits now in it */
+
+static char * output_buffer;   /* output buffer */
+static int bytes_in_buffer;
+
+
+
+LOCAL void
+fix_huff_tbl (HUFF_TBL * htbl)
+/* Compute derived values for a Huffman table */
+{
+  int p, i, l, lastp, si;
+  char huffsize[257];
+  UINT16 huffcode[257];
+  UINT16 code;
+  
+  /* Figure 7.3.5.4.2.1: make table of Huffman code length for each symbol */
+  /* Note that this is in code-length order. */
+
+  p = 0;
+  for (l = 1; l <= 16; l++) {
+    for (i = 1; i <= htbl->bits[l]; i++)
+      huffsize[p++] = l;
+  }
+  huffsize[p] = 0;
+  lastp = p;
+  
+  /* Figure 7.3.5.4.2.2: generate the codes themselves */
+  /* Note that this is in code-length order. */
+  
+  code = 0;
+  si = huffsize[0];
+  p = 0;
+  while (huffsize[p]) {
+    while (huffsize[p] == si) {
+      huffcode[p++] = code;
+      code++;
+    }
+    code <<= 1;
+    si++;
+  }
+  
+  /* Figure 7.3.5.4.2.3: generate encoding tables */
+  /* These are code and size indexed by symbol value */
+
+  for (p = 0; p < lastp; p++) {
+    htbl->ehufco[htbl->huffval[p]] = huffcode[p];
+    htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
+  }
+  
+  /* Figure 13.4.2.3.1: generate decoding tables */
+
+  p = 0;
+  for (l = 1; l <= 16; l++) {
+    if (htbl->bits[l]) {
+      htbl->valptr[l] = p;     /* huffval[] index of 1st sym of code len l */
+      htbl->mincode[l] = huffcode[p]; /* minimum code of length l */
+      p += htbl->bits[l];
+      htbl->maxcode[l] = huffcode[p-1];        /* maximum code of length l */
+    } else {
+      htbl->maxcode[l] = -1;
+    }
+  }
+}
+
+
+/* Outputting bytes to the file */
+
+LOCAL void
+flush_bytes (void)
+{
+  if (bytes_in_buffer)
+    (*cinfo->methods->entropy_output) (cinfo, output_buffer, bytes_in_buffer);
+  bytes_in_buffer = 0;
+}
+
+
+#define emit_byte(val) ((bytes_in_buffer >= JPEG_BUF_SIZE ? \
+                               (flush_bytes(), 0) : 0), \
+                        output_buffer[bytes_in_buffer] = (val), \
+                        bytes_in_buffer++)
+
+
+
+/* Outputting bits to the file */
+
+/* Only the right 24 bits of huff_put_buffer are used; the valid bits are
+ * left-justified in this part.  At most 16 bits can be passed to emit_bits
+ * in one call, and we never retain more than 7 bits in huff_put_buffer
+ * between calls, so 24 bits are sufficient.
+ */
+
+LOCAL void
+emit_bits (UINT16 code, int size)
+{
+  /* This routine is heavily used, so it's worth coding tightly. */
+  register INT32 put_buffer = code;
+  register int put_bits = huff_put_bits;
+
+  put_buffer &= (((INT32) 1) << size) - 1; /* Mask off any excess bits in code */
+  
+  put_bits += size;            /* new number of bits in buffer */
+  
+  put_buffer <<= 24 - put_bits; /* align incoming bits */
+
+  put_buffer |= huff_put_buffer; /* and merge with old buffer contents */
+  
+  while (put_bits >= 8) {
+    int c = (int) ((put_buffer >> 16) & 0xFF);
+    
+    emit_byte(c);
+    if (c == 0xFF) {           /* need to stuff a zero byte? */
+      emit_byte(0);
+    }
+    put_buffer <<= 8;
+    put_bits -= 8;
+  }
+
+  huff_put_buffer = put_buffer;        /* Update global variables */
+  huff_put_bits = put_bits;
+}
+
+
+LOCAL void
+flush_bits (void)
+{
+  emit_bits((UINT16) 0x7F, 7); /* fill any partial byte with ones */
+  huff_put_buffer = 0;         /* and reset bit-buffer to empty */
+  huff_put_bits = 0;
+}
+
+
+
+/* Encode a single block's worth of coefficients */
+/* Note that the DC coefficient has already been converted to a difference */
+
+LOCAL void
+encode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
+{
+  register INT32 temp;
+  register int nbits;
+  register int k, r, i;
+  
+  /* Encode the DC coefficient difference per section 7.3.5.1 */
+  
+  /* Find the number of bits needed for the magnitude of the coefficient */
+  temp = block[0];
+  if (temp < 0) temp = -temp;
+  
+  nbits = 0;
+  while (temp) {
+    nbits++;
+    temp >>= 1;
+  }
+  
+  /* Emit the Huffman-coded symbol for the number of bits */
+  emit_bits(dctbl->ehufco[nbits], dctbl->ehufsi[nbits]);
+  
+  /* If positive, emit nbits low order bits; */
+  /* if negative, emit nbits low order bits of value-1 */
+  if ((temp = block[0]) < 0)
+    temp--;
+  
+  emit_bits((UINT16) temp, nbits);
+  
+  /* Encode the AC coefficients per section 7.3.5.2 */
+  
+  r = 0;                       /* r = run length of zeros */
+  
+  for (k = 1; k < DCTSIZE2; k++) {
+    if ((temp = block[k]) == 0) {
+      r++;
+    } else {
+      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+      while (r > 15) {
+       emit_bits(actbl->ehufco[0xF0], actbl->ehufsi[0xF0]);
+       r -= 16;
+      }
+      
+      /* Find the number of bits needed for the magnitude of the coefficient */
+      if (temp < 0) temp = -temp;
+
+      nbits = 1;               /* there must be at least one 1 bit */
+      while (temp >>= 1)
+       nbits++;
+      
+      /* Emit Huffman symbol for run length / number of bits */
+      i = (r << 4) + nbits;
+      emit_bits(actbl->ehufco[i], actbl->ehufsi[i]);
+      
+      /* If positive, emit nbits low order bits; */
+      /* if negative, emit nbits low order bits of value-1 */
+      if ((temp = block[k]) < 0)
+       temp--;
+      
+      emit_bits((UINT16) temp, nbits);
+      
+      r = 0;
+    }
+  }
+
+  /* If the last coef(s) were zero, emit an end-of-block code */
+  if (r > 0)
+    emit_bits(actbl->ehufco[0], actbl->ehufsi[0]);
+}
+
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ * This is invoked after writing the SOS marker.
+ * The pipeline controller must establish the entropy_output method pointer
+ * before calling this routine.
+ */
+
+METHODDEF void
+huff_init (compress_info_ptr xinfo)
+{
+  short ci;
+  jpeg_component_info * compptr;
+
+  /* Initialize static variables */
+  cinfo = xinfo;
+  huff_put_buffer = 0;
+  huff_put_bits = 0;
+
+  /* Initialize the output buffer */
+  output_buffer = (char *) (*cinfo->emethods->alloc_small)
+                               ((size_t) JPEG_BUF_SIZE);
+  bytes_in_buffer = 0;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    /* Make sure requested tables are present */
+    if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
+       cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
+      ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
+    /* Compute derived values for Huffman tables */
+    /* We may do this more than once for same table, but it's not a big deal */
+    fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
+    fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
+    /* Initialize DC predictions to 0 */
+    cinfo->last_dc_val[ci] = 0;
+  }
+
+  /* Initialize restart stuff */
+  cinfo->restarts_to_go = cinfo->restart_interval;
+  cinfo->next_restart_num = 0;
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL void
+emit_restart (compress_info_ptr cinfo)
+{
+  short ci;
+
+  flush_bits();
+
+  emit_byte(0xFF);
+  emit_byte(RST0 + cinfo->next_restart_num);
+
+  /* Re-initialize DC predictions to 0 */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+    cinfo->last_dc_val[ci] = 0;
+
+  /* Update restart state */
+  cinfo->restarts_to_go = cinfo->restart_interval;
+  cinfo->next_restart_num++;
+  cinfo->next_restart_num &= 7;
+}
+
+
+/*
+ * Encode and output one MCU's worth of Huffman-compressed coefficients.
+ */
+
+METHODDEF void
+huff_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
+{
+  short blkn, ci;
+  jpeg_component_info * compptr;
+  JCOEF temp;
+
+  /* Account for restart interval, emit restart marker if needed */
+  if (cinfo->restart_interval) {
+    if (cinfo->restarts_to_go == 0)
+      emit_restart(cinfo);
+    cinfo->restarts_to_go--;
+  }
+
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+    /* Convert DC value to difference, update last_dc_val */
+    temp = MCU_data[blkn][0];
+    MCU_data[blkn][0] -= cinfo->last_dc_val[ci];
+    cinfo->last_dc_val[ci] = temp;
+    encode_one_block(MCU_data[blkn],
+                    cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no],
+                    cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
+  }
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed scan.
+ */
+
+METHODDEF void
+huff_term (compress_info_ptr cinfo)
+{
+  /* Flush out the last data */
+  flush_bits();
+  flush_bytes();
+  /* Release the I/O buffer */
+  (*cinfo->emethods->free_small) ((void *) output_buffer);
+}
+
+
+
+\f
+/*
+ * Huffman coding optimization.
+ *
+ * This actually is optimization, in the sense that we find the best possible
+ * Huffman table(s) for the given data.  We first scan the supplied data and
+ * count the number of uses of each symbol that is to be Huffman-coded.
+ * (This process must agree with the code above.)  Then we build an
+ * optimal Huffman coding tree for the observed counts.
+ */
+
+#ifdef ENTROPY_OPT_SUPPORTED
+
+
+/* These are static so htest_one_block can find 'em */
+static long * dc_count_ptrs[NUM_HUFF_TBLS];
+static long * ac_count_ptrs[NUM_HUFF_TBLS];
+
+
+LOCAL void
+gen_huff_coding (compress_info_ptr cinfo, HUFF_TBL *htbl, long freq[])
+/* Generate the optimal coding for the given counts */
+{
+#define MAX_CLEN 32            /* assumed maximum initial code length */
+  UINT8 bits[MAX_CLEN+1];      /* bits[k] = # of symbols with code length k */
+  short codesize[257];         /* codesize[k] = code length of symbol k */
+  short others[257];           /* next symbol in current branch of tree */
+  int c1, c2;
+  int p, i, j;
+  long v;
+
+  /* This algorithm is explained in section 13.2 of JPEG-8-R8 */
+
+  MEMZERO((void *) bits, SIZEOF(bits));
+  MEMZERO((void *) codesize, SIZEOF(codesize));
+  for (i = 0; i < 257; i++)
+    others[i] = -1;            /* init links to empty */
+  
+  freq[256] = 1;               /* make sure there is a nonzero count */
+  /* including the pseudo-symbol 256 in the Huffman procedure guarantees
+   * that no real symbol is given code-value of all ones, because 256
+   * will be placed in the largest codeword category.
+   */
+
+  /* Huffman's basic algorithm to assign optimal code lengths to symbols */
+
+  for (;;) {
+    /* Find the smallest nonzero frequency, set c1 = its symbol */
+    /* In case of ties, take the larger symbol number */
+    c1 = -1;
+    v = 1000000000L;
+    for (i = 0; i <= 256; i++) {
+      if (freq[i] && freq[i] <= v) {
+       v = freq[i];
+       c1 = i;
+      }
+    }
+
+    /* Find the next smallest nonzero frequency, set c2 = its symbol */
+    /* In case of ties, take the larger symbol number */
+    c2 = -1;
+    v = 1000000000L;
+    for (i = 0; i <= 256; i++) {
+      if (freq[i] && freq[i] <= v && i != c1) {
+       v = freq[i];
+       c2 = i;
+      }
+    }
+
+    /* Done if we've merged everything into one frequency */
+    if (c2 < 0)
+      break;
+    
+    /* Else merge the two counts/trees */
+    freq[c1] += freq[c2];
+    freq[c2] = 0;
+
+    /* Increment the codesize of everything in c1's tree branch */
+    codesize[c1]++;
+    while (others[c1] >= 0) {
+      c1 = others[c1];
+      codesize[c1]++;
+    }
+    
+    others[c1] = c2;           /* chain c2 onto c1's tree branch */
+    
+    /* Increment the codesize of everything in c2's tree branch */
+    codesize[c2]++;
+    while (others[c2] >= 0) {
+      c2 = others[c2];
+      codesize[c2]++;
+    }
+  }
+
+  /* Now count the number of symbols of each code length */
+  for (i = 0; i <= 256; i++) {
+    if (codesize[i]) {
+      /* The JPEG standard seems to think that this can't happen, */
+      /* but I'm paranoid... */
+      if (codesize[i] > MAX_CLEN)
+       ERREXIT(cinfo->emethods, "Huffman code size table overflow");
+
+      bits[codesize[i]]++;
+    }
+  }
+
+  /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
+   * Huffman procedure assigned any such lengths, we must adjust the coding.
+   * Here is what the JPEG spec says about how this next bit works:
+   * Since symbols are paired for the longest Huffman code, the symbols are
+   * removed from this length category two at a time.  The prefix for the pair
+   * (which is one bit shorter) is allocated to one of the pair; then,
+   * skipping the BITS entry for that prefix length, a code word from the next
+   * shortest nonzero BITS entry is converted into a prefix for two code words
+   * one bit longer.
+   */
+  
+  for (i = MAX_CLEN; i > 16; i--) {
+    while (bits[i] > 0) {
+      j = i - 2;               /* find length of new prefix to be used */
+      while (bits[j] == 0)
+       j--;
+      
+      bits[i] -= 2;            /* remove two symbols */
+      bits[i-1]++;             /* one goes in this length */
+      bits[j+1] += 2;          /* two new symbols in this length */
+      bits[j]--;               /* symbol of this length is now a prefix */
+    }
+  }
+
+  /* Remove the count for the pseudo-symbol 256 from the largest codelength */
+  while (bits[i] == 0)         /* find largest codelength still in use */
+    i--;
+  bits[i]--;
+  
+  /* Return final symbol counts (only for lengths 0..16) */
+  memcpy((void *) htbl->bits, (void *) bits, SIZEOF(htbl->bits));
+  
+  /* Return a list of the symbols sorted by code length */
+  /* It's not real clear to me why we don't need to consider the codelength
+   * changes made above, but the JPEG spec seems to think this works.
+   */
+  p = 0;
+  for (i = 1; i <= MAX_CLEN; i++) {
+    for (j = 0; j <= 255; j++) {
+      if (codesize[j] == i) {
+       htbl->huffval[p] = j;
+       p++;
+      }
+    }
+  }
+}
+
+
+/* Process a single block's worth of coefficients */
+/* Note that the DC coefficient has already been converted to a difference */
+
+LOCAL void
+htest_one_block (JBLOCK block, JCOEF block0,
+                long dc_counts[], long ac_counts[])
+{
+  register INT32 temp;
+  register int nbits;
+  register int k, r;
+  
+  /* Encode the DC coefficient difference per section 7.3.5.1 */
+  
+  /* Find the number of bits needed for the magnitude of the coefficient */
+  temp = block0;
+  if (temp < 0) temp = -temp;
+  
+  for (nbits = 0; temp; nbits++)
+    temp >>= 1;
+  
+  /* Count the Huffman symbol for the number of bits */
+  dc_counts[nbits]++;
+  
+  /* Encode the AC coefficients per section 7.3.5.2 */
+  
+  r = 0;                       /* r = run length of zeros */
+  
+  for (k = 1; k < DCTSIZE2; k++) {
+    if ((temp = block[k]) == 0) {
+      r++;
+    } else {
+      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+      while (r > 15) {
+       ac_counts[0xF0]++;
+       r -= 16;
+      }
+      
+      /* Find the number of bits needed for the magnitude of the coefficient */
+      if (temp < 0) temp = -temp;
+      
+      for (nbits = 0; temp; nbits++)
+       temp >>= 1;
+      
+      /* Count Huffman symbol for run length / number of bits */
+      ac_counts[(r << 4) + nbits]++;
+      
+      r = 0;
+    }
+  }
+
+  /* If the last coef(s) were zero, emit an end-of-block code */
+  if (r > 0)
+    ac_counts[0]++;
+}
+
+
+
+/*
+ * Trial-encode one MCU's worth of Huffman-compressed coefficients.
+ */
+
+LOCAL void
+htest_encode (compress_info_ptr cinfo, JBLOCK *MCU_data)
+{
+  short blkn, ci;
+  jpeg_component_info * compptr;
+
+  /* Take care of restart intervals if needed */
+  if (cinfo->restart_interval) {
+    if (cinfo->restarts_to_go == 0) {
+      /* Re-initialize DC predictions to 0 */
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+       cinfo->last_dc_val[ci] = 0;
+      /* Update restart state */
+      cinfo->restarts_to_go = cinfo->restart_interval;
+    }
+    cinfo->restarts_to_go--;
+  }
+
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+    /* NB: unlike the real entropy encoder, we may not change the input data */
+    htest_one_block(MCU_data[blkn],
+                   (JCOEF) (MCU_data[blkn][0] - cinfo->last_dc_val[ci]),
+                   dc_count_ptrs[compptr->dc_tbl_no],
+                   ac_count_ptrs[compptr->ac_tbl_no]);
+    cinfo->last_dc_val[ci] = MCU_data[blkn][0];
+  }
+}
+
+
+
+/*
+ * Find the best coding parameters for a Huffman-coded scan.
+ * When called, the scan data has already been converted to a sequence of
+ * MCU groups of quantized coefficients, which are stored in a "big" array.
+ * The source_method knows how to iterate through that array.
+ * On return, the MCU data is unmodified, but the Huffman tables referenced
+ * by the scan components may have been altered.
+ */
+
+METHODDEF void
+huff_optimize (compress_info_ptr cinfo, MCU_output_caller_ptr source_method)
+/* Optimize Huffman-coding parameters (Huffman symbol table) */
+{
+  int i, tbl;
+  HUFF_TBL **htblptr;
+
+  /* Allocate and zero the count tables */
+  /* Note that gen_huff_coding expects 257 entries in each table! */
+
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    dc_count_ptrs[i] = NULL;
+    ac_count_ptrs[i] = NULL;
+  }
+
+  for (i = 0; i < cinfo->comps_in_scan; i++) {
+    /* Create DC table */
+    tbl = cinfo->cur_comp_info[i]->dc_tbl_no;
+    if (dc_count_ptrs[tbl] == NULL) {
+      dc_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
+                                       (257 * SIZEOF(long));
+      MEMZERO((void *) dc_count_ptrs[tbl], 257 * SIZEOF(long));
+    }
+    /* Create AC table */
+    tbl = cinfo->cur_comp_info[i]->ac_tbl_no;
+    if (ac_count_ptrs[tbl] == NULL) {
+      ac_count_ptrs[tbl] = (long *) (*cinfo->emethods->alloc_small)
+                                       (257 * SIZEOF(long));
+      MEMZERO((void *) ac_count_ptrs[tbl], 257 * SIZEOF(long));
+    }
+  }
+
+  /* Initialize DC predictions to 0 */
+  for (i = 0; i < cinfo->comps_in_scan; i++) {
+    cinfo->last_dc_val[i] = 0;
+  }
+  /* Initialize restart stuff */
+  cinfo->restarts_to_go = cinfo->restart_interval;
+
+  /* Scan the MCU data, count symbol uses */
+  (*source_method) (cinfo, htest_encode);
+
+  /* Now generate optimal Huffman tables */
+  for (tbl = 0; tbl < NUM_HUFF_TBLS; tbl++) {
+    if (dc_count_ptrs[tbl] != NULL) {
+      htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
+      if (*htblptr == NULL)
+       *htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
+      /* Set sent_table FALSE so updated table will be written to JPEG file. */
+      (*htblptr)->sent_table = FALSE;
+      /* Compute the optimal Huffman encoding */
+      gen_huff_coding(cinfo, *htblptr, dc_count_ptrs[tbl]);
+      /* Release the count table */
+      (*cinfo->emethods->free_small) ((void *) dc_count_ptrs[tbl]);
+    }
+    if (ac_count_ptrs[tbl] != NULL) {
+      htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
+      if (*htblptr == NULL)
+       *htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
+      /* Set sent_table FALSE so updated table will be written to JPEG file. */
+      (*htblptr)->sent_table = FALSE;
+      /* Compute the optimal Huffman encoding */
+      gen_huff_coding(cinfo, *htblptr, ac_count_ptrs[tbl]);
+      /* Release the count table */
+      (*cinfo->emethods->free_small) ((void *) ac_count_ptrs[tbl]);
+    }
+  }
+}
+
+
+#endif /* ENTROPY_OPT_SUPPORTED */
+
+
+/*
+ * The method selection routine for Huffman entropy encoding.
+ */
+
+GLOBAL void
+jselchuffman (compress_info_ptr cinfo)
+{
+  if (! cinfo->arith_code) {
+    cinfo->methods->entropy_encoder_init = huff_init;
+    cinfo->methods->entropy_encode = huff_encode;
+    cinfo->methods->entropy_encoder_term = huff_term;
+#ifdef ENTROPY_OPT_SUPPORTED
+    cinfo->methods->entropy_optimize = huff_optimize;
+#endif
+  }
+}
diff --git a/jcmain.c b/jcmain.c
new file mode 100644 (file)
index 0000000..f71d5ad
--- /dev/null
+++ b/jcmain.c
@@ -0,0 +1,272 @@
+/*
+ * jcmain.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a trivial test user interface for the JPEG compressor.
+ * It should work on any system with Unix- or MS-DOS-style command lines.
+ *
+ * Two different command line styles are permitted, depending on the
+ * compile-time switch TWO_FILE_COMMANDLINE:
+ *     cjpeg [options]  inputfile outputfile
+ *     cjpeg [options]  [inputfile]
+ * In the second style, output is always to standard output, which you'd
+ * normally redirect to a file or pipe to some other program.  Input is
+ * either from a named file or from standard input (typically redirected).
+ * The second style is convenient on Unix but is unhelpful on systems that
+ * don't support pipes.  Also, you MUST use the first style if your system
+ * doesn't do binary I/O to stdin/stdout.
+ */
+
+#include "jinclude.h"
+#ifdef __STDC__
+#include <stdlib.h>            /* to declare exit() */
+#endif
+
+#ifdef THINK_C
+#include <console.h>           /* command-line reader for Macintosh */
+#endif
+
+#ifdef DONT_USE_B_MODE         /* define mode parameters for fopen() */
+#define READ_BINARY    "r"
+#define WRITE_BINARY   "w"
+#else
+#define READ_BINARY    "rb"
+#define WRITE_BINARY   "wb"
+#endif
+
+
+/*
+ * If your system has getopt(3), you can use your library version by
+ * defining HAVE_GETOPT.  By default, we use the PD 'egetopt'.
+ */
+
+#ifdef HAVE_GETOPT
+extern int getopt PP((int argc, char **argv, char *optstring));
+extern char * optarg;
+extern int optind;
+#else
+#include "egetopt.c"
+#define getopt(argc,argv,opt)  egetopt(argc,argv,opt)
+#endif
+
+
+/*
+ * This routine determines what format the input file is,
+ * and selects the appropriate input-reading module.
+ *
+ * To determine which family of input formats the file belongs to,
+ * we look only at the first byte of the file, since C does not
+ * guarantee that more than one character can be pushed back with ungetc.
+ * This is sufficient for the currently envisioned set of input formats.
+ *
+ * If you need to look at more than one character to select an input module,
+ * you can either
+ *     1) assume you can fseek() the input file (may fail for piped input);
+ *     2) assume you can push back more than one character (works in
+ *        some C implementations, but unportable);
+ * or  3) don't put back the data, and modify the various input_init
+ *        methods to assume they start reading after the start of file.
+ */
+
+LOCAL void
+select_file_type (compress_info_ptr cinfo)
+{
+  int c;
+
+  if ((c = getc(cinfo->input_file)) == EOF)
+    ERREXIT(cinfo->emethods, "Empty input file");
+
+  switch (c) {
+#ifdef GIF_SUPPORTED
+  case 'G':
+    jselrgif(cinfo);
+    break;
+#endif
+#ifdef PPM_SUPPORTED
+  case 'P':
+    jselrppm(cinfo);
+    break;
+#endif
+  default:
+    ERREXIT(cinfo->emethods, "Unsupported input file format");
+    break;
+  }
+
+  if (ungetc(c, cinfo->input_file) == EOF)
+    ERREXIT(cinfo->emethods, "ungetc failed");
+}
+
+
+/*
+ * This routine gets control after the input file header has been read.
+ * It must determine what output JPEG file format is to be written,
+ * and make any other compression parameter changes that are desirable.
+ */
+
+METHODDEF void
+c_ui_method_selection (compress_info_ptr cinfo)
+{
+  /* If the input is gray scale, generate a monochrome JPEG file. */
+  if (cinfo->in_color_space == CS_GRAYSCALE)
+    j_monochrome_default(cinfo);
+  /* For now, always select JFIF output format. */
+#ifdef JFIF_SUPPORTED
+  jselwjfif(cinfo);
+#else
+  You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
+#endif
+}
+
+
+LOCAL void
+usage (char * progname)
+/* complain about bad command line */
+{
+  fprintf(stderr, "usage: %s ", progname);
+  fprintf(stderr, "[-I] [-Q quality 0..100] [-a] [-o] [-d]");
+#ifdef TWO_FILE_COMMANDLINE
+  fprintf(stderr, " inputfile outputfile\n");
+#else
+  fprintf(stderr, " [inputfile]\n");
+#endif
+  exit(2);
+}
+
+
+/*
+ * The main program.
+ */
+
+GLOBAL void
+main (int argc, char **argv)
+{
+  struct compress_info_struct cinfo;
+  struct compress_methods_struct c_methods;
+  struct external_methods_struct e_methods;
+  int c;
+
+  /* On Mac, fetch a command line. */
+#ifdef THINK_C
+  argc = ccommand(&argv);
+#endif
+
+  /* Initialize the system-dependent method pointers. */
+  cinfo.methods = &c_methods;
+  cinfo.emethods = &e_methods;
+  jselerror(&e_methods);       /* error/trace message routines */
+  jselvirtmem(&e_methods);     /* memory allocation routines */
+  c_methods.c_ui_method_selection = c_ui_method_selection;
+
+  /* Set up default input and output file references. */
+  /* (These may be overridden below.) */
+  cinfo.input_file = stdin;
+  cinfo.output_file = stdout;
+
+  /* Set up default parameters. */
+  e_methods.trace_level = 0;
+  j_default_compression(&cinfo, 75); /* default quality level */
+
+  /* Scan parameters */
+  
+  while ((c = getopt(argc, argv, "IQ:aod")) != EOF)
+    switch (c) {
+    case 'I':                  /* Create noninterleaved file. */
+#ifdef MULTISCAN_FILES_SUPPORTED
+      cinfo.interleave = FALSE;
+#else
+      fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n",
+             argv[0]);
+      exit(2);
+#endif
+      break;
+    case 'Q':                  /* Quality factor. */
+      { int val;
+       if (optarg == NULL)
+         usage(argv[0]);
+       if (sscanf(optarg, "%d", &val) != 1)
+         usage(argv[0]);
+       /* Note: for now, we leave force_baseline FALSE.
+        * In a production user interface, probably should make it TRUE
+        * unless overridden by a separate switch.
+        */
+       j_set_quality(&cinfo, val, FALSE);
+      }
+      break;
+    case 'a':                  /* Use arithmetic coding. */
+#ifdef ARITH_CODING_SUPPORTED
+      cinfo.arith_code = TRUE;
+#else
+      fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
+             argv[0]);
+      exit(2);
+#endif
+      break;
+    case 'o':                  /* Enable entropy parm optimization. */
+#ifdef ENTROPY_OPT_SUPPORTED
+      cinfo.optimize_coding = TRUE;
+#else
+      fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
+             argv[0]);
+      exit(2);
+#endif
+      break;
+    case 'd':                  /* Debugging. */
+      e_methods.trace_level++;
+      break;
+    case '?':
+    default:
+      usage(argv[0]);
+      break;
+    }
+
+  /* Select the input and output files */
+
+#ifdef TWO_FILE_COMMANDLINE
+
+  if (optind != argc-2) {
+    fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
+    usage(argv[0]);
+  }
+  if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
+    fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
+    exit(2);
+  }
+  if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
+    fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
+    exit(2);
+  }
+
+#else /* not TWO_FILE_COMMANDLINE -- use Unix style */
+
+  if (optind < argc-1) {
+    fprintf(stderr, "%s: only one input file\n", argv[0]);
+    usage(argv[0]);
+  }
+  if (optind < argc) {
+    if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
+      fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
+      exit(2);
+    }
+  }
+
+#endif /* TWO_FILE_COMMANDLINE */
+
+  /* Figure out the input file format, and set up to read it. */
+  select_file_type(&cinfo);
+
+  /* Do it to it! */
+  jpeg_compress(&cinfo);
+
+  /* Release memory. */
+  j_free_defaults(&cinfo);
+#ifdef MEM_STATS
+  if (e_methods.trace_level > 0)
+    j_mem_stats();
+#endif
+
+  /* All done. */
+  exit(0);
+}
diff --git a/jcmaster.c b/jcmaster.c
new file mode 100644 (file)
index 0000000..b15217a
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * jcmaster.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the main control for the JPEG compressor.
+ * The system-dependent (user interface) code should call jpeg_compress()
+ * after doing appropriate setup of the compress_info_struct parameter.
+ */
+
+#include "jinclude.h"
+
+
+METHODDEF void
+c_per_scan_method_selection (compress_info_ptr cinfo)
+/* Central point for per-scan method selection */
+{
+  /* Edge expansion */
+  jselexpand(cinfo);
+  /* Subsampling of pixels */
+  jselsubsample(cinfo);
+  /* MCU extraction */
+  jselcmcu(cinfo);
+}
+
+
+LOCAL void
+c_initial_method_selection (compress_info_ptr cinfo)
+/* Central point for initial method selection */
+{
+  /* Input image reading method selection is already done. */
+  /* So is output file header formatting (both are done by user interface). */
+
+  /* Gamma and color space conversion */
+  jselccolor(cinfo);
+  /* Entropy encoding: either Huffman or arithmetic coding. */
+#ifdef ARITH_CODING_SUPPORTED
+  jselcarithmetic(cinfo);
+#else
+  cinfo->arith_code = FALSE;   /* force Huffman mode */
+#endif
+  jselchuffman(cinfo);
+  /* Pipeline control */
+  jselcpipeline(cinfo);
+  /* Overall control (that's me!) */
+  cinfo->methods->c_per_scan_method_selection = c_per_scan_method_selection;
+}
+
+
+LOCAL void
+initial_setup (compress_info_ptr cinfo)
+/* Do computations that are needed before initial method selection */
+{
+  short ci;
+  jpeg_component_info *compptr;
+
+  /* Compute maximum sampling factors; check factor validity */
+  cinfo->max_h_samp_factor = 1;
+  cinfo->max_v_samp_factor = 1;
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    compptr = &cinfo->comp_info[ci];
+    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+       compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+      ERREXIT(cinfo->emethods, "Bogus sampling factors");
+    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+                                  compptr->h_samp_factor);
+    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+                                  compptr->v_samp_factor);
+
+  }
+
+  /* Compute logical subsampled dimensions of components */
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    compptr = &cinfo->comp_info[ci];
+    compptr->true_comp_width = (cinfo->image_width * compptr->h_samp_factor
+                               + cinfo->max_h_samp_factor - 1)
+                               / cinfo->max_h_samp_factor;
+    compptr->true_comp_height = (cinfo->image_height * compptr->v_samp_factor
+                                + cinfo->max_v_samp_factor - 1)
+                                / cinfo->max_v_samp_factor;
+  }
+}
+
+
+/*
+ * This is the main entry point to the JPEG compressor.
+ */
+
+
+GLOBAL void
+jpeg_compress (compress_info_ptr cinfo)
+{
+  /* Read the input file header: determine image size & component count.
+   * NOTE: the user interface must have initialized the input_init method
+   * pointer (eg, by calling jselrppm) before calling me.
+   * The other file reading methods (get_input_row etc.) were probably
+   * set at the same time, but could be set up by input_init itself,
+   * or by c_ui_method_selection.
+   */
+  (*cinfo->methods->input_init) (cinfo);
+
+  /* Give UI a chance to adjust compression parameters and select */
+  /* output file format based on results of input_init. */
+  (*cinfo->methods->c_ui_method_selection) (cinfo);
+
+  /* Now select methods for compression steps. */
+  initial_setup(cinfo);
+  c_initial_method_selection(cinfo);
+
+  /* Initialize the output file & other modules as needed */
+  /* (entropy_encoder is inited by pipeline controller) */
+
+  (*cinfo->methods->colorin_init) (cinfo);
+  (*cinfo->methods->write_file_header) (cinfo);
+
+  /* And let the pipeline controller do the rest. */
+  (*cinfo->methods->c_pipeline_controller) (cinfo);
+
+  /* Finish output file, release working storage, etc */
+  (*cinfo->methods->write_file_trailer) (cinfo);
+  (*cinfo->methods->colorin_term) (cinfo);
+  (*cinfo->methods->input_term) (cinfo);
+
+  /* My, that was easy, wasn't it? */
+}
diff --git a/jcmcu.c b/jcmcu.c
new file mode 100644 (file)
index 0000000..1400eab
--- /dev/null
+++ b/jcmcu.c
@@ -0,0 +1,212 @@
+/*
+ * jcmcu.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains MCU extraction routines and quantization scaling.
+ * These routines are invoked via the extract_MCUs and
+ * extract_init/term methods.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * If this file is compiled with -DDCT_ERR_STATS, it will reverse-DCT each
+ * block and sum the total errors across the whole picture.  This provides
+ * a convenient method of using real picture data to test the roundoff error
+ * of a DCT algorithm.  DCT_ERR_STATS should *not* be defined for a production
+ * compression program, since compression is much slower with it defined.
+ * Also note that jrevdct.o must be linked into the compressor when this
+ * switch is defined.
+ */
+
+#ifdef DCT_ERR_STATS
+static int dcterrorsum;                /* these hold the error statistics */
+static int dcterrormax;
+static int dctcoefcount;       /* This will probably overflow on a 16-bit-int machine */
+#endif
+
+
+/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
+
+static const short ZAG[DCTSIZE2] = {
+  0,  1,  8, 16,  9,  2,  3, 10,
+ 17, 24, 32, 25, 18, 11,  4,  5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13,  6,  7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+
+LOCAL void
+extract_block (JSAMPARRAY input_data, int start_row, long start_col,
+              JBLOCK output_data, QUANT_TBL_PTR quanttbl)
+/* Extract one 8x8 block from the specified location in the sample array; */
+/* perform forward DCT, quantization scaling, and zigzag reordering on it. */
+{
+  /* This routine is heavily used, so it's worth coding it tightly. */
+  DCTBLOCK block;
+#ifdef DCT_ERR_STATS
+  DCTBLOCK svblock;            /* saves input data for comparison */
+#endif
+
+  { register JSAMPROW elemptr;
+    register DCTELEM *localblkptr = block;
+#if DCTSIZE != 8
+    register short elemc;
+#endif
+    register short elemr;
+
+    for (elemr = DCTSIZE; elemr > 0; elemr--) {
+      elemptr = input_data[start_row++] + start_col;
+#if DCTSIZE == 8               /* unroll the inner loop */
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+#else
+      for (elemc = DCTSIZE; elemc > 0; elemc--) {
+       *localblkptr++ = (DCTELEM) GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+      }
+#endif
+    }
+  }
+
+#ifdef DCT_ERR_STATS
+  memcpy((void *) svblock, (void *) block, SIZEOF(DCTBLOCK));
+#endif
+
+  j_fwd_dct(block);
+
+  { register JCOEF temp;
+    register short i;
+
+    for (i = 0; i < DCTSIZE2; i++) {
+      temp = (JCOEF) block[ZAG[i]];
+      /* divide by *quanttbl, ensuring proper rounding */
+      if (temp < 0) {
+       temp = -temp;
+       temp += *quanttbl>>1;
+       temp /= *quanttbl;
+       temp = -temp;
+      } else {
+       temp += *quanttbl>>1;
+       temp /= *quanttbl;
+      }
+      *output_data++ = temp;
+      quanttbl++;
+    }
+  }
+
+#ifdef DCT_ERR_STATS
+  j_rev_dct(block);
+
+  { register int diff;
+    register short i;
+
+    for (i = 0; i < DCTSIZE2; i++) {
+      diff = block[i] - svblock[i];
+      if (diff < 0) diff = -diff;
+      dcterrorsum += diff;
+      if (dcterrormax < diff) dcterrormax = diff;
+    }
+    dctcoefcount += DCTSIZE2;
+  }
+#endif
+}
+
+
+/*
+ * Extract samples in MCU order, process & hand off to output_method.
+ * The input is always exactly N MCU rows worth of data.
+ */
+
+METHODDEF void
+extract_MCUs (compress_info_ptr cinfo,
+             JSAMPIMAGE image_data,
+             int num_mcu_rows,
+             MCU_output_method_ptr output_method)
+{
+  JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
+  int mcurow;
+  long mcuindex;
+  short blkn, ci, xpos, ypos;
+  jpeg_component_info * compptr;
+  QUANT_TBL_PTR quant_ptr;
+
+  for (mcurow = 0; mcurow < num_mcu_rows; mcurow++) {
+    for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
+      /* Extract data from the image array, DCT it, and quantize it */
+      blkn = 0;
+      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+       compptr = cinfo->cur_comp_info[ci];
+       quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
+       for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
+         for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
+           extract_block(image_data[ci],
+                         (mcurow * compptr->MCU_height + ypos)*DCTSIZE,
+                         (mcuindex * compptr->MCU_width + xpos)*DCTSIZE,
+                         MCU_data[blkn], quant_ptr);
+           blkn++;
+         }
+       }
+      }
+      /* Send the MCU whereever the pipeline controller wants it to go */
+      (*output_method) (cinfo, MCU_data);
+    }
+  }
+}
+
+
+/*
+ * Initialize for processing a scan.
+ */
+
+METHODDEF void
+extract_init (compress_info_ptr cinfo)
+{
+  /* no work for now */
+#ifdef DCT_ERR_STATS
+  dcterrorsum = dcterrormax = dctcoefcount = 0;
+#endif
+}
+
+
+/*
+ * Clean up after a scan.
+ */
+
+METHODDEF void
+extract_term (compress_info_ptr cinfo)
+{
+  /* no work for now */
+#ifdef DCT_ERR_STATS
+  TRACEMS3(cinfo->emethods, 0, "DCT roundoff errors = %d/%d,  max = %d",
+          dcterrorsum, dctcoefcount, dcterrormax);
+#endif
+}
+
+
+
+/*
+ * The method selection routine for MCU extraction.
+ */
+
+GLOBAL void
+jselcmcu (compress_info_ptr cinfo)
+{
+  /* just one implementation for now */
+  cinfo->methods->extract_init = extract_init;
+  cinfo->methods->extract_MCUs = extract_MCUs;
+  cinfo->methods->extract_term = extract_term;
+}
diff --git a/jconfig.h b/jconfig.h
new file mode 100644 (file)
index 0000000..3b22acb
--- /dev/null
+++ b/jconfig.h
@@ -0,0 +1,320 @@
+/*
+ * jconfig.h
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains preprocessor declarations that help customize
+ * the JPEG software for a particular application, machine, or compiler.
+ * Edit these declarations as needed (or add -D flags to the Makefile).
+ */
+
+
+/*
+ * These symbols indicate the properties of your machine or compiler.
+ * The conditional definitions given may do the right thing already,
+ * but you'd best look them over closely, especially if your compiler
+ * does not handle full ANSI C.  An ANSI-compliant C compiler should
+ * provide all the necessary features; __STDC__ is supposed to be
+ * predefined by such compilers.
+ */
+
+/* Does your compiler support function prototypes? */
+/* (If not, you also need to use ansi2knr, see README) */
+
+#ifdef __STDC__                        /* ANSI C compilers always have prototypes */
+#define PROTO
+#else
+#ifdef __cplusplus             /* So do C++ compilers */
+#define PROTO
+#endif
+#endif
+
+/* Does your compiler support the declaration "unsigned char" ? */
+/* How about "unsigned short" ? */
+
+#ifdef __STDC__                        /* ANSI C compilers must support both */
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+#endif
+
+/* Define this if an ordinary "char" type is unsigned.
+ * If you're not sure, leaving it undefined will work at some cost in speed.
+ * If you defined HAVE_UNSIGNED_CHAR then it doesn't matter very much.
+ */
+
+/* #define CHAR_IS_UNSIGNED */
+
+/* Define this if your compiler implements ">>" on signed values as a logical
+ * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
+ * which is the normal and rational definition.
+ * The DCT and IDCT routines will compute wrong values if you get this wrong!
+ */
+
+/* #define RIGHT_SHIFT_IS_UNSIGNED */
+
+/* Define "void" as "char" if your compiler doesn't know about type void.
+ * NOTE: be sure to define void such that "void *" represents the most general
+ * pointer type, e.g., that returned by malloc().
+ */
+
+/* #define void char */
+
+/* Define const as empty if your compiler doesn't know the "const" keyword. */
+/* (Even if it does, defining const as empty won't break anything.) */
+
+#ifndef __STDC__               /* ANSI C and C++ compilers should know it. */
+#ifndef __cplusplus
+#define const
+#endif
+#endif
+
+/* For 80x86 machines, you need to define NEED_FAR_POINTERS,
+ * unless you are using a large-data memory model or 80386 flat-memory mode.
+ * On less brain-damaged CPUs this symbol must not be defined.
+ * (Defining this symbol causes large data structures to be referenced through
+ * "far" pointers and to be allocated with a special version of malloc.)
+ */
+
+#ifdef MSDOS                   /* Microsoft C and compatibles */
+#define NEED_FAR_POINTERS
+#else
+#ifdef __TURBOC__              /* Turbo C doesn't define MSDOS */
+#define NEED_FAR_POINTERS
+#endif
+#endif
+
+
+/* The next couple of symbols only affect the system-dependent user interface
+ * modules (jcmain.c, jdmain.c).  You can ignore these if you are supplying
+ * your own user interface code.
+ */
+
+/* Define this if you want to name both input and output files on the command
+ * line, rather than using stdout and optionally stdin.  You MUST do this if
+ * your system can't cope with binary I/O to stdin/stdout.  See comments at
+ * head of jcmain.c or jdmain.c.
+ */
+
+#ifdef MSDOS                   /* two-file style is needed for PCs */
+#define TWO_FILE_COMMANDLINE
+#else
+#ifdef __TURBOC__              /* Turbo C doesn't define MSDOS */
+#define TWO_FILE_COMMANDLINE
+#endif
+#endif
+#ifdef THINK_C                 /* needed for Macintosh too */
+#define TWO_FILE_COMMANDLINE
+#endif
+
+/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
+ * This is necessary on systems that distinguish text files from binary files,
+ * and is harmless on most systems that don't.  If you have one of the rare
+ * systems that complains about the "b" spec, define this symbol.
+ */
+
+/* #define DONT_USE_B_MODE */
+
+
+/* If you're getting bored, that's the end of the symbols you HAVE to
+ * worry about.  Go fix the makefile and compile.
+ */
+
+
+/* If your compiler supports inline functions, define INLINE as
+ * the inline keyword; otherwise define it as empty.
+ */
+
+#ifdef __GNUC__                        /* GNU C has inline... */
+#define INLINE inline
+#else                          /* ...but I don't think anyone else does. */
+#define INLINE
+#endif
+
+/* On a few systems, type boolean and/or macros FALSE, TRUE may appear
+ * in standard header files.  Or you may have conflicts with application-
+ * specific header files that you want to include together with these files.
+ * In that case you need only comment out these definitions.
+ */
+
+typedef int boolean;
+#define FALSE  0               /* values of boolean */
+#define TRUE   1
+
+/* This defines the size of the I/O buffers for entropy compression
+ * and decompression; you could reduce it if memory is tight.
+ */
+
+#define JPEG_BUF_SIZE  4096 /* bytes */
+
+
+
+/* These symbols determine the JPEG functionality supported. */
+
+/*
+ * These defines indicate whether to include various optional functions.
+ * Undefining some of these symbols will produce a smaller but less capable
+ * program file.  Note that you can leave certain source files out of the
+ * compilation/linking process if you've #undef'd the corresponding symbols.
+ * (You may HAVE to do that if your compiler doesn't like null source files.)
+ */
+
+/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
+#undef  ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
+#define MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define ENTROPY_OPT_SUPPORTED  /* Optimization of entropy coding parms? */
+#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing during decoding? */
+#define QUANT_1PASS_SUPPORTED  /* 1-pass color quantization? */
+#undef  QUANT_2PASS_SUPPORTED  /* 2-pass color quantization? (not yet impl.) */
+/* these defines indicate which JPEG file formats are allowed */
+#define JFIF_SUPPORTED         /* JFIF or "raw JPEG" files */
+#undef  JTIFF_SUPPORTED                /* JPEG-in-TIFF (not yet implemented) */
+/* these defines indicate which image (non-JPEG) file formats are allowed */
+#define PPM_SUPPORTED          /* PPM/PGM image file format */
+#define GIF_SUPPORTED          /* GIF image file format */
+#undef  TIFF_SUPPORTED         /* TIFF image file format (not yet impl.) */
+
+/* more capability options later, no doubt */
+
+
+/*
+ * Define exactly one of these three symbols to indicate whether you want
+ * 8-bit, 12-bit, or 16-bit sample (pixel component) values.  8-bit is the
+ * default and is nearly always the right thing to use.  You can use 12-bit if
+ * you need to support image formats with more than 8 bits of resolution in a
+ * color value.  16-bit should only be used for the lossless JPEG mode (not
+ * currently supported).  Note that 12- and 16-bit values take up twice as
+ * much memory as 8-bit!
+ */
+
+#define EIGHT_BIT_SAMPLES
+#undef  TWELVE_BIT_SAMPLES
+#undef  SIXTEEN_BIT_SAMPLES
+
+
+
+/*
+ * The remaining definitions don't need to be hand-edited in most cases.
+ * You may need to change these if you have a machine with unusual data
+ * types; for example, "char" not 8 bits, "short" not 16 bits,
+ * or "long" not 32 bits.  We don't care whether "int" is 16 or 32 bits,
+ * but it had better be at least 16.
+ */
+
+/* First define the representation of a single pixel element value. */
+
+#ifdef EIGHT_BIT_SAMPLES
+/* JSAMPLE should be the smallest type that will hold the values 0..255.
+ * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
+ * If you have only signed chars, and you are more worried about speed than
+ * memory usage, it might be a win to make JSAMPLE be short.
+ */
+
+#ifdef HAVE_UNSIGNED_CHAR
+
+typedef unsigned char JSAMPLE;
+#define GETJSAMPLE(value)  (value)
+
+#else /* not HAVE_UNSIGNED_CHAR */
+#ifdef CHAR_IS_UNSIGNED
+
+typedef char JSAMPLE;
+#define GETJSAMPLE(value)  (value)
+
+#else /* not CHAR_IS_UNSIGNED */
+
+typedef char JSAMPLE;
+#define GETJSAMPLE(value)  ((value) & 0xFF)
+
+#endif /* CHAR_IS_UNSIGNED */
+#endif /* HAVE_UNSIGNED_CHAR */
+
+#define MAXJSAMPLE     255
+#define CENTERJSAMPLE  128
+
+#endif /* EIGHT_BIT_SAMPLES */
+
+
+#ifdef TWELVE_BIT_SAMPLES
+/* JSAMPLE should be the smallest type that will hold the values 0..4095. */
+/* On nearly all machines "short" will do nicely. */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value)  (value)
+
+#define MAXJSAMPLE     4095
+#define CENTERJSAMPLE  2048
+
+#endif /* TWELVE_BIT_SAMPLES */
+
+
+#ifdef SIXTEEN_BIT_SAMPLES
+/* JSAMPLE should be the smallest type that will hold the values 0..65535. */
+
+#ifdef HAVE_UNSIGNED_SHORT
+
+typedef unsigned short JSAMPLE;
+#define GETJSAMPLE(value)  (value)
+
+#else /* not HAVE_UNSIGNED_SHORT */
+
+/* If int is 32 bits this'll be horrendously inefficient storage-wise.
+ * But since we don't actually support 16-bit samples (ie lossless coding) yet,
+ * I'm not going to worry about making a smarter definition ...
+ */
+typedef unsigned int JSAMPLE;
+#define GETJSAMPLE(value)  (value)
+
+#endif /* HAVE_UNSIGNED_SHORT */
+
+#define MAXJSAMPLE     65535
+#define CENTERJSAMPLE  32768
+
+#endif /* SIXTEEN_BIT_SAMPLES */
+
+
+/* Here we define the representation of a DCT frequency coefficient.
+ * This should be a signed 16-bit value; "short" is usually right.
+ * It's important that this be exactly 16 bits, no more and no less;
+ * more will cost you a BIG hit of memory, less will give wrong answers.
+ */
+
+typedef short JCOEF;
+
+
+/* The remaining typedefs are used for various table entries and so forth.
+ * They must be at least as wide as specified; but making them too big
+ * won't cost a huge amount of memory, so we don't provide special
+ * extraction code like we did for JSAMPLE.  (In other words, these
+ * typedefs live at a different point on the speed/space tradeoff curve.)
+ */
+
+/* UINT8 must hold at least the values 0..255. */
+
+#ifdef HAVE_UNSIGNED_CHAR
+typedef unsigned char UINT8;
+#else /* not HAVE_UNSIGNED_CHAR */
+#ifdef CHAR_IS_UNSIGNED
+typedef char UINT8;
+#else /* not CHAR_IS_UNSIGNED */
+typedef short UINT8;
+#endif /* CHAR_IS_UNSIGNED */
+#endif /* HAVE_UNSIGNED_CHAR */
+
+/* UINT16 must hold at least the values 0..65535. */
+
+#ifdef HAVE_UNSIGNED_SHORT
+typedef unsigned short UINT16;
+#else /* not HAVE_UNSIGNED_SHORT */
+typedef unsigned int UINT16;
+#endif /* HAVE_UNSIGNED_SHORT */
+
+/* INT16 must hold at least the values -32768..32767. */
+
+typedef short INT16;
+
+/* INT32 must hold signed 32-bit values; if your machine happens */
+/* to have 64-bit longs, you might want to change this. */
+
+typedef long INT32;
diff --git a/jcpipe.c b/jcpipe.c
new file mode 100644 (file)
index 0000000..f58e7db
--- /dev/null
+++ b/jcpipe.c
@@ -0,0 +1,715 @@
+/*
+ * jcpipe.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains compression pipeline controllers.
+ * These routines are invoked via the c_pipeline_controller method.
+ *
+ * There are four basic pipeline controllers, one for each combination of:
+ *     single-scan JPEG file (single component or fully interleaved)
+ *  vs. multiple-scan JPEG file (noninterleaved or partially interleaved).
+ *
+ *     optimization of entropy encoding parameters
+ *  vs. usage of default encoding parameters.
+ *
+ * Note that these conditions determine the needs for "big" arrays:
+ * multiple scans imply a big array for splitting the color components;
+ * entropy encoding optimization needs a big array for the MCU data.
+ *
+ * All but the simplest controller (single-scan, no optimization) can be
+ * compiled out through configuration options, if you need to make a minimal
+ * implementation.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * About the data structures:
+ *
+ * The processing chunk size for subsampling is referred to in this file as
+ * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
+ * any component after subsampling, or Vmax (max_v_samp_factor) unsubsampled
+ * rows.  In an interleaved scan each MCU row contains exactly DCTSIZE row
+ * groups of each component in the scan.  In a noninterleaved scan an MCU row
+ * is one row of blocks, which might not be an integral number of row groups;
+ * for convenience we use a buffer of the same size as in interleaved scans,
+ * and process Vk MCU rows in each burst of subsampling.
+ * To provide context for the subsampling step, we have to retain the last
+ * two row groups of the previous MCU row while reading in the next MCU row
+ * (or set of Vk MCU rows).  To do this without copying data about, we create
+ * a rather strange data structure.  Exactly DCTSIZE+2 row groups of samples
+ * are allocated, but we create two different sets of pointers to this array.
+ * The second set swaps the last two pairs of row groups.  By working
+ * alternately with the two sets of pointers, we can access the data in the
+ * desired order.
+ */
+
+
+
+/*
+ * Utility routines: common code for pipeline controllers
+ */
+
+LOCAL void
+interleaved_scan_setup (compress_info_ptr cinfo)
+/* Compute all derived info for an interleaved (multi-component) scan */
+/* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
+{
+  short ci, mcublks;
+  jpeg_component_info *compptr;
+
+  if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+    ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
+
+  cinfo->MCUs_per_row = (cinfo->image_width
+                        + cinfo->max_h_samp_factor*DCTSIZE - 1)
+                       / (cinfo->max_h_samp_factor*DCTSIZE);
+
+  cinfo->MCU_rows_in_scan = (cinfo->image_height
+                            + cinfo->max_v_samp_factor*DCTSIZE - 1)
+                           / (cinfo->max_v_samp_factor*DCTSIZE);
+  
+  cinfo->blocks_in_MCU = 0;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    /* for interleaved scan, sampling factors give # of blocks per component */
+    compptr->MCU_width = compptr->h_samp_factor;
+    compptr->MCU_height = compptr->v_samp_factor;
+    compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+    /* compute physical dimensions of component */
+    compptr->subsampled_width = jround_up(compptr->true_comp_width,
+                                         (long) (compptr->MCU_width*DCTSIZE));
+    compptr->subsampled_height = jround_up(compptr->true_comp_height,
+                                          (long) (compptr->MCU_height*DCTSIZE));
+    /* Sanity check */
+    if (compptr->subsampled_width !=
+       (cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
+      ERREXIT(cinfo->emethods, "I'm confused about the image width");
+    /* Prepare array describing MCU composition */
+    mcublks = compptr->MCU_blocks;
+    if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
+      ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
+    while (mcublks-- > 0) {
+      cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+    }
+  }
+
+  (*cinfo->methods->c_per_scan_method_selection) (cinfo);
+}
+
+
+LOCAL void
+noninterleaved_scan_setup (compress_info_ptr cinfo)
+/* Compute all derived info for a noninterleaved (single-component) scan */
+/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
+{
+  jpeg_component_info *compptr = cinfo->cur_comp_info[0];
+
+  /* for noninterleaved scan, always one block per MCU */
+  compptr->MCU_width = 1;
+  compptr->MCU_height = 1;
+  compptr->MCU_blocks = 1;
+  /* compute physical dimensions of component */
+  compptr->subsampled_width = jround_up(compptr->true_comp_width,
+                                       (long) DCTSIZE);
+  compptr->subsampled_height = jround_up(compptr->true_comp_height,
+                                        (long) DCTSIZE);
+
+  cinfo->MCUs_per_row = compptr->subsampled_width / DCTSIZE;
+  cinfo->MCU_rows_in_scan = compptr->subsampled_height / DCTSIZE;
+
+  /* Prepare array describing MCU composition */
+  cinfo->blocks_in_MCU = 1;
+  cinfo->MCU_membership[0] = 0;
+
+  (*cinfo->methods->c_per_scan_method_selection) (cinfo);
+}
+
+
+
+LOCAL void
+alloc_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2],
+                      long fullsize_width)
+/* Create a pre-subsampling data buffer having the desired structure */
+/* (see comments at head of file) */
+{
+  short ci, vs, i;
+
+  vs = cinfo->max_v_samp_factor; /* row group height */
+
+  /* Get top-level space for array pointers */
+  fullsize_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->num_components * SIZEOF(JSAMPARRAY));
+  fullsize_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->num_components * SIZEOF(JSAMPARRAY));
+
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    /* Allocate the real storage */
+    fullsize_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
+                               (fullsize_width,
+                               (long) (vs * (DCTSIZE+2)));
+    /* Create space for the scrambled-order pointers */
+    fullsize_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
+                               (vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
+    /* Duplicate the first DCTSIZE-2 row groups */
+    for (i = 0; i < vs * (DCTSIZE-2); i++) {
+      fullsize_data[1][ci][i] = fullsize_data[0][ci][i];
+    }
+    /* Copy the last four row groups in swapped order */
+    for (i = 0; i < vs * 2; i++) {
+      fullsize_data[1][ci][vs*DCTSIZE + i] = fullsize_data[0][ci][vs*(DCTSIZE-2) + i];
+      fullsize_data[1][ci][vs*(DCTSIZE-2) + i] = fullsize_data[0][ci][vs*DCTSIZE + i];
+    }
+  }
+}
+
+
+LOCAL void
+free_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2])
+/* Release a sampling buffer created by alloc_sampling_buffer */
+{
+  short ci, vs;
+
+  vs = cinfo->max_v_samp_factor; /* row group height */
+
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    /* Free the real storage */
+    (*cinfo->emethods->free_small_sarray)
+               (fullsize_data[0][ci], (long) (vs * (DCTSIZE+2)));
+    /* Free the scrambled-order pointers */
+    (*cinfo->emethods->free_small) ((void *) fullsize_data[1][ci]);
+  }
+
+  /* Free the top-level space */
+  (*cinfo->emethods->free_small) ((void *) fullsize_data[0]);
+  (*cinfo->emethods->free_small) ((void *) fullsize_data[1]);
+}
+
+
+LOCAL void
+subsample (compress_info_ptr cinfo,
+          JSAMPIMAGE fullsize_data, JSAMPIMAGE subsampled_data,
+          long fullsize_width,
+          short above, short current, short below, short out)
+/* Do subsampling of a single row group (of each component). */
+/* above, current, below are indexes of row groups in fullsize_data;      */
+/* out is the index of the target row group in subsampled_data.           */
+/* Special case: above, below can be -1 to indicate top, bottom of image. */
+{
+  jpeg_component_info *compptr;
+  JSAMPARRAY above_ptr, below_ptr;
+  JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for subsample expansion at top/bottom */
+  short ci, vs, i;
+
+  vs = cinfo->max_v_samp_factor; /* row group height */
+
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    compptr = & cinfo->comp_info[ci];
+
+    if (above >= 0)
+      above_ptr = fullsize_data[ci] + above * vs;
+    else {
+      /* Top of image: make a dummy above-context with copies of 1st row */
+      /* We assume current=0 in this case */
+      for (i = 0; i < vs; i++)
+       dummy[i] = fullsize_data[ci][0];
+      above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
+    }
+
+    if (below >= 0)
+      below_ptr = fullsize_data[ci] + below * vs;
+    else {
+      /* Bot of image: make a dummy below-context with copies of last row */
+      for (i = 0; i < vs; i++)
+       dummy[i] = fullsize_data[ci][(current+1)*vs-1];
+      below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
+    }
+
+    (*cinfo->methods->subsample[ci])
+               (cinfo, (int) ci,
+                fullsize_width, (int) vs,
+                compptr->subsampled_width, (int) compptr->v_samp_factor,
+                above_ptr,
+                fullsize_data[ci] + current * vs,
+                below_ptr,
+                subsampled_data[ci] + out * compptr->v_samp_factor);
+  }
+}
+
+
+/* These vars are initialized by the pipeline controller for use by
+ * MCU_output_catcher.
+ * To avoid a lot of row-pointer overhead, we cram as many MCUs into each
+ * row of whole_scan_MCUs as we can get without exceeding 64KB per row.
+ */
+
+#define MAX_WHOLE_ROW_BLOCKS   (65500 / SIZEOF(JBLOCK)) /* max blocks/row */
+
+static big_barray_ptr whole_scan_MCUs; /* Big array for saving the MCUs */
+static int MCUs_in_big_row;    /* # of MCUs in each row of whole_scan_MCUs */
+static long next_whole_row;    /* next row to access in whole_scan_MCUs */
+static int next_MCU_index;     /* next MCU in current row */
+
+
+METHODDEF void
+MCU_output_catcher (compress_info_ptr cinfo, JBLOCK *MCU_data)
+/* Output method for siphoning off extract_MCUs output into a big array */
+{
+  static JBLOCKARRAY rowptr;
+
+  if (next_MCU_index >= MCUs_in_big_row) {
+    rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
+                                                   next_whole_row, TRUE);
+    next_whole_row++;
+    next_MCU_index = 0;
+  }
+
+  /*
+   * note that on 80x86, the cast applied to MCU_data implies
+   * near to far pointer conversion.
+   */
+  jcopy_block_row((JBLOCKROW) MCU_data,
+                 rowptr[0] + next_MCU_index * cinfo->blocks_in_MCU,
+                 (long) cinfo->blocks_in_MCU);
+  next_MCU_index++;
+}
+
+
+METHODDEF void
+dump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
+/* Dump the MCUs saved in whole_scan_MCUs to the output method. */
+/* The method may be either the entropy encoder or some routine supplied */
+/* by the entropy optimizer. */
+{
+  /* On an 80x86 machine, the entropy encoder expects the passed data block
+   * to be in NEAR memory (for performance reasons), so we have to copy it
+   * back from the big array to a local array.  On less brain-damaged CPUs
+   * we needn't do that.
+   */
+#ifdef NEED_FAR_POINTERS
+  JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
+#endif
+  long mcurow, mcuindex, next_row;
+  int next_index;
+  JBLOCKARRAY rowptr = NULL;   /* init only to suppress compiler complaint */
+
+  next_row = 0;
+  next_index = MCUs_in_big_row;
+
+  for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) {
+    for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
+      if (next_index >= MCUs_in_big_row) {
+       rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
+                                                       next_row, FALSE);
+       next_row++;
+       next_index = 0;
+      }
+#ifdef NEED_FAR_POINTERS
+      jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU,
+                     (JBLOCKROW) MCU_data, /* note cast */
+                     (long) cinfo->blocks_in_MCU);
+      (*output_method) (cinfo, MCU_data);
+#else
+      (*output_method) (cinfo, rowptr[0] + next_index * cinfo->blocks_in_MCU);
+#endif
+      next_index++;
+    }
+  }
+}
+
+
+
+/*
+ * Compression pipeline controller used for single-scan files
+ * with no optimization of entropy parameters.
+ */
+
+METHODDEF void
+single_ccontroller (compress_info_ptr cinfo)
+{
+  int rows_in_mem;             /* # of sample rows in full-size buffers */
+  long fullsize_width;         /* # of samples per row in full-size buffers */
+  long cur_pixel_row;          /* counts # of pixel rows processed */
+  long mcu_rows_output;                /* # of MCU rows actually emitted */
+  int mcu_rows_per_loop;       /* # of MCU rows processed per outer loop */
+  /* Work buffer for pre-subsampling data (see comments at head of file) */
+  JSAMPIMAGE fullsize_data[2];
+  /* Work buffer for subsampled data */
+  JSAMPIMAGE subsampled_data;
+  int rows_this_time;
+  short ci, whichss, i;
+
+  /* Prepare for single scan containing all components */
+  if (cinfo->num_components > MAX_COMPS_IN_SCAN)
+    ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
+  cinfo->comps_in_scan = cinfo->num_components;
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
+  }
+  if (cinfo->comps_in_scan == 1) {
+    noninterleaved_scan_setup(cinfo);
+    /* Vk block rows constitute the same number of MCU rows */
+    mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
+  } else {
+    interleaved_scan_setup(cinfo);
+    /* in an interleaved scan, one MCU row contains Vk block rows */
+    mcu_rows_per_loop = 1;
+  }
+
+  /* Compute dimensions of full-size pixel buffers */
+  /* Note these are the same whether interleaved or not. */
+  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
+  fullsize_width = jround_up(cinfo->image_width,
+                            (long) (cinfo->max_h_samp_factor * DCTSIZE));
+
+  /* Allocate working memory: */
+  /* fullsize_data is sample data before subsampling */
+  alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
+  /* subsampled_data is sample data after subsampling */
+  subsampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->num_components * SIZEOF(JSAMPARRAY));
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    subsampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
+                       (cinfo->comp_info[ci].subsampled_width,
+                        (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
+  }
+
+  /* Tell the memory manager to instantiate big arrays.
+   * We don't need any big arrays in this controller,
+   * but some other module (like the input file reader) may need one.
+   */
+  (*cinfo->emethods->alloc_big_arrays)
+       ((long) 0,                              /* no more small sarrays */
+        (long) 0,                              /* no more small barrays */
+        (long) 0);                             /* no more "medium" objects */
+
+  /* Initialize output file & do per-scan object init */
+
+  (*cinfo->methods->write_scan_header) (cinfo);
+  cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
+  (*cinfo->methods->entropy_encoder_init) (cinfo);
+  (*cinfo->methods->subsample_init) (cinfo);
+  (*cinfo->methods->extract_init) (cinfo);
+
+  /* Loop over input image: rows_in_mem pixel rows are processed per loop */
+
+  mcu_rows_output = 0;
+  whichss = 1;                 /* arrange to start with fullsize_data[0] */
+
+  for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
+       cur_pixel_row += rows_in_mem) {
+    whichss ^= 1;              /* switch to other fullsize_data buffer */
+    
+    /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
+    /* Then we have exactly DCTSIZE row groups for subsampling. */   
+    rows_this_time = MIN(rows_in_mem, cinfo->image_height - cur_pixel_row);
+    (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
+                                       fullsize_data[whichss]);
+    (*cinfo->methods->edge_expand) (cinfo,
+                                   cinfo->image_width, rows_this_time,
+                                   fullsize_width, rows_in_mem,
+                                   fullsize_data[whichss]);
+    
+    /* Subsample the data (all components) */
+    /* First time through is a special case */
+    
+    if (cur_pixel_row) {
+      /* Subsample last row group of previous set */
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
+               (short) (DCTSIZE-1));
+      /* and dump the previous set's subsampled data */
+      (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
+                                      mcu_rows_per_loop,
+                                      cinfo->methods->entropy_encode);
+      mcu_rows_output += mcu_rows_per_loop;
+      /* Subsample first row group of this set */
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) (DCTSIZE+1), (short) 0, (short) 1,
+               (short) 0);
+    } else {
+      /* Subsample first row group with dummy above-context */
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) (-1), (short) 0, (short) 1,
+               (short) 0);
+    }
+    /* Subsample second through next-to-last row groups of this set */
+    for (i = 1; i <= DCTSIZE-2; i++) {
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) (i-1), (short) i, (short) (i+1),
+               (short) i);
+    }
+  } /* end of outer loop */
+  
+  /* Subsample the last row group with dummy below-context */
+  /* Note whichss points to last buffer side used */
+  subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+           (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
+           (short) (DCTSIZE-1));
+  /* Dump the remaining data (may be less than full height if uninterleaved) */
+  (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
+               (int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
+               cinfo->methods->entropy_encode);
+
+  /* Finish output file */
+  (*cinfo->methods->extract_term) (cinfo);
+  (*cinfo->methods->subsample_term) (cinfo);
+  (*cinfo->methods->entropy_encoder_term) (cinfo);
+  (*cinfo->methods->write_scan_trailer) (cinfo);
+
+  /* Release working memory */
+  free_sampling_buffer(cinfo, fullsize_data);
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    (*cinfo->emethods->free_small_sarray)
+               (subsampled_data[ci],
+                (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
+  }
+  (*cinfo->emethods->free_small) ((void *) subsampled_data);
+}
+
+
+/*
+ * Compression pipeline controller used for single-scan files
+ * with optimization of entropy parameters.
+ */
+
+#ifdef ENTROPY_OPT_SUPPORTED
+
+METHODDEF void
+single_eopt_ccontroller (compress_info_ptr cinfo)
+{
+  int rows_in_mem;             /* # of sample rows in full-size buffers */
+  long fullsize_width;         /* # of samples per row in full-size buffers */
+  long cur_pixel_row;          /* counts # of pixel rows processed */
+  long mcu_rows_output;                /* # of MCU rows actually emitted */
+  int mcu_rows_per_loop;       /* # of MCU rows processed per outer loop */
+  /* Work buffer for pre-subsampling data (see comments at head of file) */
+  JSAMPIMAGE fullsize_data[2];
+  /* Work buffer for subsampled data */
+  JSAMPIMAGE subsampled_data;
+  int rows_this_time;
+  int blocks_in_big_row;
+  short ci, whichss, i;
+
+  /* Prepare for single scan containing all components */
+  if (cinfo->num_components > MAX_COMPS_IN_SCAN)
+    ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
+  cinfo->comps_in_scan = cinfo->num_components;
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
+  }
+  if (cinfo->comps_in_scan == 1) {
+    noninterleaved_scan_setup(cinfo);
+    /* Vk block rows constitute the same number of MCU rows */
+    mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
+  } else {
+    interleaved_scan_setup(cinfo);
+    /* in an interleaved scan, one MCU row contains Vk block rows */
+    mcu_rows_per_loop = 1;
+  }
+
+  /* Compute dimensions of full-size pixel buffers */
+  /* Note these are the same whether interleaved or not. */
+  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
+  fullsize_width = jround_up(cinfo->image_width,
+                            (long) (cinfo->max_h_samp_factor * DCTSIZE));
+
+  /* Allocate working memory: */
+  /* fullsize_data is sample data before subsampling */
+  alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
+  /* subsampled_data is sample data after subsampling */
+  subsampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->num_components * SIZEOF(JSAMPARRAY));
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    subsampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
+                       (cinfo->comp_info[ci].subsampled_width,
+                        (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
+  }
+
+  /* Figure # of MCUs to be packed in a row of whole_scan_MCUs */
+  MCUs_in_big_row = MAX_WHOLE_ROW_BLOCKS / cinfo->blocks_in_MCU;
+  blocks_in_big_row = MCUs_in_big_row * cinfo->blocks_in_MCU;
+
+  /* Request a big array: whole_scan_MCUs saves the MCU data for the scan */
+  whole_scan_MCUs = (*cinfo->emethods->request_big_barray)
+               ((long) blocks_in_big_row,
+                (long) (cinfo->MCUs_per_row * cinfo->MCU_rows_in_scan
+                        + MCUs_in_big_row-1) / MCUs_in_big_row,
+                1L);           /* unit height is 1 row */
+
+  next_whole_row = 0;          /* init output ptr for MCU_output_catcher */
+  next_MCU_index = MCUs_in_big_row; /* forces access on first call! */
+
+  /* Tell the memory manager to instantiate big arrays */
+  (*cinfo->emethods->alloc_big_arrays)
+       ((long) 0,                              /* no more small sarrays */
+        (long) 0,                              /* no more small barrays */
+        (long) 0);                             /* no more "medium" objects */
+
+  /* Do per-scan object init */
+
+  (*cinfo->methods->subsample_init) (cinfo);
+  (*cinfo->methods->extract_init) (cinfo);
+
+  /* Loop over input image: rows_in_mem pixel rows are processed per loop */
+  /* MCU data goes into whole_scan_MCUs, not to the entropy encoder */
+
+  mcu_rows_output = 0;
+  whichss = 1;                 /* arrange to start with fullsize_data[0] */
+
+  for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
+       cur_pixel_row += rows_in_mem) {
+    whichss ^= 1;              /* switch to other fullsize_data buffer */
+    
+    /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
+    /* Then we have exactly DCTSIZE row groups for subsampling. */   
+    rows_this_time = MIN(rows_in_mem, cinfo->image_height - cur_pixel_row);
+    (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
+                                       fullsize_data[whichss]);
+    (*cinfo->methods->edge_expand) (cinfo,
+                                   cinfo->image_width, rows_this_time,
+                                   fullsize_width, rows_in_mem,
+                                   fullsize_data[whichss]);
+    
+    /* Subsample the data (all components) */
+    /* First time through is a special case */
+    
+    if (cur_pixel_row) {
+      /* Subsample last row group of previous set */
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
+               (short) (DCTSIZE-1));
+      /* and dump the previous set's subsampled data */
+      (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
+                                      mcu_rows_per_loop,
+                                      MCU_output_catcher);
+      mcu_rows_output += mcu_rows_per_loop;
+      /* Subsample first row group of this set */
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) (DCTSIZE+1), (short) 0, (short) 1,
+               (short) 0);
+    } else {
+      /* Subsample first row group with dummy above-context */
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) (-1), (short) 0, (short) 1,
+               (short) 0);
+    }
+    /* Subsample second through next-to-last row groups of this set */
+    for (i = 1; i <= DCTSIZE-2; i++) {
+      subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+               (short) (i-1), (short) i, (short) (i+1),
+               (short) i);
+    }
+  } /* end of outer loop */
+  
+  /* Subsample the last row group with dummy below-context */
+  /* Note whichss points to last buffer side used */
+  subsample(cinfo, fullsize_data[whichss], subsampled_data, fullsize_width,
+           (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
+           (short) (DCTSIZE-1));
+  /* Dump the remaining data (may be less than full height if uninterleaved) */
+  (*cinfo->methods->extract_MCUs) (cinfo, subsampled_data, 
+               (int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
+               MCU_output_catcher);
+
+  /* Clean up after that stuff, then find the optimal entropy parameters */
+
+  (*cinfo->methods->extract_term) (cinfo);
+  (*cinfo->methods->subsample_term) (cinfo);
+
+  (*cinfo->methods->entropy_optimize) (cinfo, dump_scan_MCUs);
+
+  /* Emit scan to output file */
+  /* Note: we can't do write_scan_header until entropy parameters are set! */
+
+  (*cinfo->methods->write_scan_header) (cinfo);
+  cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
+  (*cinfo->methods->entropy_encoder_init) (cinfo);
+  dump_scan_MCUs(cinfo, cinfo->methods->entropy_encode);
+  (*cinfo->methods->entropy_encoder_term) (cinfo);
+  (*cinfo->methods->write_scan_trailer) (cinfo);
+
+  /* Release working memory */
+  free_sampling_buffer(cinfo, fullsize_data);
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    (*cinfo->emethods->free_small_sarray)
+               (subsampled_data[ci],
+                (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
+  }
+  (*cinfo->emethods->free_small) ((void *) subsampled_data);
+  (*cinfo->emethods->free_big_barray) (whole_scan_MCUs);
+}
+
+#endif /* ENTROPY_OPT_SUPPORTED */
+
+
+/*
+ * Compression pipeline controller used for multiple-scan files
+ * with no optimization of entropy parameters.
+ */
+
+#ifdef MULTISCAN_FILES_SUPPORTED
+
+METHODDEF void
+multi_ccontroller (compress_info_ptr cinfo)
+{
+  ERREXIT(cinfo->emethods, "Not implemented yet");
+}
+
+#endif /* MULTISCAN_FILES_SUPPORTED */
+
+
+/*
+ * Compression pipeline controller used for multiple-scan files
+ * with optimization of entropy parameters.
+ */
+
+#ifdef MULTISCAN_FILES_SUPPORTED
+#ifdef ENTROPY_OPT_SUPPORTED
+
+METHODDEF void
+multi_eopt_ccontroller (compress_info_ptr cinfo)
+{
+  ERREXIT(cinfo->emethods, "Not implemented yet");
+}
+
+#endif /* ENTROPY_OPT_SUPPORTED */
+#endif /* MULTISCAN_FILES_SUPPORTED */
+
+
+/*
+ * The method selection routine for compression pipeline controllers.
+ */
+
+GLOBAL void
+jselcpipeline (compress_info_ptr cinfo)
+{
+  if (cinfo->interleave || cinfo->num_components == 1) {
+    /* single scan needed */
+#ifdef ENTROPY_OPT_SUPPORTED
+    if (cinfo->optimize_coding)
+      cinfo->methods->c_pipeline_controller = single_eopt_ccontroller;
+    else
+#endif
+      cinfo->methods->c_pipeline_controller = single_ccontroller;
+  } else {
+    /* multiple scans needed */
+#ifdef MULTISCAN_FILES_SUPPORTED
+#ifdef ENTROPY_OPT_SUPPORTED
+    if (cinfo->optimize_coding)
+      cinfo->methods->c_pipeline_controller = multi_eopt_ccontroller;
+    else
+#endif
+      cinfo->methods->c_pipeline_controller = multi_ccontroller;
+#else
+    ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
+#endif
+  }
+}
diff --git a/jcsample.c b/jcsample.c
new file mode 100644 (file)
index 0000000..d23e23a
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * jcsample.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains subsampling routines.
+ * These routines are invoked via the subsample and
+ * subsample_init/term methods.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * Initialize for subsampling a scan.
+ */
+
+METHODDEF void
+subsample_init (compress_info_ptr cinfo)
+{
+  /* no work for now */
+}
+
+
+/*
+ * Subsample pixel values of a single component.
+ * This version only handles integral sampling ratios.
+ */
+
+METHODDEF void
+subsample (compress_info_ptr cinfo, int which_component,
+          long input_cols, int input_rows,
+          long output_cols, int output_rows,
+          JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
+          JSAMPARRAY output_data)
+{
+  jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
+  int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
+  long outcol;
+  JSAMPROW inptr, outptr;
+  INT32 outvalue;
+
+  /* TEMP FOR DEBUGGING PIPELINE CONTROLLER */
+  if (output_rows != compptr->v_samp_factor ||
+      input_rows != cinfo->max_v_samp_factor ||
+      (output_cols % compptr->h_samp_factor) != 0 ||
+      (input_cols % cinfo->max_h_samp_factor) != 0 ||
+      input_cols*compptr->h_samp_factor != output_cols*cinfo->max_h_samp_factor)
+    ERREXIT(cinfo->emethods, "Bogus subsample parameters");
+
+  h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
+  v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
+  numpix = h_expand * v_expand;
+  numpix2 = numpix/2;
+
+  inrow = 0;
+  for (outrow = 0; outrow < output_rows; outrow++) {
+    outptr = output_data[outrow];
+    for (outcol = 0; outcol < output_cols; outcol++) {
+      outvalue = 0;
+      for (v = 0; v < v_expand; v++) {
+       inptr = input_data[inrow+v] + (outcol*h_expand);
+       for (h = 0; h < h_expand; h++) {
+         outvalue += GETJSAMPLE(*inptr++);
+       }
+      }
+      *outptr++ = (outvalue + numpix2) / numpix;
+    }
+    inrow += v_expand;
+  }
+}
+
+
+/*
+ * Subsample pixel values of a single component.
+ * This version handles the special case of a full-size component.
+ */
+
+METHODDEF void
+fullsize_subsample (compress_info_ptr cinfo, int which_component,
+                   long input_cols, int input_rows,
+                   long output_cols, int output_rows,
+                   JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
+                   JSAMPARRAY output_data)
+{
+  if (input_cols != output_cols || input_rows != output_rows) /* DEBUG */
+    ERREXIT(cinfo->emethods, "Pipeline controller messed up");
+
+  jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols);
+}
+
+
+/*
+ * Clean up after a scan.
+ */
+
+METHODDEF void
+subsample_term (compress_info_ptr cinfo)
+{
+  /* no work for now */
+}
+
+
+
+/*
+ * The method selection routine for subsampling.
+ * Note that we must select a routine for each component.
+ */
+
+GLOBAL void
+jselsubsample (compress_info_ptr cinfo)
+{
+  short ci;
+  jpeg_component_info * compptr;
+
+  if (cinfo->CCIR601_sampling)
+    ERREXIT(cinfo->emethods, "CCIR601 subsampling not implemented yet");
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
+       compptr->v_samp_factor == cinfo->max_v_samp_factor)
+      cinfo->methods->subsample[ci] = fullsize_subsample;
+    else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
+            (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
+      cinfo->methods->subsample[ci] = subsample;
+    else
+      ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
+  }
+
+  cinfo->methods->subsample_init = subsample_init;
+  cinfo->methods->subsample_term = subsample_term;
+}
diff --git a/jdarith.c b/jdarith.c
new file mode 100644 (file)
index 0000000..0f19be8
--- /dev/null
+++ b/jdarith.c
@@ -0,0 +1,42 @@
+/*
+ * jdarith.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains arithmetic entropy decoding routines.
+ * These routines are invoked via the methods entropy_decode
+ * and entropy_decoder_init/term.
+ */
+
+#include "jinclude.h"
+
+#ifdef ARITH_CODING_SUPPORTED
+
+
+/*
+ * The arithmetic coding option of the JPEG standard specifies Q-coding,
+ * which is covered by patents held by IBM (and possibly AT&T and Mitsubishi).
+ * At this time it does not appear to be legal for the Independent JPEG
+ * Group to distribute software that implements arithmetic coding.
+ * We have therefore removed arithmetic coding support from the
+ * distributed source code.
+ *
+ * We're not happy about it either.
+ */
+
+
+/*
+ * The method selection routine for arithmetic entropy decoding.
+ */
+
+GLOBAL void
+jseldarithmetic (decompress_info_ptr cinfo)
+{
+  if (cinfo->arith_code) {
+    ERREXIT(cinfo->emethods, "Sorry, there are legal restrictions on arithmetic coding");
+  }
+}
+
+#endif /* ARITH_CODING_SUPPORTED */
diff --git a/jdcolor.c b/jdcolor.c
new file mode 100644 (file)
index 0000000..a39ebff
--- /dev/null
+++ b/jdcolor.c
@@ -0,0 +1,194 @@
+/*
+ * jdcolor.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains output colorspace conversion routines.
+ * These routines are invoked via the methods color_convert
+ * and colorout_init/term.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * Initialize for colorspace conversion.
+ */
+
+METHODDEF void
+colorout_init (decompress_info_ptr cinfo)
+{
+  /* no work needed */
+}
+
+
+/*
+ * Convert some rows of samples to the output colorspace.
+ * This version handles YCbCr -> RGB conversion.
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ */
+
+METHODDEF void
+ycc_rgb_convert (decompress_info_ptr cinfo, int num_rows,
+                JSAMPIMAGE input_data, JSAMPIMAGE output_data)
+{
+  register INT32 y, u, v, x;
+  register JSAMPROW inptr0, inptr1, inptr2;
+  register JSAMPROW outptr0, outptr1, outptr2;
+  register long col;
+  register long width = cinfo->image_width;
+  register int row;
+  
+  for (row = 0; row < num_rows; row++) {
+    inptr0 = input_data[0][row];
+    inptr1 = input_data[1][row];
+    inptr2 = input_data[2][row];
+    outptr0 = output_data[0][row];
+    outptr1 = output_data[1][row];
+    outptr2 = output_data[2][row];
+    for (col = width; col > 0; col--) {
+      y = GETJSAMPLE(*inptr0++);
+      u = (int) GETJSAMPLE(*inptr1++) - CENTERJSAMPLE;
+      v = (int) GETJSAMPLE(*inptr2++) - CENTERJSAMPLE;
+      /* Note: if the inputs were computed directly from RGB values,
+       * range-limiting would be unnecessary here; but due to possible
+       * noise in the DCT/IDCT phase, we do need to apply range limits.
+       */
+      y *= 1024;       /* in case compiler can't spot common subexpression */
+      x = y          + 1436*v + 512; /* red */
+      if (x < 0) x = 0;
+      if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024;
+      *outptr0++ = x >> 10;
+      x = y -  352*u -  731*v + 512; /* green */
+      if (x < 0) x = 0;
+      if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024;
+      *outptr1++ = x >> 10;
+      x = y + 1815*u          + 512; /* blue */
+      if (x < 0) x = 0;
+      if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024;
+      *outptr2++ = x >> 10;
+    }
+  }
+}
+
+
+/*
+ * Color conversion for no colorspace change: just copy the data.
+ */
+
+METHODDEF void
+null_convert (decompress_info_ptr cinfo, int num_rows,
+             JSAMPIMAGE input_data, JSAMPIMAGE output_data)
+{
+  short ci;
+
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    jcopy_sample_rows(input_data[ci], 0, output_data[ci], 0,
+                     num_rows, cinfo->image_width);
+  }
+}
+
+
+/*
+ * Color conversion for grayscale: just copy the data.
+ * This also works for YCbCr/YIQ -> grayscale conversion, in which
+ * we just copy the Y (luminance) component and ignore chrominance.
+ */
+
+METHODDEF void
+grayscale_convert (decompress_info_ptr cinfo, int num_rows,
+                  JSAMPIMAGE input_data, JSAMPIMAGE output_data)
+{
+  jcopy_sample_rows(input_data[0], 0, output_data[0], 0,
+                   num_rows, cinfo->image_width);
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+colorout_term (decompress_info_ptr cinfo)
+{
+  /* no work needed */
+}
+
+
+/*
+ * The method selection routine for output colorspace conversion.
+ */
+
+GLOBAL void
+jseldcolor (decompress_info_ptr cinfo)
+{
+  /* Make sure num_components agrees with jpeg_color_space */
+  switch (cinfo->jpeg_color_space) {
+  case CS_GRAYSCALE:
+    if (cinfo->num_components != 1)
+      ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
+    break;
+
+  case CS_RGB:
+  case CS_YIQ:
+  case CS_YCbCr:
+    if (cinfo->num_components != 3)
+      ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
+    break;
+
+  case CS_CMYK:
+    if (cinfo->num_components != 4)
+      ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
+    break;
+
+  default:
+    ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace");
+    break;
+  }
+
+  /* Set color_out_comps and conversion method based on requested space */
+  switch (cinfo->out_color_space) {
+  case CS_GRAYSCALE:
+    cinfo->color_out_comps = 1;
+    if (cinfo->jpeg_color_space == CS_GRAYSCALE ||
+       cinfo->jpeg_color_space == CS_YCbCr ||
+       cinfo->jpeg_color_space == CS_YIQ)
+      cinfo->methods->color_convert = grayscale_convert;
+    else
+      ERREXIT(cinfo->emethods, "Unsupported color conversion request");
+    break;
+
+  case CS_RGB:
+    cinfo->color_out_comps = 3;
+    if (cinfo->jpeg_color_space == CS_YCbCr)
+      cinfo->methods->color_convert = ycc_rgb_convert;
+    else if (cinfo->jpeg_color_space == CS_RGB)
+      cinfo->methods->color_convert = null_convert;
+    else
+      ERREXIT(cinfo->emethods, "Unsupported color conversion request");
+    break;
+
+  case CS_CMYK:
+    cinfo->color_out_comps = 4;
+    if (cinfo->jpeg_color_space == CS_CMYK)
+      cinfo->methods->color_convert = null_convert;
+    else
+      ERREXIT(cinfo->emethods, "Unsupported color conversion request");
+    break;
+
+  default:
+    ERREXIT(cinfo->emethods, "Unsupported output colorspace");
+    break;
+  }
+
+  if (cinfo->quantize_colors)
+    cinfo->final_out_comps = 1;        /* single colormapped output component */
+  else
+    cinfo->final_out_comps = cinfo->color_out_comps;
+
+  cinfo->methods->colorout_init = colorout_init;
+  cinfo->methods->colorout_term = colorout_term;
+}
diff --git a/jdhuff.c b/jdhuff.c
new file mode 100644 (file)
index 0000000..e9af688
--- /dev/null
+++ b/jdhuff.c
@@ -0,0 +1,318 @@
+/*
+ * jdhuff.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains Huffman entropy decoding routines.
+ * These routines are invoked via the methods entropy_decode
+ * and entropy_decoder_init/term.
+ */
+
+#include "jinclude.h"
+
+
+/* Static variables to avoid passing 'round extra parameters */
+
+static decompress_info_ptr dcinfo;
+
+static unsigned int get_buffer; /* current bit-extraction buffer */
+static int bits_left;          /* # of unused bits in it */
+
+
+LOCAL void
+fix_huff_tbl (HUFF_TBL * htbl)
+/* Compute derived values for a Huffman table */
+{
+  int p, i, l, lastp, si;
+  char huffsize[257];
+  UINT16 huffcode[257];
+  UINT16 code;
+  
+  /* Figure 7.3.5.4.2.1: make table of Huffman code length for each symbol */
+  /* Note that this is in code-length order. */
+
+  p = 0;
+  for (l = 1; l <= 16; l++) {
+    for (i = 1; i <= htbl->bits[l]; i++)
+      huffsize[p++] = l;
+  }
+  huffsize[p] = 0;
+  lastp = p;
+  
+  /* Figure 7.3.5.4.2.2: generate the codes themselves */
+  /* Note that this is in code-length order. */
+  
+  code = 0;
+  si = huffsize[0];
+  p = 0;
+  while (huffsize[p]) {
+    while (huffsize[p] == si) {
+      huffcode[p++] = code;
+      code++;
+    }
+    code <<= 1;
+    si++;
+  }
+  
+  /* Figure 7.3.5.4.2.3: generate encoding tables */
+  /* These are code and size indexed by symbol value */
+
+  for (p = 0; p < lastp; p++) {
+    htbl->ehufco[htbl->huffval[p]] = huffcode[p];
+    htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
+  }
+  
+  /* Figure 13.4.2.3.1: generate decoding tables */
+
+  p = 0;
+  for (l = 1; l <= 16; l++) {
+    if (htbl->bits[l]) {
+      htbl->valptr[l] = p;     /* huffval[] index of 1st sym of code len l */
+      htbl->mincode[l] = huffcode[p]; /* minimum code of length l */
+      p += htbl->bits[l];
+      htbl->maxcode[l] = huffcode[p-1];        /* maximum code of length l */
+    } else {
+      htbl->maxcode[l] = -1;
+    }
+  }
+}
+
+
+/* Extract the next N bits from the input stream (N <= 8) */
+
+LOCAL int
+get_bits (int nbits)
+{
+  int result;
+  
+  while (nbits > bits_left) {
+    int c = JGETC(dcinfo);
+    
+    get_buffer = (get_buffer << 8) + c;
+    bits_left += 8;
+    /* If it's 0xFF, check and discard stuffed zero byte */
+    if (c == 0xff) {
+      c = JGETC(dcinfo);  /* Byte stuffing */
+      if (c != 0)
+       ERREXIT1(dcinfo->emethods,
+                "Unexpected marker 0x%02x in compressed data", c);
+    }
+  }
+  
+  bits_left -= nbits;
+  result = (get_buffer >> bits_left) & ((1 << nbits) - 1);
+  return result;
+}
+
+/* Macro to make things go at some speed! */
+
+#define get_bit()      (bits_left ? \
+                        ((get_buffer >> (--bits_left)) & 1) : \
+                        get_bits(1))
+
+
+/* Figure 13.4.2.3.2: extract next coded symbol from input stream */
+  
+LOCAL int
+huff_DECODE (HUFF_TBL * htbl)
+{
+  int l, p;
+  INT32 code;
+  
+  code = get_bit();
+  l = 1;
+  while (code > htbl->maxcode[l]) {
+    code = (code << 1) + get_bit();
+    l++;
+  }
+  
+  p = htbl->valptr[l] + (code - htbl->mincode[l]);
+  
+  return htbl->huffval[p];
+}
+
+
+/* Figure 13.4.2.1.1: extend sign bit */
+
+#define huff_EXTEND(x, s)      ((x) < (1 << ((s)-1)) ? \
+                                (x) + (-1 << (s)) + 1 : \
+                                (x))
+
+
+/* Decode a single block's worth of coefficients */
+/* Note that only the difference is returned for the DC coefficient */
+
+LOCAL void
+decode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
+{
+  int s, k, r, n;
+
+  /* zero out the coefficient block */
+
+  MEMZERO((void *) block, SIZEOF(JBLOCK));
+  
+  /* Section 13.4.2.1: decode the DC coefficient difference */
+
+  s = huff_DECODE(dctbl);
+  r = get_bits(s);
+  block[0] = huff_EXTEND(r, s);
+  
+  /* Section 13.4.2.2: decode the AC coefficients */
+  
+  for (k = 1; k < DCTSIZE2; k++) {
+    r = huff_DECODE(actbl);
+    
+    s = r & 15;
+    n = r >> 4;
+    
+    if (s) {
+      k = k + n;
+      r = get_bits(s);
+      block[k] = huff_EXTEND(r, s);
+    } else {
+      if (n != 15)
+       break;
+      k += 15;
+    }
+  }
+}
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ * This is invoked after reading the SOS marker.
+ */
+
+METHODDEF void
+huff_decoder_init (decompress_info_ptr cinfo)
+{
+  short ci;
+  jpeg_component_info * compptr;
+
+  /* Initialize static variables */
+  dcinfo = cinfo;
+  bits_left = 0;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    /* Make sure requested tables are present */
+    if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
+       cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
+      ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
+    /* Compute derived values for Huffman tables */
+    /* We may do this more than once for same table, but it's not a big deal */
+    fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
+    fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
+    /* Initialize DC predictions to 0 */
+    cinfo->last_dc_val[ci] = 0;
+  }
+
+  /* Initialize restart stuff */
+  cinfo->restarts_to_go = cinfo->restart_interval;
+  cinfo->next_restart_num = 0;
+}
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ */
+
+LOCAL void
+process_restart (decompress_info_ptr cinfo)
+{
+  int c, nbytes;
+  short ci;
+
+  /* Throw away any partial unread byte */
+  bits_left = 0;
+
+  /* Scan for next JPEG marker */
+  nbytes = 0;
+  do {
+    do {                       /* skip any non-FF bytes */
+      nbytes++;
+      c = JGETC(cinfo);
+    } while (c != 0xFF);
+    do {                       /* skip any duplicate FFs */
+      nbytes++;
+      c = JGETC(cinfo);
+    } while (c == 0xFF);
+  } while (c == 0);            /* repeat if it was a stuffed FF/00 */
+
+  if (c != (RST0 + cinfo->next_restart_num))
+    ERREXIT2(cinfo->emethods, "Found 0x%02x marker instead of RST%d",
+            c, cinfo->next_restart_num);
+
+  if (nbytes != 2)
+    TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before RST%d",
+            nbytes-2, cinfo->next_restart_num);
+  else
+    TRACEMS1(cinfo->emethods, 2, "RST%d", cinfo->next_restart_num);
+
+  /* Re-initialize DC predictions to 0 */
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+    cinfo->last_dc_val[ci] = 0;
+
+  /* Update restart state */
+  cinfo->restarts_to_go = cinfo->restart_interval;
+  cinfo->next_restart_num++;
+  cinfo->next_restart_num &= 7;
+}
+
+
+/*
+ * Decode and return one MCU's worth of Huffman-compressed coefficients.
+ */
+
+METHODDEF void
+huff_decode (decompress_info_ptr cinfo, JBLOCK *MCU_data)
+{
+  short blkn, ci;
+  jpeg_component_info * compptr;
+
+  /* Account for restart interval, process restart marker if needed */
+  if (cinfo->restart_interval) {
+    if (cinfo->restarts_to_go == 0)
+      process_restart(cinfo);
+    cinfo->restarts_to_go--;
+  }
+
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+    decode_one_block(MCU_data[blkn],
+                    cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no],
+                    cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
+    /* Convert DC difference to actual value, update last_dc_val */
+    MCU_data[blkn][0] += cinfo->last_dc_val[ci];
+    cinfo->last_dc_val[ci] = MCU_data[blkn][0];
+  }
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed scan.
+ */
+
+METHODDEF void
+huff_decoder_term (decompress_info_ptr cinfo)
+{
+  /* No work needed */
+}
+
+
+/*
+ * The method selection routine for Huffman entropy decoding.
+ */
+
+GLOBAL void
+jseldhuffman (decompress_info_ptr cinfo)
+{
+  if (! cinfo->arith_code) {
+    cinfo->methods->entropy_decoder_init = huff_decoder_init;
+    cinfo->methods->entropy_decode = huff_decode;
+    cinfo->methods->entropy_decoder_term = huff_decoder_term;
+  }
+}
diff --git a/jdmain.c b/jdmain.c
new file mode 100644 (file)
index 0000000..109d124
--- /dev/null
+++ b/jdmain.c
@@ -0,0 +1,289 @@
+/*
+ * jdmain.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains a trivial test user interface for the JPEG decompressor.
+ * It should work on any system with Unix- or MS-DOS-style command lines.
+ *
+ * Two different command line styles are permitted, depending on the
+ * compile-time switch TWO_FILE_COMMANDLINE:
+ *     djpeg [options]  inputfile outputfile
+ *     djpeg [options]  [inputfile]
+ * In the second style, output is always to standard output, which you'd
+ * normally redirect to a file or pipe to some other program.  Input is
+ * either from a named file or from standard input (typically redirected).
+ * The second style is convenient on Unix but is unhelpful on systems that
+ * don't support pipes.  Also, you MUST use the first style if your system
+ * doesn't do binary I/O to stdin/stdout.
+ */
+
+#include "jinclude.h"
+#ifdef __STDC__
+#include <stdlib.h>            /* to declare exit() */
+#endif
+
+#ifdef THINK_C
+#include <console.h>           /* command-line reader for Macintosh */
+#endif
+
+#ifdef DONT_USE_B_MODE         /* define mode parameters for fopen() */
+#define READ_BINARY    "r"
+#define WRITE_BINARY   "w"
+#else
+#define READ_BINARY    "rb"
+#define WRITE_BINARY   "wb"
+#endif
+
+
+/*
+ * If your system has getopt(3), you can use your library version by
+ * defining HAVE_GETOPT.  By default, we use the PD 'egetopt'.
+ */
+
+#ifdef HAVE_GETOPT
+extern int getopt PP((int argc, char **argv, char *optstring));
+extern char * optarg;
+extern int optind;
+#else
+#include "egetopt.c"
+#define getopt(argc,argv,opt)  egetopt(argc,argv,opt)
+#endif
+
+
+typedef enum {                 /* defines known output image formats */
+       FMT_PPM,                /* PPM/PGM (PBMPLUS formats) */
+       FMT_GIF,                /* GIF format */
+       FMT_TIFF                /* TIFF format */
+} IMAGE_FORMATS;
+
+static IMAGE_FORMATS requested_fmt;
+
+
+/*
+ * This routine gets control after the input file header has been read.
+ * It must determine what output file format is to be written,
+ * and make any other decompression parameter changes that are desirable.
+ */
+
+METHODDEF void
+d_ui_method_selection (decompress_info_ptr cinfo)
+{
+  /* if grayscale or CMYK input, force similar output; */
+  /* else leave the output colorspace as set by options. */
+  if (cinfo->jpeg_color_space == CS_GRAYSCALE)
+    cinfo->out_color_space = CS_GRAYSCALE;
+  else if (cinfo->jpeg_color_space == CS_CMYK)
+    cinfo->out_color_space = CS_CMYK;
+
+  /* select output file format */
+  /* Note: jselwxxx routine may make additional parameter changes,
+   * such as forcing color quantization if it's a colormapped format.
+   */
+  switch (requested_fmt) {
+#ifdef GIF_SUPPORTED
+  case FMT_GIF:
+    jselwgif(cinfo);
+    break;
+#endif
+#ifdef PPM_SUPPORTED
+  case FMT_PPM:
+    jselwppm(cinfo);
+    break;
+#endif
+  default:
+    ERREXIT(cinfo->emethods, "Unsupported output file format");
+    break;
+  }
+}
+
+
+/*
+ * Reload the input buffer after it's been emptied, and return the next byte.
+ * See the JGETC macro for calling conditions.
+ *
+ * This routine would need to be replaced if reading JPEG data from something
+ * other than a stdio stream.
+ */
+
+METHODDEF int
+read_jpeg_data (decompress_info_ptr cinfo)
+{
+  cinfo->bytes_in_buffer = fread(cinfo->input_buffer + MIN_UNGET,
+                                1, JPEG_BUF_SIZE,
+                                cinfo->input_file);
+  
+  cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
+  
+  if (cinfo->bytes_in_buffer <= 0)
+    ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
+
+  return JGETC(cinfo);
+}
+
+
+
+LOCAL void
+usage (char * progname)
+/* complain about bad command line */
+{
+  fprintf(stderr, "usage: %s ", progname);
+  fprintf(stderr, "[-b] [-q colors] [-2] [-d] [-g] [-G]");
+#ifdef TWO_FILE_COMMANDLINE
+  fprintf(stderr, " inputfile outputfile\n");
+#else
+  fprintf(stderr, " [inputfile]\n");
+#endif
+  exit(2);
+}
+
+
+/*
+ * The main program.
+ */
+
+GLOBAL void
+main (int argc, char **argv)
+{
+  struct decompress_info_struct cinfo;
+  struct decompress_methods_struct dc_methods;
+  struct external_methods_struct e_methods;
+  int c;
+
+  /* On Mac, fetch a command line. */
+#ifdef THINK_C
+  argc = ccommand(&argv);
+#endif
+
+  /* Initialize the system-dependent method pointers. */
+  cinfo.methods = &dc_methods;
+  cinfo.emethods = &e_methods;
+  jselerror(&e_methods);       /* error/trace message routines */
+  jselvirtmem(&e_methods);     /* memory allocation routines */
+  dc_methods.d_ui_method_selection = d_ui_method_selection;
+  dc_methods.read_jpeg_data = read_jpeg_data;
+
+  /* Allocate memory for input buffer. */
+  cinfo.input_buffer = (char *) (*cinfo.emethods->alloc_small)
+                                       ((size_t) (JPEG_BUF_SIZE + MIN_UNGET));
+  cinfo.bytes_in_buffer = 0;   /* initialize buffer to empty */
+
+  /* Set up default input and output file references. */
+  /* (These may be overridden below.) */
+  cinfo.input_file = stdin;
+  cinfo.output_file = stdout;
+
+  /* Set up default parameters. */
+  e_methods.trace_level = 0;
+  cinfo.output_gamma = 1.0;
+  cinfo.quantize_colors = FALSE;
+  cinfo.two_pass_quantize = FALSE;
+  cinfo.use_dithering = FALSE;
+  cinfo.desired_number_of_colors = 256;
+  cinfo.do_block_smoothing = FALSE;
+  cinfo.do_pixel_smoothing = FALSE;
+  cinfo.out_color_space = CS_RGB;
+  cinfo.jpeg_color_space = CS_UNKNOWN;
+  /* setting any other value in jpeg_color_space overrides heuristics */
+  /* in jrdjfif.c ... */
+  /* You may wanta change the default output format; here's the place: */
+#ifdef PPM_SUPPORTED
+  requested_fmt = FMT_PPM;
+#else
+  requested_fmt = FMT_GIF;
+#endif
+
+  /* Scan parameters */
+  
+  while ((c = getopt(argc, argv, "bq:2DdgG")) != EOF)
+    switch (c) {
+    case 'b':                  /* Enable cross-block smoothing. */
+      cinfo.do_block_smoothing = TRUE;
+      break;
+    case 'q':                  /* Do color quantization. */
+      { int val;
+       if (optarg == NULL)
+         usage(argv[0]);
+       if (sscanf(optarg, "%d", &val) != 1)
+         usage(argv[0]);
+       cinfo.desired_number_of_colors = val;
+      }
+      cinfo.quantize_colors = TRUE;
+      break;
+    case '2':                  /* Use two-pass quantization. */
+      cinfo.two_pass_quantize = TRUE;
+      break;
+    case 'D':                  /* Use dithering in color quantization. */
+      cinfo.use_dithering = TRUE;
+      break;
+    case 'd':                  /* Debugging. */
+      e_methods.trace_level++;
+      break;
+    case 'g':                  /* Force grayscale output. */
+      cinfo.out_color_space = CS_GRAYSCALE;
+      break;
+    case 'G':                  /* GIF output format. */
+      requested_fmt = FMT_GIF;
+      break;
+    case '?':
+    default:
+      usage(argv[0]);
+      break;
+    }
+
+  /* Select the input and output files */
+
+#ifdef TWO_FILE_COMMANDLINE
+
+  if (optind != argc-2) {
+    fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
+    usage(argv[0]);
+  }
+  if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
+    fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
+    exit(2);
+  }
+  if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
+    fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
+    exit(2);
+  }
+
+#else /* not TWO_FILE_COMMANDLINE -- use Unix style */
+
+  if (optind < argc-1) {
+    fprintf(stderr, "%s: only one input file\n", argv[0]);
+    usage(argv[0]);
+  }
+  if (optind < argc) {
+    if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
+      fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
+      exit(2);
+    }
+  }
+
+#endif /* TWO_FILE_COMMANDLINE */
+  
+  /* Set up to read a JFIF or baseline-JPEG file. */
+  /* A smarter UI would inspect the first few bytes of the input file */
+  /* to determine its type. */
+#ifdef JFIF_SUPPORTED
+  jselrjfif(&cinfo);
+#else
+  You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
+#endif
+
+  /* Do it to it! */
+  jpeg_decompress(&cinfo);
+
+  /* Release memory. */
+  (*cinfo.emethods->free_small) ((void *) cinfo.input_buffer);
+#ifdef MEM_STATS
+  if (e_methods.trace_level > 0)
+    j_mem_stats();
+#endif
+
+  /* All done. */
+  exit(0);
+}
diff --git a/jdmaster.c b/jdmaster.c
new file mode 100644 (file)
index 0000000..5693882
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * jdmaster.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the main control for the JPEG decompressor.
+ * The system-dependent (user interface) code should call jpeg_decompress()
+ * after doing appropriate setup of the decompress_info_struct parameter.
+ */
+
+#include "jinclude.h"
+
+
+METHODDEF void
+d_per_scan_method_selection (decompress_info_ptr cinfo)
+/* Central point for per-scan method selection */
+{
+  /* MCU disassembly */
+  jseldmcu(cinfo);
+  /* Un-subsampling of pixels */
+  jselunsubsample(cinfo);
+}
+
+
+LOCAL void
+d_initial_method_selection (decompress_info_ptr cinfo)
+/* Central point for initial method selection (after reading file header) */
+{
+  /* JPEG file scanning method selection is already done. */
+  /* So is output file format selection (both are done by user interface). */
+
+  /* Entropy decoding: either Huffman or arithmetic coding. */
+#ifdef ARITH_CODING_SUPPORTED
+  jseldarithmetic(cinfo);
+#else
+  if (cinfo->arith_code) {
+    ERREXIT(cinfo->emethods, "Arithmetic coding not supported");
+  }
+#endif
+  jseldhuffman(cinfo);
+  /* Cross-block smoothing */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  jselbsmooth(cinfo);
+#else
+  cinfo->do_block_smoothing = FALSE;
+#endif
+  /* Gamma and color space conversion */
+  jseldcolor(cinfo);
+
+  /* Color quantization */
+#ifdef QUANT_1PASS_SUPPORTED
+#ifndef QUANT_2PASS_SUPPORTED
+  cinfo->two_pass_quantize = FALSE; /* only have 1-pass */
+#endif
+#else /* not QUANT_1PASS_SUPPORTED */
+#ifdef QUANT_2PASS_SUPPORTED
+  cinfo->two_pass_quantize = TRUE; /* only have 2-pass */
+#else /* not QUANT_2PASS_SUPPORTED */
+  if (cinfo->quantize_colors) {
+    ERREXIT(cinfo->emethods, "Color quantization was not compiled");
+  }
+#endif
+#endif
+
+#ifdef QUANT_1PASS_SUPPORTED
+  jsel1quantize(cinfo);
+#endif
+#ifdef QUANT_2PASS_SUPPORTED
+  jsel2quantize(cinfo);
+#endif
+
+  /* Pipeline control */
+  jseldpipeline(cinfo);
+  /* Overall control (that's me!) */
+  cinfo->methods->d_per_scan_method_selection = d_per_scan_method_selection;
+}
+
+
+LOCAL void
+initial_setup (decompress_info_ptr cinfo)
+/* Do computations that are needed before initial method selection */
+{
+  short ci;
+  jpeg_component_info *compptr;
+
+  /* Compute maximum sampling factors; check factor validity */
+  cinfo->max_h_samp_factor = 1;
+  cinfo->max_v_samp_factor = 1;
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    compptr = &cinfo->comp_info[ci];
+    if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+       compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+      ERREXIT(cinfo->emethods, "Bogus sampling factors");
+    cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+                                  compptr->h_samp_factor);
+    cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+                                  compptr->v_samp_factor);
+
+  }
+
+  /* Compute logical subsampled dimensions of components */
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    compptr = &cinfo->comp_info[ci];
+    compptr->true_comp_width = (cinfo->image_width * compptr->h_samp_factor
+                               + cinfo->max_h_samp_factor - 1)
+                               / cinfo->max_h_samp_factor;
+    compptr->true_comp_height = (cinfo->image_height * compptr->v_samp_factor
+                                + cinfo->max_v_samp_factor - 1)
+                                / cinfo->max_v_samp_factor;
+  }
+}
+
+
+/*
+ * This is the main entry point to the JPEG decompressor.
+ */
+
+
+GLOBAL void
+jpeg_decompress (decompress_info_ptr cinfo)
+{
+  short i;
+
+  /* Initialize pointers as needed to mark stuff unallocated. */
+  cinfo->comp_info = NULL;
+  for (i = 0; i < NUM_QUANT_TBLS; i++)
+    cinfo->quant_tbl_ptrs[i] = NULL;
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    cinfo->dc_huff_tbl_ptrs[i] = NULL;
+    cinfo->ac_huff_tbl_ptrs[i] = NULL;
+  }
+
+  /* Read the JPEG file header markers; everything up through the first SOS
+   * marker is read now.  NOTE: the user interface must have initialized the
+   * read_file_header method pointer (eg, by calling jselrjfif or jselrtiff).
+   * The other file reading methods (read_scan_header etc.) were probably
+   * set at the same time, but could be set up by read_file_header itself.
+   */
+  (*cinfo->methods->read_file_header) (cinfo);
+  if (! ((*cinfo->methods->read_scan_header) (cinfo)))
+    ERREXIT(cinfo->emethods, "Empty JPEG file");
+
+  /* Give UI a chance to adjust decompression parameters and select */
+  /* output file format based on info from file header. */
+  (*cinfo->methods->d_ui_method_selection) (cinfo);
+
+  /* Now select methods for decompression steps. */
+  initial_setup(cinfo);
+  d_initial_method_selection(cinfo);
+
+  /* Initialize the output file & other modules as needed */
+  /* (color_quant and entropy_decoder are inited by pipeline controller) */
+
+  (*cinfo->methods->output_init) (cinfo);
+  (*cinfo->methods->colorout_init) (cinfo);
+
+  /* And let the pipeline controller do the rest. */
+  (*cinfo->methods->d_pipeline_controller) (cinfo);
+
+  /* Finish output file, release working storage, etc */
+  (*cinfo->methods->colorout_term) (cinfo);
+  (*cinfo->methods->output_term) (cinfo);
+  (*cinfo->methods->read_file_trailer) (cinfo);
+
+  /* Release allocated storage for tables */
+#define FREE(ptr)  if ((ptr) != NULL) \
+                       (*cinfo->emethods->free_small) ((void *) ptr)
+
+  FREE(cinfo->comp_info);
+  for (i = 0; i < NUM_QUANT_TBLS; i++)
+    FREE(cinfo->quant_tbl_ptrs[i]);
+  for (i = 0; i < NUM_HUFF_TBLS; i++) {
+    FREE(cinfo->dc_huff_tbl_ptrs[i]);
+    FREE(cinfo->ac_huff_tbl_ptrs[i]);
+  }
+
+  /* My, that was easy, wasn't it? */
+}
diff --git a/jdmcu.c b/jdmcu.c
new file mode 100644 (file)
index 0000000..0d99170
--- /dev/null
+++ b/jdmcu.c
@@ -0,0 +1,146 @@
+/*
+ * jdmcu.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains MCU disassembly routines and quantization descaling.
+ * These routines are invoked via the disassemble_MCU and
+ * disassemble_init/term methods.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * Quantization descaling and zigzag reordering
+ */
+
+
+/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
+
+static const short ZAG[DCTSIZE2] = {
+  0,  1,  8, 16,  9,  2,  3, 10,
+ 17, 24, 32, 25, 18, 11,  4,  5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13,  6,  7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+
+LOCAL void
+qdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl)
+{
+  short i;
+
+  for (i = 0; i < DCTSIZE2; i++) {
+    (*outputptr)[ZAG[i]] = (*input++) * (*quanttbl++);
+  }
+}
+
+
+
+/*
+ * Fetch one MCU row from entropy_decode, build coefficient array.
+ * This version is used for noninterleaved (single-component) scans.
+ */
+
+METHODDEF void
+disassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
+                               JBLOCKIMAGE image_data)
+{
+  JBLOCK MCU_data[1];
+  long mcuindex;
+  jpeg_component_info * compptr;
+  QUANT_TBL_PTR quant_ptr;
+
+  /* this is pretty easy since there is one component and one block per MCU */
+  compptr = cinfo->cur_comp_info[0];
+  quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
+  for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
+    /* Fetch the coefficient data */
+    (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
+    /* Descale, reorder, and distribute it into the image array */
+    qdescale_zig(MCU_data[0], image_data[0][0] + mcuindex, quant_ptr);
+  }
+}
+
+
+/*
+ * Fetch one MCU row from entropy_decode, build coefficient array.
+ * This version is used for interleaved (multi-component) scans.
+ */
+
+METHODDEF void
+disassemble_interleaved_MCU (decompress_info_ptr cinfo,
+                            JBLOCKIMAGE image_data)
+{
+  JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
+  long mcuindex;
+  short blkn, ci, xpos, ypos;
+  jpeg_component_info * compptr;
+  QUANT_TBL_PTR quant_ptr;
+  JBLOCKROW image_ptr;
+
+  for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
+    /* Fetch the coefficient data */
+    (*cinfo->methods->entropy_decode) (cinfo, MCU_data);
+    /* Descale, reorder, and distribute it into the image array */
+    blkn = 0;
+    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+      compptr = cinfo->cur_comp_info[ci];
+      quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
+      for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
+       image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
+       for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
+         qdescale_zig(MCU_data[blkn], image_ptr, quant_ptr);
+         image_ptr++;
+         blkn++;
+       }
+      }
+    }
+  }
+}
+
+
+/*
+ * Initialize for processing a scan.
+ */
+
+METHODDEF void
+disassemble_init (decompress_info_ptr cinfo)
+{
+  /* no work for now */
+}
+
+
+/*
+ * Clean up after a scan.
+ */
+
+METHODDEF void
+disassemble_term (decompress_info_ptr cinfo)
+{
+  /* no work for now */
+}
+
+
+
+/*
+ * The method selection routine for MCU disassembly.
+ */
+
+GLOBAL void
+jseldmcu (decompress_info_ptr cinfo)
+{
+  if (cinfo->comps_in_scan == 1)
+    cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
+  else
+    cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
+  cinfo->methods->disassemble_init = disassemble_init;
+  cinfo->methods->disassemble_term = disassemble_term;
+}
diff --git a/jdpipe.c b/jdpipe.c
new file mode 100644 (file)
index 0000000..8e08874
--- /dev/null
+++ b/jdpipe.c
@@ -0,0 +1,1309 @@
+/*
+ * jdpipe.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains decompression pipeline controllers.
+ * These routines are invoked via the d_pipeline_controller method.
+ *
+ * There are four basic pipeline controllers, one for each combination of:
+ *     single-scan JPEG file (single component or fully interleaved)
+ *  vs. multiple-scan JPEG file (noninterleaved or partially interleaved).
+ *
+ *     2-pass color quantization
+ *  vs. no color quantization or 1-pass quantization.
+ *
+ * Note that these conditions determine the needs for "big" images:
+ * multiple scans imply a big image for recombining the color components;
+ * 2-pass color quantization needs a big image for saving the data for pass 2.
+ *
+ * All but the simplest controller (single-scan, no 2-pass quantization) can be
+ * compiled out through configuration options, if you need to make a minimal
+ * implementation.  You should leave in multiple-scan support if at all
+ * possible, so that you can handle all legal JPEG files.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * About the data structures:
+ *
+ * The processing chunk size for unsubsampling is referred to in this file as
+ * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
+ * any component while subsampled, or Vmax (max_v_samp_factor) unsubsampled
+ * rows.  In an interleaved scan each MCU row contains exactly DCTSIZE row
+ * groups of each component in the scan.  In a noninterleaved scan an MCU row
+ * is one row of blocks, which might not be an integral number of row groups;
+ * therefore, we read in Vk MCU rows to obtain the same amount of data as we'd
+ * have in an interleaved scan.
+ * To provide context for the unsubsampling step, we have to retain the last
+ * two row groups of the previous MCU row while reading in the next MCU row
+ * (or set of Vk MCU rows).  To do this without copying data about, we create
+ * a rather strange data structure.  Exactly DCTSIZE+2 row groups of samples
+ * are allocated, but we create two different sets of pointers to this array.
+ * The second set swaps the last two pairs of row groups.  By working
+ * alternately with the two sets of pointers, we can access the data in the
+ * desired order.
+ *
+ * Cross-block smoothing also needs context above and below the "current" row.
+ * Since this is an optional feature, I've implemented it in a way that is
+ * much simpler but requires more than the minimum amount of memory.  We
+ * simply allocate three extra MCU rows worth of coefficient blocks and use
+ * them to "read ahead" one MCU row in the file.  For a typical 1000-pixel-wide
+ * image with 2x2,1x1,1x1 sampling, each MCU row is about 50Kb; an 80x86
+ * machine may be unable to apply cross-block smoothing to wider images.
+ */
+
+
+/*
+ * These variables are logically local to the pipeline controller,
+ * but we make them static so that scan_big_image can use them
+ * without having to pass them through the quantization routines.
+ * If you don't support 2-pass quantization, you could make them locals.
+ */
+
+static int rows_in_mem;                /* # of sample rows in full-size buffers */
+/* Full-size image array holding desubsampled, color-converted data. */
+static big_sarray_ptr *fullsize_cnvt_image;
+static JSAMPIMAGE fullsize_cnvt_ptrs; /* workspace for access_big_sarray() results */
+/* Work buffer for color quantization output (full size, only 1 component). */
+static JSAMPARRAY quantize_out;
+
+
+/*
+ * Utility routines: common code for pipeline controllers
+ */
+
+LOCAL void
+interleaved_scan_setup (decompress_info_ptr cinfo)
+/* Compute all derived info for an interleaved (multi-component) scan */
+/* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
+{
+  short ci, mcublks;
+  jpeg_component_info *compptr;
+
+  if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+    ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
+
+  cinfo->MCUs_per_row = (cinfo->image_width
+                        + cinfo->max_h_samp_factor*DCTSIZE - 1)
+                       / (cinfo->max_h_samp_factor*DCTSIZE);
+
+  cinfo->MCU_rows_in_scan = (cinfo->image_height
+                            + cinfo->max_v_samp_factor*DCTSIZE - 1)
+                           / (cinfo->max_v_samp_factor*DCTSIZE);
+  
+  cinfo->blocks_in_MCU = 0;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    /* for interleaved scan, sampling factors give # of blocks per component */
+    compptr->MCU_width = compptr->h_samp_factor;
+    compptr->MCU_height = compptr->v_samp_factor;
+    compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+    /* compute physical dimensions of component */
+    compptr->subsampled_width = jround_up(compptr->true_comp_width,
+                                         (long) (compptr->MCU_width*DCTSIZE));
+    compptr->subsampled_height = jround_up(compptr->true_comp_height,
+                                          (long) (compptr->MCU_height*DCTSIZE));
+    /* Sanity check */
+    if (compptr->subsampled_width !=
+       (cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
+      ERREXIT(cinfo->emethods, "I'm confused about the image width");
+    /* Prepare array describing MCU composition */
+    mcublks = compptr->MCU_blocks;
+    if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
+      ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
+    while (mcublks-- > 0) {
+      cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+    }
+  }
+
+  (*cinfo->methods->d_per_scan_method_selection) (cinfo);
+}
+
+
+LOCAL void
+noninterleaved_scan_setup (decompress_info_ptr cinfo)
+/* Compute all derived info for a noninterleaved (single-component) scan */
+/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
+{
+  jpeg_component_info *compptr = cinfo->cur_comp_info[0];
+
+  /* for noninterleaved scan, always one block per MCU */
+  compptr->MCU_width = 1;
+  compptr->MCU_height = 1;
+  compptr->MCU_blocks = 1;
+  /* compute physical dimensions of component */
+  compptr->subsampled_width = jround_up(compptr->true_comp_width,
+                                       (long) DCTSIZE);
+  compptr->subsampled_height = jround_up(compptr->true_comp_height,
+                                        (long) DCTSIZE);
+
+  cinfo->MCUs_per_row = compptr->subsampled_width / DCTSIZE;
+  cinfo->MCU_rows_in_scan = compptr->subsampled_height / DCTSIZE;
+
+  /* Prepare array describing MCU composition */
+  cinfo->blocks_in_MCU = 1;
+  cinfo->MCU_membership[0] = 0;
+
+  (*cinfo->methods->d_per_scan_method_selection) (cinfo);
+}
+
+
+LOCAL void
+reverse_DCT (decompress_info_ptr cinfo,
+            JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data,
+            int start_row)
+/* Perform inverse DCT on each block in an MCU row's worth of data; */
+/* output the results into a sample array starting at row start_row. */
+/* NB: start_row can only be nonzero when dealing with a single-component */
+/* scan; otherwise we'd have to provide for different offsets for different */
+/* components, since the heights of interleaved MCU rows can vary. */
+{
+  DCTBLOCK block;
+  JBLOCKROW browptr;
+  JSAMPARRAY srowptr;
+  long blocksperrow, bi;
+  short numrows, ri;
+  short ci;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    /* calc size of an MCU row in this component */
+    blocksperrow = cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE;
+    numrows = cinfo->cur_comp_info[ci]->MCU_height;
+    /* iterate through all blocks in MCU row */
+    for (ri = 0; ri < numrows; ri++) {
+      browptr = coeff_data[ci][ri];
+      srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
+      for (bi = 0; bi < blocksperrow; bi++) {
+       /* copy the data into a local DCTBLOCK.  This allows for change of
+        * representation (if DCTELEM != JCOEF).  On 80x86 machines it also
+        * brings the data back from FAR storage to NEAR storage.
+        */
+       { register JCOEFPTR elemptr = browptr[bi];
+         register DCTELEM *localblkptr = block;
+         register short elem = DCTSIZE2;
+
+         while (--elem >= 0)
+           *localblkptr++ = (DCTELEM) *elemptr++;
+       }
+
+       j_rev_dct(block);       /* perform inverse DCT */
+
+       /* output the data into the sample array.
+        * Note change from signed to unsigned representation:
+        * DCT calculation works with values +-CENTERJSAMPLE,
+        * but sample arrays always hold 0..MAXJSAMPLE.
+        * Have to do explicit range-limiting because of quantization errors
+        * and so forth in the DCT/IDCT phase.
+        */
+       { register JSAMPROW elemptr;
+         register DCTELEM *localblkptr = block;
+         register short elemr, elemc;
+         register DCTELEM temp;
+
+         for (elemr = 0; elemr < DCTSIZE; elemr++) {
+           elemptr = srowptr[elemr] + (bi * DCTSIZE);
+           for (elemc = 0; elemc < DCTSIZE; elemc++) {
+             temp = (*localblkptr++) + CENTERJSAMPLE;
+             if (temp < 0) temp = 0;
+             else if (temp > MAXJSAMPLE) temp = MAXJSAMPLE;
+             *elemptr++ = (JSAMPLE) temp;
+           }
+         }
+       }
+      }
+    }
+  }
+}
+
+
+
+LOCAL JSAMPIMAGE
+alloc_sampimage (decompress_info_ptr cinfo,
+                int num_comps, long num_rows, long num_cols)
+/* Allocate an in-memory sample image (all components same size) */
+{
+  JSAMPIMAGE image;
+  int ci;
+
+  image = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (num_comps * SIZEOF(JSAMPARRAY));
+  for (ci = 0; ci < num_comps; ci++) {
+    image[ci] = (*cinfo->emethods->alloc_small_sarray) (num_cols, num_rows);
+  }
+  return image;
+}
+
+
+LOCAL void
+free_sampimage (decompress_info_ptr cinfo, JSAMPIMAGE image,
+               int num_comps, long num_rows)
+/* Release a sample image created by alloc_sampimage */
+{
+  int ci;
+
+  for (ci = 0; ci < num_comps; ci++) {
+      (*cinfo->emethods->free_small_sarray) (image[ci], num_rows);
+  }
+  (*cinfo->emethods->free_small) ((void *) image);
+}
+
+
+LOCAL JBLOCKIMAGE
+alloc_MCU_row (decompress_info_ptr cinfo)
+/* Allocate one MCU row's worth of coefficient blocks */
+{
+  JBLOCKIMAGE image;
+  int ci;
+
+  image = (JBLOCKIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->comps_in_scan * SIZEOF(JBLOCKARRAY));
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    image[ci] = (*cinfo->emethods->alloc_small_barray)
+                       (cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE,
+                        (long) cinfo->cur_comp_info[ci]->MCU_height);
+  }
+  return image;
+}
+
+
+LOCAL void
+free_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image)
+/* Release a coefficient block array created by alloc_MCU_row */
+{
+  int ci;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    (*cinfo->emethods->free_small_barray)
+               (image[ci], (long) cinfo->cur_comp_info[ci]->MCU_height);
+  }
+  (*cinfo->emethods->free_small) ((void *) image);
+}
+
+
+LOCAL void
+alloc_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
+/* Create a subsampled-data buffer having the desired structure */
+/* (see comments at head of file) */
+{
+  short ci, vs, i;
+
+  /* Get top-level space for array pointers */
+  subsampled_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
+  subsampled_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    vs = cinfo->cur_comp_info[ci]->v_samp_factor; /* row group height */
+    /* Allocate the real storage */
+    subsampled_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
+                               (cinfo->cur_comp_info[ci]->subsampled_width,
+                               (long) (vs * (DCTSIZE+2)));
+    /* Create space for the scrambled-order pointers */
+    subsampled_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
+                               (vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
+    /* Duplicate the first DCTSIZE-2 row groups */
+    for (i = 0; i < vs * (DCTSIZE-2); i++) {
+      subsampled_data[1][ci][i] = subsampled_data[0][ci][i];
+    }
+    /* Copy the last four row groups in swapped order */
+    for (i = 0; i < vs * 2; i++) {
+      subsampled_data[1][ci][vs*DCTSIZE + i] = subsampled_data[0][ci][vs*(DCTSIZE-2) + i];
+      subsampled_data[1][ci][vs*(DCTSIZE-2) + i] = subsampled_data[0][ci][vs*DCTSIZE + i];
+    }
+  }
+}
+
+
+LOCAL void
+free_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
+/* Release a sampling buffer created by alloc_sampling_buffer */
+{
+  short ci, vs;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    vs = cinfo->cur_comp_info[ci]->v_samp_factor; /* row group height */
+    /* Free the real storage */
+    (*cinfo->emethods->free_small_sarray)
+               (subsampled_data[0][ci], (long) (vs * (DCTSIZE+2)));
+    /* Free the scrambled-order pointers */
+    (*cinfo->emethods->free_small) ((void *) subsampled_data[1][ci]);
+  }
+
+  /* Free the top-level space */
+  (*cinfo->emethods->free_small) ((void *) subsampled_data[0]);
+  (*cinfo->emethods->free_small) ((void *) subsampled_data[1]);
+}
+
+
+LOCAL void
+duplicate_row (JSAMPARRAY image_data,
+              long num_cols, int source_row, int num_rows)
+/* Duplicate the source_row at source_row+1 .. source_row+num_rows */
+/* This happens only at the bottom of the image, */
+/* so it needn't be super-efficient */
+{
+  register int row;
+
+  for (row = 1; row <= num_rows; row++) {
+    jcopy_sample_rows(image_data, source_row, image_data, source_row + row,
+                     1, num_cols);
+  }
+}
+
+
+LOCAL void
+expand (decompress_info_ptr cinfo,
+       JSAMPIMAGE subsampled_data, JSAMPIMAGE fullsize_data,
+       long fullsize_width,
+       short above, short current, short below, short out)
+/* Do unsubsampling expansion of a single row group (of each component).  */
+/* above, current, below are indexes of row groups in subsampled_data;    */
+/* out is the index of the target row group in fullsize_data.             */
+/* Special case: above, below can be -1 to indicate top, bottom of image. */
+{
+  jpeg_component_info *compptr;
+  JSAMPARRAY above_ptr, below_ptr;
+  JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for subsample expansion at top/bottom */
+  short ci, vs, i;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    vs = compptr->v_samp_factor; /* row group height */
+
+    if (above >= 0)
+      above_ptr = subsampled_data[ci] + above * vs;
+    else {
+      /* Top of image: make a dummy above-context with copies of 1st row */
+      /* We assume current=0 in this case */
+      for (i = 0; i < vs; i++)
+       dummy[i] = subsampled_data[ci][0];
+      above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
+    }
+
+    if (below >= 0)
+      below_ptr = subsampled_data[ci] + below * vs;
+    else {
+      /* Bot of image: make a dummy below-context with copies of last row */
+      for (i = 0; i < vs; i++)
+       dummy[i] = subsampled_data[ci][(current+1)*vs-1];
+      below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
+    }
+
+    (*cinfo->methods->unsubsample[ci])
+               (cinfo, (int) ci,
+                compptr->subsampled_width, (int) vs,
+                fullsize_width, (int) cinfo->max_v_samp_factor,
+                above_ptr,
+                subsampled_data[ci] + current * vs,
+                below_ptr,
+                fullsize_data[ci] + out * cinfo->max_v_samp_factor);
+  }
+}
+
+
+LOCAL void
+emit_1pass (decompress_info_ptr cinfo, int num_rows,
+           JSAMPIMAGE fullsize_data, JSAMPIMAGE color_data)
+/* Do color conversion and output of num_rows full-size rows. */
+/* This is not used for 2-pass color quantization. */
+{
+  (*cinfo->methods->color_convert) (cinfo, num_rows,
+                                   fullsize_data, color_data);
+
+  if (cinfo->quantize_colors) {
+    (*cinfo->methods->color_quantize) (cinfo, num_rows,
+                                      color_data, quantize_out);
+
+    (*cinfo->methods->put_pixel_rows) (cinfo, num_rows,
+                                      &quantize_out);
+  } else {
+    (*cinfo->methods->put_pixel_rows) (cinfo, num_rows,
+                                      color_data);
+  }
+}
+
+
+/*
+ * Support routines for 2-pass color quantization.
+ */
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+LOCAL void
+emit_2pass (decompress_info_ptr cinfo, long top_row, int num_rows,
+           JSAMPIMAGE fullsize_data)
+/* Do color conversion and output data to the quantization buffer image. */
+/* This is used only with 2-pass color quantization. */
+{
+  short ci;
+
+  /* Realign the big buffers */
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    fullsize_cnvt_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
+      (fullsize_cnvt_image[ci], top_row, TRUE);
+  }
+
+  /* Do colorspace conversion */
+  (*cinfo->methods->color_convert) (cinfo, num_rows,
+                                   fullsize_data, fullsize_cnvt_ptrs);
+  /* Let quantizer get first-pass peek at the data. */
+  /* (Quantizer could change data if it wants to.)  */
+  (*cinfo->methods->color_quant_prescan) (cinfo, num_rows, fullsize_cnvt_ptrs);
+}
+
+
+METHODDEF void
+scan_big_image (decompress_info_ptr cinfo, quantize_method_ptr quantize_method)
+/* This is the "iterator" routine used by the quantizer. */
+{
+  long pixel_rows_output;
+  short ci;
+
+  for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height;
+       pixel_rows_output += rows_in_mem) {
+    /* Realign the big buffers */
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      fullsize_cnvt_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
+       (fullsize_cnvt_image[ci], pixel_rows_output, FALSE);
+    }
+    /* Let the quantizer have its way with the data.
+     * Note that quantize_out is simply workspace for the quantizer;
+     * when it's ready to output, it must call put_pixel_rows itself.
+     */
+    (*quantize_method) (cinfo,
+                       (int) MIN(rows_in_mem,
+                                 cinfo->image_height - pixel_rows_output),
+                       fullsize_cnvt_ptrs, quantize_out);
+  }
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Support routines for cross-block smoothing.
+ */
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+
+
+LOCAL void
+smooth_mcu_row (decompress_info_ptr cinfo,
+               JBLOCKIMAGE above, JBLOCKIMAGE input, JBLOCKIMAGE below,
+               JBLOCKIMAGE output)
+/* Apply cross-block smoothing to one MCU row's worth of coefficient blocks. */
+/* above,below are NULL if at top/bottom of image. */
+{
+  jpeg_component_info *compptr;
+  short ci, ri, last;
+  JBLOCKROW prev;
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    last = compptr->MCU_height - 1;
+
+    if (above == NULL)
+      prev = NULL;
+    else
+      prev = above[ci][last];
+
+    for (ri = 0; ri < last; ri++) {
+      (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
+                               prev, input[ci][ri], input[ci][ri+1],
+                               output[ci][ri]);
+      prev = input[ci][ri];
+    }
+
+    if (below == NULL)
+      (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
+                               prev, input[ci][last], (JBLOCKROW) NULL,
+                               output[ci][last]);
+    else
+      (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
+                               prev, input[ci][last], below[ci][0],
+                               output[ci][last]);
+  }
+}
+
+
+LOCAL void
+get_smoothed_row (decompress_info_ptr cinfo, JBLOCKIMAGE coeff_data,
+                 JBLOCKIMAGE bsmooth[3], int * whichb, long cur_mcu_row)
+/* Get an MCU row of coefficients, applying cross-block smoothing. */
+/* The output row is placed in coeff_data.  bsmooth and whichb hold */
+/* working state, and cur_row is needed to check for image top/bottom. */
+/* This routine just takes care of the buffering logic. */
+{
+  int prev, cur, next;
+  
+  /* Special case for top of image: need to pre-fetch a row & init whichb */
+  if (cur_mcu_row == 0) {
+    (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[0]);
+    if (cinfo->MCU_rows_in_scan > 1) {
+      (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[1]);
+      smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], bsmooth[1],
+                    coeff_data);
+    } else {
+      smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], (JBLOCKIMAGE) NULL,
+                    coeff_data);
+    }
+    *whichb = 1;               /* points to next bsmooth[] element to use */
+    return;
+  }
+  
+  cur = *whichb;               /* set up references */
+  prev = (cur == 0 ? 2 : cur - 1);
+  next = (cur == 2 ? 0 : cur + 1);
+  *whichb = next;              /* advance whichb for next time */
+  
+  /* Special case for bottom of image: don't read another row */
+  if (cur_mcu_row >= cinfo->MCU_rows_in_scan - 1) {
+    smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], (JBLOCKIMAGE) NULL,
+                  coeff_data);
+    return;
+  }
+  
+  /* Normal case: read ahead a new row, smooth the one I got before */
+  (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[next]);
+  smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], bsmooth[next],
+                coeff_data);
+}
+
+
+#endif /* BLOCK_SMOOTHING_SUPPORTED */
+
+
+
+/*
+ * Decompression pipeline controller used for single-scan files
+ * without 2-pass color quantization.
+ */
+
+METHODDEF void
+single_dcontroller (decompress_info_ptr cinfo)
+{
+  long fullsize_width;         /* # of samples per row in full-size buffers */
+  long cur_mcu_row;            /* counts # of MCU rows processed */
+  long pixel_rows_output;      /* # of pixel rows actually emitted */
+  int mcu_rows_per_loop;       /* # of MCU rows processed per outer loop */
+  /* Work buffer for dequantized coefficients (IDCT input) */
+  JBLOCKIMAGE coeff_data;
+  /* Work buffer for cross-block smoothing input */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  JBLOCKIMAGE bsmooth[3];      /* this is optional */
+  int whichb;
+#endif
+  /* Work buffer for subsampled image data (see comments at head of file) */
+  JSAMPIMAGE subsampled_data[2];
+  /* Work buffer for desubsampled data */
+  JSAMPIMAGE fullsize_data;
+  /* Work buffer for color conversion output (full size) */
+  JSAMPIMAGE color_data;
+  int whichss, ri;
+  short i;
+
+  /* Initialize for 1-pass color quantization, if needed */
+  if (cinfo->quantize_colors)
+    (*cinfo->methods->color_quant_init) (cinfo);
+
+  /* Prepare for single scan containing all components */
+  if (cinfo->comps_in_scan == 1) {
+    noninterleaved_scan_setup(cinfo);
+    /* Need to read Vk MCU rows to obtain Vk block rows */
+    mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
+  } else {
+    interleaved_scan_setup(cinfo);
+    /* in an interleaved scan, one MCU row provides Vk block rows */
+    mcu_rows_per_loop = 1;
+  }
+
+  /* Compute dimensions of full-size pixel buffers */
+  /* Note these are the same whether interleaved or not. */
+  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
+  fullsize_width = jround_up(cinfo->image_width,
+                            (long) (cinfo->max_h_samp_factor * DCTSIZE));
+
+  /* Allocate working memory: */
+  /* coeff_data holds a single MCU row of coefficient blocks */
+  coeff_data = alloc_MCU_row(cinfo);
+  /* if doing cross-block smoothing, need extra space for its input */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  if (cinfo->do_block_smoothing) {
+    bsmooth[0] = alloc_MCU_row(cinfo);
+    bsmooth[1] = alloc_MCU_row(cinfo);
+    bsmooth[2] = alloc_MCU_row(cinfo);
+  }
+#endif
+  /* subsampled_data is sample data before unsubsampling */
+  alloc_sampling_buffer(cinfo, subsampled_data);
+  /* fullsize_data is sample data after unsubsampling */
+  fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
+                                 (long) rows_in_mem, fullsize_width);
+  /* color_data is the result of the colorspace conversion step */
+  color_data = alloc_sampimage(cinfo, (int) cinfo->color_out_comps,
+                              (long) rows_in_mem, fullsize_width);
+  /* if quantizing colors, also need a one-component output area for that. */
+  if (cinfo->quantize_colors)
+    quantize_out = (*cinfo->emethods->alloc_small_sarray)
+                               (fullsize_width, (long) rows_in_mem);
+
+  /* Tell the memory manager to instantiate big arrays.
+   * We don't need any big arrays in this controller,
+   * but some other module (like the output file writer) may need one.
+   */
+  (*cinfo->emethods->alloc_big_arrays)
+       ((long) 0,                              /* no more small sarrays */
+        (long) 0,                              /* no more small barrays */
+        (long) 0);                             /* no more "medium" objects */
+        /* NB: quantizer must get any such objects at color_quant_init time */
+
+  /* Initialize to read scan data */
+
+  (*cinfo->methods->entropy_decoder_init) (cinfo);
+  (*cinfo->methods->unsubsample_init) (cinfo);
+  (*cinfo->methods->disassemble_init) (cinfo);
+
+  /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
+
+  pixel_rows_output = 0;
+  whichss = 1;                 /* arrange to start with subsampled_data[0] */
+
+  for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
+       cur_mcu_row += mcu_rows_per_loop) {
+    whichss ^= 1;              /* switch to other subsample buffer */
+
+    /* Obtain v_samp_factor block rows of each component in the scan. */
+    /* This is a single MCU row if interleaved, multiple MCU rows if not. */
+    /* In the noninterleaved case there might be fewer than v_samp_factor */
+    /* block rows remaining; if so, pad with copies of the last pixel row */
+    /* so that unsubsampling doesn't have to treat it as a special case. */
+
+    for (ri = 0; ri < mcu_rows_per_loop; ri++) {
+      if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
+       /* OK to actually read an MCU row. */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+       if (cinfo->do_block_smoothing)
+         get_smoothed_row(cinfo, coeff_data,
+                          bsmooth, &whichb, cur_mcu_row + ri);
+       else
+#endif
+         (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
+      
+       reverse_DCT(cinfo, coeff_data, subsampled_data[whichss],
+                   ri * DCTSIZE);
+      } else {
+       /* Need to pad out with copies of the last subsampled row. */
+       /* This can only happen if there is just one component. */
+       duplicate_row(subsampled_data[whichss][0],
+                     cinfo->cur_comp_info[0]->subsampled_width,
+                     ri * DCTSIZE - 1, DCTSIZE);
+      }
+    }
+
+    /* Unsubsample the data */
+    /* First time through is a special case */
+
+    if (cur_mcu_row) {
+      /* Expand last row group of previous set */
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
+            (short) (DCTSIZE-1));
+      /* and dump the previous set's expanded data */
+      emit_1pass (cinfo, rows_in_mem, fullsize_data, color_data);
+      pixel_rows_output += rows_in_mem;
+      /* Expand first row group of this set */
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) (DCTSIZE+1), (short) 0, (short) 1,
+            (short) 0);
+    } else {
+      /* Expand first row group with dummy above-context */
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) (-1), (short) 0, (short) 1,
+            (short) 0);
+    }
+    /* Expand second through next-to-last row groups of this set */
+    for (i = 1; i <= DCTSIZE-2; i++) {
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) (i-1), (short) i, (short) (i+1),
+            (short) i);
+    }
+  } /* end of outer loop */
+
+  /* Expand the last row group with dummy below-context */
+  /* Note whichss points to last buffer side used */
+  expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+        (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
+        (short) (DCTSIZE-1));
+  /* and dump the remaining data (may be less than full height) */
+  emit_1pass (cinfo, (int) (cinfo->image_height - pixel_rows_output),
+             fullsize_data, color_data);
+
+  /* Clean up after the scan */
+  (*cinfo->methods->disassemble_term) (cinfo);
+  (*cinfo->methods->unsubsample_term) (cinfo);
+  (*cinfo->methods->entropy_decoder_term) (cinfo);
+  (*cinfo->methods->read_scan_trailer) (cinfo);
+
+  /* Verify that we've seen the whole input file */
+  if ((*cinfo->methods->read_scan_header) (cinfo))
+    ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
+
+  /* Release working memory */
+  free_MCU_row(cinfo, coeff_data);
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  if (cinfo->do_block_smoothing) {
+    free_MCU_row(cinfo, bsmooth[0]);
+    free_MCU_row(cinfo, bsmooth[1]);
+    free_MCU_row(cinfo, bsmooth[2]);
+  }
+#endif
+  free_sampling_buffer(cinfo, subsampled_data);
+  free_sampimage(cinfo, fullsize_data, (int) cinfo->num_components,
+                (long) rows_in_mem);
+  free_sampimage(cinfo, color_data, (int) cinfo->color_out_comps,
+                (long) rows_in_mem);
+  if (cinfo->quantize_colors)
+    (*cinfo->emethods->free_small_sarray)
+               (quantize_out, (long) rows_in_mem);
+
+  /* Close up shop */
+  if (cinfo->quantize_colors)
+    (*cinfo->methods->color_quant_term) (cinfo);
+}
+
+
+/*
+ * Decompression pipeline controller used for single-scan files
+ * with 2-pass color quantization.
+ */
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+METHODDEF void
+single_2quant_dcontroller (decompress_info_ptr cinfo)
+{
+  long fullsize_width;         /* # of samples per row in full-size buffers */
+  long cur_mcu_row;            /* counts # of MCU rows processed */
+  long pixel_rows_output;      /* # of pixel rows actually emitted */
+  int mcu_rows_per_loop;       /* # of MCU rows processed per outer loop */
+  /* Work buffer for dequantized coefficients (IDCT input) */
+  JBLOCKIMAGE coeff_data;
+  /* Work buffer for cross-block smoothing input */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  JBLOCKIMAGE bsmooth[3];      /* this is optional */
+  int whichb;
+#endif
+  /* Work buffer for subsampled image data (see comments at head of file) */
+  JSAMPIMAGE subsampled_data[2];
+  /* Work buffer for desubsampled data */
+  JSAMPIMAGE fullsize_data;
+  int whichss, ri;
+  short ci, i;
+
+  /* Initialize for 2-pass color quantization */
+  (*cinfo->methods->color_quant_init) (cinfo);
+
+  /* Prepare for single scan containing all components */
+  if (cinfo->comps_in_scan == 1) {
+    noninterleaved_scan_setup(cinfo);
+    /* Need to read Vk MCU rows to obtain Vk block rows */
+    mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
+  } else {
+    interleaved_scan_setup(cinfo);
+    /* in an interleaved scan, one MCU row provides Vk block rows */
+    mcu_rows_per_loop = 1;
+  }
+
+  /* Compute dimensions of full-size pixel buffers */
+  /* Note these are the same whether interleaved or not. */
+  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
+  fullsize_width = jround_up(cinfo->image_width,
+                            (long) (cinfo->max_h_samp_factor * DCTSIZE));
+
+  /* Allocate working memory: */
+  /* coeff_data holds a single MCU row of coefficient blocks */
+  coeff_data = alloc_MCU_row(cinfo);
+  /* if doing cross-block smoothing, need extra space for its input */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  if (cinfo->do_block_smoothing) {
+    bsmooth[0] = alloc_MCU_row(cinfo);
+    bsmooth[1] = alloc_MCU_row(cinfo);
+    bsmooth[2] = alloc_MCU_row(cinfo);
+  }
+#endif
+  /* subsampled_data is sample data before unsubsampling */
+  alloc_sampling_buffer(cinfo, subsampled_data);
+  /* fullsize_data is sample data after unsubsampling */
+  fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
+                                 (long) rows_in_mem, fullsize_width);
+  /* Also need a one-component output area for color quantizer. */
+  quantize_out = (*cinfo->emethods->alloc_small_sarray)
+                               (fullsize_width, (long) rows_in_mem);
+
+  /* Get a big image for quantizer input: desubsampled, color-converted data */
+  fullsize_cnvt_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
+                       (cinfo->num_components * SIZEOF(big_sarray_ptr));
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    fullsize_cnvt_image[ci] = (*cinfo->emethods->request_big_sarray)
+                       (fullsize_width,
+                        jround_up(cinfo->image_height, (long) rows_in_mem),
+                        (long) rows_in_mem);
+  }
+  /* Also get an area for pointers to currently accessible chunks */
+  fullsize_cnvt_ptrs = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->num_components * SIZEOF(JSAMPARRAY));
+
+  /* Tell the memory manager to instantiate big arrays */
+  (*cinfo->emethods->alloc_big_arrays)
+       ((long) 0,                              /* no more small sarrays */
+        (long) 0,                              /* no more small barrays */
+        (long) 0);                             /* no more "medium" objects */
+        /* NB: quantizer must get any such objects at color_quant_init time */
+
+  /* Initialize to read scan data */
+
+  (*cinfo->methods->entropy_decoder_init) (cinfo);
+  (*cinfo->methods->unsubsample_init) (cinfo);
+  (*cinfo->methods->disassemble_init) (cinfo);
+
+  /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
+
+  pixel_rows_output = 0;
+  whichss = 1;                 /* arrange to start with subsampled_data[0] */
+
+  for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
+       cur_mcu_row += mcu_rows_per_loop) {
+    whichss ^= 1;              /* switch to other subsample buffer */
+
+    /* Obtain v_samp_factor block rows of each component in the scan. */
+    /* This is a single MCU row if interleaved, multiple MCU rows if not. */
+    /* In the noninterleaved case there might be fewer than v_samp_factor */
+    /* block rows remaining; if so, pad with copies of the last pixel row */
+    /* so that unsubsampling doesn't have to treat it as a special case. */
+
+    for (ri = 0; ri < mcu_rows_per_loop; ri++) {
+      if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
+       /* OK to actually read an MCU row. */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+       if (cinfo->do_block_smoothing)
+         get_smoothed_row(cinfo, coeff_data,
+                          bsmooth, &whichb, cur_mcu_row + ri);
+       else
+#endif
+         (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
+      
+       reverse_DCT(cinfo, coeff_data, subsampled_data[whichss],
+                   ri * DCTSIZE);
+      } else {
+       /* Need to pad out with copies of the last subsampled row. */
+       /* This can only happen if there is just one component. */
+       duplicate_row(subsampled_data[whichss][0],
+                     cinfo->cur_comp_info[0]->subsampled_width,
+                     ri * DCTSIZE - 1, DCTSIZE);
+      }
+    }
+
+    /* Unsubsample the data */
+    /* First time through is a special case */
+
+    if (cur_mcu_row) {
+      /* Expand last row group of previous set */
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
+            (short) (DCTSIZE-1));
+      /* and dump the previous set's expanded data */
+      emit_2pass (cinfo, pixel_rows_output, rows_in_mem, fullsize_data);
+      pixel_rows_output += rows_in_mem;
+      /* Expand first row group of this set */
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) (DCTSIZE+1), (short) 0, (short) 1,
+            (short) 0);
+    } else {
+      /* Expand first row group with dummy above-context */
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) (-1), (short) 0, (short) 1,
+            (short) 0);
+    }
+    /* Expand second through next-to-last row groups of this set */
+    for (i = 1; i <= DCTSIZE-2; i++) {
+      expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+            (short) (i-1), (short) i, (short) (i+1),
+            (short) i);
+    }
+  } /* end of outer loop */
+
+  /* Expand the last row group with dummy below-context */
+  /* Note whichss points to last buffer side used */
+  expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
+        (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
+        (short) (DCTSIZE-1));
+  /* and dump the remaining data (may be less than full height) */
+  emit_2pass (cinfo, pixel_rows_output,
+             (int) (cinfo->image_height - pixel_rows_output),
+             fullsize_data);
+
+  /* Clean up after the scan */
+  (*cinfo->methods->disassemble_term) (cinfo);
+  (*cinfo->methods->unsubsample_term) (cinfo);
+  (*cinfo->methods->entropy_decoder_term) (cinfo);
+  (*cinfo->methods->read_scan_trailer) (cinfo);
+
+  /* Verify that we've seen the whole input file */
+  if ((*cinfo->methods->read_scan_header) (cinfo))
+    ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
+
+  /* Now that we've collected the data, let the color quantizer do its thing */
+  (*cinfo->methods->color_quant_doit) (cinfo, scan_big_image);
+
+  /* Release working memory */
+  free_MCU_row(cinfo, coeff_data);
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  if (cinfo->do_block_smoothing) {
+    free_MCU_row(cinfo, bsmooth[0]);
+    free_MCU_row(cinfo, bsmooth[1]);
+    free_MCU_row(cinfo, bsmooth[2]);
+  }
+#endif
+  free_sampling_buffer(cinfo, subsampled_data);
+  free_sampimage(cinfo, fullsize_data, (int) cinfo->num_components,
+                (long) rows_in_mem);
+  (*cinfo->emethods->free_small_sarray)
+               (quantize_out, (long) rows_in_mem);
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    (*cinfo->emethods->free_big_sarray) (fullsize_cnvt_image[ci]);
+  }
+  (*cinfo->emethods->free_small) ((void *) fullsize_cnvt_image);
+  (*cinfo->emethods->free_small) ((void *) fullsize_cnvt_ptrs);
+
+  /* Close up shop */
+  (*cinfo->methods->color_quant_term) (cinfo);
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Decompression pipeline controller used for multiple-scan files
+ * without 2-pass color quantization.
+ *
+ * The current implementation places the "big" buffer at the stage of
+ * desubsampled data.  Buffering subsampled data instead would reduce the
+ * size of temp files (by about a factor of 2 in typical cases).  However,
+ * the unsubsampling logic is dependent on the assumption that unsubsampling
+ * occurs during a scan, so it's much easier to do the enlargement as the
+ * JPEG file is read.  This also simplifies life for the memory manager,
+ * which would otherwise have to deal with overlapping access_big_sarray()
+ * requests.
+ *
+ * At present it appears that most JPEG files will be single-scan, so
+ * it doesn't seem worthwhile to try to make this implementation smarter.
+ */
+
+#ifdef MULTISCAN_FILES_SUPPORTED
+
+METHODDEF void
+multi_dcontroller (decompress_info_ptr cinfo)
+{
+  long fullsize_width;         /* # of samples per row in full-size buffers */
+  long cur_mcu_row;            /* counts # of MCU rows processed */
+  long pixel_rows_output;      /* # of pixel rows actually emitted */
+  int mcu_rows_per_loop;       /* # of MCU rows processed per outer loop */
+  /* Work buffer for dequantized coefficients (IDCT input) */
+  JBLOCKIMAGE coeff_data;
+  /* Work buffer for cross-block smoothing input */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+  JBLOCKIMAGE bsmooth[3];      /* this is optional */
+  int whichb;
+#endif
+  /* Work buffer for subsampled image data (see comments at head of file) */
+  JSAMPIMAGE subsampled_data[2];
+  /* Full-image buffer holding desubsampled, but not color-converted, data */
+  big_sarray_ptr *fullsize_image;
+  JSAMPIMAGE fullsize_ptrs;    /* workspace for access_big_sarray() results */
+  /* Work buffer for color conversion output (full size) */
+  JSAMPIMAGE color_data;
+  int whichss, ri;
+  short ci, i;
+
+  /* Initialize for 1-pass color quantization, if needed */
+  if (cinfo->quantize_colors)
+    (*cinfo->methods->color_quant_init) (cinfo);
+
+  /* Compute dimensions of full-size pixel buffers */
+  /* Note these are the same whether interleaved or not. */
+  rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
+  fullsize_width = jround_up(cinfo->image_width,
+                            (long) (cinfo->max_h_samp_factor * DCTSIZE));
+
+  /* Allocate all working memory that doesn't depend on scan info */
+  /* color_data is the result of the colorspace conversion step */
+  color_data = alloc_sampimage(cinfo, (int) cinfo->color_out_comps,
+                              (long) rows_in_mem, fullsize_width);
+  /* if quantizing colors, also need a one-component output area for that. */
+  if (cinfo->quantize_colors)
+    quantize_out = (*cinfo->emethods->alloc_small_sarray)
+                               (fullsize_width, (long) rows_in_mem);
+
+  /* Get a big image: fullsize_image is sample data after unsubsampling. */
+  fullsize_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
+                       (cinfo->num_components * SIZEOF(big_sarray_ptr));
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    fullsize_image[ci] = (*cinfo->emethods->request_big_sarray)
+                       (fullsize_width,
+                        jround_up(cinfo->image_height, (long) rows_in_mem),
+                        (long) rows_in_mem);
+  }
+  /* Also get an area for pointers to currently accessible chunks */
+  fullsize_ptrs = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
+                               (cinfo->num_components * SIZEOF(JSAMPARRAY));
+
+  /* Tell the memory manager to instantiate big arrays */
+  (*cinfo->emethods->alloc_big_arrays)
+        /* extra sarray space is for subsampled-data buffers: */
+       ((long) (fullsize_width                 /* max width in samples */
+        * cinfo->max_v_samp_factor*(DCTSIZE+2) /* max height */
+        * cinfo->num_components),              /* max components per scan */
+        /* extra barray space is for MCU-row buffers: */
+        (long) ((fullsize_width / DCTSIZE)     /* max width in blocks */
+        * cinfo->max_v_samp_factor             /* max height */
+        * cinfo->num_components                /* max components per scan */
+        * (cinfo->do_block_smoothing ? 4 : 1)),/* how many of these we need */
+        /* no extra "medium"-object space */
+        /* NB: quantizer must get any such objects at color_quant_init time */
+        (long) 0);
+
+
+  /* Loop over scans in file */
+
+  do {
+    
+    /* Prepare for this scan */
+    if (cinfo->comps_in_scan == 1) {
+      noninterleaved_scan_setup(cinfo);
+      /* Need to read Vk MCU rows to obtain Vk block rows */
+      mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
+    } else {
+      interleaved_scan_setup(cinfo);
+      /* in an interleaved scan, one MCU row provides Vk block rows */
+      mcu_rows_per_loop = 1;
+    }
+    
+    /* Allocate scan-local working memory */
+    /* coeff_data holds a single MCU row of coefficient blocks */
+    coeff_data = alloc_MCU_row(cinfo);
+    /* if doing cross-block smoothing, need extra space for its input */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+    if (cinfo->do_block_smoothing) {
+      bsmooth[0] = alloc_MCU_row(cinfo);
+      bsmooth[1] = alloc_MCU_row(cinfo);
+      bsmooth[2] = alloc_MCU_row(cinfo);
+    }
+#endif
+    /* subsampled_data is sample data before unsubsampling */
+    alloc_sampling_buffer(cinfo, subsampled_data);
+
+    /* line up the big buffers */
+    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+      fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
+       (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
+        (long) 0, TRUE);
+    }
+    
+    /* Initialize to read scan data */
+    
+    (*cinfo->methods->entropy_decoder_init) (cinfo);
+    (*cinfo->methods->unsubsample_init) (cinfo);
+    (*cinfo->methods->disassemble_init) (cinfo);
+    
+    /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
+    
+    pixel_rows_output = 0;
+    whichss = 1;               /* arrange to start with subsampled_data[0] */
+    
+    for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
+        cur_mcu_row += mcu_rows_per_loop) {
+      whichss ^= 1;            /* switch to other subsample buffer */
+
+      /* Obtain v_samp_factor block rows of each component in the scan. */
+      /* This is a single MCU row if interleaved, multiple MCU rows if not. */
+      /* In the noninterleaved case there might be fewer than v_samp_factor */
+      /* block rows remaining; if so, pad with copies of the last pixel row */
+      /* so that unsubsampling doesn't have to treat it as a special case. */
+      
+      for (ri = 0; ri < mcu_rows_per_loop; ri++) {
+       if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
+         /* OK to actually read an MCU row. */
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+         if (cinfo->do_block_smoothing)
+           get_smoothed_row(cinfo, coeff_data,
+                            bsmooth, &whichb, cur_mcu_row + ri);
+         else
+#endif
+           (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
+         
+         reverse_DCT(cinfo, coeff_data, subsampled_data[whichss],
+                     ri * DCTSIZE);
+       } else {
+         /* Need to pad out with copies of the last subsampled row. */
+         /* This can only happen if there is just one component. */
+         duplicate_row(subsampled_data[whichss][0],
+                       cinfo->cur_comp_info[0]->subsampled_width,
+                       ri * DCTSIZE - 1, DCTSIZE);
+       }
+      }
+      
+      /* Unsubsample the data */
+      /* First time through is a special case */
+      
+      if (cur_mcu_row) {
+       /* Expand last row group of previous set */
+       expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
+              (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
+              (short) (DCTSIZE-1));
+       /* Realign the big buffers */
+       pixel_rows_output += rows_in_mem;
+       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+         fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
+           (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
+            pixel_rows_output, TRUE);
+       }
+       /* Expand first row group of this set */
+       expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
+              (short) (DCTSIZE+1), (short) 0, (short) 1,
+              (short) 0);
+      } else {
+       /* Expand first row group with dummy above-context */
+       expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
+              (short) (-1), (short) 0, (short) 1,
+              (short) 0);
+      }
+      /* Expand second through next-to-last row groups of this set */
+      for (i = 1; i <= DCTSIZE-2; i++) {
+       expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
+              (short) (i-1), (short) i, (short) (i+1),
+              (short) i);
+      }
+    } /* end of outer loop */
+    
+    /* Expand the last row group with dummy below-context */
+    /* Note whichss points to last buffer side used */
+    expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
+          (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
+          (short) (DCTSIZE-1));
+    
+    /* Clean up after the scan */
+    (*cinfo->methods->disassemble_term) (cinfo);
+    (*cinfo->methods->unsubsample_term) (cinfo);
+    (*cinfo->methods->entropy_decoder_term) (cinfo);
+    (*cinfo->methods->read_scan_trailer) (cinfo);
+
+    /* Release scan-local working memory */
+    free_MCU_row(cinfo, coeff_data);
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+    if (cinfo->do_block_smoothing) {
+      free_MCU_row(cinfo, bsmooth[0]);
+      free_MCU_row(cinfo, bsmooth[1]);
+      free_MCU_row(cinfo, bsmooth[2]);
+    }
+#endif
+    free_sampling_buffer(cinfo, subsampled_data);
+    
+    /* Repeat if there is another scan */
+  } while ((*cinfo->methods->read_scan_header) (cinfo));
+
+  /* Now that we've collected all the data, color convert & output it. */
+
+  for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height;
+       pixel_rows_output += rows_in_mem) {
+
+    /* realign the big buffers */
+    for (ci = 0; ci < cinfo->num_components; ci++) {
+      fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
+       (fullsize_image[ci], pixel_rows_output, FALSE);
+    }
+
+    emit_1pass (cinfo,
+               (int) MIN(rows_in_mem, cinfo->image_height-pixel_rows_output),
+               fullsize_ptrs, color_data);
+  }
+
+  /* Release working memory */
+  free_sampimage(cinfo, color_data, (int) cinfo->color_out_comps,
+                (long) rows_in_mem);
+  if (cinfo->quantize_colors)
+    (*cinfo->emethods->free_small_sarray)
+               (quantize_out, (long) rows_in_mem);
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    (*cinfo->emethods->free_big_sarray) (fullsize_image[ci]);
+  }
+  (*cinfo->emethods->free_small) ((void *) fullsize_image);
+  (*cinfo->emethods->free_small) ((void *) fullsize_ptrs);
+
+  /* Close up shop */
+  if (cinfo->quantize_colors)
+    (*cinfo->methods->color_quant_term) (cinfo);
+}
+
+#endif /* MULTISCAN_FILES_SUPPORTED */
+
+
+/*
+ * Decompression pipeline controller used for multiple-scan files
+ * with 2-pass color quantization.
+ */
+
+#ifdef MULTISCAN_FILES_SUPPORTED
+#ifdef QUANT_2PASS_SUPPORTED
+
+METHODDEF void
+multi_2quant_dcontroller (decompress_info_ptr cinfo)
+{
+  ERREXIT(cinfo->emethods, "Not implemented yet");
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
+#endif /* MULTISCAN_FILES_SUPPORTED */
+
+
+/*
+ * The method selection routine for decompression pipeline controllers.
+ * Note that at this point we've already read the JPEG header and first SOS,
+ * so we can tell whether the input is one scan or not.
+ */
+
+GLOBAL void
+jseldpipeline (decompress_info_ptr cinfo)
+{
+  /* simplify subsequent tests on color quantization */
+  if (! cinfo->quantize_colors)
+    cinfo->two_pass_quantize = FALSE;
+  
+  if (cinfo->comps_in_scan == cinfo->num_components) {
+    /* It's a single-scan file */
+#ifdef QUANT_2PASS_SUPPORTED
+    if (cinfo->two_pass_quantize)
+      cinfo->methods->d_pipeline_controller = single_2quant_dcontroller;
+    else
+#endif
+      cinfo->methods->d_pipeline_controller = single_dcontroller;
+  } else {
+    /* It's a multiple-scan file */
+#ifdef MULTISCAN_FILES_SUPPORTED
+#ifdef QUANT_2PASS_SUPPORTED
+    if (cinfo->two_pass_quantize)
+      cinfo->methods->d_pipeline_controller = multi_2quant_dcontroller;
+    else
+#endif
+      cinfo->methods->d_pipeline_controller = multi_dcontroller;
+#else
+    ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
+#endif
+  }
+}
diff --git a/jdsample.c b/jdsample.c
new file mode 100644 (file)
index 0000000..15dbf4f
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * jdsample.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains un-subsampling routines.
+ * These routines are invoked via the unsubsample and
+ * unsubsample_init/term methods.
+ */
+
+#include "jinclude.h"
+
+
+/*
+ * Initialize for un-subsampling a scan.
+ */
+
+METHODDEF void
+unsubsample_init (decompress_info_ptr cinfo)
+{
+  /* no work for now */
+}
+
+
+/*
+ * Un-subsample pixel values of a single component.
+ * This version only handles integral sampling ratios.
+ */
+
+METHODDEF void
+unsubsample (decompress_info_ptr cinfo, int which_component,
+            long input_cols, int input_rows,
+            long output_cols, int output_rows,
+            JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
+            JSAMPARRAY output_data)
+{
+  jpeg_component_info * compptr = cinfo->cur_comp_info[which_component];
+  short h_expand, v_expand, h, v;
+  int inrow, outrow;
+  long incol;
+  JSAMPROW inptr, outptr;
+  JSAMPLE invalue;
+
+  /* TEMP FOR DEBUGGING PIPELINE CONTROLLER */
+  if (input_rows != compptr->v_samp_factor ||
+      output_rows != cinfo->max_v_samp_factor ||
+      (input_cols % compptr->h_samp_factor) != 0 ||
+      (output_cols % cinfo->max_h_samp_factor) != 0 ||
+      output_cols*compptr->h_samp_factor != input_cols*cinfo->max_h_samp_factor)
+    ERREXIT(cinfo->emethods, "Bogus unsubsample parameters");
+
+  h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
+  v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
+
+  outrow = 0;
+  for (inrow = 0; inrow < input_rows; inrow++) {
+    for (v = 0; v < v_expand; v++) {
+      inptr = input_data[inrow];
+      outptr = output_data[outrow++];
+      for (incol = 0; incol < input_cols; incol++) {
+       invalue = GETJSAMPLE(*inptr++);
+       for (h = 0; h < h_expand; h++) {
+         *outptr++ = invalue;
+       }
+      }
+    }
+  }
+}
+
+
+/*
+ * Un-subsample pixel values of a single component.
+ * This version handles the special case of a full-size component.
+ */
+
+METHODDEF void
+fullsize_unsubsample (decompress_info_ptr cinfo, int which_component,
+                     long input_cols, int input_rows,
+                     long output_cols, int output_rows,
+                     JSAMPARRAY above, JSAMPARRAY input_data, JSAMPARRAY below,
+                     JSAMPARRAY output_data)
+{
+  if (input_cols != output_cols || input_rows != output_rows) /* DEBUG */
+    ERREXIT(cinfo->emethods, "Pipeline controller messed up");
+
+  jcopy_sample_rows(input_data, 0, output_data, 0, output_rows, output_cols);
+}
+
+
+
+/*
+ * Clean up after a scan.
+ */
+
+METHODDEF void
+unsubsample_term (decompress_info_ptr cinfo)
+{
+  /* no work for now */
+}
+
+
+
+/*
+ * The method selection routine for unsubsampling.
+ * Note that we must select a routine for each component.
+ */
+
+GLOBAL void
+jselunsubsample (decompress_info_ptr cinfo)
+{
+  short ci;
+  jpeg_component_info * compptr;
+
+  if (cinfo->CCIR601_sampling)
+    ERREXIT(cinfo->emethods, "CCIR601 subsampling not implemented yet");
+
+  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+    compptr = cinfo->cur_comp_info[ci];
+    if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
+       compptr->v_samp_factor == cinfo->max_v_samp_factor)
+      cinfo->methods->unsubsample[ci] = fullsize_unsubsample;
+    else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
+            (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0)
+      cinfo->methods->unsubsample[ci] = unsubsample;
+    else
+      ERREXIT(cinfo->emethods, "Fractional subsampling not implemented yet");
+  }
+
+  cinfo->methods->unsubsample_init = unsubsample_init;
+  cinfo->methods->unsubsample_term = unsubsample_term;
+}
diff --git a/jerror.c b/jerror.c
new file mode 100644 (file)
index 0000000..591b185
--- /dev/null
+++ b/jerror.c
@@ -0,0 +1,67 @@
+/*
+ * jerror.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains simple error-reporting and trace-message routines.
+ * These are suitable for Unix-like systems and others where writing to
+ * stderr is the right thing to do.  If the JPEG software is integrated
+ * into a larger application, you may well need to replace these.
+ *
+ * The error_exit() routine should not return to its caller.  Within a
+ * larger application, you might want to have it do a longjmp() to return
+ * control to the outer user interface routine.  This should work since
+ * the portable JPEG code doesn't use setjmp/longjmp.  However, this won't
+ * release allocated memory or close temp files --- some bookkeeping would
+ * need to be added to the memory manager module to make that work.
+ *
+ * These routines are used by both the compression and decompression code.
+ */
+
+#include "jinclude.h"
+#ifdef __STDC__
+#include <stdlib.h>            /* to declare exit() */
+#endif
+
+
+static external_methods_ptr methods; /* saved for access to message_parm */
+
+
+METHODDEF void
+trace_message (char *msgtext)
+{
+  fprintf(stderr, msgtext,
+         methods->message_parm[0], methods->message_parm[1],
+         methods->message_parm[2], methods->message_parm[3],
+         methods->message_parm[4], methods->message_parm[5],
+         methods->message_parm[6], methods->message_parm[7]);
+  fprintf(stderr, "\n");
+}
+
+
+METHODDEF void
+error_exit (char *msgtext)
+{
+  trace_message(msgtext);
+  exit(1);
+}
+
+
+/*
+ * The method selection routine for simple error handling.
+ * The system-dependent setup routine should call this routine
+ * to install the necessary method pointers in the supplied struct.
+ */
+
+GLOBAL void
+jselerror (external_methods_ptr emethods)
+{
+  methods = emethods;          /* save struct addr for msg parm access */
+
+  emethods->error_exit = error_exit;
+  emethods->trace_message = trace_message;
+
+  emethods->trace_level = 0;   /* default = no tracing */
+}
diff --git a/jfwddct.c b/jfwddct.c
new file mode 100644 (file)
index 0000000..58291ac
--- /dev/null
+++ b/jfwddct.c
@@ -0,0 +1,179 @@
+/*
+ * jfwddct.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the basic DCT (Discrete Cosine Transform)
+ * transformation subroutine.
+ *
+ * This implementation is based on Appendix A.2 of the book
+ * "Discrete Cosine Transform---Algorithms, Advantages, Applications"
+ * by K.R. Rao and P. Yip  (Academic Press, Inc, London, 1990).
+ * It uses scaled fixed-point arithmetic instead of floating point.
+ */
+
+#include "jinclude.h"
+
+
+/* The poop on this scaling stuff is as follows:
+ *
+ * Most of the numbers (after multiplication by the constants) are
+ * (logically) shifted left by LG2_DCT_SCALE. This is undone by UNFIXH
+ * before assignment to the output array. Note that we want an additional
+ * division by 2 on the output (required by the equations).
+ *
+ * If right shifts are unsigned, then there is a potential problem.
+ * However, shifting right by 16 and then assigning to a short
+ * (assuming short = 16 bits) will keep the sign right!!
+ *
+ * For other shifts,
+ *
+ *     ((x + (1 << 30)) >> shft) - (1 << (30 - shft))
+ *
+ * gives a nice right shift with sign (assuming no overflow). However, all the
+ * scaling is such that this isn't a problem. (Is this true?)
+ */
+
+
+#define ONE 1L                 /* remove L if long > 32 bits */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define LG2_DCT_SCALE 15
+#define RIGHT_SHIFT(_x,_shft)   ((((_x) + (ONE << 30)) >> (_shft)) - (ONE << (30 - (_shft))))
+#else
+#define LG2_DCT_SCALE 16
+#define RIGHT_SHIFT(_x,_shft)   ((_x) >> (_shft))
+#endif
+
+#define DCT_SCALE (ONE << LG2_DCT_SCALE)
+
+#define LG2_OVERSCALE 2
+#define OVERSCALE (ONE << LG2_OVERSCALE)
+
+#define FIX(x)  ((INT32) ((x) * DCT_SCALE + 0.5))
+#define FIXO(x)  ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5))
+#define UNFIX(x)   RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
+#define UNFIXH(x)  RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
+#define UNFIXO(x)  RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)), LG2_DCT_SCALE-LG2_OVERSCALE)
+#define OVERSH(x)   ((x) << LG2_OVERSCALE)
+
+#define SIN_1_4 FIX(0.7071067811856476)
+#define COS_1_4 SIN_1_4
+
+#define SIN_1_8 FIX(0.3826834323650898)
+#define COS_1_8 FIX(0.9238795325112870)
+#define SIN_3_8 COS_1_8
+#define COS_3_8 SIN_1_8
+
+#define SIN_1_16 FIX(0.1950903220161282)
+#define COS_1_16 FIX(0.9807852804032300)
+#define SIN_7_16 COS_1_16
+#define COS_7_16 SIN_1_16
+
+#define SIN_3_16 FIX(0.5555702330196022)
+#define COS_3_16 FIX(0.8314696123025450)
+#define SIN_5_16 COS_3_16
+#define COS_5_16 SIN_3_16
+
+#define OSIN_1_4 FIXO(0.707106781185647)
+#define OCOS_1_4 OSIN_1_4
+
+#define OSIN_1_8 FIXO(0.3826834323650898)
+#define OCOS_1_8 FIXO(0.9238795325112870)
+#define OSIN_3_8 OCOS_1_8
+#define OCOS_3_8 OSIN_1_8
+
+#define OSIN_1_16 FIXO(0.1950903220161282)
+#define OCOS_1_16 FIXO(0.9807852804032300)
+#define OSIN_7_16 OCOS_1_16
+#define OCOS_7_16 OSIN_1_16
+
+#define OSIN_3_16 FIXO(0.5555702330196022)
+#define OCOS_3_16 FIXO(0.8314696123025450)
+#define OSIN_5_16 OCOS_3_16
+#define OCOS_5_16 OSIN_3_16
+
+
+INLINE
+LOCAL void
+fast_dct_8 (DCTELEM *in, int stride)
+{
+  /* tmp1x are new values of tmpx -- flashy register colourers
+   * should be able to do this lot very well
+   */
+  INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+  INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17;
+  INT32 tmp25, tmp26;
+  INT32 in0, in1, in2, in3, in4, in5, in6, in7;
+  
+  in0 = in[       0];
+  in1 = in[stride  ];
+  in2 = in[stride*2];
+  in3 = in[stride*3];
+  in4 = in[stride*4];
+  in5 = in[stride*5];
+  in6 = in[stride*6];
+  in7 = in[stride*7];
+  
+  tmp0 = in7 + in0;
+  tmp1 = in6 + in1;
+  tmp2 = in5 + in2;
+  tmp3 = in4 + in3;
+  tmp4 = in3 - in4;
+  tmp5 = in2 - in5;
+  tmp6 = in1 - in6;
+  tmp7 = in0 - in7;
+  
+  tmp10 = tmp3 + tmp0 ;
+  tmp11 = tmp2 + tmp1 ;
+  tmp12 = tmp1 - tmp2 ;
+  tmp13 = tmp0 - tmp3 ;
+  
+  /* Now using tmp10, tmp11, tmp12, tmp13 */
+  
+  in[       0] = UNFIXH((tmp10 + tmp11) * SIN_1_4);
+  in[stride*4] = UNFIXH((tmp10 - tmp11) * COS_1_4);
+  
+  in[stride*2] = UNFIXH(tmp13*COS_1_8 + tmp12*SIN_1_8);
+  in[stride*6] = UNFIXH(tmp13*SIN_1_8 - tmp12*COS_1_8);
+  
+  tmp16 = UNFIXO((tmp6 + tmp5) * SIN_1_4);
+  tmp15 = UNFIXO((tmp6 - tmp5) * COS_1_4);
+  
+  /* Now using tmp10, tmp11, tmp13, tmp14, tmp15, tmp16 */
+  
+  tmp14 = OVERSH(tmp4) + tmp15;
+  tmp25 = OVERSH(tmp4) - tmp15;
+  tmp26 = OVERSH(tmp7) - tmp16;
+  tmp17 = OVERSH(tmp7) + tmp16;
+  
+  /* These are now overscaled by OVERSCALE */
+  
+  /* tmp10, tmp11, tmp12, tmp13, tmp14, tmp25, tmp26, tmp17 */
+  
+  in[stride  ] = UNFIXH(tmp17*OCOS_1_16 + tmp14*OSIN_1_16);
+  in[stride*7] = UNFIXH(tmp17*OCOS_7_16 - tmp14*OSIN_7_16);
+  in[stride*5] = UNFIXH(tmp26*OCOS_5_16 + tmp25*OSIN_5_16);
+  in[stride*3] = UNFIXH(tmp26*OCOS_3_16 - tmp25*OSIN_3_16);
+}
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ *
+ * Note that this code is specialized to the case DCTSIZE = 8.
+ */
+
+GLOBAL void
+j_fwd_dct (DCTBLOCK data)
+{
+  int i;
+  
+  for (i = 0; i < DCTSIZE; i++)
+    fast_dct_8(data+i*DCTSIZE, 1);
+
+  for (i = 0; i < DCTSIZE; i++)
+    fast_dct_8(data+i, DCTSIZE);
+}
diff --git a/jinclude.h b/jinclude.h
new file mode 100644 (file)
index 0000000..ec7a7e8
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * jinclude.h
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This is the central file that's #include'd by all the JPEG .c files.
+ * Its purpose is to provide a single place to fix any problems with
+ * including the wrong system include files.
+ * You can edit these declarations if you use a system with nonstandard
+ * system include files.
+ */
+
+
+/*
+ * <stdio.h> is included to get the FILE typedef and NULL macro.
+ * Note that the core portable-JPEG files do not actually do any I/O
+ * using the stdio library; only the user interface, error handler,
+ * and file reading/writing modules invoke any stdio functions.
+ * (Well, we did cheat a bit in jvirtmem.c, but only if MEM_STATS is defined.)
+ */
+
+#include <stdio.h>
+
+/*
+ * We need the size_t typedef, which defines the parameter type of malloc().
+ * In an ANSI-conforming implementation this is provided by <stdio.h>,
+ * but on non-ANSI systems it's more likely to be in <sys/types.h>.
+ */
+
+#ifndef __STDC__               /* shouldn't need this if __STDC__ */
+#include <sys/types.h>
+#endif
+
+/*
+ * In ANSI C, and indeed any rational implementation, size_t is also the
+ * type returned by sizeof().  However, it seems there are some irrational
+ * implementations out there, in which sizeof() returns an int even though
+ * size_t is defined as long or unsigned long.  To ensure consistent results
+ * we always use this SIZEOF() macro in place of using sizeof() directly.
+ */
+
+#define SIZEOF(object) ((size_t) sizeof(object))
+
+/*
+ * We need the memcpy() and strcmp() functions, plus memory zeroing.
+ * ANSI and System V implementations declare these in <string.h>.
+ * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
+ * NOTE: we assume the size parameters to these functions are of type size_t.
+ * Insert casts in these macros if not!
+ */
+
+#ifdef __STDC__
+#include <string.h>
+#define MEMZERO(voidptr,size)  memset((voidptr), 0, (size))
+#else /* not STDC */
+#ifdef BSD
+#include <strings.h>
+#define MEMZERO(voidptr,size)  bzero((voidptr), (size))
+#define memcpy(dest,src,size)  bcopy((src), (dest), (size))
+#else /* not BSD, assume Sys V or compatible */
+#include <string.h>
+#define MEMZERO(voidptr,size)  memset((voidptr), 0, (size))
+#endif /* BSD */
+#endif /* STDC */
+
+
+/* Now include the portable JPEG definition files. */
+
+#include "jconfig.h"
+
+#include "jpegdata.h"
diff --git a/jpegdata.h b/jpegdata.h
new file mode 100644 (file)
index 0000000..3e4d753
--- /dev/null
@@ -0,0 +1,812 @@
+/*
+ * jpegdata.h
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines shared data structures for the various JPEG modules.
+ */
+
+
+/*
+ * You might need to change some of the following declarations if you are
+ * using the JPEG software within a surrounding application program
+ * or porting it to an unusual system.
+ */
+
+
+/* If the source or destination of image data is not to be stdio streams,
+ * these types may need work.  You can replace them with some kind of
+ * pointer or indicator that is useful to you, or just ignore 'em.
+ * Note that the user interface and the various jrdxxx/jwrxxx modules
+ * will also need work for non-stdio input/output.
+ */
+
+typedef FILE * JFILEREF;       /* source or dest of JPEG-compressed data */
+
+typedef FILE * IFILEREF;       /* source or dest of non-JPEG image data */
+
+
+/* These defines are used in all function definitions and extern declarations.
+ * You could modify them if you need to change function linkage conventions,
+ * as is shown below for use with C++.  Another application would be to make
+ * all functions global for use with code profilers that require it.
+ * NOTE: the C++ test does the right thing if you are reading this include
+ * file in a C++ application to link to JPEG code that's been compiled with a
+ * regular C compiler.  I'm not sure it works if you try to compile the JPEG
+ * code with C++.
+ */
+
+#define METHODDEF static       /* a function called through method pointers */
+#define LOCAL    static        /* a function used only in its module */
+#define GLOBAL                 /* a function referenced thru EXTERNs */
+#ifdef __cplusplus
+#define EXTERN   extern "C"    /* a reference to a GLOBAL function */
+#else
+#define EXTERN   extern        /* a reference to a GLOBAL function */
+#endif
+
+
+/* Here is the pseudo-keyword for declaring pointers that must be "far"
+ * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
+ * by just saying "FAR *" where such a pointer is needed.  In a few places
+ * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
+ */
+
+#ifdef NEED_FAR_POINTERS
+#define FAR  far
+#else
+#define FAR
+#endif
+
+
+
+/* The remaining declarations are not system-dependent, we hope. */
+
+
+/*
+ * NOTE: if you have an ancient, strict-K&R C compiler, it may choke on the
+ * similarly-named fields in compress_info_struct and decompress_info_struct.
+ * If this happens, you can get around it by rearranging the two structs so
+ * that the similarly-named fields appear first and in the same order in
+ * each struct.  Since such compilers are now pretty rare, we haven't done
+ * this in the portable code, preferring to maintain a logical ordering.
+ */
+
+
+
+/* This macro is used to declare a "method", that is, a function pointer. */
+/* We want to supply prototype parameters if the compiler can cope. */
+/* Note that the arglist parameter must be parenthesized! */
+
+#ifdef PROTO
+#define METHOD(type,methodname,arglist)  type (*methodname) arglist
+#else
+#define METHOD(type,methodname,arglist)  type (*methodname) ()
+#endif
+
+/* Forward references to lists of method pointers */
+typedef struct external_methods_struct * external_methods_ptr;
+typedef struct compress_methods_struct * compress_methods_ptr;
+typedef struct decompress_methods_struct * decompress_methods_ptr;
+
+
+/* Data structures for images containing either samples or coefficients. */
+/* Note that the topmost (leftmost) index is always color component. */
+/* On 80x86 machines, the image arrays are too big for near pointers, */
+/* but the pointer arrays can fit in near memory. */
+
+typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */
+typedef JSAMPROW *JSAMPARRAY;  /* ptr to some rows (a 2-D sample array) */
+typedef JSAMPARRAY *JSAMPIMAGE;        /* a 3-D sample array: top index is color */
+
+
+#define DCTSIZE                8       /* The basic DCT block is 8x8 samples */
+#define DCTSIZE2       64      /* DCTSIZE squared; # of elements in a block */
+
+typedef JCOEF JBLOCK[DCTSIZE2];        /* one block of coefficients */
+typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */
+typedef JBLOCKROW *JBLOCKARRAY;                /* a 2-D array of coefficient blocks */
+typedef JBLOCKARRAY *JBLOCKIMAGE;      /* a 3-D array of coefficient blocks */
+
+typedef JCOEF FAR *JCOEFPTR;   /* useful in a couple of places */
+
+
+/* The input and output data of the DCT transform subroutines are of
+ * the following type, which need not be the same as JCOEF.
+ * For example, on a machine with fast floating point, it might make sense
+ * to recode the DCT routines to use floating point; then DCTELEM would be
+ * 'float' or 'double'.
+ */
+
+typedef JCOEF DCTELEM;
+typedef DCTELEM DCTBLOCK[DCTSIZE2];
+
+
+/* Types for JPEG compression parameters and working tables. */
+
+
+typedef enum {                 /* defines known color spaces */
+       CS_UNKNOWN,             /* error/unspecified */
+       CS_GRAYSCALE,           /* monochrome (only 1 component) */
+       CS_RGB,                 /* red/green/blue */
+       CS_YCbCr,               /* Y/Cb/Cr (also known as YUV) */
+       CS_YIQ,                 /* Y/I/Q */
+       CS_CMYK                 /* C/M/Y/K */
+} COLOR_SPACE;
+
+
+typedef struct {               /* Basic info about one component */
+  /* These values are fixed over the whole image */
+  /* For compression, they must be supplied by the user interface; */
+  /* for decompression, they are read from the SOF marker. */
+       short component_id;     /* identifier for this component (0..255) */
+       short component_index;  /* its index in SOF or cinfo->comp_info[] */
+       short h_samp_factor;    /* horizontal sampling factor (1..4) */
+       short v_samp_factor;    /* vertical sampling factor (1..4) */
+       short quant_tbl_no;     /* quantization table selector (0..3) */
+  /* These values may vary between scans */
+  /* For compression, they must be supplied by the user interface; */
+  /* for decompression, they are read from the SOS marker. */
+       short dc_tbl_no;        /* DC entropy table selector (0..3) */
+       short ac_tbl_no;        /* AC entropy table selector (0..3) */
+  /* These values are computed during compression or decompression startup */
+       long true_comp_width;   /* component's image width in samples */
+       long true_comp_height;  /* component's image height in samples */
+       /* the above are the logical dimensions of the subsampled image */
+  /* These values are computed before starting a scan of the component */
+       short MCU_width;        /* number of blocks per MCU, horizontally */
+       short MCU_height;       /* number of blocks per MCU, vertically */
+       short MCU_blocks;       /* MCU_width * MCU_height */
+       long subsampled_width;  /* image width in samples, after expansion */
+       long subsampled_height; /* image height in samples, after expansion */
+       /* the above are the true_comp_xxx values rounded up to multiples of */
+       /* the MCU dimensions; these are the working dimensions of the array */
+       /* as it is passed through the DCT or IDCT step.  NOTE: these values */
+       /* differ depending on whether the component is interleaved or not!! */
+} jpeg_component_info;
+
+
+/* DCT coefficient quantization tables.
+ * For 8-bit precision, 'INT16' should be good enough for quantization values;
+ * for more precision, we go for the full 16 bits.  'INT16' provides a useful
+ * speedup on many machines (multiplication & division of JCOEFs by
+ * quantization values is a significant chunk of the runtime).
+ * Note: the values in a QUANT_TBL are always given in zigzag order.
+ */
+#ifdef EIGHT_BIT_SAMPLES
+typedef INT16 QUANT_VAL;       /* element of a quantization table */
+#else
+typedef UINT16 QUANT_VAL;      /* element of a quantization table */
+#endif
+typedef QUANT_VAL QUANT_TBL[DCTSIZE2]; /* A quantization table */
+typedef QUANT_VAL * QUANT_TBL_PTR;     /* pointer to same */
+
+
+typedef struct {               /* A Huffman coding table */
+  /* These two fields directly represent the contents of a JPEG DHT marker */
+       UINT8 bits[17];         /* bits[k] = # of symbols with codes of */
+                               /* length k bits; bits[0] is unused */
+       UINT8 huffval[256];     /* The symbols, in order of incr code length */
+  /* This field is used only during compression.  It's initialized FALSE when
+   * the table is created, and set TRUE when it's been output to the file.
+   */
+       boolean sent_table;     /* TRUE when table has been output */
+  /* The remaining fields are computed from the above to allow more efficient
+   * coding and decoding.  These fields should be considered private to the
+   * Huffman compression & decompression modules.
+   */
+       UINT16 ehufco[256];     /* code for each symbol */
+       char ehufsi[256];       /* length of code for each symbol */
+       UINT16 mincode[17];     /* smallest code of length k */
+       INT32 maxcode[17];      /* largest code of length k (-1 if none) */
+       short valptr[17];       /* huffval[] index of 1st symbol of length k */
+} HUFF_TBL;
+
+
+#define NUM_QUANT_TBLS      4  /* quantization tables are numbered 0..3 */
+#define NUM_HUFF_TBLS       4  /* Huffman tables are numbered 0..3 */
+#define NUM_ARITH_TBLS      16 /* arith-coding tables are numbered 0..15 */
+#define MAX_COMPS_IN_SCAN   4  /* JPEG limit on # of components in one scan */
+#define MAX_SAMP_FACTOR     4  /* JPEG limit on sampling factors */
+#define MAX_BLOCKS_IN_MCU   10 /* JPEG limit on # of blocks in an MCU */
+
+
+/* Working data for compression */
+
+struct compress_info_struct {
+/*
+ * All of these fields shall be established by the user interface before
+ * calling jpeg_compress, or by the input_init or c_ui_method_selection
+ * methods.
+ * Most parameters can be set to reasonable defaults by j_default_compression.
+ * Note that the UI must supply the storage for the main methods struct,
+ * though it sets only a few of the methods there.
+ */
+       compress_methods_ptr methods; /* Points to list of methods to use */
+
+       external_methods_ptr emethods; /* Points to list of methods to use */
+
+       IFILEREF input_file;    /* tells input routines where to read image */
+       JFILEREF output_file;   /* tells output routines where to write JPEG */
+
+       long image_width;       /* input image width */
+       long image_height;      /* input image height */
+       short input_components; /* # of color components in input image */
+
+       short data_precision;   /* bits of precision in image data */
+
+       COLOR_SPACE in_color_space; /* colorspace of input file */
+       COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file */
+
+       double input_gamma;     /* image gamma of input file */
+
+       boolean write_JFIF_header; /* should a JFIF marker be written? */
+       /* These three values are not used by the JPEG code, only copied */
+       /* into the JFIF APP0 marker.  density_unit can be 0 for unknown, */
+       /* 1 for dots/inch, or 2 for dots/cm.  Note that the pixel aspect */
+       /* ratio is defined by X_density/Y_density even when density_unit=0. */
+       UINT8 density_unit;     /* JFIF code for pixel size units */
+       UINT16 X_density;       /* Horizontal pixel density */
+       UINT16 Y_density;       /* Vertical pixel density */
+
+       short num_components;   /* # of color components in JPEG image */
+       jpeg_component_info * comp_info;
+       /* comp_info[i] describes component that appears i'th in SOF */
+
+       QUANT_TBL_PTR quant_tbl_ptrs[NUM_QUANT_TBLS];
+       /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+       HUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+       HUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+       /* ptrs to Huffman coding tables, or NULL if not defined */
+
+       UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arithmetic-coding tables */
+       UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arithmetic-coding tables */
+       UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arithmetic-coding tables */
+
+       boolean arith_code;     /* TRUE=arithmetic coding, FALSE=Huffman */
+       boolean interleave;     /* TRUE=interleaved output, FALSE=not */
+       boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
+       boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+
+       UINT16 restart_interval;/* MDUs per restart interval, or 0 for no restart */
+
+/*
+ * These fields are computed during jpeg_compress startup
+ */
+       short max_h_samp_factor; /* largest h_samp_factor */
+       short max_v_samp_factor; /* largest v_samp_factor */
+
+/*
+ * These fields are valid during any one scan
+ */
+       short comps_in_scan;    /* # of JPEG components output this time */
+       jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+       /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+       long MCUs_per_row;      /* # of MCUs across the image */
+       long MCU_rows_in_scan;  /* # of MCU rows in the image */
+
+       short blocks_in_MCU;    /* # of DCT blocks per MCU */
+       short MCU_membership[MAX_BLOCKS_IN_MCU];
+       /* MCU_membership[i] is index in cur_comp_info of component owning */
+       /* i'th block in an MCU */
+
+       /* these fields are private data for the entropy encoder */
+       JCOEF last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each comp */
+       JCOEF last_dc_diff[MAX_COMPS_IN_SCAN]; /* last DC diff for each comp */
+       UINT16 restarts_to_go;  /* MDUs left in this restart interval */
+       short next_restart_num; /* # of next RSTn marker (0..7) */
+};
+
+typedef struct compress_info_struct * compress_info_ptr;
+
+
+/* Working data for decompression */
+
+struct decompress_info_struct {
+/*
+ * These fields shall be established by the user interface before
+ * calling jpeg_decompress.  Note that the UI must supply the storage for
+ * the main methods struct, though it sets only a few of the methods there.
+ */
+       decompress_methods_ptr methods; /* Points to list of methods to use */
+
+       external_methods_ptr emethods; /* Points to list of methods to use */
+
+       JFILEREF input_file;    /* tells input routines where to read JPEG */
+       IFILEREF output_file;   /* tells output routines where to write image */
+
+       /* these can be set at d_ui_method_selection time: */
+
+       COLOR_SPACE out_color_space; /* colorspace of output */
+
+       double output_gamma;    /* image gamma wanted in output */
+
+       boolean quantize_colors; /* T if output is a colormapped format */
+       /* the following are ignored if not quantize_colors: */
+       boolean two_pass_quantize;      /* use two-pass color quantization? */
+       boolean use_dithering;          /* want color dithering? */
+       int desired_number_of_colors;   /* number of colors to use */
+
+       boolean do_block_smoothing; /* T = apply cross-block smoothing */
+       boolean do_pixel_smoothing; /* T = apply post-subsampling smoothing */
+
+/*
+ * These fields are used for efficient buffering of data between read_jpeg_data
+ * and the entropy decoding object.  By using a shared buffer, we avoid copying
+ * data and eliminate the need for an "unget" operation at the end of a scan.
+ * The actual source of the data is known only to read_jpeg_data; see the
+ * JGETC macro, below.
+ * Note: the user interface is expected to allocate the input_buffer and
+ * initialize bytes_in_buffer to 0.  Also, for JFIF/raw-JPEG input, the UI
+ * actually supplies the read_jpeg_data method.
+ */
+       char * input_buffer;    /* start of buffer (private to input code) */
+       char * next_input_byte; /* => next byte to read from buffer */
+       int bytes_in_buffer;    /* # of bytes remaining in buffer */
+
+/*
+ * These fields are set by read_file_header or read_scan_header
+ */
+       long image_width;       /* overall image width */
+       long image_height;      /* overall image height */
+
+       short data_precision;   /* bits of precision in image data */
+
+       COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file */
+
+        /* These three values are not used by the JPEG code, merely copied */
+       /* from the JFIF APP0 marker (if any). */
+       UINT8 density_unit;     /* JFIF code for pixel size units */
+       UINT16 X_density;       /* Horizontal pixel density */
+       UINT16 Y_density;       /* Vertical pixel density */
+
+       short num_components;   /* # of color components in JPEG image */
+       jpeg_component_info * comp_info;
+       /* comp_info[i] describes component that appears i'th in SOF */
+
+       QUANT_TBL_PTR quant_tbl_ptrs[NUM_QUANT_TBLS];
+       /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+       HUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+       HUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+       /* ptrs to Huffman coding tables, or NULL if not defined */
+
+       UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+       UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+       UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+       boolean arith_code;     /* TRUE=arithmetic coding, FALSE=Huffman */
+       boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+
+       UINT16 restart_interval;/* MDUs per restart interval, or 0 for no restart */
+
+/*
+ * These fields are computed during jpeg_decompress startup
+ */
+       short max_h_samp_factor; /* largest h_samp_factor */
+       short max_v_samp_factor; /* largest v_samp_factor */
+
+       short color_out_comps;  /* # of color components output by color_convert */
+                               /* (need not match num_components) */
+       short final_out_comps;  /* # of color components in output image */
+       /* (1 when quantizing colors, else same as color_out_comps) */
+
+/*
+ * These fields are valid during any one scan
+ */
+       short comps_in_scan;    /* # of JPEG components input this time */
+       jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+       /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+       long MCUs_per_row;      /* # of MCUs across the image */
+       long MCU_rows_in_scan;  /* # of MCU rows in the image */
+
+       short blocks_in_MCU;    /* # of DCT blocks per MCU */
+       short MCU_membership[MAX_BLOCKS_IN_MCU];
+       /* MCU_membership[i] is index in cur_comp_info of component owning */
+       /* i'th block in an MCU */
+
+       /* these fields are private data for the entropy encoder */
+       JCOEF last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each comp */
+       JCOEF last_dc_diff[MAX_COMPS_IN_SCAN]; /* last DC diff for each comp */
+       UINT16 restarts_to_go;  /* MDUs left in this restart interval */
+       short next_restart_num; /* # of next RSTn marker (0..7) */
+};
+
+typedef struct decompress_info_struct * decompress_info_ptr;
+
+
+/* Macros for reading data from the decompression input buffer */
+
+#ifdef CHAR_IS_UNSIGNED
+#define JGETC(cinfo)   ( --(cinfo)->bytes_in_buffer < 0 ? \
+                        (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
+                        (int) *(cinfo)->next_input_byte++ )
+#else
+#define JGETC(cinfo)   ( --(cinfo)->bytes_in_buffer < 0 ? \
+                        (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
+                        (int) (*(cinfo)->next_input_byte++) & 0xFF )
+#endif
+
+#define JUNGETC(ch,cinfo)  ((cinfo)->bytes_in_buffer++, \
+                           *(--((cinfo)->next_input_byte)) = (ch))
+
+#define MIN_UNGET      2       /* may always do at least 2 JUNGETCs */
+
+
+/* A virtual image has a control block whose contents are private to the
+ * memory manager module (and may differ between managers).  The rest of the
+ * code only refers to virtual images by these pointer types.
+ */
+
+typedef struct big_sarray_control * big_sarray_ptr;
+typedef struct big_barray_control * big_barray_ptr;
+
+
+/* Method types that need typedefs */
+
+typedef METHOD(void, MCU_output_method_ptr, (compress_info_ptr cinfo,
+                                            JBLOCK *MCU_data));
+typedef METHOD(void, MCU_output_caller_ptr, (compress_info_ptr cinfo,
+                                            MCU_output_method_ptr output_method));
+typedef METHOD(void, subsample_ptr, (compress_info_ptr cinfo,
+                                    int which_component,
+                                    long input_cols, int input_rows,
+                                    long output_cols, int output_rows,
+                                    JSAMPARRAY above,
+                                    JSAMPARRAY input_data,
+                                    JSAMPARRAY below,
+                                    JSAMPARRAY output_data));
+typedef METHOD(void, unsubsample_ptr, (decompress_info_ptr cinfo,
+                                      int which_component,
+                                      long input_cols, int input_rows,
+                                      long output_cols, int output_rows,
+                                      JSAMPARRAY above,
+                                      JSAMPARRAY input_data,
+                                      JSAMPARRAY below,
+                                      JSAMPARRAY output_data));
+typedef METHOD(void, quantize_method_ptr, (decompress_info_ptr cinfo,
+                                          int num_rows,
+                                          JSAMPIMAGE input_data,
+                                          JSAMPARRAY output_workspace));
+typedef METHOD(void, quantize_caller_ptr, (decompress_info_ptr cinfo,
+                                          quantize_method_ptr quantize_method));
+
+
+/* These structs contain function pointers for the various JPEG methods. */
+
+/* Routines to be provided by the surrounding application, rather than the
+ * portable JPEG code proper.  These are the same for compression and
+ * decompression.
+ */
+
+struct external_methods_struct {
+       /* User interface: error exit and trace message routines */
+       /* NOTE: the string msgtext parameters will eventually be replaced */
+       /* by an enumerated-type code so that non-English error messages */
+       /* can be substituted easily.  This will not be done until all the */
+       /* code is in place, so that we know what messages are needed. */
+       METHOD(void, error_exit, (char *msgtext));
+       METHOD(void, trace_message, (char *msgtext));
+
+       /* Working data for error/trace facility */
+       /* See macros below for the usage of these variables */
+       int trace_level;        /* level of detail of tracing messages */
+       /* Use level 0 for unsuppressable messages (nonfatal errors) */
+       /* Use levels 1, 2, 3 for successively more detailed trace options */
+
+       int message_parm[8];    /* store numeric parms for messages here */
+
+       /* Memory management */
+       /* NB: alloc routines never return NULL. They exit to */
+       /* error_exit if not successful. */
+       METHOD(void *, alloc_small, (size_t sizeofobject));
+       METHOD(void, free_small, (void *ptr));
+#ifdef NEED_FAR_POINTERS       /* routines for getting far-heap space */
+       METHOD(void FAR *, alloc_medium, (size_t sizeofobject));
+       METHOD(void, free_medium, (void FAR *ptr));
+#else
+#define alloc_medium alloc_small
+#define free_medium  free_small
+#endif
+       METHOD(JSAMPARRAY, alloc_small_sarray, (long samplesperrow,
+                                               long numrows));
+       METHOD(void, free_small_sarray, (JSAMPARRAY ptr,
+                                        long numrows));
+       METHOD(JBLOCKARRAY, alloc_small_barray, (long blocksperrow,
+                                                long numrows));
+       METHOD(void, free_small_barray, (JBLOCKARRAY ptr,
+                                        long numrows));
+       METHOD(big_sarray_ptr, request_big_sarray, (long samplesperrow,
+                                                   long numrows,
+                                                   long unitheight));
+       METHOD(big_barray_ptr, request_big_barray, (long blocksperrow,
+                                                   long numrows,
+                                                   long unitheight));
+       METHOD(void, alloc_big_arrays, (long extra_small_samples,
+                                       long extra_small_blocks,
+                                       long extra_medium_space));
+       METHOD(JSAMPARRAY, access_big_sarray, (big_sarray_ptr ptr,
+                                              long start_row,
+                                              boolean writable));
+       METHOD(JBLOCKARRAY, access_big_barray, (big_barray_ptr ptr,
+                                               long start_row,
+                                               boolean writable));
+       METHOD(void, free_big_sarray, (big_sarray_ptr ptr));
+       METHOD(void, free_big_barray, (big_barray_ptr ptr));
+};
+
+/* Macros to simplify using the error and trace message stuff */
+/* The first parameter is generally cinfo->emethods */
+
+#define ERREXIT(emeth,msg)             ((*(emeth)->error_exit) (msg))
+#define ERREXIT1(emeth,msg,p1)         ((emeth)->message_parm[0] = (p1), \
+                                        (*(emeth)->error_exit) (msg))
+#define ERREXIT2(emeth,msg,p1,p2)      ((emeth)->message_parm[0] = (p1), \
+                                        (emeth)->message_parm[1] = (p2), \
+                                        (*(emeth)->error_exit) (msg))
+#define ERREXIT3(emeth,msg,p1,p2,p3)   ((emeth)->message_parm[0] = (p1), \
+                                        (emeth)->message_parm[1] = (p2), \
+                                        (emeth)->message_parm[2] = (p3), \
+                                        (*(emeth)->error_exit) (msg))
+#define ERREXIT4(emeth,msg,p1,p2,p3,p4) ((emeth)->message_parm[0] = (p1), \
+                                        (emeth)->message_parm[1] = (p2), \
+                                        (emeth)->message_parm[2] = (p3), \
+                                        (emeth)->message_parm[3] = (p4), \
+                                        (*(emeth)->error_exit) (msg))
+
+#define TRACEMS(emeth,lvl,msg)    \
+  ( (emeth)->trace_level >= (lvl) ? \
+   ((*(emeth)->trace_message) (msg), 0) : 0)
+#define TRACEMS1(emeth,lvl,msg,p1)    \
+  ( (emeth)->trace_level >= (lvl) ? \
+   ((emeth)->message_parm[0] = (p1), \
+    (*(emeth)->trace_message) (msg), 0) : 0)
+#define TRACEMS2(emeth,lvl,msg,p1,p2)    \
+  ( (emeth)->trace_level >= (lvl) ? \
+   ((emeth)->message_parm[0] = (p1), \
+    (emeth)->message_parm[1] = (p2), \
+    (*(emeth)->trace_message) (msg), 0) : 0)
+#define TRACEMS3(emeth,lvl,msg,p1,p2,p3)    \
+  ( (emeth)->trace_level >= (lvl) ? \
+   ((emeth)->message_parm[0] = (p1), \
+    (emeth)->message_parm[1] = (p2), \
+    (emeth)->message_parm[2] = (p3), \
+    (*(emeth)->trace_message) (msg), 0) : 0)
+#define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4)    \
+  ( (emeth)->trace_level >= (lvl) ? \
+   ((emeth)->message_parm[0] = (p1), \
+    (emeth)->message_parm[1] = (p2), \
+    (emeth)->message_parm[2] = (p3), \
+    (emeth)->message_parm[3] = (p4), \
+    (*(emeth)->trace_message) (msg), 0) : 0)
+#define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8)    \
+  ( (emeth)->trace_level >= (lvl) ? \
+   ((emeth)->message_parm[0] = (p1), \
+    (emeth)->message_parm[1] = (p2), \
+    (emeth)->message_parm[2] = (p3), \
+    (emeth)->message_parm[3] = (p4), \
+    (emeth)->message_parm[4] = (p5), \
+    (emeth)->message_parm[5] = (p6), \
+    (emeth)->message_parm[6] = (p7), \
+    (emeth)->message_parm[7] = (p8), \
+    (*(emeth)->trace_message) (msg), 0) : 0)
+
+
+/* Methods used during JPEG compression. */
+
+struct compress_methods_struct {
+       /* Hook for user interface to get control after input_init */
+       METHOD(void, c_ui_method_selection, (compress_info_ptr cinfo));
+       /* Input image reading & conversion to standard form */
+       METHOD(void, input_init, (compress_info_ptr cinfo));
+       METHOD(void, get_input_row, (compress_info_ptr cinfo,
+                                    JSAMPARRAY pixel_row));
+       METHOD(void, input_term, (compress_info_ptr cinfo));
+       /* Gamma and color space conversion */
+       METHOD(void, colorin_init, (compress_info_ptr cinfo));
+       METHOD(void, get_sample_rows, (compress_info_ptr cinfo,
+                                      int rows_to_read,
+                                      JSAMPIMAGE image_data));
+       METHOD(void, colorin_term, (compress_info_ptr cinfo));
+       /* Expand picture data at edges */
+       METHOD(void, edge_expand, (compress_info_ptr cinfo,
+                                  long input_cols, int input_rows,
+                                  long output_cols, int output_rows,
+                                  JSAMPIMAGE image_data));
+       /* Subsample pixel values of a single component */
+       /* There can be a different subsample method for each component */
+       METHOD(void, subsample_init, (compress_info_ptr cinfo));
+       subsample_ptr subsample[MAX_COMPS_IN_SCAN];
+       METHOD(void, subsample_term, (compress_info_ptr cinfo));
+       /* Extract samples in MCU order, process & hand off to output_method */
+       /* The input is always exactly N MCU rows worth of data */
+       METHOD(void, extract_init, (compress_info_ptr cinfo));
+       METHOD(void, extract_MCUs, (compress_info_ptr cinfo,
+                                   JSAMPIMAGE image_data,
+                                   int num_mcu_rows,
+                                   MCU_output_method_ptr output_method));
+       METHOD(void, extract_term, (compress_info_ptr cinfo));
+       /* Entropy encoding parameter optimization */
+       METHOD(void, entropy_optimize, (compress_info_ptr cinfo,
+                                       MCU_output_caller_ptr source_method));
+       /* Entropy encoding */
+       METHOD(void, entropy_encoder_init, (compress_info_ptr cinfo));
+       METHOD(void, entropy_encode, (compress_info_ptr cinfo,
+                                     JBLOCK *MCU_data));
+       METHOD(void, entropy_encoder_term, (compress_info_ptr cinfo));
+       /* JPEG file header construction */
+       METHOD(void, write_file_header, (compress_info_ptr cinfo));
+       METHOD(void, write_scan_header, (compress_info_ptr cinfo));
+       METHOD(void, write_jpeg_data, (compress_info_ptr cinfo,
+                                      char *dataptr,
+                                      int datacount));
+       METHOD(void, write_scan_trailer, (compress_info_ptr cinfo));
+       METHOD(void, write_file_trailer, (compress_info_ptr cinfo));
+       /* Pipeline control */
+       METHOD(void, c_pipeline_controller, (compress_info_ptr cinfo));
+       METHOD(void, entropy_output, (compress_info_ptr cinfo,
+                                     char *dataptr,
+                                     int datacount));
+       /* Overall control */
+       METHOD(void, c_per_scan_method_selection, (compress_info_ptr cinfo));
+};
+
+/* Methods used during JPEG decompression. */
+
+struct decompress_methods_struct {
+       /* Hook for user interface to get control after reading file header */
+       METHOD(void, d_ui_method_selection, (decompress_info_ptr cinfo));
+       /* JPEG file scanning */
+       /* Note: user interface supplies read_jpeg_data for JFIF/raw-JPEG
+        * reading.  For file formats that require random access (eg, TIFF)
+        * the JPEG file header module will override the UI read_jpeg_data.
+        */
+       METHOD(void, read_file_header, (decompress_info_ptr cinfo));
+       METHOD(boolean, read_scan_header, (decompress_info_ptr cinfo));
+       METHOD(int, read_jpeg_data, (decompress_info_ptr cinfo));
+       METHOD(void, read_scan_trailer, (decompress_info_ptr cinfo));
+       METHOD(void, read_file_trailer, (decompress_info_ptr cinfo));
+       /* Entropy decoding */
+       METHOD(void, entropy_decoder_init, (decompress_info_ptr cinfo));
+       METHOD(void, entropy_decode, (decompress_info_ptr cinfo,
+                                     JBLOCK *MCU_data));
+       METHOD(void, entropy_decoder_term, (decompress_info_ptr cinfo));
+       /* MCU disassembly: fetch MCUs from entropy_decode, build coef array */
+       METHOD(void, disassemble_init, (decompress_info_ptr cinfo));
+       METHOD(void, disassemble_MCU, (decompress_info_ptr cinfo,
+                                      JBLOCKIMAGE image_data));
+       METHOD(void, disassemble_term, (decompress_info_ptr cinfo));
+       /* Cross-block smoothing */
+       METHOD(void, smooth_coefficients, (decompress_info_ptr cinfo,
+                                          jpeg_component_info *compptr,
+                                          JBLOCKROW above,
+                                          JBLOCKROW currow,
+                                          JBLOCKROW below,
+                                          JBLOCKROW output));
+       /* Un-subsample pixel values of a single component */
+       /* There can be a different unsubsample method for each component */
+       METHOD(void, unsubsample_init, (decompress_info_ptr cinfo));
+       unsubsample_ptr unsubsample[MAX_COMPS_IN_SCAN];
+       METHOD(void, unsubsample_term, (decompress_info_ptr cinfo));
+       /* Gamma and color space conversion */
+       METHOD(void, colorout_init, (decompress_info_ptr cinfo));
+       METHOD(void, color_convert, (decompress_info_ptr cinfo,
+                                    int num_rows,
+                                    JSAMPIMAGE input_data,
+                                    JSAMPIMAGE output_data));
+       METHOD(void, colorout_term, (decompress_info_ptr cinfo));
+       /* Color quantization */
+       METHOD(void, color_quant_init, (decompress_info_ptr cinfo));
+       METHOD(void, color_quantize, (decompress_info_ptr cinfo,
+                                     int num_rows,
+                                     JSAMPIMAGE input_data,
+                                     JSAMPARRAY output_data));
+       METHOD(void, color_quant_prescan, (decompress_info_ptr cinfo,
+                                          int num_rows,
+                                          JSAMPIMAGE image_data));
+       METHOD(void, color_quant_doit, (decompress_info_ptr cinfo,
+                                       quantize_caller_ptr source_method));
+       METHOD(void, color_quant_term, (decompress_info_ptr cinfo));
+       /* Output image writing */
+       METHOD(void, output_init, (decompress_info_ptr cinfo));
+       METHOD(void, put_color_map, (decompress_info_ptr cinfo,
+                                    int num_colors, JSAMPARRAY colormap));
+       METHOD(void, put_pixel_rows, (decompress_info_ptr cinfo,
+                                     int num_rows,
+                                     JSAMPIMAGE pixel_data));
+       METHOD(void, output_term, (decompress_info_ptr cinfo));
+       /* Pipeline control */
+       METHOD(void, d_pipeline_controller, (decompress_info_ptr cinfo));
+       /* Overall control */
+       METHOD(void, d_per_scan_method_selection, (decompress_info_ptr cinfo));
+};
+
+
+/* External declarations for routines that aren't called via method ptrs. */
+/* Note: use "j" as first char of names to minimize namespace pollution. */
+/* The PP macro hides prototype parameters from compilers that can't cope. */
+
+#ifdef PROTO
+#define PP(arglist)    arglist
+#else
+#define PP(arglist)    ()
+#endif
+
+
+/* main entry for compression */
+EXTERN void jpeg_compress PP((compress_info_ptr cinfo));
+/* default parameter setup for compression */
+EXTERN void j_default_compression PP((compress_info_ptr cinfo, int quality));
+EXTERN void j_monochrome_default PP((compress_info_ptr cinfo));
+EXTERN void j_set_quality PP((compress_info_ptr cinfo, int quality,
+                             boolean force_baseline));
+EXTERN void j_free_defaults PP((compress_info_ptr cinfo));
+
+/* main entry for decompression */
+EXTERN void jpeg_decompress PP((decompress_info_ptr cinfo));
+
+/* forward DCT */
+EXTERN void j_fwd_dct PP((DCTBLOCK data));
+/* inverse DCT */
+EXTERN void j_rev_dct PP((DCTBLOCK data));
+
+/* utility routines in jutils.c */
+EXTERN long jround_up PP((long a, long b));
+EXTERN void jcopy_sample_rows PP((JSAMPARRAY input_array, int source_row,
+                                 JSAMPARRAY output_array, int dest_row,
+                                 int num_rows, long num_cols));
+EXTERN void jcopy_block_row PP((JBLOCKROW input_row, JBLOCKROW output_row,
+                               long num_blocks));
+EXTERN void jzero_far PP((void FAR * target, size_t bytestozero));
+
+/* method selection routines for compression modules */
+EXTERN void jselcpipeline PP((compress_info_ptr cinfo)); /* jcpipe.c */
+EXTERN void jselchuffman PP((compress_info_ptr cinfo)); /* jchuff.c */
+EXTERN void jselcarithmetic PP((compress_info_ptr cinfo)); /* jcarith.c */
+EXTERN void jselexpand PP((compress_info_ptr cinfo)); /* jcexpand.c */
+EXTERN void jselsubsample PP((compress_info_ptr cinfo)); /* jcsample.c */
+EXTERN void jselcmcu PP((compress_info_ptr cinfo)); /* jcmcu.c */
+EXTERN void jselccolor PP((compress_info_ptr cinfo));  /* jccolor.c */
+/* The user interface should call one of these to select input format: */
+EXTERN void jselrgif PP((compress_info_ptr cinfo)); /* jrdgif.c */
+EXTERN void jselrppm PP((compress_info_ptr cinfo)); /* jrdppm.c */
+/* and one of these to select output header format: */
+EXTERN void jselwjfif PP((compress_info_ptr cinfo)); /* jwrjfif.c */
+
+/* method selection routines for decompression modules */
+EXTERN void jseldpipeline PP((decompress_info_ptr cinfo)); /* jdpipe.c */
+EXTERN void jseldhuffman PP((decompress_info_ptr cinfo)); /* jdhuff.c */
+EXTERN void jseldarithmetic PP((decompress_info_ptr cinfo)); /* jdarith.c */
+EXTERN void jseldmcu PP((decompress_info_ptr cinfo)); /* jdmcu.c */
+EXTERN void jselbsmooth PP((decompress_info_ptr cinfo)); /* jbsmooth.c */
+EXTERN void jselunsubsample PP((decompress_info_ptr cinfo)); /* jdsample.c */
+EXTERN void jseldcolor PP((decompress_info_ptr cinfo));        /* jdcolor.c */
+EXTERN void jsel1quantize PP((decompress_info_ptr cinfo)); /* jquant1.c */
+EXTERN void jsel2quantize PP((decompress_info_ptr cinfo)); /* jquant2.c */
+/* The user interface should call one of these to select input format: */
+EXTERN void jselrjfif PP((decompress_info_ptr cinfo)); /* jrdjfif.c */
+/* and one of these to select output image format: */
+EXTERN void jselwgif PP((decompress_info_ptr cinfo)); /* jwrgif.c */
+EXTERN void jselwppm PP((decompress_info_ptr cinfo)); /* jwrppm.c */
+
+/* method selection routines for system-dependent modules */
+EXTERN void jselerror PP((external_methods_ptr emethods)); /* jerror.c */
+EXTERN void jselvirtmem PP((external_methods_ptr emethods)); /* jvirtmem.c */
+
+/* debugging hook in jvirtmem.c */
+#ifdef MEM_STATS
+EXTERN void j_mem_stats PP((void));
+#endif
+
+/* Miscellaneous useful macros */
+
+#define MAX(a,b)       ((a) > (b) ? (a) : (b))
+#define MIN(a,b)       ((a) < (b) ? (a) : (b))
+
+
+#define RST0   0xD0            /* RST0 marker code */
diff --git a/jquant1.c b/jquant1.c
new file mode 100644 (file)
index 0000000..49dfd97
--- /dev/null
+++ b/jquant1.c
@@ -0,0 +1,387 @@
+/*
+ * jquant1.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains 1-pass color quantization (color mapping) routines.
+ * These routines are invoked via the methods color_quantize
+ * and color_quant_init/term.
+ */
+
+#include "jinclude.h"
+
+#ifdef QUANT_1PASS_SUPPORTED
+
+
+/*
+ * This implementation is a fairly dumb, quick-and-dirty quantizer;
+ * it's here mostly so that we can start working on colormapped output formats.
+ *
+ * We quantize to a color map that is selected in advance of seeing the image;
+ * the map depends only on the requested number of colors (at least 8).
+ * The map consists of all combinations of Ncolors[j] color values for each
+ * component j; we choose Ncolors[] based on the requested # of colors.
+ * We always use 0 and MAXJSAMPLE in each color (hence the minimum 8 colors).
+ * Any additional color values are equally spaced between these limits.
+ *
+ * The result almost always needs dithering to look decent.
+ */
+
+#define MAX_COMPONENTS 4       /* max components I can handle */
+
+static int total_colors;       /* Number of distinct output colors */
+static int Ncolors[MAX_COMPONENTS]; /* # of values alloced to each component */
+/* total_colors is the product of the Ncolors[] values */
+
+static JSAMPARRAY colormap;    /* The actual color map */
+/* colormap[i][j] = value of i'th color component for output pixel value j */
+
+static JSAMPARRAY colorindex;  /* Precomputed mapping for speed */
+/* colorindex[i][j] = index of color closest to pixel value j in component i,
+ * premultiplied so that the correct mapped value for a pixel (r,g,b) is:
+ *   colorindex[0][r] + colorindex[1][g] + colorindex[2][b]
+ */
+
+
+/* Declarations for Floyd-Steinberg dithering.
+ * Errors are accumulated into the arrays evenrowerrs[] and oddrowerrs[],
+ * each of which have #colors * (#columns + 2) entries (so that first/last
+ * pixels need not be special cases).  These have resolutions of 1/16th of
+ * a pixel count.  The error at a given pixel is propagated to its unprocessed
+ * neighbors using the standard F-S fractions,
+ *             ...     (here)  7/16
+ *             3/16    5/16    1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * Note: on a wide image, we might not have enough room in a PC's near data
+ * segment to hold the error arrays; so they are allocated with alloc_medium.
+ */
+
+#ifdef EIGHT_BIT_SAMPLES
+typedef short FSERROR;         /* 16 bits should be enough */
+#else
+typedef INT32 FSERROR;         /* may need more than 16 bits? */
+#endif
+
+typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
+
+static FSERRPTR evenrowerrs, oddrowerrs; /* current-row and next-row errors */
+static boolean on_odd_row;     /* flag to remember which row we are on */
+
+
+/*
+ * Initialize for one-pass color quantization.
+ */
+
+METHODDEF void
+color_quant_init (decompress_info_ptr cinfo)
+{
+  int max_colors = cinfo->desired_number_of_colors;
+  int i,j,k, ntc, nci, blksize, blkdist, ptr, val;
+
+  if (cinfo->color_out_comps > MAX_COMPONENTS)
+    ERREXIT1(cinfo->emethods, "Cannot quantize more than %d color components",
+            MAX_COMPONENTS);
+  if (max_colors > (MAXJSAMPLE+1))
+    ERREXIT1(cinfo->emethods, "Cannot request more than %d quantized colors",
+           MAXJSAMPLE+1);
+
+  /* Initialize to 2 color values for each component */
+  total_colors = 1;
+  for (i = 0; i < cinfo->color_out_comps; i++) {
+    Ncolors[i] = 2;
+    total_colors *= 2;
+  }
+  if (total_colors > max_colors)
+    ERREXIT1(cinfo->emethods, "Cannot quantize to fewer than %d colors",
+            total_colors);
+
+  /* Increase the number of color values until requested limit is reached. */
+  /* Note that for standard RGB color space, we will have at least as many */
+  /* red values as green, and at least as many green values as blue. */
+  i = 0;                       /* component index to increase next */
+  /* test calculates ntc = new total_colors if Ncolors[i] is incremented */
+  while ((ntc = (total_colors / Ncolors[i]) * (Ncolors[i]+1)) <= max_colors) {
+    Ncolors[i]++;              /* OK, apply the increment */
+    total_colors = ntc;
+    i++;                       /* advance to next component */
+    if (i >= cinfo->color_out_comps) i = 0;
+  }
+
+  /* Report selected color counts */
+  if (cinfo->color_out_comps == 3)
+    TRACEMS4(cinfo->emethods, 1, "Quantizing to %d = %d*%d*%d colors",
+            total_colors, Ncolors[0], Ncolors[1], Ncolors[2]);
+  else
+    TRACEMS1(cinfo->emethods, 1, "Quantizing to %d colors", total_colors);
+
+  /* Allocate and fill in the colormap and color index. */
+  /* The colors are ordered in the map in standard row-major order, */
+  /* i.e. rightmost (highest-indexed) color changes most rapidly. */
+
+  colormap = (*cinfo->emethods->alloc_small_sarray)
+               ((long) total_colors, (long) cinfo->color_out_comps);
+  colorindex = (*cinfo->emethods->alloc_small_sarray)
+               ((long) (MAXJSAMPLE+1), (long) cinfo->color_out_comps);
+
+  /* blksize is number of adjacent repeated entries for a component */
+  /* blkdist is distance between groups of identical entries for a component */
+  blkdist = total_colors;
+
+  for (i = 0; i < cinfo->color_out_comps; i++) {
+    /* fill in colormap entries for i'th color component */
+    nci = Ncolors[i];          /* # of distinct values for this color */
+    blksize = blkdist / nci;
+    for (j = 0; j < nci; j++) {
+      val = (j * MAXJSAMPLE + (nci-1)/2) / (nci-1); /* j'th value of color */
+      for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
+       /* fill in blksize entries beginning at ptr */
+       for (k = 0; k < blksize; k++)
+         colormap[i][ptr+k] = val;
+      }
+    }
+    blkdist = blksize;         /* blksize of this color is blkdist of next */
+
+    /* fill in colorindex entries for i'th color component */
+    for (j = 0; j <= MAXJSAMPLE; j++) {
+      /* compute index of color closest to pixel value j */
+      val = (j * (nci-1) + CENTERJSAMPLE) / MAXJSAMPLE;
+      /* premultiply so that no multiplication needed in main processing */
+      val *= blksize;
+      colorindex[i][j] = val;
+    }
+  }
+
+  /* Pass the colormap to the output module.  Note that the output */
+  /* module is allowed to save this pointer and use the map during */
+  /* any put_pixel_rows call! */
+  (*cinfo->methods->put_color_map) (cinfo, total_colors, colormap);
+
+  /* Allocate Floyd-Steinberg workspace if necessary */
+  if (cinfo->use_dithering) {
+    size_t arraysize = (cinfo->image_width + 2L) * cinfo->color_out_comps
+                      * SIZEOF(FSERROR);
+
+    evenrowerrs = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
+    oddrowerrs  = (FSERRPTR) (*cinfo->emethods->alloc_medium) (arraysize);
+    /* we only need to zero the forward contribution for current row. */
+    jzero_far((void FAR *) evenrowerrs, arraysize);
+    on_odd_row = FALSE;
+  }
+
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ */
+
+METHODDEF void
+color_quantize (decompress_info_ptr cinfo, int num_rows,
+               JSAMPIMAGE input_data, JSAMPARRAY output_data)
+/* General case, no dithering */
+{
+  register int pixcode, ci;
+  register long col;
+  register int row;
+  register long widthm1 = cinfo->image_width - 1;
+  register int nc = cinfo->color_out_comps;  
+
+  for (row = 0; row < num_rows; row++) {
+    for (col = widthm1; col >= 0; col--) {
+      pixcode = 0;
+      for (ci = 0; ci < nc; ci++) {
+       pixcode += GETJSAMPLE(colorindex[ci]
+                             [GETJSAMPLE(input_data[ci][row][col])]);
+      }
+      output_data[row][col] = pixcode;
+    }
+  }
+}
+
+
+METHODDEF void
+color_quantize3 (decompress_info_ptr cinfo, int num_rows,
+                JSAMPIMAGE input_data, JSAMPARRAY output_data)
+/* Fast path for color_out_comps==3, no dithering */
+{
+  register int pixcode;
+  register JSAMPROW ptr0, ptr1, ptr2, ptrout;
+  register long col;
+  register int row;
+  register long width = cinfo->image_width;
+
+  for (row = 0; row < num_rows; row++) {
+    ptr0 = input_data[0][row];
+    ptr1 = input_data[1][row];
+    ptr2 = input_data[2][row];
+    ptrout = output_data[row];
+    for (col = width; col > 0; col--) {
+      pixcode  = GETJSAMPLE(colorindex[0][GETJSAMPLE(*ptr0++)]);
+      pixcode += GETJSAMPLE(colorindex[1][GETJSAMPLE(*ptr1++)]);
+      pixcode += GETJSAMPLE(colorindex[2][GETJSAMPLE(*ptr2++)]);
+      *ptrout++ = pixcode;
+    }
+  }
+}
+
+
+METHODDEF void
+color_quantize_dither (decompress_info_ptr cinfo, int num_rows,
+                      JSAMPIMAGE input_data, JSAMPARRAY output_data)
+/* General case, with Floyd-Steinberg dithering */
+{
+  register int pixcode, ci;
+  register FSERROR val;
+  register FSERRPTR thisrowerr, nextrowerr;
+  register long col;
+  register int row;
+  register long width = cinfo->image_width;
+  register int nc = cinfo->color_out_comps;  
+
+  for (row = 0; row < num_rows; row++) {
+    if (on_odd_row) {
+      /* work right to left in this row */
+      thisrowerr = oddrowerrs + width*nc;
+      nextrowerr = evenrowerrs + width*nc;
+      for (ci = 0; ci < nc; ci++) /* need only initialize this one entry */
+       nextrowerr[ci] = 0;
+      for (col = width - 1; col >= 0; col--) {
+       /* select the output pixel value */
+       pixcode = 0;
+       for (ci = 0; ci < nc; ci++) {
+         /* compute pixel value + accumulated error */
+         val = (((FSERROR) GETJSAMPLE(input_data[ci][row][col])) << 4)
+               + thisrowerr[ci];
+         if (val < 0) val = 0; /* must watch for range overflow! */
+         else {
+           val += 8;           /* divide by 16 with proper rounding */
+           val >>= 4;
+           if (val > MAXJSAMPLE) val = MAXJSAMPLE;
+         }
+         thisrowerr[ci] = val; /* save for error propagation */
+         pixcode += GETJSAMPLE(colorindex[ci][val]);
+       }
+       output_data[row][col] = pixcode;
+       /* propagate error to adjacent pixels */
+       for (ci = 0; ci < nc; ci++) {
+         val = thisrowerr[ci] - GETJSAMPLE(colormap[ci][pixcode]);
+         thisrowerr[ci-nc] += val * 7;
+         nextrowerr[ci+nc] += val * 3;
+         nextrowerr[ci   ] += val * 5;
+         nextrowerr[ci-nc]  = val; /* not +=, since not initialized yet */
+       }
+       thisrowerr -= nc;       /* advance error ptrs to next pixel entry */
+       nextrowerr -= nc;
+      }
+      on_odd_row = FALSE;
+    } else {
+      /* work left to right in this row */
+      thisrowerr = evenrowerrs + nc;
+      nextrowerr = oddrowerrs + nc;
+      for (ci = 0; ci < nc; ci++) /* need only initialize this one entry */
+       nextrowerr[ci] = 0;
+      for (col = 0; col < width; col++) {
+       /* select the output pixel value */
+       pixcode = 0;
+       for (ci = 0; ci < nc; ci++) {
+         /* compute pixel value + accumulated error */
+         val = (((FSERROR) GETJSAMPLE(input_data[ci][row][col])) << 4)
+               + thisrowerr[ci];
+         if (val < 0) val = 0; /* must watch for range overflow! */
+         else {
+           val += 8;           /* divide by 16 with proper rounding */
+           val >>= 4;
+           if (val > MAXJSAMPLE) val = MAXJSAMPLE;
+         }
+         thisrowerr[ci] = val; /* save for error propagation */
+         pixcode += GETJSAMPLE(colorindex[ci][val]);
+       }
+       output_data[row][col] = pixcode;
+       /* propagate error to adjacent pixels */
+       for (ci = 0; ci < nc; ci++) {
+         val = thisrowerr[ci] - GETJSAMPLE(colormap[ci][pixcode]);
+         thisrowerr[ci+nc] += val * 7;
+         nextrowerr[ci-nc] += val * 3;
+         nextrowerr[ci   ] += val * 5;
+         nextrowerr[ci+nc]  = val; /* not +=, since not initialized yet */
+       }
+       thisrowerr += nc;       /* advance error ptrs to next pixel entry */
+       nextrowerr += nc;
+      }
+      on_odd_row = TRUE;
+    }
+  }
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+color_quant_term (decompress_info_ptr cinfo)
+{
+  /* We can't free the colormap until now, since output module may use it! */
+  (*cinfo->emethods->free_small_sarray)
+               (colormap, (long) cinfo->color_out_comps);
+  (*cinfo->emethods->free_small_sarray)
+               (colorindex, (long) cinfo->color_out_comps);
+  if (cinfo->use_dithering) {
+    (*cinfo->emethods->free_medium) ((void FAR *) evenrowerrs);
+    (*cinfo->emethods->free_medium) ((void FAR *) oddrowerrs);
+  }
+}
+
+
+/*
+ * Prescan some rows of pixels.
+ * Not used in one-pass case.
+ */
+
+METHODDEF void
+color_quant_prescan (decompress_info_ptr cinfo, int num_rows,
+                    JSAMPIMAGE image_data)
+{
+  ERREXIT(cinfo->emethods, "Should not get here!");
+}
+
+
+/*
+ * Do two-pass quantization.
+ * Not used in one-pass case.
+ */
+
+METHODDEF void
+color_quant_doit (decompress_info_ptr cinfo, quantize_caller_ptr source_method)
+{
+  ERREXIT(cinfo->emethods, "Should not get here!");
+}
+
+
+/*
+ * The method selection routine for 1-pass color quantization.
+ */
+
+GLOBAL void
+jsel1quantize (decompress_info_ptr cinfo)
+{
+  if (! cinfo->two_pass_quantize) {
+    cinfo->methods->color_quant_init = color_quant_init;
+    if (cinfo->use_dithering) {
+      cinfo->methods->color_quantize = color_quantize_dither;
+    } else {
+      if (cinfo->color_out_comps == 3)
+       cinfo->methods->color_quantize = color_quantize3;
+      else
+       cinfo->methods->color_quantize = color_quantize;
+    }
+    cinfo->methods->color_quant_prescan = color_quant_prescan;
+    cinfo->methods->color_quant_doit = color_quant_doit;
+    cinfo->methods->color_quant_term = color_quant_term;
+  }
+}
+
+#endif /* QUANT_1PASS_SUPPORTED */
diff --git a/jquant2.c b/jquant2.c
new file mode 100644 (file)
index 0000000..2569b20
--- /dev/null
+++ b/jquant2.c
@@ -0,0 +1,122 @@
+/*
+ * jquant2.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains 2-pass color quantization (color mapping) routines.
+ * These routines are invoked via the methods color_quant_prescan,
+ * color_quant_doit, and color_quant_init/term.
+ */
+
+#include "jinclude.h"
+
+#ifdef QUANT_2PASS_SUPPORTED
+
+
+/*
+ * Initialize for two-pass color quantization.
+ */
+
+METHODDEF void
+color_quant_init (decompress_info_ptr cinfo)
+{
+  TRACEMS(cinfo->emethods, 1, "color_quant_init 2 pass");
+}
+
+
+/*
+ * Prescan some rows of pixels.
+ * Note: this could change the data being written into the big image array,
+ * if there were any benefit to doing so.  The doit routine is not allowed
+ * to modify the big image array, because the memory manager is not required
+ * to support multiple write passes on a big image.
+ */
+
+METHODDEF void
+color_quant_prescan (decompress_info_ptr cinfo, int num_rows,
+                    JSAMPIMAGE image_data)
+{
+  TRACEMS1(cinfo->emethods, 2, "color_quant_prescan %d rows", num_rows);
+}
+
+
+/*
+ * This routine makes the final pass over the image data.
+ * output_workspace is a one-component array of pixel dimensions at least
+ * as large as the input image strip; it can be used to hold the converted
+ * pixels' colormap indexes.
+ */
+
+METHODDEF void
+final_pass (decompress_info_ptr cinfo, int num_rows,
+           JSAMPIMAGE image_data, JSAMPARRAY output_workspace)
+{
+  TRACEMS1(cinfo->emethods, 2, "final_pass %d rows", num_rows);
+  /* for debug purposes, just emit input data */
+  /* NB: this only works for PPM output */
+  (*cinfo->methods->put_pixel_rows) (cinfo, num_rows, image_data);
+}
+
+
+/*
+ * Perform two-pass quantization: rescan the image data and output the
+ * converted data via put_color_map and put_pixel_rows.
+ * The source_method is a routine that can scan the image data; it can
+ * be called as many times as desired.  The processing routine called by
+ * source_method has the same interface as color_quantize does in the
+ * one-pass case, except it must call put_pixel_rows itself.  (This allows
+ * me to use multiple passes in which earlier passes don't output anything.)
+ */
+
+METHODDEF void
+color_quant_doit (decompress_info_ptr cinfo, quantize_caller_ptr source_method)
+{
+  TRACEMS(cinfo->emethods, 1, "color_quant_doit 2 pass");
+  (*source_method) (cinfo, final_pass);
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+color_quant_term (decompress_info_ptr cinfo)
+{
+  TRACEMS(cinfo->emethods, 1, "color_quant_term 2 pass");
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ * Not used in two-pass case.
+ */
+
+METHODDEF void
+color_quantize (decompress_info_ptr cinfo, int num_rows,
+               JSAMPIMAGE input_data, JSAMPARRAY output_data)
+{
+  ERREXIT(cinfo->emethods, "Should not get here!");
+}
+
+
+/*
+ * The method selection routine for 2-pass color quantization.
+ */
+
+GLOBAL void
+jsel2quantize (decompress_info_ptr cinfo)
+{
+  if (cinfo->two_pass_quantize) {
+    /* just one alternative for the moment */
+    cinfo->methods->color_quant_init = color_quant_init;
+    cinfo->methods->color_quant_prescan = color_quant_prescan;
+    cinfo->methods->color_quant_doit = color_quant_doit;
+    cinfo->methods->color_quant_term = color_quant_term;
+    cinfo->methods->color_quantize = color_quantize;
+  }
+}
+
+#endif /* QUANT_2PASS_SUPPORTED */
diff --git a/jrdgif.c b/jrdgif.c
new file mode 100644 (file)
index 0000000..e2d4b33
--- /dev/null
+++ b/jrdgif.c
@@ -0,0 +1,620 @@
+/*
+ * jrdgif.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to read input images in GIF format.
+ *
+ * These routines may need modification for non-Unix environments or
+ * specialized applications.  As they stand, they assume input from
+ * an ordinary stdio stream.  They further assume that reading begins
+ * at the start of the file; input_init may need work if the
+ * user interface has already read some data (e.g., to determine that
+ * the file is indeed GIF format).
+ *
+ * These routines are invoked via the methods get_input_row
+ * and input_init/term.
+ */
+
+/*
+ * This code is loosely based on giftoppm from the PBMPLUS distribution
+ * of Feb. 1991.  That file contains the following copyright notice:
+ * +-------------------------------------------------------------------+
+ * | Copyright 1990, David Koblas.                                     |
+ * |   Permission to use, copy, modify, and distribute this software   |
+ * |   and its documentation for any purpose and without fee is hereby |
+ * |   granted, provided that the above copyright notice appear in all |
+ * |   copies and that both that copyright notice and this permission  |
+ * |   notice appear in supporting documentation.  This software is    |
+ * |   provided "as is" without express or implied warranty.           |
+ * +-------------------------------------------------------------------+
+ *
+ * We are also required to state that
+ *    "The Graphics Interchange Format(c) is the Copyright property of
+ *    CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ *    CompuServe Incorporated."
+ */
+
+#include "jinclude.h"
+
+#ifdef GIF_SUPPORTED
+
+
+#define        MAXCOLORMAPSIZE 256     /* max # of colors in a GIF colormap */
+#define NUMCOLORS      3       /* # of colors */
+#define CM_RED         0       /* color component numbers */
+#define CM_GREEN       1
+#define CM_BLUE                2
+
+static JSAMPARRAY colormap;    /* the colormap to use */
+/* colormap[i][j] = value of i'th color component for pixel value j */
+
+#define        MAX_LZW_BITS    12      /* maximum LZW code size */
+#define LZW_TABLE_SIZE (1<<MAX_LZW_BITS) /* # of possible LZW symbols */
+
+/* Macros for extracting header data --- note we assume chars may be signed */
+
+#define LM_to_uint(a,b)                ((((b)&0xFF) << 8) | ((a)&0xFF))
+
+#define BitSet(byte, bit)      ((byte) & (bit))
+#define INTERLACE      0x40    /* mask for bit signifying interlaced image */
+#define COLORMAPFLAG   0x80    /* mask for bit signifying colormap presence */
+
+#define        ReadOK(file,buffer,len) (fread(buffer, 1, len, file) == (len))
+
+/* Static vars for GetCode and LZWReadByte */
+
+static char code_buf[256+4];   /* current input data block */
+static int last_byte;          /* # of bytes in code_buf */
+static int last_bit;           /* # of bits in code_buf */
+static int cur_bit;            /* next bit index to read */
+static boolean out_of_blocks;  /* TRUE if hit terminator data block */
+
+static int input_code_size;    /* codesize given in GIF file */
+static int clear_code,end_code; /* values for Clear and End codes */
+
+static int code_size;          /* current actual code size */
+static int limit_code;         /* 2^code_size */
+static int max_code;           /* first unused code value */
+static boolean first_time;     /* flags first call to LZWReadByte */
+
+/* LZW decompression tables:
+ *   symbol_head[K] = prefix symbol of any LZW symbol K (0..LZW_TABLE_SIZE-1)
+ *   symbol_tail[K] = suffix byte   of any LZW symbol K (0..LZW_TABLE_SIZE-1)
+ * Note that entries 0..end_code of the above tables are not used,
+ * since those symbols represent raw bytes or special codes.
+ *
+ * The stack represents the not-yet-used expansion of the last LZW symbol.
+ * In the worst case, a symbol could expand to as many bytes as there are
+ * LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
+ * (This is conservative since that number includes the raw-byte symbols.)
+ *
+ * The tables are allocated from FAR heap space since they would use up
+ * rather a lot of the near data space in a PC.
+ */
+
+static UINT16 FAR *symbol_head; /* => table of prefix symbols */
+static UINT8  FAR *symbol_tail; /* => table of suffix bytes */
+static UINT8  FAR *symbol_stack; /* stack for symbol expansions */
+static UINT8  FAR *sp;         /* stack pointer */
+
+/* Static state for interlaced image processing */
+
+static boolean is_interlaced;  /* TRUE if have interlaced image */
+static big_sarray_ptr interlaced_image;        /* full image in interlaced order */
+static long cur_row_number;    /* need to know actual row number */
+static long pass2_offset;      /* # of pixel rows in pass 1 */
+static long pass3_offset;      /* # of pixel rows in passes 1&2 */
+static long pass4_offset;      /* # of pixel rows in passes 1,2,3 */
+
+
+/* Forward declarations */
+METHODDEF void load_interlaced_image PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
+METHODDEF void get_interlaced_row PP((compress_info_ptr cinfo, JSAMPARRAY pixel_row));
+
+
+
+LOCAL int
+ReadByte (compress_info_ptr cinfo)
+/* Read next byte from GIF file */
+{
+  register FILE * infile = cinfo->input_file;
+  int c;
+
+  if ((c = getc(infile)) == EOF)
+    ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
+  return c;
+}
+
+
+LOCAL int
+GetDataBlock (compress_info_ptr cinfo, char *buf)
+/* Read a GIF data block, which has a leading count byte */
+/* A zero-length block marks the end of a data block sequence */
+{
+  int count;
+
+  count = ReadByte(cinfo);
+  if (count > 0) {
+    if (! ReadOK(cinfo->input_file, buf, count))
+      ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
+  }
+  return count;
+}
+
+
+LOCAL void
+SkipDataBlocks (compress_info_ptr cinfo)
+/* Skip a series of data blocks, until a block terminator is found */
+{
+  char buf[256];
+
+  while (GetDataBlock(cinfo, buf) > 0)
+    /* skip */;
+}
+
+
+LOCAL void
+ReInitLZW (void)
+/* (Re)initialize LZW state; shared code for startup and Clear processing */
+{
+  code_size = input_code_size+1;
+  limit_code = clear_code << 1;        /* 2^code_size */
+  max_code = clear_code + 2;   /* first unused code value */
+  sp = symbol_stack;           /* init stack to empty */
+}
+
+
+LOCAL void
+InitLZWCode (void)
+/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
+{
+  /* GetCode initialization */
+  last_byte = 2;               /* make safe to "recopy last two bytes" */
+  last_bit = 0;                        /* nothing in the buffer */
+  cur_bit = 0;                 /* force buffer load on first call */
+  out_of_blocks = FALSE;
+
+  /* LZWReadByte initialization */
+  clear_code = 1 << input_code_size; /* compute special code values */
+  end_code = clear_code + 1;   /* note that these do not change */
+  first_time = TRUE;
+  ReInitLZW();
+}
+
+
+LOCAL int
+GetCode (compress_info_ptr cinfo)
+/* Fetch the next code_size bits from the GIF data */
+/* We assume code_size is less than 16 */
+{
+  register INT32 accum;
+  int offs, ret, count;
+
+  if ( (cur_bit+code_size) > last_bit) {
+    /* Time to reload the buffer */
+    if (out_of_blocks) {
+      TRACEMS(cinfo->emethods, 1, "Ran out of GIF bits");
+      return end_code;         /* fake something useful */
+    }
+    /* preserve last two bytes of what we have -- assume code_size <= 16 */
+    code_buf[0] = code_buf[last_byte-2];
+    code_buf[1] = code_buf[last_byte-1];
+    /* Load more bytes; set flag if we reach the terminator block */
+    if ((count = GetDataBlock(cinfo, &code_buf[2])) == 0) {
+      out_of_blocks = TRUE;
+      TRACEMS(cinfo->emethods, 1, "Ran out of GIF bits");
+      return end_code;         /* fake something useful */
+    }
+    /* Reset counters */
+    cur_bit = (cur_bit - last_bit) + 16;
+    last_byte = 2 + count;
+    last_bit = last_byte * 8;
+  }
+
+  /* Form up next 24 bits in accum */
+  offs = cur_bit >> 3;         /* byte containing cur_bit */
+#ifdef CHAR_IS_UNSIGNED
+  accum = code_buf[offs+2];
+  accum <<= 8;
+  accum |= code_buf[offs+1];
+  accum <<= 8;
+  accum |= code_buf[offs];
+#else
+  accum = code_buf[offs+2] & 0xFF;
+  accum <<= 8;
+  accum |= code_buf[offs+1] & 0xFF;
+  accum <<= 8;
+  accum |= code_buf[offs] & 0xFF;
+#endif
+
+  /* Right-align cur_bit in accum, then mask off desired number of bits */
+  accum >>= (cur_bit & 7);
+  ret = ((int) accum) & ((1 << code_size) - 1);
+  
+  cur_bit += code_size;
+  return ret;
+}
+
+
+LOCAL int
+LZWReadByte (compress_info_ptr cinfo)
+/* Read an LZW-compressed byte */
+{
+  static int oldcode;          /* previous LZW symbol */
+  static int firstcode;                /* first byte of oldcode's expansion */
+  register int code;           /* current working code */
+  int incode;                  /* saves actual input code */
+
+  /* First time, just eat the expected Clear code(s) and return next code, */
+  /* which is assumed to be a raw byte. */
+  if (first_time) {
+    first_time = FALSE;
+    do {
+      code = GetCode(cinfo);
+    } while (code == clear_code);
+    firstcode = oldcode = code;        /* make firstcode, oldcode valid! */
+    return code;
+  }
+
+  /* If any codes are stacked from a previously read symbol, return them */
+  if (sp > symbol_stack)
+    return *(--sp);
+
+  code = GetCode(cinfo);
+
+  if (code == clear_code) {
+    /* Reinit static state, swallow any extra Clear codes, and return */
+    ReInitLZW();
+    do {
+      code = GetCode(cinfo);
+    } while (code == clear_code);
+    firstcode = oldcode = code; /* gotta reinit these too */
+    return code;
+  }
+
+  if (code == end_code) {
+    /* Skip the rest of the image, unless GetCode already read terminator */
+    if (! out_of_blocks)
+      SkipDataBlocks(cinfo);
+    return -1;
+  }
+
+  /* Normal raw byte or LZW symbol */
+  incode = code;               /* save for a moment */
+  
+  if (code >= max_code) {      /* special case for not-yet-defined symbol */
+    *sp++ = firstcode;         /* it will be defined as oldcode/firstcode */
+    code = oldcode;
+  }
+
+  /* If it's a symbol, expand it into the stack */
+  while (code >= clear_code) {
+    *sp++ = symbol_tail[code]; /* tail of symbol: a simple byte value */
+    code = symbol_head[code];  /* head of symbol: another LZW symbol */
+  }
+  /* At this point code just represents a raw byte */
+  firstcode = code;            /* save for possible future use */
+
+  /* If there's room in table, */
+  if ((code = max_code) < LZW_TABLE_SIZE) {
+    /* Define a new symbol = prev sym + head of this sym's expansion */
+    symbol_head[code] = oldcode;
+    symbol_tail[code] = firstcode;
+    max_code++;
+    /* Is it time to increase code_size? */
+    if ((max_code >= limit_code) && (code_size < MAX_LZW_BITS)) {
+      code_size++;
+      limit_code <<= 1;                /* keep equal to 2^code_size */
+    }
+  }
+  
+  oldcode = incode;            /* save last input symbol for future use */
+  return firstcode;            /* return first byte of symbol's expansion */
+}
+
+
+LOCAL void
+ReadColorMap (compress_info_ptr cinfo, int cmaplen, JSAMPARRAY cmap)
+/* Read a GIF colormap */
+{
+  int i;
+
+  for (i = 0; i < cmaplen; i++) {
+    cmap[CM_RED][i]   = ReadByte(cinfo);
+    cmap[CM_GREEN][i] = ReadByte(cinfo);
+    cmap[CM_BLUE][i]  = ReadByte(cinfo);
+  }
+}
+
+
+LOCAL void
+DoExtension (compress_info_ptr cinfo)
+/* Process an extension block */
+/* Currently we ignore 'em all */
+{
+  int extlabel;
+
+  /* Read extension label byte */
+  extlabel = ReadByte(cinfo);
+  TRACEMS1(cinfo->emethods, 1, "Ignoring GIF extension block of type 0x%02x",
+          extlabel);
+  /* Skip the data block(s) associated with the extension */
+  SkipDataBlocks(cinfo);
+}
+
+
+/*
+ * Read the file header; return image size and component count.
+ */
+
+METHODDEF void
+input_init (compress_info_ptr cinfo)
+{
+  char hdrbuf[10];             /* workspace for reading control blocks */
+  UINT16 width, height;                /* image dimensions */
+  int colormaplen, aspectRatio;
+  int c;
+
+  /* Allocate space to store the colormap */
+  colormap = (*cinfo->emethods->alloc_small_sarray)
+               ((long) MAXCOLORMAPSIZE, (long) NUMCOLORS);
+
+  /* Read and verify GIF Header */
+  if (! ReadOK(cinfo->input_file, hdrbuf, 6))
+    ERREXIT(cinfo->emethods, "Not a GIF file");
+  if (strncmp(hdrbuf, "GIF", 3) != 0)
+    ERREXIT(cinfo->emethods, "Not a GIF file");
+  /* Check for expected version numbers.
+   * If unknown version, give warning and try to process anyway;
+   * this is per recommendation in GIF89a standard.
+   */
+  if ((strncmp(hdrbuf+3, "87a", 3) != 0) &&
+      (strncmp(hdrbuf+3, "89a", 3) != 0))
+    TRACEMS3(cinfo->emethods, 1,
+            "Warning: unexpected GIF version number '%c%c%c'",
+            hdrbuf[3], hdrbuf[4], hdrbuf[5]);
+
+  /* Read and decipher Logical Screen Descriptor */
+  if (! ReadOK(cinfo->input_file, hdrbuf, 7))
+    ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
+  width = LM_to_uint(hdrbuf[0],hdrbuf[1]);
+  height = LM_to_uint(hdrbuf[2],hdrbuf[3]);
+  colormaplen = 2 << (hdrbuf[4] & 0x07);
+  /* we ignore the color resolution, sort flag, and background color index */
+  aspectRatio = hdrbuf[6] & 0xFF;
+  if (aspectRatio != 0 && aspectRatio != 49)
+    TRACEMS(cinfo->emethods, 1, "Warning: nonsquare pixels in input");
+
+  /* Read global colormap if header indicates it is present */
+  if (BitSet(hdrbuf[4], COLORMAPFLAG))
+    ReadColorMap(cinfo, colormaplen, colormap);
+
+  /* Scan until we reach start of desired image.
+   * We don't currently support skipping images, but could add it easily.
+   */
+  for (;;) {
+    c = ReadByte(cinfo);
+
+    if (c == ';')              /* GIF terminator?? */
+      ERREXIT(cinfo->emethods, "Too few images in GIF file");
+
+    if (c == '!') {            /* Extension */
+      DoExtension(cinfo);
+      continue;
+    }
+    
+    if (c != ',') {            /* Not an image separator? */
+      TRACEMS1(cinfo->emethods, 1, "Bogus input char 0x%02x, ignoring", c);
+      continue;
+    }
+
+    /* Read and decipher Local Image Descriptor */
+    if (! ReadOK(cinfo->input_file, hdrbuf, 9))
+      ERREXIT(cinfo->emethods, "Premature EOF in GIF file");
+    /* we ignore top/left position info, also sort flag */
+    width = LM_to_uint(hdrbuf[4],hdrbuf[5]);
+    height = LM_to_uint(hdrbuf[6],hdrbuf[7]);
+    is_interlaced = BitSet(hdrbuf[8], INTERLACE);
+    colormaplen = 2 << (hdrbuf[8] & 0x07);
+
+    /* Read local colormap if header indicates it is present */
+    /* Note: if we wanted to support skipping images, */
+    /* we'd need to skip rather than read colormap for ignored images */
+    if (BitSet(hdrbuf[8], COLORMAPFLAG))
+      ReadColorMap(cinfo, colormaplen, colormap);
+
+    input_code_size = ReadByte(cinfo); /* get minimum-code-size byte */
+    if (input_code_size < 2 || input_code_size >= MAX_LZW_BITS)
+      ERREXIT1(cinfo->emethods, "Bogus codesize %d", input_code_size);
+
+    /* Reached desired image, so break out of loop */
+    /* If we wanted to skip this image, */
+    /* we'd call SkipDataBlocks and then continue the loop */
+    break;
+  }
+
+  /* Prepare to read selected image: first initialize LZW decompressor */
+  symbol_head = (UINT16 FAR *) (*cinfo->emethods->alloc_medium)
+                               (LZW_TABLE_SIZE * SIZEOF(UINT16));
+  symbol_tail = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
+                               (LZW_TABLE_SIZE * SIZEOF(UINT8));
+  symbol_stack = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
+                               (LZW_TABLE_SIZE * SIZEOF(UINT8));
+  InitLZWCode();
+
+  /*
+   * If image is interlaced, we read it into a full-size sample array,
+   * decompressing as we go; then get_input_row selects rows from the
+   * sample array in the proper order.
+   */
+  if (is_interlaced) {
+    /* We request the big array now, but can't access it until the pipeline
+     * controller causes all the big arrays to be allocated.  Hence, the
+     * actual work of reading the image is postponed until the first call
+     * of get_input_row.
+     */
+    interlaced_image = (*cinfo->emethods->request_big_sarray)
+               ((long) width, (long) height, (long) 1);
+    cinfo->methods->get_input_row = load_interlaced_image;
+  }
+
+  /* Return info about the image. */
+  cinfo->input_components = NUMCOLORS;
+  cinfo->in_color_space = CS_RGB;
+  cinfo->image_width = width;
+  cinfo->image_height = height;
+  cinfo->data_precision = 8;
+}
+
+
+/*
+ * Read one row of pixels.
+ * This version is used for noninterlaced GIF images:
+ * we read directly from the GIF file.
+ */
+
+METHODDEF void
+get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
+{
+  register JSAMPROW ptr0, ptr1, ptr2;
+  register long col;
+  register int c;
+  
+  ptr0 = pixel_row[0];
+  ptr1 = pixel_row[1];
+  ptr2 = pixel_row[2];
+  for (col = cinfo->image_width; col > 0; col--) {
+    if ((c = LZWReadByte(cinfo)) < 0)
+      ERREXIT(cinfo->emethods, "Premature end of GIF image");
+    *ptr0++ = colormap[CM_RED][c];
+    *ptr1++ = colormap[CM_GREEN][c];
+    *ptr2++ = colormap[CM_BLUE][c];
+  }
+}
+
+
+/*
+ * Read one row of pixels.
+ * This version is used for the first call on get_input_row when
+ * reading an interlaced GIF file: we read the whole image into memory.
+ */
+
+METHODDEF void
+load_interlaced_image (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
+{
+  JSAMPARRAY image_ptr;
+  register JSAMPROW sptr;
+  register long col;
+  register int c;
+  long row;
+
+  /* Read the interlaced image into the big array we've created. */
+  for (row = 0; row < cinfo->image_height; row++) {
+    image_ptr = (*cinfo->emethods->access_big_sarray)
+                       (interlaced_image, row, TRUE);
+    sptr = image_ptr[0];
+    for (col = cinfo->image_width; col > 0; col--) {
+      if ((c = LZWReadByte(cinfo)) < 0)
+       ERREXIT(cinfo->emethods, "Premature end of GIF image");
+      *sptr++ = c;
+    }
+  }
+
+  /* Replace method pointer so subsequent calls don't come here. */
+  cinfo->methods->get_input_row = get_interlaced_row;
+  /* Initialize for get_interlaced_row, and perform first call on it. */
+  cur_row_number = 0;
+  pass2_offset = (cinfo->image_height + 7L) / 8L;
+  pass3_offset = pass2_offset + (cinfo->image_height + 3L) / 8L;
+  pass4_offset = pass3_offset + (cinfo->image_height + 1L) / 4L;
+
+  get_interlaced_row(cinfo, pixel_row);
+}
+
+
+/*
+ * Read one row of pixels.
+ * This version is used for interlaced GIF images:
+ * we read from the big in-memory image.
+ */
+
+METHODDEF void
+get_interlaced_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
+{
+  JSAMPARRAY image_ptr;
+  register JSAMPROW sptr, ptr0, ptr1, ptr2;
+  register long col;
+  register int c;
+  long irow;
+
+  /* Figure out which row of interlaced image is needed, and access it. */
+  switch ((int) (cur_row_number & 7L)) {
+  case 0:                      /* first-pass row */
+    irow = cur_row_number >> 3;
+    break;
+  case 4:                      /* second-pass row */
+    irow = (cur_row_number >> 3) + pass2_offset;
+    break;
+  case 2:                      /* third-pass row */
+  case 6:
+    irow = (cur_row_number >> 2) + pass3_offset;
+    break;
+  default:                     /* fourth-pass row */
+    irow = (cur_row_number >> 1) + pass4_offset;
+    break;
+  }
+  image_ptr = (*cinfo->emethods->access_big_sarray)
+                       (interlaced_image, irow, FALSE);
+  /* Scan the row, expand colormap, and output */
+  sptr = image_ptr[0];
+  ptr0 = pixel_row[0];
+  ptr1 = pixel_row[1];
+  ptr2 = pixel_row[2];
+  for (col = cinfo->image_width; col > 0; col--) {
+    c = GETJSAMPLE(*sptr++);
+    *ptr0++ = colormap[CM_RED][c];
+    *ptr1++ = colormap[CM_GREEN][c];
+    *ptr2++ = colormap[CM_BLUE][c];
+  }
+  cur_row_number++;            /* for next time */
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+input_term (compress_info_ptr cinfo)
+{
+  if (is_interlaced) {
+    (*cinfo->emethods->free_big_sarray) (interlaced_image);
+  }
+  (*cinfo->emethods->free_small_sarray)
+               (colormap, (long) NUMCOLORS);
+  (*cinfo->emethods->free_medium) ((void FAR *) symbol_head);
+  (*cinfo->emethods->free_medium) ((void FAR *) symbol_tail);
+  (*cinfo->emethods->free_medium) ((void FAR *) symbol_stack);
+}
+
+
+/*
+ * The method selection routine for GIF format input.
+ * Note that this must be called by the user interface before calling
+ * jpeg_compress.  If multiple input formats are supported, the
+ * user interface is responsible for discovering the file format and
+ * calling the appropriate method selection routine.
+ */
+
+GLOBAL void
+jselrgif (compress_info_ptr cinfo)
+{
+  cinfo->methods->input_init = input_init;
+  cinfo->methods->get_input_row = get_input_row; /* assume uninterlaced */
+  cinfo->methods->input_term = input_term;
+}
+
+#endif /* GIF_SUPPORTED */
diff --git a/jrdjfif.c b/jrdjfif.c
new file mode 100644 (file)
index 0000000..5ff14ba
--- /dev/null
+++ b/jrdjfif.c
@@ -0,0 +1,733 @@
+/*
+ * jrdjfif.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to decode standard JPEG file headers/markers.
+ * This will handle baseline and JFIF-convention JPEG files.
+ *
+ * This module relies on the JGETC macro and the read_jpeg_data method (which
+ * is provided by the user interface) to read from the JPEG data stream.
+ * Therefore, this module is NOT dependent on any particular assumption about
+ * the data source.  This fact does not carry over to more complex JPEG file
+ * formats such as JPEG-in-TIFF; those format control modules may well need to
+ * assume stdio input.
+ *
+ * read_file_header assumes that reading begins at the JPEG SOI marker
+ * (although it will skip non-FF bytes looking for a JPEG marker).
+ * The user interface must position the data stream appropriately.
+ *
+ * These routines are invoked via the methods read_file_header,
+ * read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer.
+ */
+
+#include "jinclude.h"
+
+#ifdef JFIF_SUPPORTED
+
+
+typedef enum {                 /* JPEG marker codes */
+  M_SOF0  = 0xc0,
+  M_SOF1  = 0xc1,
+  M_SOF2  = 0xc2,
+  M_SOF3  = 0xc3,
+  
+  M_SOF5  = 0xc5,
+  M_SOF6  = 0xc6,
+  M_SOF7  = 0xc7,
+  
+  M_JPG   = 0xc8,
+  M_SOF9  = 0xc9,
+  M_SOF10 = 0xca,
+  M_SOF11 = 0xcb,
+  
+  M_SOF13 = 0xcd,
+  M_SOF14 = 0xce,
+  M_SOF15 = 0xcf,
+  
+  M_DHT   = 0xc4,
+  
+  M_DAC   = 0xcc,
+  
+  M_RST0  = 0xd0,
+  M_RST1  = 0xd1,
+  M_RST2  = 0xd2,
+  M_RST3  = 0xd3,
+  M_RST4  = 0xd4,
+  M_RST5  = 0xd5,
+  M_RST6  = 0xd6,
+  M_RST7  = 0xd7,
+  
+  M_SOI   = 0xd8,
+  M_EOI   = 0xd9,
+  M_SOS   = 0xda,
+  M_DQT   = 0xdb,
+  M_DNL   = 0xdc,
+  M_DRI   = 0xdd,
+  M_DHP   = 0xde,
+  M_EXP   = 0xdf,
+  
+  M_APP0  = 0xe0,
+  M_APP15 = 0xef,
+  
+  M_JPG0  = 0xf0,
+  M_JPG13 = 0xfd,
+  M_COM   = 0xfe,
+  
+  M_TEM   = 0x01,
+  
+  M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+/*
+ * Reload the input buffer after it's been emptied, and return the next byte.
+ * This is exported for direct use by the entropy decoder.
+ * See the JGETC macro for calling conditions.
+ *
+ * For this header control module, read_jpeg_data is supplied by the
+ * user interface.  However, header formats that require random access
+ * to the input file would need to supply their own code.  This code is
+ * left here to indicate what is required.
+ */
+
+#if 0                          /* not needed in this module */
+
+METHODDEF int
+read_jpeg_data (decompress_info_ptr cinfo)
+{
+  cinfo->bytes_in_buffer = fread(cinfo->input_buffer + MIN_UNGET,
+                                1, JPEG_BUF_SIZE,
+                                cinfo->input_file);
+  
+  cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
+  
+  if (cinfo->bytes_in_buffer <= 0)
+    ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
+
+  return JGETC(cinfo);
+}
+
+#endif
+
+
+/*
+ * Routines to parse JPEG markers & save away the useful info.
+ */
+
+
+LOCAL INT32
+get_2bytes (decompress_info_ptr cinfo)
+/* Get a 2-byte unsigned integer (e.g., a marker parameter length field) */
+{
+  INT32 a;
+  
+  a = JGETC(cinfo);
+  return (a << 8) + JGETC(cinfo);
+}
+
+
+LOCAL void
+skip_variable (decompress_info_ptr cinfo, int code)
+/* Skip over an unknown or uninteresting variable-length marker */
+{
+  INT32 length;
+  
+  length = get_2bytes(cinfo);
+  
+  TRACEMS2(cinfo->emethods, 1,
+          "Skipping marker 0x%02x, length %d", code, length);
+  
+  for (length -= 2; length > 0; length--)
+    (void) JGETC(cinfo);
+}
+
+
+LOCAL void
+get_dht (decompress_info_ptr cinfo)
+/* Process a DHT marker */
+{
+  INT32 length;
+  UINT8 bits[17];
+  UINT8 huffval[256];
+  int i, index, count;
+  HUFF_TBL **htblptr;
+  
+  length = get_2bytes(cinfo)-2;
+  
+  while (length > 0) {
+    index = JGETC(cinfo);
+
+    TRACEMS1(cinfo->emethods, 1, "Define Huffman Table 0x%02x", index);
+      
+    bits[0] = 0;
+    count = 0;
+    for (i = 1; i <= 16; i++) {
+      bits[i] = JGETC(cinfo);
+      count += bits[i];
+    }
+
+    TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
+            bits[1], bits[2], bits[3], bits[4],
+            bits[5], bits[6], bits[7], bits[8]);
+    TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
+            bits[9], bits[10], bits[11], bits[12],
+            bits[13], bits[14], bits[15], bits[16]);
+
+    if (count > 256)
+      ERREXIT(cinfo->emethods, "Bogus DHT counts");
+
+    for (i = 0; i < count; i++)
+      huffval[i] = JGETC(cinfo);
+
+    length -= 1 + 16 + count;
+
+    if (index & 0x10) {                /* AC table definition */
+      index -= 0x10;
+      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
+    } else {                   /* DC table definition */
+      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
+    }
+
+    if (index < 0 || index >= NUM_HUFF_TBLS)
+      ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index);
+
+    if (*htblptr == NULL)
+      *htblptr = (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
+  
+    memcpy((void *) (*htblptr)->bits, (void *) bits,
+          SIZEOF((*htblptr)->bits));
+    memcpy((void *) (*htblptr)->huffval, (void *) huffval,
+          SIZEOF((*htblptr)->huffval));
+    }
+}
+
+
+LOCAL void
+get_dac (decompress_info_ptr cinfo)
+/* Process a DAC marker */
+{
+  INT32 length;
+  int index, val;
+
+  length = get_2bytes(cinfo)-2;
+  
+  while (length > 0) {
+    index = JGETC(cinfo);
+    val = JGETC(cinfo);
+
+    TRACEMS2(cinfo->emethods, 1,
+            "Define Arithmetic Table 0x%02x: 0x%02x", index, val);
+
+    if (index < 0 || index >= (2*NUM_ARITH_TBLS))
+      ERREXIT1(cinfo->emethods, "Bogus DAC index %d", index);
+
+    if (index >= NUM_ARITH_TBLS) { /* define AC table */
+      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = val;
+    } else {                   /* define DC table */
+      cinfo->arith_dc_L[index] = val & 0x0F;
+      cinfo->arith_dc_U[index] = val >> 4;
+      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
+       ERREXIT1(cinfo->emethods, "Bogus DAC value 0x%x", val);
+    }
+
+    length -= 2;
+  }
+}
+
+
+LOCAL void
+get_dqt (decompress_info_ptr cinfo)
+/* Process a DQT marker */
+{
+  INT32 length;
+  int n, i, prec;
+  UINT16 tmp;
+  QUANT_TBL_PTR quant_ptr;
+  
+  length = get_2bytes(cinfo) - 2;
+  
+  while (length > 0) {
+    n = JGETC(cinfo);
+    prec = n >> 4;
+    n &= 0x0F;
+
+    TRACEMS2(cinfo->emethods, 1,
+            "Define Quantization Table %d  precision %d", n, prec);
+
+    if (n >= NUM_QUANT_TBLS)
+      ERREXIT1(cinfo->emethods, "Bogus table number %d", n);
+      
+    if (cinfo->quant_tbl_ptrs[n] == NULL)
+      cinfo->quant_tbl_ptrs[n] = (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
+    quant_ptr = cinfo->quant_tbl_ptrs[n];
+
+    for (i = 0; i < DCTSIZE2; i++) {
+      tmp = JGETC(cinfo);
+      if (prec)
+       tmp = (tmp<<8) + JGETC(cinfo);
+      quant_ptr[i] = tmp;
+    }
+
+    for (i = 0; i < DCTSIZE2; i += 8) {
+      TRACEMS8(cinfo->emethods, 2, "        %4d %4d %4d %4d %4d %4d %4d %4d",
+              quant_ptr[i  ], quant_ptr[i+1], quant_ptr[i+2], quant_ptr[i+3],
+              quant_ptr[i+4], quant_ptr[i+5], quant_ptr[i+6], quant_ptr[i+7]);
+    }
+
+    length -= DCTSIZE2+1;
+    if (prec) length -= DCTSIZE2;
+  }
+}
+
+
+LOCAL void
+get_dri (decompress_info_ptr cinfo)
+/* Process a DRI marker */
+{
+  if (get_2bytes(cinfo) != 4)
+    ERREXIT(cinfo->emethods, "Bogus length in DRI");
+
+  cinfo->restart_interval = get_2bytes(cinfo);
+
+  TRACEMS1(cinfo->emethods, 1,
+          "Define Restart Interval %d", cinfo->restart_interval);
+}
+
+
+LOCAL void
+get_app0 (decompress_info_ptr cinfo)
+/* Process an APP0 marker */
+{
+#define JFIF_LEN 14
+  INT32 length;
+  UINT8 b[JFIF_LEN];
+  int buffp;
+
+  length = get_2bytes(cinfo) - 2;
+
+  /* See if a JFIF APP0 marker is present */
+
+  if (length >= JFIF_LEN) {
+    for (buffp = 0; buffp < JFIF_LEN; buffp++)
+      b[buffp] = JGETC(cinfo);
+    length -= JFIF_LEN;
+
+    if (b[0]=='J' && b[1]=='F' && b[2]=='I' && b[3]=='F' && b[4]==0) {
+      /* Found JFIF APP0 marker: check version */
+      /* Major version must be 1 */
+      if (b[5] != 1)
+       ERREXIT2(cinfo->emethods, "Unsupported JFIF revision number %d.%02d",
+                b[5], b[6]);
+      /* Minor version should be 0 or 1, but try to process anyway if newer */
+      if (b[6] != 0 && b[6] != 1)
+       TRACEMS2(cinfo->emethods, 0, "Warning: unknown JFIF revision number %d.%02d",
+                b[5], b[6]);
+      /* Save info */
+      cinfo->density_unit = b[7];
+      cinfo->X_density = (b[8] << 8) + b[9];
+      cinfo->Y_density = (b[10] << 8) + b[11];
+      /* Assume colorspace is YCbCr, unless UI has overridden me */
+      if (cinfo->jpeg_color_space == CS_UNKNOWN)
+       cinfo->jpeg_color_space = CS_YCbCr;
+      TRACEMS3(cinfo->emethods, 1, "JFIF APP0 marker, density %dx%d  %d",
+              cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
+    } else {
+      TRACEMS(cinfo->emethods, 1, "Unknown APP0 marker (not JFIF)");
+    }
+  } else {
+    TRACEMS1(cinfo->emethods, 1,
+            "Short APP0 marker, length %d", (int) length);
+  }
+
+  while (length-- > 0)         /* skip any remaining data */
+    (void) JGETC(cinfo);
+}
+
+
+LOCAL void
+get_sof (decompress_info_ptr cinfo, int code)
+/* Process a SOFn marker */
+{
+  INT32 length;
+  short ci;
+  int c;
+  jpeg_component_info * compptr;
+  
+  length = get_2bytes(cinfo);
+  
+  cinfo->data_precision = JGETC(cinfo);
+  cinfo->image_height   = get_2bytes(cinfo);
+  cinfo->image_width    = get_2bytes(cinfo);
+  cinfo->num_components = JGETC(cinfo);
+
+  TRACEMS4(cinfo->emethods, 1,
+          "Start Of Frame 0x%02x: width=%d, height=%d, components=%d",
+          code, cinfo->image_width, cinfo->image_height,
+          cinfo->num_components);
+
+  /* We don't support files in which the image height is initially specified */
+  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
+  /* might as well have a general sanity check. */
+  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
+      || cinfo->num_components <= 0)
+    ERREXIT(cinfo->emethods, "Empty JPEG image (DNL not supported)");
+
+#ifdef EIGHT_BIT_SAMPLES
+  if (cinfo->data_precision != 8)
+    ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
+#endif
+#ifdef TWELVE_BIT_SAMPLES
+  if (cinfo->data_precision != 12) /* this needs more thought?? */
+    ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
+#endif
+#ifdef SIXTEEN_BIT_SAMPLES
+  if (cinfo->data_precision != 16) /* this needs more thought?? */
+    ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
+#endif
+
+  if (length != (cinfo->num_components * 3 + 8))
+    ERREXIT(cinfo->emethods, "Bogus SOF length");
+
+  cinfo->comp_info = (*cinfo->emethods->alloc_small)
+                       (cinfo->num_components * SIZEOF(jpeg_component_info));
+  
+  for (ci = 0; ci < cinfo->num_components; ci++) {
+    compptr = &cinfo->comp_info[ci];
+    compptr->component_index = ci;
+    compptr->component_id = JGETC(cinfo);
+    c = JGETC(cinfo);
+    compptr->h_samp_factor = (c >> 4) & 15;
+    compptr->v_samp_factor = (c     ) & 15;
+    compptr->quant_tbl_no  = JGETC(cinfo);
+      
+    TRACEMS4(cinfo->emethods, 1, "    Component %d: %dhx%dv q=%d",
+            compptr->component_id, compptr->h_samp_factor,
+            compptr->v_samp_factor, compptr->quant_tbl_no);
+  }
+}
+
+
+LOCAL void
+get_sos (decompress_info_ptr cinfo)
+/* Process a SOS marker */
+{
+  INT32 length;
+  int i, ci, n, c, cc;
+  jpeg_component_info * compptr;
+  
+  length = get_2bytes(cinfo);
+  
+  n = JGETC(cinfo);  /* Number of components */
+  cinfo->comps_in_scan = n;
+  length -= 3;
+  
+  if (length != (n * 2 + 3) || n < 1 || n > MAX_COMPS_IN_SCAN)
+    ERREXIT(cinfo->emethods, "Bogus SOS length");
+
+  TRACEMS1(cinfo->emethods, 1, "Start Of Scan: %d components", n);
+  
+  for (i = 0; i < n; i++) {
+    cc = JGETC(cinfo);
+    c = JGETC(cinfo);
+    length -= 2;
+    
+    for (ci = 0; ci < cinfo->num_components; ci++)
+      if (cc == cinfo->comp_info[ci].component_id)
+       break;
+    
+    if (ci >= cinfo->num_components)
+      ERREXIT(cinfo->emethods, "Invalid component number in SOS");
+    
+    compptr = &cinfo->comp_info[ci];
+    cinfo->cur_comp_info[i] = compptr;
+    compptr->dc_tbl_no = (c >> 4) & 15;
+    compptr->ac_tbl_no = (c     ) & 15;
+    
+    TRACEMS3(cinfo->emethods, 1, "    c%d: [dc=%d ac=%d]", cc,
+            compptr->dc_tbl_no, compptr->ac_tbl_no);
+  }
+  
+  while (length > 0) {
+    (void) JGETC(cinfo);
+    length--;
+  }
+}
+
+
+LOCAL void
+get_soi (decompress_info_ptr cinfo)
+/* Process an SOI marker */
+{
+  int i;
+  
+  TRACEMS(cinfo->emethods, 1, "Start of Image");
+
+  /* Reset all parameters that are defined to be reset by SOI */
+
+  for (i = 0; i < NUM_ARITH_TBLS; i++) {
+    cinfo->arith_dc_L[i] = 0;
+    cinfo->arith_dc_U[i] = 1;
+    cinfo->arith_ac_K[i] = 5;
+  }
+  cinfo->restart_interval = 0;
+
+  cinfo->density_unit = 0;     /* set default JFIF APP0 values */
+  cinfo->X_density = 1;
+  cinfo->Y_density = 1;
+
+  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling */
+}
+
+
+LOCAL int
+next_marker (decompress_info_ptr cinfo)
+/* Find the next JPEG marker */
+/* Note that the output might not be a valid marker code, */
+/* but it will never be 0 or FF */
+{
+  int c, nbytes;
+
+  nbytes = 0;
+  do {
+    do {                       /* skip any non-FF bytes */
+      nbytes++;
+      c = JGETC(cinfo);
+    } while (c != 0xFF);
+    do {                       /* skip any duplicate FFs */
+      nbytes++;
+      c = JGETC(cinfo);
+    } while (c == 0xFF);
+  } while (c == 0);            /* repeat if it was a stuffed FF/00 */
+
+  if (nbytes != 2)
+    TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before marker 0x%02x",
+            nbytes-2, c);
+
+  return c;
+}
+
+
+LOCAL JPEG_MARKER
+process_tables (decompress_info_ptr cinfo)
+/* Scan and process JPEG markers that can appear in any order */
+/* Return when an SOI, EOI, SOFn, or SOS is found */
+{
+  int c;
+
+  while (TRUE) {
+    c = next_marker(cinfo);
+      
+    switch (c) {
+    case M_SOF0:
+    case M_SOF1:
+    case M_SOF2:
+    case M_SOF3:
+    case M_SOF5:
+    case M_SOF6:
+    case M_SOF7:
+    case M_JPG:
+    case M_SOF9:
+    case M_SOF10:
+    case M_SOF11:
+    case M_SOF13:
+    case M_SOF14:
+    case M_SOF15:
+    case M_SOI:
+    case M_EOI:
+    case M_SOS:
+      return c;
+      
+    case M_DHT:
+      get_dht(cinfo);
+      break;
+      
+    case M_DAC:
+      get_dac(cinfo);
+      break;
+      
+    case M_DQT:
+      get_dqt(cinfo);
+      break;
+      
+    case M_DRI:
+      get_dri(cinfo);
+      break;
+      
+    case M_APP0:
+      get_app0(cinfo);
+      break;
+
+    case M_RST0:               /* these are all parameterless */
+    case M_RST1:
+    case M_RST2:
+    case M_RST3:
+    case M_RST4:
+    case M_RST5:
+    case M_RST6:
+    case M_RST7:
+    case M_TEM:
+      TRACEMS1(cinfo->emethods, 1, "Unexpected marker 0x%02x", c);
+      break;
+
+    default:   /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn */
+      skip_variable(cinfo, c);
+      break;
+    }
+  }
+}
+
+
+
+/*
+ * Initialize and read the file header (everything through the SOF marker).
+ */
+
+METHODDEF void
+read_file_header (decompress_info_ptr cinfo)
+{
+  int c;
+
+  /* Expect an SOI marker first */
+  if (next_marker(cinfo) == M_SOI)
+    get_soi(cinfo);
+  else
+    ERREXIT(cinfo->emethods, "File does not start with JPEG SOI marker");
+
+  /* Process markers until SOF */
+  c = process_tables(cinfo);
+
+  switch (c) {
+  case M_SOF0:
+  case M_SOF1:
+    get_sof(cinfo, c);
+    cinfo->arith_code = FALSE;
+    break;
+      
+  case M_SOF9:
+    get_sof(cinfo, c);
+    cinfo->arith_code = TRUE;
+    break;
+
+  default:
+    ERREXIT1(cinfo->emethods, "Unsupported SOF marker type 0x%02x", c);
+    break;
+  }
+
+  /* Figure out what colorspace we have */
+  /* (too bad the JPEG committee didn't provide a real way to specify this) */
+
+  switch (cinfo->num_components) {
+  case 1:
+    cinfo->jpeg_color_space = CS_GRAYSCALE;
+    break;
+
+  case 3:
+    /* if we saw a JFIF marker, leave it set to YCbCr; */
+    /* also leave it alone if UI has provided a value */
+    if (cinfo->jpeg_color_space == CS_UNKNOWN) {
+      short cid0 = cinfo->comp_info[0].component_id;
+      short cid1 = cinfo->comp_info[1].component_id;
+      short cid2 = cinfo->comp_info[2].component_id;
+
+      if (cid0 == 1 && cid1 == 2 && cid2 == 3)
+       cinfo->jpeg_color_space = CS_YCbCr; /* assume it's JFIF w/out marker */
+      else if (cid0 == 1 && cid1 == 4 && cid2 == 5)
+       cinfo->jpeg_color_space = CS_YIQ; /* prototype's YIQ matrix */
+      else {
+       TRACEMS3(cinfo->emethods, 0,
+                "Unrecognized component IDs %d %d %d, assuming YCbCr",
+                cid0, cid1, cid2);
+       cinfo->jpeg_color_space = CS_YCbCr;
+      }
+    }
+    break;
+
+  case 4:
+    cinfo->jpeg_color_space = CS_CMYK;
+    break;
+
+  default:
+    cinfo->jpeg_color_space = CS_UNKNOWN;
+    break;
+  }
+}
+
+
+/*
+ * Read the start of a scan (everything through the SOS marker).
+ * Return TRUE if find SOS, FALSE if find EOI.
+ */
+
+METHODDEF boolean
+read_scan_header (decompress_info_ptr cinfo)
+{
+  int c;
+  
+  /* Process markers until SOS or EOI */
+  c = process_tables(cinfo);
+  
+  switch (c) {
+  case M_SOS:
+    get_sos(cinfo);
+    return TRUE;
+    
+  case M_EOI:
+    TRACEMS(cinfo->emethods, 1, "End Of Image");
+    return FALSE;
+
+  default:
+    ERREXIT1(cinfo->emethods, "Unexpected marker 0x%02x", c);
+    break;
+  }
+  return FALSE;                        /* keeps lint happy */
+}
+
+
+/*
+ * Finish up after a compressed scan (series of read_jpeg_data calls);
+ * prepare for another read_scan_header call.
+ */
+
+METHODDEF void
+read_scan_trailer (decompress_info_ptr cinfo)
+{
+  /* no work needed */
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+read_file_trailer (decompress_info_ptr cinfo)
+{
+  /* no work needed */
+}
+
+
+/*
+ * The method selection routine for standard JPEG header reading.
+ * Note that this must be called by the user interface before calling
+ * jpeg_decompress.  When a non-JFIF file is to be decompressed (TIFF,
+ * perhaps), the user interface must discover the file type and call
+ * the appropriate method selection routine.
+ */
+
+GLOBAL void
+jselrjfif (decompress_info_ptr cinfo)
+{
+  cinfo->methods->read_file_header = read_file_header;
+  cinfo->methods->read_scan_header = read_scan_header;
+  /* For JFIF/raw-JPEG format, the user interface supplies read_jpeg_data. */
+#if 0
+  cinfo->methods->read_jpeg_data = read_jpeg_data;
+#endif
+  cinfo->methods->read_scan_trailer = read_scan_trailer;
+  cinfo->methods->read_file_trailer = read_file_trailer;
+}
+
+#endif /* JFIF_SUPPORTED */
diff --git a/jrdppm.c b/jrdppm.c
new file mode 100644 (file)
index 0000000..15e2393
--- /dev/null
+++ b/jrdppm.c
@@ -0,0 +1,124 @@
+/*
+ * jrdppm.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to read input images in PPM format.
+ * The PBMPLUS library is required (well, it will be in the real version).
+ *
+ * These routines may need modification for non-Unix environments or
+ * specialized applications.  As they stand, they assume input from
+ * an ordinary stdio stream.  They further assume that reading begins
+ * at the start of the file; input_init may need work if the
+ * user interface has already read some data (e.g., to determine that
+ * the file is indeed PPM format).
+ *
+ * These routines are invoked via the methods get_input_row
+ * and input_init/term.
+ */
+
+#include "jinclude.h"
+
+#ifdef PPM_SUPPORTED
+
+
+/*
+ * Read the file header; return image size and component count.
+ */
+
+METHODDEF void
+input_init (compress_info_ptr cinfo)
+{
+  int c, w, h, prec;
+
+  if (getc(cinfo->input_file) != 'P')
+    ERREXIT(cinfo->emethods, "Not a PPM file");
+
+  c = getc(cinfo->input_file);
+  switch (c) {
+  case '5':                    /* it's a PGM file */
+    cinfo->input_components = 1;
+    cinfo->in_color_space = CS_GRAYSCALE;
+    break;
+
+  case '6':                    /* it's a PPM file */
+    cinfo->input_components = 3;
+    cinfo->in_color_space = CS_RGB;
+    break;
+
+  default:
+    ERREXIT(cinfo->emethods, "Not a PPM file");
+    break;
+  }
+
+  if (fscanf(cinfo->input_file, " %d %d %d", &w, &h, &prec) != 3)
+    ERREXIT(cinfo->emethods, "Not a PPM file");
+
+  if (getc(cinfo->input_file) != '\n' || w <= 0 || h <= 0 || prec != 255)
+    ERREXIT(cinfo->emethods, "Not a PPM file");
+
+  cinfo->image_width = w;
+  cinfo->image_height = h;
+  cinfo->data_precision = 8;
+}
+
+
+/*
+ * Read one row of pixels.
+ */
+
+METHODDEF void
+get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
+{
+  register FILE * infile = cinfo->input_file;
+  register JSAMPROW ptr0, ptr1, ptr2;
+  register long col;
+  
+  if (cinfo->input_components == 1) {
+    ptr0 = pixel_row[0];
+    for (col = cinfo->image_width; col > 0; col--) {
+      *ptr0++ = getc(infile);
+    }
+  } else {
+    ptr0 = pixel_row[0];
+    ptr1 = pixel_row[1];
+    ptr2 = pixel_row[2];
+    for (col = cinfo->image_width; col > 0; col--) {
+      *ptr0++ = getc(infile);
+      *ptr1++ = getc(infile);
+      *ptr2++ = getc(infile);
+    }
+  }
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+input_term (compress_info_ptr cinfo)
+{
+  /* no work required */
+}
+
+
+/*
+ * The method selection routine for PPM format input.
+ * Note that this must be called by the user interface before calling
+ * jpeg_compress.  If multiple input formats are supported, the
+ * user interface is responsible for discovering the file format and
+ * calling the appropriate method selection routine.
+ */
+
+GLOBAL void
+jselrppm (compress_info_ptr cinfo)
+{
+  cinfo->methods->input_init = input_init;
+  cinfo->methods->get_input_row = get_input_row;
+  cinfo->methods->input_term = input_term;
+}
+
+#endif /* PPM_SUPPORTED */
diff --git a/jrevdct.c b/jrevdct.c
new file mode 100644 (file)
index 0000000..bafbf55
--- /dev/null
+++ b/jrevdct.c
@@ -0,0 +1,171 @@
+/*
+ * jrevdct.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains the basic inverse-DCT transformation subroutine.
+ *
+ * This implementation is based on Appendix A.2 of the book
+ * "Discrete Cosine Transform---Algorithms, Advantages, Applications"
+ * by K.R. Rao and P. Yip  (Academic Press, Inc, London, 1990).
+ * It uses scaled fixed-point arithmetic instead of floating point.
+ */
+
+#include "jinclude.h"
+
+
+/* The poop on this scaling stuff is as follows:
+ *
+ * Most of the numbers (after multiplication by the constants) are
+ * (logically) shifted left by LG2_DCT_SCALE. This is undone by UNFIXH
+ * before assignment to the output array. Note that we want an additional
+ * division by 2 on the output (required by the equations).
+ *
+ * If right shifts are unsigned, then there is a potential problem.
+ * However, shifting right by 16 and then assigning to a short
+ * (assuming short = 16 bits) will keep the sign right!!
+ *
+ * For other shifts,
+ *
+ *     ((x + (1 << 30)) >> shft) - (1 << (30 - shft))
+ *
+ * gives a nice right shift with sign (assuming no overflow). However, all the
+ * scaling is such that this isn't a problem. (Is this true?)
+ */
+
+
+#define ONE 1L                 /* remove L if long > 32 bits */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define LG2_DCT_SCALE 15
+#define RIGHT_SHIFT(_x,_shft)   ((((_x) + (ONE << 30)) >> (_shft)) - (ONE << (30 - (_shft))))
+#else
+#define LG2_DCT_SCALE 16
+#define RIGHT_SHIFT(_x,_shft)   ((_x) >> (_shft))
+#endif
+
+#define DCT_SCALE (ONE << LG2_DCT_SCALE)
+
+#define LG2_OVERSCALE 2
+#define OVERSCALE (ONE << LG2_OVERSCALE)
+
+#define FIX(x)  ((INT32) ((x) * DCT_SCALE + 0.5))
+#define FIXO(x)  ((INT32) ((x) * DCT_SCALE / OVERSCALE + 0.5))
+#define UNFIX(x)   RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1)), LG2_DCT_SCALE)
+#define UNFIXH(x)  RIGHT_SHIFT((x) + (ONE << LG2_DCT_SCALE), LG2_DCT_SCALE+1)
+#define UNFIXO(x)  RIGHT_SHIFT((x) + (ONE << (LG2_DCT_SCALE-1-LG2_OVERSCALE)), LG2_DCT_SCALE-LG2_OVERSCALE)
+#define OVERSH(x)   ((x) << LG2_OVERSCALE)
+
+#define SIN_1_4 FIX(0.7071067811856476)
+#define COS_1_4 SIN_1_4
+
+#define SIN_1_8 FIX(0.3826834323650898)
+#define COS_1_8 FIX(0.9238795325112870)
+#define SIN_3_8 COS_1_8
+#define COS_3_8 SIN_1_8
+
+#define SIN_1_16 FIX(0.1950903220161282)
+#define COS_1_16 FIX(0.9807852804032300)
+#define SIN_7_16 COS_1_16
+#define COS_7_16 SIN_1_16
+
+#define SIN_3_16 FIX(0.5555702330196022)
+#define COS_3_16 FIX(0.8314696123025450)
+#define SIN_5_16 COS_3_16
+#define COS_5_16 SIN_3_16
+
+#define OSIN_1_4 FIXO(0.707106781185647)
+#define OCOS_1_4 OSIN_1_4
+
+#define OSIN_1_8 FIXO(0.3826834323650898)
+#define OCOS_1_8 FIXO(0.9238795325112870)
+#define OSIN_3_8 OCOS_1_8
+#define OCOS_3_8 OSIN_1_8
+
+#define OSIN_1_16 FIXO(0.1950903220161282)
+#define OCOS_1_16 FIXO(0.9807852804032300)
+#define OSIN_7_16 OCOS_1_16
+#define OCOS_7_16 OSIN_1_16
+
+#define OSIN_3_16 FIXO(0.5555702330196022)
+#define OCOS_3_16 FIXO(0.8314696123025450)
+#define OSIN_5_16 OCOS_3_16
+#define OCOS_5_16 OSIN_3_16
+
+
+INLINE
+LOCAL void
+fast_idct_8 (DCTELEM *in, int stride)
+{
+  /* tmp1x are new values of tmpx -- flashy register colourers
+   * should be able to do this lot very well
+   */
+  INT32 tmp10, tmp11, tmp12, tmp13;
+  INT32 tmp20, tmp21, tmp22, tmp23;
+  INT32 tmp30, tmp31;
+  INT32 tmp40, tmp41, tmp42, tmp43;
+  INT32 tmp50, tmp51, tmp52, tmp53;
+  INT32 in0, in1, in2, in3, in4, in5, in6, in7;
+  
+  in0 = in[       0];
+  in1 = in[stride  ];
+  in2 = in[stride*2];
+  in3 = in[stride*3];
+  in4 = in[stride*4];
+  in5 = in[stride*5];
+  in6 = in[stride*6];
+  in7 = in[stride*7];
+  
+  tmp10 = (in0 + in4) * COS_1_4;
+  tmp11 = (in0 - in4) * COS_1_4;
+  tmp12 = in2 * SIN_1_8 - in6 * COS_1_8;
+  tmp13 = in6 * SIN_1_8 + in2 * COS_1_8;
+  
+  tmp20 = tmp10 + tmp13;
+  tmp21 = tmp11 + tmp12;
+  tmp22 = tmp11 - tmp12;
+  tmp23 = tmp10 - tmp13;
+  
+  tmp30 = UNFIXO((in3 + in5) * COS_1_4);
+  tmp31 = UNFIXO((in3 - in5) * COS_1_4);
+  
+  tmp40 = OVERSH(in1) + tmp30;
+  tmp41 = OVERSH(in7) + tmp31;
+  tmp42 = OVERSH(in1) - tmp30;
+  tmp43 = OVERSH(in7) - tmp31;
+  
+  tmp50 = tmp40 * OCOS_1_16 + tmp41 * OSIN_1_16;
+  tmp51 = tmp40 * OSIN_1_16 - tmp41 * OCOS_1_16;
+  tmp52 = tmp42 * OCOS_5_16 + tmp43 * OSIN_5_16;
+  tmp53 = tmp42 * OSIN_5_16 - tmp43 * OCOS_5_16;
+  
+  in[       0] = UNFIXH(tmp20 + tmp50);
+  in[stride  ] = UNFIXH(tmp21 + tmp53);
+  in[stride*2] = UNFIXH(tmp22 + tmp52);
+  in[stride*3] = UNFIXH(tmp23 + tmp51);
+  in[stride*4] = UNFIXH(tmp23 - tmp51);
+  in[stride*5] = UNFIXH(tmp22 - tmp52);
+  in[stride*6] = UNFIXH(tmp21 - tmp53);
+  in[stride*7] = UNFIXH(tmp20 - tmp50);
+}
+
+
+/*
+ * Perform the inverse DCT on one block of coefficients.
+ *
+ * Note that this code is specialized to the case DCTSIZE = 8.
+ */
+
+GLOBAL void
+j_rev_dct (DCTBLOCK data)
+{
+  int i;
+  
+  for (i = 0; i < DCTSIZE; i++)
+    fast_idct_8(data+i*DCTSIZE, 1);
+  
+  for (i = 0; i < DCTSIZE; i++)
+    fast_idct_8(data+i, DCTSIZE);
+}
diff --git a/jutils.c b/jutils.c
new file mode 100644 (file)
index 0000000..aebcaa9
--- /dev/null
+++ b/jutils.c
@@ -0,0 +1,106 @@
+/*
+ * jutils.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains miscellaneous utility routines needed for both
+ * compression and decompression.
+ * Note we prefix all global names with "j" to minimize conflicts with
+ * a surrounding application.
+ */
+
+#include "jinclude.h"
+
+
+GLOBAL long
+jround_up (long a, long b)
+/* Compute a rounded up to next multiple of b; a >= 0, b > 0 */
+{
+  a += b-1;
+  return a - (a % b);
+}
+
+
+GLOBAL void
+jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
+                  JSAMPARRAY output_array, int dest_row,
+                  int num_rows, long num_cols)
+/* Copy some rows of samples from one place to another.
+ * num_rows rows are copied from input_array[source_row++]
+ * to output_array[dest_row++]; these areas should not overlap.
+ * The source and destination arrays must be at least as wide as num_cols.
+ */
+{
+  /* On normal machines we can use memcpy().  This won't work on 80x86 because
+   * the sample arrays are FAR and we're assuming a small-pointer memory model.
+   */
+  register JSAMPROW inptr, outptr;
+#ifdef NEED_FAR_POINTERS
+  register long count;
+#else
+  register size_t count = num_cols * SIZEOF(JSAMPLE);
+#endif
+  register int row;
+
+  input_array += source_row;
+  output_array += dest_row;
+
+  for (row = num_rows; row > 0; row--) {
+    inptr = *input_array++;
+    outptr = *output_array++;
+#ifdef NEED_FAR_POINTERS
+    for (count = num_cols; count > 0; count--)
+      *outptr++ = *inptr++;    /* needn't bother with GETJSAMPLE() here */
+#else
+    memcpy((void *) outptr, (void *) inptr, count);
+#endif
+  }
+}
+
+
+GLOBAL void
+jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, long num_blocks)
+/* Copy a row of coefficient blocks from one place to another. */
+{
+  /* On normal machines we can use memcpy().  This won't work on 80x86 because
+   * the block arrays are FAR and we're assuming a small-pointer memory model.
+   */
+#ifdef NEED_FAR_POINTERS
+  register JCOEFPTR inptr, outptr;
+  register int i;
+  register long count;
+
+  for (count = num_blocks; count > 0; count--) {
+    inptr = *input_row++;
+    outptr = *output_row++;
+    for (i = DCTSIZE2; i > 0; i--)
+      *outptr++ = *inptr++;
+  }
+#else
+    memcpy((void *) output_row, (void *) input_row,
+          (size_t) (num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))));
+#endif
+}
+
+
+GLOBAL void
+jzero_far (void FAR * target, size_t bytestozero)
+/* Zero out a chunk of FAR memory. */
+/* This might be sample-array data, block-array data, or alloc_medium data. */
+{
+  /* On normal machines we can use MEMZERO().  This won't work on 80x86
+   * because we're assuming a small-pointer memory model.
+   */
+#ifdef NEED_FAR_POINTERS
+  register char FAR * ptr = (char FAR *) target;
+  register size_t count;
+
+  for (count = bytestozero; count > 0; count--) {
+    *ptr++ = 0;
+  }
+#else
+  MEMZERO((void *) target, bytestozero);
+#endif
+}
diff --git a/jvirtmem.c b/jvirtmem.c
new file mode 100644 (file)
index 0000000..4a0627c
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+ * jvirtmem.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file provides the system-dependent memory allocation routines
+ * for the case where we can rely on virtual memory to handle large arrays.
+ *
+ * This includes some MS-DOS code just for trial purposes; "big" arrays will
+ * have to be handled with temp files on MS-DOS, so a real implementation of
+ * a DOS memory manager will probably be a separate file.  (See additional
+ * comments about big arrays, below.)
+ * 
+ * NB: allocation routines never return NULL.
+ * They should exit to error_exit if unsuccessful.
+ */
+
+#include "jinclude.h"
+
+#ifdef __STDC__
+#include <stdlib.h>            /* to declare malloc(), free() */
+#else
+extern void * malloc PP((size_t size));
+extern void free PP((void *ptr));
+#endif
+
+
+/* Insert system-specific definitions of far_malloc, far_free here. */
+
+#ifndef NEED_FAR_POINTERS      /* Generic for non-braindamaged CPUs */
+
+#define far_malloc(x)  malloc(x)
+#define far_free(x)    free(x)
+
+#else /* NEED_FAR_POINTERS */
+
+#ifdef __TURBOC__
+/* These definitions work for Turbo C */
+#include <alloc.h>             /* need farmalloc(), farfree() */
+#define far_malloc(x)  farmalloc(x)
+#define far_free(x)    farfree(x)
+#else
+#ifdef MSDOS
+/* These definitions work for Microsoft C and compatible compilers */
+#include <malloc.h>            /* need _fmalloc(), _ffree() */
+#define far_malloc(x)  _fmalloc(x)
+#define far_free(x)    _ffree(x)
+#endif
+#endif
+
+#endif /* NEED_FAR_POINTERS */
+
+
+/*
+ * Some important notes:
+ *   The array alloc/dealloc routines are not merely a convenience;
+ *   on 80x86 machines the bottom-level pointers in an array are FAR
+ *   and thus may not be allocatable by alloc_small.
+ *
+ *   Also, it's not a good idea to try to merge the sarray and barray
+ *   routines, even though they are textually almost the same, because
+ *   samples are usually stored as bytes while coefficients are shorts.
+ *   Thus, in machines where byte pointers have a different representation
+ *   from word pointers, the resulting machine code could not be the same.
+ */
+
+
+static external_methods_ptr methods; /* saved for access to error_exit */
+
+
+#ifdef MEM_STATS               /* optional extra stuff for statistics */
+
+#define MALLOC_OVERHEAD  (SIZEOF(char *)) /* assumed overhead per request */
+#define MALLOC_FAR_OVERHEAD  (SIZEOF(char FAR *)) /* for "far" storage */
+
+static long total_num_small = 0;       /* total # of small objects alloced */
+static long total_bytes_small = 0;     /* total bytes requested */
+static long cur_num_small = 0;         /* # currently alloced */
+static long max_num_small = 0;         /* max simultaneously alloced */
+
+#ifdef NEED_FAR_POINTERS
+static long total_num_medium = 0;      /* total # of medium objects alloced */
+static long total_bytes_medium = 0;    /* total bytes requested */
+static long cur_num_medium = 0;                /* # currently alloced */
+static long max_num_medium = 0;                /* max simultaneously alloced */
+#endif
+
+static long total_num_sarray = 0;      /* total # of sarray objects alloced */
+static long total_bytes_sarray = 0;    /* total bytes requested */
+static long cur_num_sarray = 0;                /* # currently alloced */
+static long max_num_sarray = 0;                /* max simultaneously alloced */
+
+static long total_num_barray = 0;      /* total # of barray objects alloced */
+static long total_bytes_barray = 0;    /* total bytes requested */
+static long cur_num_barray = 0;                /* # currently alloced */
+static long max_num_barray = 0;                /* max simultaneously alloced */
+
+
+GLOBAL void
+j_mem_stats (void)
+{
+  /* since this is only a debugging stub, we can cheat a little on the
+   * trace message mechanism... helps 'cuz trace can't handle longs.
+   */
+  fprintf(stderr, "total_num_small = %ld\n", total_num_small);
+  fprintf(stderr, "total_bytes_small = %ld\n", total_bytes_small);
+  if (cur_num_small)
+    fprintf(stderr, "CUR_NUM_SMALL = %ld\n", cur_num_small);
+  fprintf(stderr, "max_num_small = %ld\n", max_num_small);
+  
+#ifdef NEED_FAR_POINTERS
+  fprintf(stderr, "total_num_medium = %ld\n", total_num_medium);
+  fprintf(stderr, "total_bytes_medium = %ld\n", total_bytes_medium);
+  if (cur_num_medium)
+    fprintf(stderr, "CUR_NUM_MEDIUM = %ld\n", cur_num_medium);
+  fprintf(stderr, "max_num_medium = %ld\n", max_num_medium);
+#endif
+  
+  fprintf(stderr, "total_num_sarray = %ld\n", total_num_sarray);
+  fprintf(stderr, "total_bytes_sarray = %ld\n", total_bytes_sarray);
+  if (cur_num_sarray)
+    fprintf(stderr, "CUR_NUM_SARRAY = %ld\n", cur_num_sarray);
+  fprintf(stderr, "max_num_sarray = %ld\n", max_num_sarray);
+  
+  fprintf(stderr, "total_num_barray = %ld\n", total_num_barray);
+  fprintf(stderr, "total_bytes_barray = %ld\n", total_bytes_barray);
+  if (cur_num_barray)
+    fprintf(stderr, "CUR_NUM_BARRAY = %ld\n", cur_num_barray);
+  fprintf(stderr, "max_num_barray = %ld\n", max_num_barray);
+}
+
+#endif /* MEM_STATS */
+
+
+LOCAL void
+out_of_memory (int which)
+/* Report an out-of-memory error and stop execution */
+/* If we compiled MEM_STATS support, report alloc requests before dying */
+{
+#ifdef MEM_STATS
+  j_mem_stats();
+#endif
+  ERREXIT1(methods, "Insufficient memory (case %d)", which);
+}
+
+
+
+METHODDEF void *
+alloc_small (size_t sizeofobject)
+/* Allocate a "small" (all-in-memory) object */
+{
+  void * result;
+
+#ifdef MEM_STATS
+  total_num_small++;
+  total_bytes_small += sizeofobject + MALLOC_OVERHEAD;
+  cur_num_small++;
+  if (cur_num_small > max_num_small) max_num_small = cur_num_small;
+#endif
+
+  result = malloc(sizeofobject);
+  if (result == NULL)
+    out_of_memory(1);
+  return result;
+}
+
+
+METHODDEF void
+free_small (void *ptr)
+/* Free a "small" (all-in-memory) object */
+{
+  free(ptr);
+
+#ifdef MEM_STATS
+  cur_num_small--;
+#endif
+}
+
+
+#ifdef NEED_FAR_POINTERS
+
+METHODDEF void FAR *
+alloc_medium (size_t sizeofobject)
+/* Allocate a "medium" (all in memory, but in far heap) object */
+{
+  void FAR * result;
+
+#ifdef MEM_STATS
+  total_num_medium++;
+  total_bytes_medium += sizeofobject + MALLOC_FAR_OVERHEAD;
+  cur_num_medium++;
+  if (cur_num_medium > max_num_medium) max_num_medium = cur_num_medium;
+#endif
+
+  result = far_malloc(sizeofobject);
+  if (result == NULL)
+    out_of_memory(2);
+  return result;
+}
+
+
+METHODDEF void
+free_medium (void FAR *ptr)
+/* Free a "medium" (all in memory, but in far heap) object */
+{
+  far_free(ptr);
+
+#ifdef MEM_STATS
+  cur_num_medium--;
+#endif
+}
+
+#endif /* NEED_FAR_POINTERS */
+
+
+METHODDEF JSAMPARRAY
+alloc_small_sarray (long samplesperrow, long numrows)
+/* Allocate a "small" (all-in-memory) 2-D sample array */
+{
+  JSAMPARRAY result;
+  long i;
+
+#ifdef MEM_STATS
+  total_num_sarray++;
+  total_bytes_sarray += (samplesperrow * SIZEOF(JSAMPLE) + MALLOC_FAR_OVERHEAD)
+                       * numrows;
+  cur_num_sarray++;
+  if (cur_num_sarray > max_num_sarray) max_num_sarray = cur_num_sarray;
+#endif
+
+  /* Get space for row pointers; this is always "near" on 80x86 */
+  result = (JSAMPARRAY) alloc_small((size_t) (numrows * SIZEOF(JSAMPROW)));
+
+  /* Get the rows themselves; on 80x86 these are "far" */
+  for (i = 0; i < numrows; i++) {
+    result[i] = (JSAMPROW) far_malloc((size_t) (samplesperrow * SIZEOF(JSAMPLE)));
+    if (result[i] == NULL)
+      out_of_memory(3);
+  }
+
+  return result;
+}
+
+
+METHODDEF void
+free_small_sarray (JSAMPARRAY ptr, long numrows)
+/* Free a "small" (all-in-memory) 2-D sample array */
+{
+  long i;
+
+  /* Free the rows themselves; on 80x86 these are "far" */
+  for (i = 0; i < numrows; i++) {
+    far_free((void FAR *) ptr[i]);
+  }
+
+  /* Free space for row pointers; this is always "near" on 80x86 */
+  free_small((void *) ptr);
+
+#ifdef MEM_STATS
+  cur_num_sarray--;
+#endif
+}
+
+
+METHODDEF JBLOCKARRAY
+alloc_small_barray (long blocksperrow, long numrows)
+/* Allocate a "small" (all-in-memory) 2-D coefficient-block array */
+{
+  JBLOCKARRAY result;
+  long i;
+
+#ifdef MEM_STATS
+  total_num_barray++;
+  total_bytes_barray += (blocksperrow * SIZEOF(JBLOCK) + MALLOC_FAR_OVERHEAD)
+                       * numrows;
+  cur_num_barray++;
+  if (cur_num_barray > max_num_barray) max_num_barray = cur_num_barray;
+#endif
+
+  /* Get space for row pointers; this is always "near" on 80x86 */
+  result = (JBLOCKARRAY) alloc_small((size_t) (numrows * SIZEOF(JBLOCKROW)));
+
+  /* Get the rows themselves; on 80x86 these are "far" */
+  for (i = 0; i < numrows; i++) {
+    result[i] = (JBLOCKROW) far_malloc((size_t) (blocksperrow * SIZEOF(JBLOCK)));
+    if (result[i] == NULL)
+      out_of_memory(4);
+  }
+
+  return result;
+}
+
+
+METHODDEF void
+free_small_barray (JBLOCKARRAY ptr, long numrows)
+/* Free a "small" (all-in-memory) 2-D coefficient-block array */
+{
+  long i;
+
+  /* Free the rows themselves; on 80x86 these are "far" */
+  for (i = 0; i < numrows; i++) {
+    far_free((void FAR *) ptr[i]);
+  }
+
+  /* Free space for row pointers; this is always "near" on 80x86 */
+  free_small((void *) ptr);
+
+#ifdef MEM_STATS
+  cur_num_barray--;
+#endif
+}
+
+
+
+/*
+ * About "big" array management:
+ *
+ * To allow machines with limited memory to handle large images,
+ * all processing in the JPEG system is done a few pixel or block rows
+ * at a time.  The above "small" array routines are only used to allocate
+ * strip buffers (as wide as the image, but just a few rows high).
+ * In some cases multiple passes must be made over the data.  In these
+ * cases the "big" array routines are used.  The array is still accessed
+ * a strip at a time, but the memory manager must save the whole array
+ * for repeated accesses.  The intended implementation is that there is
+ * a strip buffer in memory (as high as is possible given the desired memory
+ * limit), plus a backing file that holds the rest of the array.
+ *
+ * The request_big_array routines are told the total size of the image (in case
+ * it is useful to know the total file size that will be needed).  They are
+ * also given the unit height, which is the number of rows that will be
+ * accessed at once; the in-memory buffer should usually be made a multiple of
+ * this height for best efficiency.
+ *
+ * The request routines create control blocks (and may open backing files),
+ * but they don't create the in-memory buffers.  This is postponed until
+ * alloc_big_arrays is called.  At that time the total amount of space needed
+ * is known (approximately, anyway), so free memory can be divided up fairly.
+ *
+ * The access_big_array routines are responsible for making a specific strip
+ * area accessible (after reading or writing the backing file, if necessary).
+ * Note that the access routines are told whether the caller intends to modify
+ * the accessed strip; during a read-only pass this saves having to rewrite
+ * data to disk.
+ *
+ * The typical access pattern is one top-to-bottom pass to write the data,
+ * followed by one or more read-only top-to-bottom passes.  However, other
+ * access patterns may occur while reading.  For example, translation of image
+ * formats that use bottom-to-top scan order will require bottom-to-top read
+ * passes.  The memory manager need not support multiple write passes nor
+ * funny write orders (meaning that rearranging rows must be handled while
+ * reading data out of the big array, not while putting it in).
+ *
+ * In current usage, the access requests are always for nonoverlapping strips;
+ * that is, successive access start_row numbers always differ by exactly the
+ * unitheight.  This allows fairly simple buffer dump/reload logic if the
+ * in-memory buffer is made a multiple of the unitheight.  It would be
+ * possible to keep subsampled rather than fullsize data in the "big" arrays,
+ * thus reducing temp file size, if we supported overlapping strip access
+ * (access requests differing by less than the unitheight).  At the moment
+ * I don't believe this is worth the extra complexity.
+ *
+ * This particular implementation doesn't use temp files; the whole of a big
+ * array is allocated in (virtual) memory, and any swapping is done behind the
+ * scenes by the operating system.
+ */
+
+
+
+/* The control blocks for virtual arrays.
+ * These are pretty minimal in this implementation.
+ * Note: in this implementation we could realize big arrays
+ * at request time and make alloc_big_arrays a no-op;
+ * however, doing it separately keeps callers honest.
+ */
+
+struct big_sarray_control {
+       JSAMPARRAY mem_buffer;  /* memory buffer (the whole thing, here) */
+       long rows_in_mem;       /* Height of memory buffer */
+       long samplesperrow;     /* Width of memory buffer */
+       long unitheight;        /* # of rows accessed by access_big_sarray() */
+       big_sarray_ptr next;    /* list link for unrealized arrays */
+};
+
+struct big_barray_control {
+       JBLOCKARRAY mem_buffer; /* memory buffer (the whole thing, here) */
+       long rows_in_mem;       /* Height of memory buffer */
+       long blocksperrow;      /* Width of memory buffer */
+       long unitheight;        /* # of rows accessed by access_big_barray() */
+       big_barray_ptr next;    /* list link for unrealized arrays */
+};
+
+
+/* Headers of lists of control blocks for unrealized big arrays */
+static big_sarray_ptr unalloced_sarrays;
+static big_barray_ptr unalloced_barrays;
+
+
+METHODDEF big_sarray_ptr
+request_big_sarray (long samplesperrow, long numrows, long unitheight)
+/* Request a "big" (virtual-memory) 2-D sample array */
+{
+  big_sarray_ptr result;
+
+  /* get control block */
+  result = (big_sarray_ptr) alloc_small(SIZEOF(struct big_sarray_control));
+
+  result->mem_buffer = NULL;   /* lets access routine spot premature access */
+  result->rows_in_mem = numrows;
+  result->samplesperrow = samplesperrow;
+  result->unitheight = unitheight;
+  result->next = unalloced_sarrays; /* add to list of unallocated arrays */
+  unalloced_sarrays = result;
+
+  return result;
+}
+
+
+METHODDEF big_barray_ptr
+request_big_barray (long blocksperrow, long numrows, long unitheight)
+/* Request a "big" (virtual-memory) 2-D coefficient-block array */
+{
+  big_barray_ptr result;
+
+  /* get control block */
+  result = (big_barray_ptr) alloc_small(SIZEOF(struct big_barray_control));
+
+  result->mem_buffer = NULL;   /* lets access routine spot premature access */
+  result->rows_in_mem = numrows;
+  result->blocksperrow = blocksperrow;
+  result->unitheight = unitheight;
+  result->next = unalloced_barrays; /* add to list of unallocated arrays */
+  unalloced_barrays = result;
+
+  return result;
+}
+
+
+METHODDEF void
+alloc_big_arrays (long extra_small_samples, long extra_small_blocks,
+                 long extra_medium_space)
+/* Allocate the in-memory buffers for any unrealized "big" arrays */
+/* 'extra' values are upper bounds for total future small-array requests */
+/* and far-heap requests */
+{
+  /* In this implementation we just malloc the whole arrays */
+  /* and expect the system's virtual memory to worry about swapping them */
+  big_sarray_ptr sptr;
+  big_barray_ptr bptr;
+
+  for (sptr = unalloced_sarrays; sptr != NULL; sptr = sptr->next) {
+    sptr->mem_buffer = alloc_small_sarray(sptr->samplesperrow,
+                                         sptr->rows_in_mem);
+  }
+
+  for (bptr = unalloced_barrays; bptr != NULL; bptr = bptr->next) {
+    bptr->mem_buffer = alloc_small_barray(bptr->blocksperrow,
+                                         bptr->rows_in_mem);
+  }
+
+  unalloced_sarrays = NULL;    /* reset for possible future cycles */
+  unalloced_barrays = NULL;
+}
+
+
+METHODDEF JSAMPARRAY
+access_big_sarray (big_sarray_ptr ptr, long start_row, boolean writable)
+/* Access the part of a "big" sample array starting at start_row */
+/* and extending for ptr->unitheight rows.  writable is true if  */
+/* caller intends to modify the accessed area. */
+{
+  /* debugging check */
+  if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_mem ||
+      ptr->mem_buffer == NULL)
+    ERREXIT(methods, "Bogus access_big_sarray request");
+
+  return ptr->mem_buffer + start_row;
+}
+
+
+METHODDEF JBLOCKARRAY
+access_big_barray (big_barray_ptr ptr, long start_row, boolean writable)
+/* Access the part of a "big" coefficient-block array starting at start_row */
+/* and extending for ptr->unitheight rows.  writable is true if  */
+/* caller intends to modify the accessed area. */
+{
+  /* debugging check */
+  if (start_row < 0 || start_row+ptr->unitheight > ptr->rows_in_mem ||
+      ptr->mem_buffer == NULL)
+    ERREXIT(methods, "Bogus access_big_barray request");
+
+  return ptr->mem_buffer + start_row;
+}
+
+
+METHODDEF void
+free_big_sarray (big_sarray_ptr ptr)
+/* Free a "big" (virtual-memory) 2-D sample array */
+{
+  free_small_sarray(ptr->mem_buffer, ptr->rows_in_mem);
+  free_small((void *) ptr);    /* free the control block too */
+}
+
+
+METHODDEF void
+free_big_barray (big_barray_ptr ptr)
+/* Free a "big" (virtual-memory) 2-D coefficient-block array */
+{
+  free_small_barray(ptr->mem_buffer, ptr->rows_in_mem);
+  free_small((void *) ptr);    /* free the control block too */
+}
+
+
+
+/*
+ * The method selection routine for virtual memory systems.
+ * The system-dependent setup routine should call this routine
+ * to install the necessary method pointers in the supplied struct.
+ */
+
+GLOBAL void
+jselvirtmem (external_methods_ptr emethods)
+{
+  methods = emethods;          /* save struct addr for error exit access */
+
+  emethods->alloc_small = alloc_small;
+  emethods->free_small = free_small;
+#ifdef NEED_FAR_POINTERS
+  emethods->alloc_medium = alloc_medium;
+  emethods->free_medium = free_medium;
+#endif
+  emethods->alloc_small_sarray = alloc_small_sarray;
+  emethods->free_small_sarray = free_small_sarray;
+  emethods->alloc_small_barray = alloc_small_barray;
+  emethods->free_small_barray = free_small_barray;
+  emethods->request_big_sarray = request_big_sarray;
+  emethods->request_big_barray = request_big_barray;
+  emethods->alloc_big_arrays = alloc_big_arrays;
+  emethods->access_big_sarray = access_big_sarray;
+  emethods->access_big_barray = access_big_barray;
+  emethods->free_big_sarray = free_big_sarray;
+  emethods->free_big_barray = free_big_barray;
+
+  unalloced_sarrays = NULL;    /* make sure list headers are empty */
+  unalloced_barrays = NULL;
+}
diff --git a/jwrgif.c b/jwrgif.c
new file mode 100644 (file)
index 0000000..44062ec
--- /dev/null
+++ b/jwrgif.c
@@ -0,0 +1,497 @@
+/*
+ * jwrgif.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to write output images in GIF format.
+ *
+ * These routines may need modification for non-Unix environments or
+ * specialized applications.  As they stand, they assume output to
+ * an ordinary stdio stream.
+ *
+ * These routines are invoked via the methods put_pixel_rows, put_color_map,
+ * and output_init/term.
+ */
+
+/*
+ * This code is loosely based on ppmtogif from the PBMPLUS distribution
+ * of Feb. 1991.  That file contains the following copyright notice:
+ *    Based on GIFENCODE by David Rowley <mgardi@watdscu.waterloo.edu>.
+ *    Lempel-Ziv compression based on "compress" by Spencer W. Thomas et al.
+ *    Copyright (C) 1989 by Jef Poskanzer.
+ *    Permission to use, copy, modify, and distribute this software and its
+ *    documentation for any purpose and without fee is hereby granted, provided
+ *    that the above copyright notice appear in all copies and that both that
+ *    copyright notice and this permission notice appear in supporting
+ *    documentation.  This software is provided "as is" without express or
+ *    implied warranty.
+ *
+ * We are also required to state that
+ *    "The Graphics Interchange Format(c) is the Copyright property of
+ *    CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ *    CompuServe Incorporated."
+ */
+
+#include "jinclude.h"
+
+#ifdef GIF_SUPPORTED
+
+
+static decompress_info_ptr dcinfo; /* to avoid passing to all functions */
+
+#define        MAX_LZW_BITS    12      /* maximum LZW code size (4096 symbols) */
+
+typedef INT16 code_int;                /* must hold -1 .. 2**MAX_LZW_BITS */
+
+#define LZW_TABLE_SIZE ((code_int) 1 << MAX_LZW_BITS)
+
+#define HSIZE          5003    /* hash table size for 80% occupancy */
+
+typedef int hash_int;          /* must hold -2*HSIZE..2*HSIZE */
+
+static int n_bits;             /* current number of bits/code */
+static code_int maxcode;       /* maximum code, given n_bits */
+#define MAXCODE(n_bits)        (((code_int) 1 << (n_bits)) - 1)
+
+static int init_bits;          /* initial n_bits ... restored after clear */
+
+static code_int ClearCode;     /* clear code (doesn't change) */
+static code_int EOFCode;       /* EOF code (ditto) */
+
+static code_int free_code;     /* first not-yet-used symbol code */
+
+/*
+ * The LZW hash table consists of three parallel arrays:
+ *   hash_code[i]      code of symbol in slot i, or 0 if empty slot
+ *   hash_prefix[i]    symbol's prefix code; undefined if empty slot
+ *   hash_suffix[i]    symbol's suffix character; undefined if empty slot
+ * where slot values (i) range from 0 to HSIZE-1.
+ *
+ * Algorithm:  use open addressing double hashing (no chaining) on the
+ * prefix code / suffix character combination.  We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe.
+ *
+ * The hash tables are allocated from FAR heap space since they would use up
+ * rather a lot of the near data space in a PC.
+ */
+
+static code_int FAR *hash_code;        /* => hash table of symbol codes */
+static code_int FAR *hash_prefix; /* => hash table of prefix symbols */
+static UINT8 FAR *hash_suffix; /* => hash table of suffix bytes */
+
+
+/*
+ * Routines to package compressed data bytes into GIF data blocks.
+ * A data block consists of a count byte (1..255) and that many data bytes.
+ */
+
+static int bytesinpkt;         /* # of bytes in current packet */
+static char packetbuf[256];    /* workspace for accumulating packet */
+
+
+LOCAL void
+flush_packet (void)
+/* flush any accumulated data */
+{
+  if (bytesinpkt > 0) {                /* never write zero-length packet */
+    packetbuf[0] = bytesinpkt++;
+    if (fwrite(packetbuf, 1, bytesinpkt, dcinfo->output_file) != bytesinpkt)
+      ERREXIT(dcinfo->emethods, "Output file write error");
+    bytesinpkt = 0;
+  }
+}
+
+
+LOCAL void
+char_out (int c)
+/* Add a character to current packet; flush to disk if necessary */
+{
+  packetbuf[++bytesinpkt] = c;
+  if (bytesinpkt >= 255)
+    flush_packet();
+}
+
+
+/* Routine to convert variable-width codes into a byte stream */
+
+static INT32 cur_accum;                /* holds bits not yet output */
+static int cur_bits;           /* # of bits in cur_accum */
+
+
+LOCAL void
+output (code_int code)
+/* Emit a code of n_bits bits */
+/* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
+{
+  if (cur_bits > 0)
+    cur_accum |= ((INT32) code << cur_bits);
+  else
+    cur_accum = code;
+  cur_bits += n_bits;
+
+  while (cur_bits >= 8) {
+    char_out((int) (cur_accum & 0xFF));
+    cur_accum >>= 8;
+    cur_bits -= 8;
+  }
+
+  /*
+   * If the next entry is going to be too big for the code size,
+   * then increase it, if possible.  We do this here to ensure
+   * that it's done in sync with the decoder's codesize increases.
+   */
+  if (free_code > maxcode) {
+    n_bits++;
+    if (n_bits == MAX_LZW_BITS)
+      maxcode = LZW_TABLE_SIZE;        /* free_code will never exceed this */
+    else
+      maxcode = MAXCODE(n_bits);
+  }
+}
+
+
+/* The LZW algorithm proper */
+
+static code_int waiting_code;  /* symbol not yet output; may be extendable */
+static boolean first_byte;     /* if TRUE, waiting_code is not valid */
+
+
+LOCAL void
+clear_hash (void)
+/* Fill the hash table with empty entries */
+{
+  /* It's sufficient to zero hash_code[] */
+  jzero_far((void FAR *) hash_code, HSIZE * SIZEOF(code_int));
+}
+
+
+LOCAL void
+clear_block (void)
+/* Reset compressor and issue a Clear code */
+{
+  clear_hash();                        /* delete all the symbols */
+  free_code = ClearCode + 2;
+  output(ClearCode);           /* inform decoder */
+  n_bits = init_bits;          /* reset code size */
+  maxcode = MAXCODE(n_bits);
+}
+
+
+LOCAL void
+compress_init (int i_bits)
+/* Initialize LZW compressor */
+{
+  /* init all the static variables */
+  n_bits = init_bits = i_bits;
+  maxcode = MAXCODE(n_bits);
+  ClearCode = ((code_int) 1 << (init_bits - 1));
+  EOFCode = ClearCode + 1;
+  free_code = ClearCode + 2;
+  first_byte = TRUE;           /* no waiting symbol yet */
+  /* init output buffering vars */
+  bytesinpkt = 0;
+  cur_accum = 0;
+  cur_bits = 0;
+  /* clear hash table */
+  clear_hash();
+  /* GIF specifies an initial Clear code */
+  output(ClearCode);
+}
+
+
+LOCAL void
+compress_byte (int c)
+/* Accept and compress one 8-bit byte */
+{
+  register hash_int i;
+  register hash_int disp;
+
+  if (first_byte) {            /* need to initialize waiting_code */
+    waiting_code = c;
+    first_byte = FALSE;
+    return;
+  }
+
+  /* Probe hash table to see if a symbol exists for
+   * waiting_code followed by c.
+   * If so, replace waiting_code by that symbol and return.
+   */
+  i = ((hash_int) c << (MAX_LZW_BITS-8)) + waiting_code;
+  /* i is less than twice 2**MAX_LZW_BITS, therefore less than twice HSIZE */
+  if (i >= HSIZE)
+    i -= HSIZE;
+  
+  if (hash_code[i] != 0) {     /* is first probed slot empty? */
+    if (hash_prefix[i] == waiting_code && hash_suffix[i] == c) {
+      waiting_code = hash_code[i];
+      return;
+    }
+    if (i == 0)                        /* secondary hash (after G. Knott) */
+      disp = 1;
+    else
+      disp = HSIZE - i;
+    while (1) {
+      i -= disp;
+      if (i < 0)
+       i += HSIZE;
+      if (hash_code[i] == 0)
+       break;                  /* hit empty slot */
+      if (hash_prefix[i] == waiting_code && hash_suffix[i] == c) {
+       waiting_code = hash_code[i];
+       return;
+      }
+    }
+  }
+
+  /* here when hashtable[i] is an empty slot; desired symbol not in table */
+  output(waiting_code);
+  if (free_code < LZW_TABLE_SIZE) {
+    hash_code[i] = free_code++;        /* add symbol to hashtable */
+    hash_prefix[i] = waiting_code;
+    hash_suffix[i] = c;
+  } else
+    clear_block();
+  waiting_code = c;
+}
+
+
+LOCAL void
+compress_term (void)
+/* Clean up at end */
+{
+  /* Flush out the buffered code */
+  if (! first_byte)
+    output(waiting_code);
+  /* Send an EOF code */
+  output(EOFCode);
+  /* Flush the bit-packing buffer */
+  if (cur_bits > 0) {
+    char_out((int) (cur_accum & 0xFF));
+  }
+  /* Flush the packet buffer */
+  flush_packet();
+}
+
+
+/* GIF header construction */
+
+
+LOCAL void
+put_word (UINT16 w)
+/* Emit a 16-bit word, LSB first */
+{
+  putc(w & 0xFF, dcinfo->output_file);
+  putc((w >> 8) & 0xFF, dcinfo->output_file);
+}
+
+
+LOCAL void
+put_3bytes (int val)
+/* Emit 3 copies of same byte value --- handy subr for colormap construction */
+{
+  putc(val, dcinfo->output_file);
+  putc(val, dcinfo->output_file);
+  putc(val, dcinfo->output_file);
+}
+
+
+LOCAL void
+emit_header (int num_colors, JSAMPARRAY colormap)
+/* Output the GIF file header, including color map */
+/* If colormap==NULL, synthesize a gray-scale colormap */
+{
+  int BitsPerPixel, ColorMapSize, InitCodeSize, FlagByte;
+  int i;
+
+  if (num_colors > 256)
+    ERREXIT(dcinfo->emethods, "GIF can only handle 256 colors");
+  /* Compute bits/pixel and related values */
+  if (num_colors <= 2)
+    BitsPerPixel = 1;
+  else if (num_colors <= 4)
+    BitsPerPixel = 2;
+  else if (num_colors <= 8)
+    BitsPerPixel = 3;
+  else if (num_colors <= 16)
+    BitsPerPixel = 4;
+  else if (num_colors <= 32)
+    BitsPerPixel = 5;
+  else if (num_colors <= 64)
+    BitsPerPixel = 6;
+  else if (num_colors <= 128)
+    BitsPerPixel = 7;
+  else
+    BitsPerPixel = 8;
+  ColorMapSize = 1 << BitsPerPixel;
+  if (BitsPerPixel <= 1)
+    InitCodeSize = 2;
+  else
+    InitCodeSize = BitsPerPixel;
+  /*
+   * Write the GIF header.
+   * Note that we generate a plain GIF87 header for maximum compatibility.
+   */
+  fwrite("GIF87a", 1, 6, dcinfo->output_file);
+  /* Write the Logical Screen Descriptor */
+  put_word((UINT16) dcinfo->image_width);
+  put_word((UINT16) dcinfo->image_height);
+  FlagByte = 0x80;             /* Yes, there is a global color table */
+  FlagByte |= (BitsPerPixel-1) << 4; /* color resolution */
+  FlagByte |= (BitsPerPixel-1);        /* size of global color table */
+  putc(FlagByte, dcinfo->output_file);
+  putc(0, dcinfo->output_file);        /* Background color index */
+  putc(0, dcinfo->output_file);        /* Reserved in GIF87 (aspect ratio in GIF89) */
+  /* Write the Global Color Map */
+  for (i=0; i < ColorMapSize; i++) {
+    if (i < num_colors) {
+      if (colormap != NULL) {
+       if (dcinfo->out_color_space == CS_RGB) {
+         /* Normal case: RGB color map */
+         putc(GETJSAMPLE(colormap[0][i]), dcinfo->output_file);
+         putc(GETJSAMPLE(colormap[1][i]), dcinfo->output_file);
+         putc(GETJSAMPLE(colormap[2][i]), dcinfo->output_file);
+       } else {
+         /* Grayscale "color map": possible if quantizing grayscale image */
+         put_3bytes(GETJSAMPLE(colormap[0][i]));
+       }
+      } else {
+       /* Create a gray-scale map of num_colors values, range 0..255 */
+       put_3bytes((i * 255 + (num_colors-1)/2) / (num_colors-1));
+      }
+    } else {
+      /* fill out the map to a power of 2 */
+      put_3bytes(0);
+    }
+  }
+  /* Write image separator and Image Descriptor */
+  putc(',', dcinfo->output_file); /* separator */
+  put_word((UINT16) 0);                /* left/top offset */
+  put_word((UINT16) 0);
+  put_word((UINT16) dcinfo->image_width); /* image size */
+  put_word((UINT16) dcinfo->image_height);
+  /* flag byte: not interlaced, no local color map */
+  putc(0x00, dcinfo->output_file);
+  /* Write Initial Code Size byte */
+  putc(InitCodeSize, dcinfo->output_file);
+
+  /* Initialize for LZW compression of image data */
+  compress_init(InitCodeSize+1);
+}
+
+
+
+/*
+ * Initialize for GIF output.
+ */
+
+METHODDEF void
+output_init (decompress_info_ptr cinfo)
+{
+  dcinfo = cinfo;              /* save for use by local routines */
+  if (cinfo->final_out_comps != 1) /* safety check */
+    ERREXIT(cinfo->emethods, "GIF output got confused");
+  /* Allocate space for hash table */
+  hash_code = (code_int FAR *) (*cinfo->emethods->alloc_medium)
+                               (HSIZE * SIZEOF(code_int));
+  hash_prefix = (code_int FAR *) (*cinfo->emethods->alloc_medium)
+                               (HSIZE * SIZEOF(code_int));
+  hash_suffix = (UINT8 FAR *) (*cinfo->emethods->alloc_medium)
+                               (HSIZE * SIZEOF(UINT8));
+  /*
+   * If we aren't quantizing, put_color_map won't be called,
+   * so emit the header now.  This only happens with gray scale output.
+   * (If we are quantizing, wait for the color map to be provided.)
+   */
+  if (! cinfo->quantize_colors)
+    emit_header(256, (JSAMPARRAY) NULL);
+}
+
+
+/*
+ * Write the color map.
+ */
+
+METHODDEF void
+put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
+{
+  emit_header(num_colors, colormap);
+}
+
+
+/*
+ * Write some pixel data.
+ */
+
+METHODDEF void
+put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
+               JSAMPIMAGE pixel_data)
+{
+  register JSAMPROW ptr;
+  register long col;
+  register long width = cinfo->image_width;
+  register int row;
+  
+  for (row = 0; row < num_rows; row++) {
+    ptr = pixel_data[0][row];
+    for (col = width; col > 0; col--) {
+      compress_byte(GETJSAMPLE(*ptr));
+      ptr++;
+    }
+  }
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+output_term (decompress_info_ptr cinfo)
+{
+  /* Flush LZW mechanism */
+  compress_term();
+  /* Write a zero-length data block to end the series */
+  putc(0, cinfo->output_file);
+  /* Write the GIF terminator mark */
+  putc(';', cinfo->output_file);
+  /* Make sure we wrote the output file OK */
+  fflush(cinfo->output_file);
+  if (ferror(cinfo->output_file))
+    ERREXIT(cinfo->emethods, "Output file write error");
+  /* Free space */
+  (*cinfo->emethods->free_medium) ((void FAR *) hash_code);
+  (*cinfo->emethods->free_medium) ((void FAR *) hash_prefix);
+  (*cinfo->emethods->free_medium) ((void FAR *) hash_suffix);
+}
+
+
+/*
+ * The method selection routine for GIF format output.
+ * This should be called from d_ui_method_selection if GIF output is wanted.
+ */
+
+GLOBAL void
+jselwgif (decompress_info_ptr cinfo)
+{
+  cinfo->methods->output_init = output_init;
+  cinfo->methods->put_color_map = put_color_map;
+  cinfo->methods->put_pixel_rows = put_pixel_rows;
+  cinfo->methods->output_term = output_term;
+
+  if (cinfo->out_color_space != CS_GRAYSCALE &&
+      cinfo->out_color_space != CS_RGB)
+    ERREXIT(cinfo->emethods, "GIF output must be grayscale or RGB");
+
+  /* Force quantization if color or if > 8 bits input */
+  if (cinfo->out_color_space == CS_RGB || cinfo->data_precision > 8) {
+    /* Force quantization to at most 256 colors */
+    cinfo->quantize_colors = TRUE;
+    if (cinfo->desired_number_of_colors > 256)
+      cinfo->desired_number_of_colors = 256;
+  }
+}
+
+#endif /* GIF_SUPPORTED */
diff --git a/jwrjfif.c b/jwrjfif.c
new file mode 100644 (file)
index 0000000..cc379ac
--- /dev/null
+++ b/jwrjfif.c
@@ -0,0 +1,468 @@
+/*
+ * jwrjfif.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to write standard JPEG file headers/markers.
+ * The file format created is a raw JPEG data stream with (optionally) an
+ * APP0 marker per the JFIF spec.  This will handle baseline and
+ * JFIF-convention JPEG files, although there is currently no provision
+ * for inserting a thumbnail image in the JFIF header.
+ *
+ * These routines may need modification for non-Unix environments or
+ * specialized applications.  As they stand, they assume output to
+ * an ordinary stdio stream.  However, the changes to write to something
+ * else are localized in the macros appearing just below.
+ *
+ * These routines are invoked via the methods write_file_header,
+ * write_scan_header, write_jpeg_data, write_scan_trailer, and
+ * write_file_trailer.
+ */
+
+#include "jinclude.h"
+
+#ifdef JFIF_SUPPORTED
+
+
+/*
+ * To output to something other than a stdio stream, you'd need to redefine
+ * these macros.
+ */
+
+/* Write a single byte */
+#define emit_byte(cinfo,x)  putc((x), cinfo->output_file)
+
+/* Write some bytes from a (char *) buffer */
+#define WRITE_BYTES(cinfo,dataptr,datacount)  \
+  { if (fwrite((dataptr), 1, (datacount), cinfo->output_file) != (datacount)) \
+      ERREXIT(cinfo->emethods, "Output file write error"); }
+
+/* Clean up and verify successful output */
+#define CHECK_OUTPUT(cinfo)  \
+  { fflush(cinfo->output_file); \
+    if (ferror(cinfo->output_file)) \
+      ERREXIT(cinfo->emethods, "Output file write error"); }
+
+
+/* End of stdio-specific code. */
+
+
+typedef enum {                 /* JPEG marker codes */
+  M_SOF0  = 0xc0,
+  M_SOF1  = 0xc1,
+  M_SOF2  = 0xc2,
+  M_SOF3  = 0xc3,
+  
+  M_SOF5  = 0xc5,
+  M_SOF6  = 0xc6,
+  M_SOF7  = 0xc7,
+  
+  M_JPG   = 0xc8,
+  M_SOF9  = 0xc9,
+  M_SOF10 = 0xca,
+  M_SOF11 = 0xcb,
+  
+  M_SOF13 = 0xcd,
+  M_SOF14 = 0xce,
+  M_SOF15 = 0xcf,
+  
+  M_DHT   = 0xc4,
+  
+  M_DAC   = 0xcc,
+  
+  M_RST0  = 0xd0,
+  M_RST1  = 0xd1,
+  M_RST2  = 0xd2,
+  M_RST3  = 0xd3,
+  M_RST4  = 0xd4,
+  M_RST5  = 0xd5,
+  M_RST6  = 0xd6,
+  M_RST7  = 0xd7,
+  
+  M_SOI   = 0xd8,
+  M_EOI   = 0xd9,
+  M_SOS   = 0xda,
+  M_DQT   = 0xdb,
+  M_DNL   = 0xdc,
+  M_DRI   = 0xdd,
+  M_DHP   = 0xde,
+  M_EXP   = 0xdf,
+  
+  M_APP0  = 0xe0,
+  M_APP15 = 0xef,
+  
+  M_JPG0  = 0xf0,
+  M_JPG13 = 0xfd,
+  M_COM   = 0xfe,
+  
+  M_TEM   = 0x01,
+  
+  M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+LOCAL void
+emit_marker (compress_info_ptr cinfo, JPEG_MARKER mark)
+/* Emit a marker code */
+{
+  emit_byte(cinfo, 0xFF);
+  emit_byte(cinfo, mark);
+}
+
+
+LOCAL void
+emit_2bytes (compress_info_ptr cinfo, int value)
+/* Emit a 2-byte integer; these are always MSB first in JPEG files */
+{
+  emit_byte(cinfo, (value >> 8) & 0xFF);
+  emit_byte(cinfo, value & 0xFF);
+}
+
+
+LOCAL int
+emit_dqt (compress_info_ptr cinfo, int index)
+/* Emit a DQT marker */
+/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
+{
+  QUANT_TBL_PTR data = cinfo->quant_tbl_ptrs[index];
+  int prec = 0;
+  int i;
+  
+  for (i = 0; i < DCTSIZE2; i++) {
+    if (data[i] > 255)
+      prec = 1;
+  }
+
+  emit_marker(cinfo, M_DQT);
+  
+  emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
+  
+  emit_byte(cinfo, index + (prec<<4));
+  
+  for (i = 0; i < DCTSIZE2; i++) {
+    if (prec)
+      emit_byte(cinfo, data[i] >> 8);
+    emit_byte(cinfo, data[i] & 0xFF);
+  }
+
+  return prec;
+}
+
+
+LOCAL void
+emit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
+/* Emit a DHT marker */
+{
+  HUFF_TBL * htbl;
+  int length, i;
+  
+  if (is_ac) {
+    htbl = cinfo->ac_huff_tbl_ptrs[index];
+    index += 0x10;             /* output index has AC bit set */
+  } else {
+    htbl = cinfo->dc_huff_tbl_ptrs[index];
+  }
+  
+  if (! htbl->sent_table) {
+    emit_marker(cinfo, M_DHT);
+    
+    length = 0;
+    for (i = 1; i <= 16; i++)
+      length += htbl->bits[i];
+    
+    emit_2bytes(cinfo, length + 2 + 1 + 16);
+    emit_byte(cinfo, index);
+    
+    for (i = 1; i <= 16; i++)
+      emit_byte(cinfo, htbl->bits[i]);
+    
+    for (i = 0; i < length; i++)
+      emit_byte(cinfo, htbl->huffval[i]);
+    
+    htbl->sent_table = TRUE;
+  }
+}
+
+
+LOCAL void
+emit_dac (compress_info_ptr cinfo)
+/* Emit a DAC marker */
+/* Since the useful info is so small, we want to emit all the tables in */
+/* one DAC marker.  Therefore this routine does its own scan of the table. */
+{
+  char dc_in_use[NUM_ARITH_TBLS];
+  char ac_in_use[NUM_ARITH_TBLS];
+  int length, i;
+  
+  for (i = 0; i < NUM_ARITH_TBLS; i++)
+    dc_in_use[i] = ac_in_use[i] = 0;
+  
+  for (i = 0; i < cinfo->num_components; i++) {
+    dc_in_use[cinfo->comp_info[i].dc_tbl_no] = 1;
+    ac_in_use[cinfo->comp_info[i].ac_tbl_no] = 1;
+  }
+  
+  length = 0;
+  for (i = 0; i < NUM_ARITH_TBLS; i++)
+    length += dc_in_use[i] + ac_in_use[i];
+  
+  emit_marker(cinfo, M_DAC);
+  
+  emit_2bytes(cinfo, length*2 + 2);
+  
+  for (i = 0; i < NUM_ARITH_TBLS; i++) {
+    if (dc_in_use[i]) {
+      emit_byte(cinfo, i);
+      emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
+    }
+    if (ac_in_use[i]) {
+      emit_byte(cinfo, i + 0x10);
+      emit_byte(cinfo, cinfo->arith_ac_K[i]);
+    }
+  }
+}
+
+
+LOCAL void
+emit_dri (compress_info_ptr cinfo)
+/* Emit a DRI marker */
+{
+  emit_marker(cinfo, M_DRI);
+  
+  emit_2bytes(cinfo, 4);       /* fixed length */
+
+  emit_2bytes(cinfo, (int) cinfo->restart_interval);
+}
+
+
+LOCAL void
+emit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
+/* Emit a SOF marker */
+{
+  int i;
+  
+  emit_marker(cinfo, code);
+  
+  emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
+
+  emit_byte(cinfo, cinfo->data_precision);
+  emit_2bytes(cinfo, (int) cinfo->image_height);
+  emit_2bytes(cinfo, (int) cinfo->image_width);
+
+  emit_byte(cinfo, cinfo->num_components);
+
+  for (i = 0; i < cinfo->num_components; i++) {
+    emit_byte(cinfo, cinfo->comp_info[i].component_id);
+    emit_byte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
+                    + cinfo->comp_info[i].v_samp_factor);
+    emit_byte(cinfo, cinfo->comp_info[i].quant_tbl_no);
+  }
+}
+
+
+LOCAL void
+emit_sos (compress_info_ptr cinfo)
+/* Emit a SOS marker */
+{
+  int i;
+  
+  emit_marker(cinfo, M_SOS);
+  
+  emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
+  
+  emit_byte(cinfo, cinfo->comps_in_scan);
+  
+  for (i = 0; i < cinfo->comps_in_scan; i++) {
+    emit_byte(cinfo, cinfo->cur_comp_info[i]->component_id);
+    emit_byte(cinfo, (cinfo->cur_comp_info[i]->dc_tbl_no << 4)
+                    + cinfo->cur_comp_info[i]->ac_tbl_no);
+  }
+
+  emit_byte(cinfo, 0);         /* Spectral selection start */
+  emit_byte(cinfo, DCTSIZE2-1);        /* Spectral selection end */
+  emit_byte(cinfo, 0);         /* Successive approximation */
+}
+
+
+LOCAL void
+emit_jfif_app0 (compress_info_ptr cinfo)
+/* Emit a JFIF-compliant APP0 marker */
+{
+  /*
+   * Length of APP0 block      (2 bytes)
+   * Block ID                  (4 bytes - ASCII "JFIF")
+   * Zero byte                 (1 byte to terminate the ID string)
+   * Version Major, Minor      (2 bytes - 0x01, 0x01)
+   * Units                     (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
+   * Xdpu                      (2 bytes - dots per unit horizontal)
+   * Ydpu                      (2 bytes - dots per unit vertical)
+   * Thumbnail X size          (1 byte)
+   * Thumbnail Y size          (1 byte)
+   */
+  
+  emit_marker(cinfo, M_APP0);
+  
+  emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
+
+  emit_byte(cinfo, 'J');       /* Identifier */
+  emit_byte(cinfo, 'F');
+  emit_byte(cinfo, 'I');
+  emit_byte(cinfo, 'F');
+  emit_byte(cinfo, 0);
+  emit_byte(cinfo, 1);         /* Major version */
+  emit_byte(cinfo, 1);         /* Minor version */
+  emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
+  emit_2bytes(cinfo, (int) cinfo->X_density);
+  emit_2bytes(cinfo, (int) cinfo->Y_density);
+  emit_byte(cinfo, 0);         /* No thumbnail image */
+  emit_byte(cinfo, 0);
+}
+
+
+/*
+ * Write the file header.
+ */
+
+
+METHODDEF void
+write_file_header (compress_info_ptr cinfo)
+{
+  char qt_in_use[NUM_QUANT_TBLS];
+  int i, prec;
+  boolean is_baseline;
+  
+  emit_marker(cinfo, M_SOI);   /* first the SOI */
+
+  if (cinfo->write_JFIF_header)        /* next an optional JFIF APP0 */
+    emit_jfif_app0(cinfo);
+
+  /* Emit DQT for each quantization table. */
+  /* Note that doing it here means we can't adjust the QTs on-the-fly. */
+  /* If we did want to do that, we'd have a problem with checking precision */
+  /* for the is_baseline determination. */
+
+  for (i = 0; i < NUM_QUANT_TBLS; i++)
+    qt_in_use[i] = 0;
+
+  for (i = 0; i < cinfo->num_components; i++)
+    qt_in_use[cinfo->comp_info[i].quant_tbl_no] = 1;
+
+  prec = 0;
+  for (i = 0; i < NUM_QUANT_TBLS; i++) {
+    if (qt_in_use[i])
+      prec += emit_dqt(cinfo, i);
+  }
+  /* now prec is nonzero iff there are any 16-bit quant tables. */
+
+  if (cinfo->restart_interval)
+    emit_dri(cinfo);
+
+  /* Check for a non-baseline specification. */
+  /* Note we assume that Huffman table numbers won't be changed later. */
+  is_baseline = TRUE;
+  if (cinfo->arith_code || (cinfo->data_precision != 8))
+    is_baseline = FALSE;
+  for (i = 0; i < cinfo->num_components; i++) {
+    if (cinfo->comp_info[i].dc_tbl_no > 1 || cinfo->comp_info[i].ac_tbl_no > 1)
+      is_baseline = FALSE;
+  }
+  if (prec && is_baseline) {
+    is_baseline = FALSE;
+    /* If it's baseline except for quantizer size, warn the user */
+    TRACEMS(cinfo->emethods, 0,
+           "Caution: quantization tables are too coarse for baseline JPEG");
+  }
+
+
+  /* Emit the proper SOF marker */
+  if (cinfo->arith_code)
+    emit_sof(cinfo, M_SOF9);   /* SOF code for arithmetic coding */
+  else if (is_baseline)
+    emit_sof(cinfo, M_SOF0);   /* SOF code for baseline implementation */
+  else
+    emit_sof(cinfo, M_SOF1);   /* SOF code for non-baseline Huffman file */
+}
+
+
+/*
+ * Write the start of a scan (everything through the SOS marker).
+ */
+
+METHODDEF void
+write_scan_header (compress_info_ptr cinfo)
+{
+  int i;
+
+  if (cinfo->arith_code) {
+    /* Emit arith conditioning info.  We will have some duplication
+     * if the file has multiple scans, but it's so small it's hardly
+     * worth worrying about.
+     */
+    emit_dac(cinfo);
+  } else {
+    /* Emit Huffman tables.  Note that emit_dht takes care of
+     * suppressing duplicate tables.
+     */
+    for (i = 0; i < cinfo->comps_in_scan; i++) {
+      emit_dht(cinfo, cinfo->cur_comp_info[i]->dc_tbl_no, FALSE);
+      emit_dht(cinfo, cinfo->cur_comp_info[i]->ac_tbl_no, TRUE);
+    }
+  }
+
+  emit_sos(cinfo);
+}
+
+
+/*
+ * Write some bytes of compressed data within a scan.
+ */
+
+METHODDEF void
+write_jpeg_data (compress_info_ptr cinfo, char *dataptr, int datacount)
+{
+  WRITE_BYTES(cinfo, dataptr, datacount);
+}
+
+
+/*
+ * Finish up after a compressed scan (series of write_jpeg_data calls).
+ */
+
+METHODDEF void
+write_scan_trailer (compress_info_ptr cinfo)
+{
+  /* no work needed in this format */
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+write_file_trailer (compress_info_ptr cinfo)
+{
+  emit_marker(cinfo, M_EOI);
+  /* Make sure we wrote the output file OK */
+  CHECK_OUTPUT(cinfo);
+}
+
+
+/*
+ * The method selection routine for standard JPEG header writing.
+ * This should be called from c_ui_method_selection if appropriate.
+ */
+
+GLOBAL void
+jselwjfif (compress_info_ptr cinfo)
+{
+  cinfo->methods->write_file_header = write_file_header;
+  cinfo->methods->write_scan_header = write_scan_header;
+  cinfo->methods->write_jpeg_data = write_jpeg_data;
+  cinfo->methods->write_scan_trailer = write_scan_trailer;
+  cinfo->methods->write_file_trailer = write_file_trailer;
+}
+
+#endif /* JFIF_SUPPORTED */
diff --git a/jwrppm.c b/jwrppm.c
new file mode 100644 (file)
index 0000000..41687fe
--- /dev/null
+++ b/jwrppm.c
@@ -0,0 +1,167 @@
+/*
+ * jwrppm.c
+ *
+ * Copyright (C) 1991, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains routines to write output images in PPM format.
+ * The PBMPLUS library is required (well, it will be in the real version).
+ *
+ * These routines may need modification for non-Unix environments or
+ * specialized applications.  As they stand, they assume output to
+ * an ordinary stdio stream.
+ *
+ * These routines are invoked via the methods put_pixel_rows, put_color_map,
+ * and output_init/term.
+ */
+
+#include "jinclude.h"
+
+#ifdef PPM_SUPPORTED
+
+
+static JSAMPARRAY color_map;   /* saves color map passed by quantizer */
+
+
+/*
+ * Write the file header.
+ */
+
+METHODDEF void
+output_init (decompress_info_ptr cinfo)
+{
+  if (cinfo->out_color_space == CS_GRAYSCALE) {
+    /* emit header for raw PGM format */
+    fprintf(cinfo->output_file, "P5\n%ld %ld\n%d\n",
+           cinfo->image_width, cinfo->image_height, 255);
+  } else if (cinfo->out_color_space == CS_RGB) {
+    /* emit header for raw PPM format */
+    fprintf(cinfo->output_file, "P6\n%ld %ld\n%d\n",
+           cinfo->image_width, cinfo->image_height, 255);
+  } else {
+    ERREXIT(cinfo->emethods, "PPM output must be grayscale or RGB");
+  }
+}
+
+
+/*
+ * Write some pixel data.
+ */
+
+METHODDEF void
+put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
+               JSAMPIMAGE pixel_data)
+{
+  register FILE * outfile = cinfo->output_file;
+  register JSAMPROW ptr0, ptr1, ptr2;
+  register long col;
+  register long width = cinfo->image_width;
+  register int row;
+  
+  if (cinfo->out_color_space == CS_GRAYSCALE) {
+    for (row = 0; row < num_rows; row++) {
+      ptr0 = pixel_data[0][row];
+      for (col = width; col > 0; col--) {
+       putc(GETJSAMPLE(*ptr0), outfile);
+       ptr0++;
+      }
+    }
+  } else {
+    for (row = 0; row < num_rows; row++) {
+      ptr0 = pixel_data[0][row];
+      ptr1 = pixel_data[1][row];
+      ptr2 = pixel_data[2][row];
+      for (col = width; col > 0; col--) {
+       putc(GETJSAMPLE(*ptr0), outfile);
+       ptr0++;
+       putc(GETJSAMPLE(*ptr1), outfile);
+       ptr1++;
+       putc(GETJSAMPLE(*ptr2), outfile);
+       ptr2++;
+      }
+    }
+  }
+}
+
+
+/*
+ * Write some pixel data when color quantization is in effect.
+ */
+
+METHODDEF void
+put_demapped_rows (decompress_info_ptr cinfo, int num_rows,
+                  JSAMPIMAGE pixel_data)
+{
+  register FILE * outfile = cinfo->output_file;
+  register JSAMPROW ptr;
+  register long col;
+  register long width = cinfo->image_width;
+  register int row;
+  
+  if (cinfo->out_color_space == CS_GRAYSCALE) {
+    for (row = 0; row < num_rows; row++) {
+      ptr = pixel_data[0][row];
+      for (col = width; col > 0; col--) {
+       putc(GETJSAMPLE(color_map[0][GETJSAMPLE(*ptr)]), outfile);
+       ptr++;
+      }
+    }
+  } else {
+    for (row = 0; row < num_rows; row++) {
+      ptr = pixel_data[0][row];
+      for (col = width; col > 0; col--) {
+       register int pixval = GETJSAMPLE(*ptr);
+
+       putc(GETJSAMPLE(color_map[0][pixval]), outfile);
+       putc(GETJSAMPLE(color_map[1][pixval]), outfile);
+       putc(GETJSAMPLE(color_map[2][pixval]), outfile);
+       ptr++;
+      }
+    }
+  }
+}
+
+
+/*
+ * Write the color map.
+ * For PPM output, we just demap the output data!
+ */
+
+METHODDEF void
+put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
+{
+  color_map = colormap;                /* save for use in output */
+  cinfo->methods->put_pixel_rows = put_demapped_rows;
+}
+
+
+/*
+ * Finish up at the end of the file.
+ */
+
+METHODDEF void
+output_term (decompress_info_ptr cinfo)
+{
+  /* No work except to make sure we wrote the output file OK */
+  fflush(cinfo->output_file);
+  if (ferror(cinfo->output_file))
+    ERREXIT(cinfo->emethods, "Output file write error");
+}
+
+
+/*
+ * The method selection routine for PPM format output.
+ * This should be called from d_ui_method_selection if PPM output is wanted.
+ */
+
+GLOBAL void
+jselwppm (decompress_info_ptr cinfo)
+{
+  cinfo->methods->output_init = output_init;
+  cinfo->methods->put_color_map = put_color_map;
+  cinfo->methods->put_pixel_rows = put_pixel_rows;
+  cinfo->methods->output_term = output_term;
+}
+
+#endif /* PPM_SUPPORTED */
diff --git a/makcjpeg.cf b/makcjpeg.cf
new file mode 100644 (file)
index 0000000..ea93ce4
--- /dev/null
@@ -0,0 +1,5 @@
+L jcmain.mix jerror.mix jcdeflts.mix jrdgif.mix jrdppm.mix jwrjfif.mix
+L jcarith.mix jccolor.mix jcexpand.mix jchuff.mix jcmaster.mix jcmcu.mix
+L jcpipe.mix jcsample.mix jfwddct.mix jutils.mix jvirtmem.mix
+fa;
+b cjpeg,8K,48K,
diff --git a/makcjpeg.lnk b/makcjpeg.lnk
new file mode 100644 (file)
index 0000000..23702b2
--- /dev/null
@@ -0,0 +1,21 @@
+jcmain.obj +
+jerror.obj +
+jcdeflts.obj +
+jrdgif.obj +
+jrdppm.obj +
+jwrjfif.obj +
+jcarith.obj +
+jccolor.obj +
+jcexpand.obj +
+jchuff.obj +
+jcmaster.obj +
+jcmcu.obj +
+jcpipe.obj +
+jcsample.obj +
+jfwddct.obj +
+jutils.obj +
+jvirtmem.obj
+cjpeg.exe /NOI
+nul.map
+
+nul.def
diff --git a/makdjpeg.cf b/makdjpeg.cf
new file mode 100644 (file)
index 0000000..968af31
--- /dev/null
@@ -0,0 +1,6 @@
+L jdmain.mix jerror.mix jrdjfif.mix jwrgif.mix jwrppm.mix
+L jbsmooth.mix jdarith.mix jdcolor.mix jdhuff.mix jdmaster.mix jdmcu.mix
+L jdpipe.mix jdsample.mix jquant1.mix jquant2.mix jrevdct.mix jutils.mix
+L jvirtmem.mix
+fa;
+b djpeg,8K,48K,
diff --git a/makdjpeg.lnk b/makdjpeg.lnk
new file mode 100644 (file)
index 0000000..6e9107c
--- /dev/null
@@ -0,0 +1,22 @@
+jdmain.obj +
+jerror.obj +
+jrdjfif.obj +
+jwrgif.obj +
+jwrppm.obj +
+jbsmooth.obj +
+jdarith.obj +
+jdcolor.obj +
+jdhuff.obj +
+jdmaster.obj +
+jdmcu.obj +
+jdpipe.obj +
+jdsample.obj +
+jquant1.obj +
+jquant2.obj +
+jrevdct.obj +
+jutils.obj +
+jvirtmem.obj /NOI
+djpeg.exe
+nul.map
+
+nul.def
diff --git a/makefile.amiga b/makefile.amiga
new file mode 100644 (file)
index 0000000..2fde93a
--- /dev/null
@@ -0,0 +1,143 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is suitable for Amiga systems using Manx Aztec C ver 5.x.
+# Thanks to D.J. James for this version.
+
+# See README and edit jconfig.h before saying "make" !!
+
+CC= cc
+
+# You may need to adjust these cc options:
+CFLAGS= -MC -MD -DTWO_FILE_COMMANDLINE
+LDFLAGS=
+LDLIBS= -lml -lcl
+
+# miscellaneous OS-dependent stuff
+LN= ln         # linker
+RM= delete quiet # file deletion command
+AR= lb         # library (.lib) file creation command
+
+
+# source files
+INCLUDES= jinclude.h jconfig.h jpegdata.h 
+SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c \
+        jchuff.c jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c \
+        jdarith.c jdcolor.c jdhuff.c jdmain.c jdmaster.c jdmcu.c \
+        jdpipe.c jdsample.c jerror.c jfwddct.c jquant1.c jquant2.c \
+        jrdjfif.c jrdgif.c jrdppm.c jrevdct.c jutils.c jvirtmem.c \
+        jwrjfif.c jwrgif.c jwrppm.c egetopt.c
+DOCS= README architecture codingrules
+MAKEFILES= makefile.unix makefile.amiga \
+          makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk \
+          makefile.pwc makcjpeg.cf makdjpeg.cf makljpeg.cf
+TESTFILES= testorig.jpg testimg.ppm testimg.jpg
+DISTFILES= $(DOCS) $(MAKEFILES) ansi2knr.c $(SOURCES) $(INCLUDES) $(TESTFILES)
+
+# compression objectfiles
+COBJECTS = jcmain.o jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \
+          jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \
+          jrdgif.o jrdppm.o jwrjfif.o \
+          jutils.o jvirtmem.o jerror.o
+# decompression objectfiles
+DOBJECTS = jdmain.o jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
+          jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \
+          jrdjfif.o jwrgif.o jwrppm.o \
+          jutils.o jvirtmem.o jerror.o
+# These objectfiles are included in libjpeg.lib (all but jcmain.o, jdmain.o)
+LIBOBJECTS = jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \
+            jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \
+            jrdgif.o jrdppm.o jwrjfif.o \
+            jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
+            jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \
+            jrdjfif.o jwrgif.o jwrppm.o \
+            jutils.o jvirtmem.o jerror.o
+
+
+all: cjpeg djpeg
+# By default, libjpeg.lib is not built unless you explicitly request it.
+
+
+# If you have a C compiler that doesn't understand function prototypes,
+# uncomment the 5 lines below and make sure PROTO is not defined by jconfig.h.
+# Then say "make ansi2knr" before "make".
+
+#.c.o:
+#      ./ansi2knr $*.c tmpansi.c
+#      $(CC) $(CFLAGS) -c tmpansi.c
+#      mv tmpansi.o $*.o
+#      $(RM) tmpansi.c
+
+ansi2knr: ansi2knr.c
+       $(CC) -o ansi2knr ansi2knr.c
+# You may need to add one of -DBSD, -DVMS, or -DMSDOS to the line above.
+
+
+cjpeg: $(COBJECTS)
+       $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
+
+djpeg: $(DOBJECTS)
+       $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
+
+# libjpeg.lib is useful if you are including the JPEG software in a larger
+# program; you'd include it in your link, rather than the individual modules.
+libjpeg.lib: $(LIBOBJECTS)
+       -$(RM) libjpeg.lib
+       $(AR) libjpeg.lib  $(LIBOBJECTS)
+
+# Use the following to test the built library
+#cjpeg: jcmain.o libjpeg.lib
+#      $(LN) $(LDFLAGS) -o cjpeg jcmain.o -llibjpeg $(LDLIBS)
+#
+#djpeg: jdmain.o libjpeg.lib
+#      $(LN) $(LDFLAGS) -o djpeg jdmain.o -llibjpeg $(LDLIBS)
+
+clean:
+       -$(RM) *.o cjpeg djpeg libjpeg.lib ansi2knr core tmpansi.* testout.ppm testout.jpg
+
+distribute:
+       -$(RM) jpegsrc.tar*
+       tar cvf jpegsrc.tar $(DISTFILES)
+       list jpegsrc.tar
+       compress -v jpegsrc.tar
+       list jpegsrc.tar*
+
+test: cjpeg djpeg
+       -$(RM) testout.ppm testout.jpg
+       ./djpeg testorig.jpg testout.ppm
+       ./cjpeg testimg.ppm testout.jpg
+       cmp testimg.ppm testout.ppm
+       cmp testimg.jpg testout.jpg
+
+
+jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h 
+jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h 
+jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h 
+jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h 
+jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h 
+jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h 
+jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c 
+jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h 
+jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h 
+jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h 
+jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h 
+jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h 
+jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h 
+jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h 
+jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c
+jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h 
+jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h 
+jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h 
+jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h 
+jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h 
+jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h 
+jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h 
+jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h 
+jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h 
+jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h 
+jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h 
+jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h 
+jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h 
+jvirtmem.o : jvirtmem.c jinclude.h jconfig.h jpegdata.h 
+jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h 
+jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h 
+jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h 
diff --git a/makefile.mc5 b/makefile.mc5
new file mode 100644 (file)
index 0000000..eee9f21
--- /dev/null
@@ -0,0 +1,115 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Microsoft C for MS-DOS, version 5.x.
+
+# See README and edit jconfig.h before saying "make" !!
+
+# Microsoft's brain-damaged version of make uses nonstandard syntax (a blank
+# line is needed to terminate a command list) and it simply scans the rules
+# in order, rather than doing a true dependency-tree walk.  Furthermore,
+# expanded command lines can't exceed 128 chars (this is a DOS bug, not
+# make's fault); so we can't just name all the objectfiles in the link steps.
+# Instead we shove each objectfile into a library as it is made, and link
+# from the library.  The objectfiles are also kept separately as timestamps.
+
+# You may need to adjust these cc options:
+CFLAGS=  /AS /I. /W3 /Oail /Gs /DMEM_STATS  # NB: /Gs turns off stack oflo checks
+LDFLAGS= /Fm /F 2000  # /F hhhh  sets stack size (in hex)
+# In particular:
+#   Add /DMSDOS if your compiler doesn't automatically #define MSDOS.
+#   Add /DHAVE_GETOPT if your library includes getopt(3) (see jcmain.c, jdmain.c).
+#   /DMEM_STATS is optional -- it enables gathering of memory usage statistics.
+
+# compression objectfiles
+COBJECTS = jcmain.obj jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
+          jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
+          jrdgif.obj jrdppm.obj jwrjfif.obj \
+          jutils.obj jvirtmem.obj jerror.obj
+# decompression objectfiles
+DOBJECTS = jdmain.obj jdmaster.obj jbsmooth.obj jdarith.obj jdcolor.obj jdhuff.obj \
+          jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj jquant2.obj jrevdct.obj \
+          jrdjfif.obj jwrgif.obj jwrppm.obj \
+          jutils.obj jvirtmem.obj jerror.obj
+
+
+# inference rule used for all compilations except jcmain.c, jdmain.c
+# notice that objectfile is also inserted into libjpeg.lib
+.c.obj:
+       cl $(CFLAGS) /c $*.c
+       lib libjpeg -+$*.obj;
+
+# these two objectfiles are not inserted into libjpeg
+# because they have duplicate global symbol names (notably main()).
+jcmain.obj: jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c 
+       cl $(CFLAGS) /c $*.c
+
+jdmain.obj: jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c
+       cl $(CFLAGS) /c $*.c
+
+
+jbsmooth.obj: jbsmooth.c jinclude.h jconfig.h jpegdata.h 
+
+jcarith.obj: jcarith.c jinclude.h jconfig.h jpegdata.h 
+
+jccolor.obj: jccolor.c jinclude.h jconfig.h jpegdata.h 
+
+jcdeflts.obj: jcdeflts.c jinclude.h jconfig.h jpegdata.h 
+
+jcexpand.obj: jcexpand.c jinclude.h jconfig.h jpegdata.h 
+
+jchuff.obj: jchuff.c jinclude.h jconfig.h jpegdata.h 
+
+jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpegdata.h 
+
+jcmcu.obj: jcmcu.c jinclude.h jconfig.h jpegdata.h 
+
+jcpipe.obj: jcpipe.c jinclude.h jconfig.h jpegdata.h 
+
+jcsample.obj: jcsample.c jinclude.h jconfig.h jpegdata.h 
+
+jdarith.obj: jdarith.c jinclude.h jconfig.h jpegdata.h 
+
+jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpegdata.h 
+
+jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpegdata.h 
+
+jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpegdata.h 
+
+jdmcu.obj: jdmcu.c jinclude.h jconfig.h jpegdata.h 
+
+jdpipe.obj: jdpipe.c jinclude.h jconfig.h jpegdata.h 
+
+jdsample.obj: jdsample.c jinclude.h jconfig.h jpegdata.h 
+
+jerror.obj: jerror.c jinclude.h jconfig.h jpegdata.h 
+
+jfwddct.obj: jfwddct.c jinclude.h jconfig.h jpegdata.h 
+
+jquant1.obj: jquant1.c jinclude.h jconfig.h jpegdata.h 
+
+jquant2.obj: jquant2.c jinclude.h jconfig.h jpegdata.h 
+
+jrdjfif.obj: jrdjfif.c jinclude.h jconfig.h jpegdata.h 
+
+jrdgif.obj: jrdgif.c jinclude.h jconfig.h jpegdata.h 
+
+jrdppm.obj: jrdppm.c jinclude.h jconfig.h jpegdata.h 
+
+jrevdct.obj: jrevdct.c jinclude.h jconfig.h jpegdata.h 
+
+jutils.obj: jutils.c jinclude.h jconfig.h jpegdata.h 
+
+jvirtmem.obj: jvirtmem.c jinclude.h jconfig.h jpegdata.h 
+
+jwrjfif.obj: jwrjfif.c jinclude.h jconfig.h jpegdata.h 
+
+jwrgif.obj: jwrgif.c jinclude.h jconfig.h jpegdata.h 
+
+jwrppm.obj: jwrppm.c jinclude.h jconfig.h jpegdata.h 
+
+
+cjpeg.exe: $(COBJECTS)
+       cl /Fecjpeg.exe jcmain.obj libjpeg.lib $(LDFLAGS)
+
+djpeg.exe: $(DOBJECTS)
+       cl /Fedjpeg.exe jdmain.obj libjpeg.lib $(LDFLAGS)
diff --git a/makefile.mc6 b/makefile.mc6
new file mode 100644 (file)
index 0000000..b9ca60f
--- /dev/null
@@ -0,0 +1,79 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Microsoft C for MS-DOS, version 6.x (use NMAKE).
+# Thanks to Alan Wright and Chris Turner of Olivetti Research Ltd.
+
+# See README and edit jconfig.h before saying "make" !!
+
+all: cjpeg.exe djpeg.exe
+
+# compiler flags. -D gives a #define to the sources:
+#       -O              default optimisation
+#       -W3             warning level 3
+#       -Za             ANSI conformance, defines__STDC__ but undefines far
+#                       and near!
+#       -D__STDC__      pretend we have full ANSI compliance. MSC is near
+#                       enough anyway
+#       -DMSDOS         we are on an MSDOS machine
+#       -DMEM_STATS     enable memory usage statistics (optional)
+#       -DHAVE_GETOPT   library has getopt routine to parse cmnd line options
+#       -c              compile, don't link (implicit in inference rules)
+
+CFLAGS = -c -O -W3 -DMSDOS -D__STDC__ -DMEM_STATS
+
+
+# compression objectfiles
+COBJECTS = jcmain.obj jcmaster.obj jcdeflts.obj jcarith.obj jccolor.obj jcexpand.obj \
+          jchuff.obj jcmcu.obj jcpipe.obj jcsample.obj jfwddct.obj \
+          jrdgif.obj jrdppm.obj jwrjfif.obj \
+          jutils.obj jvirtmem.obj jerror.obj
+# decompression objectfiles
+DOBJECTS = jdmain.obj jdmaster.obj jbsmooth.obj jdarith.obj jdcolor.obj jdhuff.obj \
+          jdmcu.obj jdpipe.obj jdsample.obj jquant1.obj jquant2.obj jrevdct.obj \
+          jrdjfif.obj jwrgif.obj jwrppm.obj \
+          jutils.obj jvirtmem.obj jerror.obj
+
+
+# default rules in nmake will use cflags and compile the list below
+
+jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h 
+jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h 
+jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h 
+jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h 
+jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h 
+jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h 
+jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c 
+jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h 
+jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h 
+jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h 
+jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h 
+jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h 
+jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h 
+jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h 
+jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c
+jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h 
+jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h 
+jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h 
+jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h 
+jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h 
+jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h 
+jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h 
+jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h 
+jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h 
+jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h 
+jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h 
+jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h 
+jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h 
+jvirtmem.o : jvirtmem.c jinclude.h jconfig.h jpegdata.h 
+jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h 
+jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h 
+jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h 
+
+
+# use linker response files because file list > 128 chars
+
+cjpeg.exe: $(COBJECTS)
+        link /STACK:8192 @makcjpeg.lnk
+
+djpeg.exe: $(DOBJECTS)
+        link /STACK:8192 @makdjpeg.lnk
diff --git a/makefile.pwc b/makefile.pwc
new file mode 100644 (file)
index 0000000..f41dd48
--- /dev/null
@@ -0,0 +1,100 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Mix Software's Power C, v2.1.1
+# and Dan Grayson's pd make 2.14 under MS-DOS.
+# Thanks to Bob Hardy for this version.
+
+# See README and edit jconfig.h before saying "make" !!
+
+# NOTE: make sure you have converted end-of-line markers to CR/LF in this file
+# and in the three mak*.cf files; otherwise pd make and the Mix linker will
+# choke.  Power C doesn't seem to care whether end-of-lines are CR/LF or just
+# LF in the *.h and *.c files.  If you blindly converted LF to CR/LF in ALL
+# the files, then you broke the test*.* files, which contain binary data.
+
+CC=pc
+
+# You may need to adjust these cc options:
+MODEL=m
+CFLAGS=-dMEM_STATS -dMSDOS -m$(MODEL)
+LDFLAGS=
+# In particular:
+#   -dMEM_STATS is optional -- it enables gathering of memory usage statistics.
+LDLIBS=
+
+# miscellaneous OS-dependent stuff
+# linker
+LN=pcl
+# file deletion command
+RM=del
+# library (.mix) file creation command
+AR=merge
+
+
+# compression objectfiles
+COBJECTS = jcmain.mix jcmaster.mix jcdeflts.mix jcarith.mix jccolor.mix jcexpand.mix jchuff.mix jcmcu.mix jcpipe.mix jcsample.mix jfwddct.mix jrdgif.mix jrdppm.mix jwrjfif.mix jutils.mix jvirtmem.mix jerror.mix
+# decompression objectfiles
+DOBJECTS = jdmain.mix jdmaster.mix jbsmooth.mix jdarith.mix jdcolor.mix jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jutils.mix jvirtmem.mix jerror.mix
+# These objectfiles are included in libjpeg.mix (all but jcmain, jdmain)
+LIBOBJECTS = jcmaster.mix jcdeflts.mix jcarith.mix jccolor.mix jcexpand.mix jchuff.mix jcmcu.mix jcpipe.mix jcsample.mix jfwddct.mix jrdgif.mix jrdppm.mix jwrjfif.mix jdmaster.mix jbsmooth.mix jdarith.mix jdcolor.mix jdhuff.mix jdmcu.mix jdpipe.mix jdsample.mix jquant1.mix jquant2.mix jrevdct.mix jrdjfif.mix jwrgif.mix jwrppm.mix jutils.mix jvirtmem.mix jerror.mix
+
+
+all: cjpeg.exe djpeg.exe test
+# By default, libjpeg.mix is not built unless you explicitly request it.
+
+
+cjpeg.exe: $(COBJECTS)
+       $(LN) $(LDFLAGS) @makcjpeg.cf
+
+djpeg.exe: $(DOBJECTS)
+       $(LN) $(LDFLAGS) @makdjpeg.cf
+
+# libjpeg.mix is useful if you are including the JPEG software in a larger
+# program; you'd include it in your link, rather than the individual modules.
+libjpeg.mix: $(LIBOBJECTS)
+       @$(RM) libjpeg.mix
+       $(AR) libjpeg.mix @makljpeg.cf
+
+clean:
+       $(RM) *.mix cjpeg.exe djpeg.exe testout.*
+
+test:
+       @$(RM) testout.*
+       +djpeg testorig.jpg testout.ppm
+       +cjpeg testimg.ppm testout.jpg
+       fc testimg.ppm testout.ppm
+       fc testimg.jpg testout.jpg
+
+
+jbsmooth.mix : jbsmooth.c jinclude.h jconfig.h jpegdata.h 
+jcarith.mix : jcarith.c jinclude.h jconfig.h jpegdata.h 
+jccolor.mix : jccolor.c jinclude.h jconfig.h jpegdata.h 
+jcdeflts.mix : jcdeflts.c jinclude.h jconfig.h jpegdata.h 
+jcexpand.mix : jcexpand.c jinclude.h jconfig.h jpegdata.h 
+jchuff.mix : jchuff.c jinclude.h jconfig.h jpegdata.h 
+jcmain.mix : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c 
+jcmaster.mix : jcmaster.c jinclude.h jconfig.h jpegdata.h 
+jcmcu.mix : jcmcu.c jinclude.h jconfig.h jpegdata.h 
+jcpipe.mix : jcpipe.c jinclude.h jconfig.h jpegdata.h 
+jcsample.mix : jcsample.c jinclude.h jconfig.h jpegdata.h 
+jdarith.mix : jdarith.c jinclude.h jconfig.h jpegdata.h 
+jdcolor.mix : jdcolor.c jinclude.h jconfig.h jpegdata.h 
+jdhuff.mix : jdhuff.c jinclude.h jconfig.h jpegdata.h 
+jdmain.mix : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c
+jdmaster.mix : jdmaster.c jinclude.h jconfig.h jpegdata.h 
+jdmcu.mix : jdmcu.c jinclude.h jconfig.h jpegdata.h 
+jdpipe.mix : jdpipe.c jinclude.h jconfig.h jpegdata.h 
+jdsample.mix : jdsample.c jinclude.h jconfig.h jpegdata.h 
+jerror.mix : jerror.c jinclude.h jconfig.h jpegdata.h 
+jfwddct.mix : jfwddct.c jinclude.h jconfig.h jpegdata.h 
+jquant1.mix : jquant1.c jinclude.h jconfig.h jpegdata.h 
+jquant2.mix : jquant2.c jinclude.h jconfig.h jpegdata.h 
+jrdjfif.mix : jrdjfif.c jinclude.h jconfig.h jpegdata.h 
+jrdgif.mix : jrdgif.c jinclude.h jconfig.h jpegdata.h 
+jrdppm.mix : jrdppm.c jinclude.h jconfig.h jpegdata.h 
+jrevdct.mix : jrevdct.c jinclude.h jconfig.h jpegdata.h 
+jutils.mix : jutils.c jinclude.h jconfig.h jpegdata.h 
+jvirtmem.mix : jvirtmem.c jinclude.h jconfig.h jpegdata.h 
+jwrjfif.mix : jwrjfif.c jinclude.h jconfig.h jpegdata.h 
+jwrgif.mix : jwrgif.c jinclude.h jconfig.h jpegdata.h 
+jwrppm.mix : jwrppm.c jinclude.h jconfig.h jpegdata.h 
diff --git a/makefile.unix b/makefile.unix
new file mode 100644 (file)
index 0000000..0f11afa
--- /dev/null
@@ -0,0 +1,152 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is suitable for Unix-like systems.
+
+# See README and edit jconfig.h before saying "make" !!
+
+# Comment out this line if you don't have gcc:
+CC=gcc
+
+# You may need to adjust these cc options:
+CFLAGS= -O -g -Wall -DHAVE_GETOPT -DMEM_STATS
+LDFLAGS= -g
+# In particular:
+#   Remove -g and -Wall if not using gcc.
+#   Add -DBSD if on a pure BSD system (see jinclude.h).
+#   Remove -DHAVE_GETOPT if you don't have getopt(3) (see jcmain.c, jdmain.c).
+#   -DMEM_STATS is optional -- it enables gathering of memory usage statistics.
+#   You may also want to add -DTWO_FILE_COMMANDLINE or -D switches for other
+#   symbols listed in jconfig.h, if you prefer not to change jconfig.h.
+# If your compiler is non-ANSI, also see the .c.o rule below.
+
+# On HP-UX (and probably other SysV systems) the alternate malloc(3X) is a lot
+# faster than the standard malloc; this makes a noticeable difference in the
+# startup time when handling big noninterleaved images.  I say "-lmalloc" to
+# get the alternate allocator.  On most non-SysV systems you can just
+# define LDLIBS as empty.
+LDLIBS= -lmalloc
+
+# miscellaneous OS-dependent stuff
+LN= $(CC)      # linker
+RM= rm -f      # file deletion command
+AR= ar rc      # library (.a) file creation command
+AR2= ranlib    # second step in .a creation (use "touch" if not needed)
+
+
+# source files
+INCLUDES= jinclude.h jconfig.h jpegdata.h 
+SOURCES= jbsmooth.c jcarith.c jccolor.c jcdeflts.c jcexpand.c \
+        jchuff.c jcmain.c jcmaster.c jcmcu.c jcpipe.c jcsample.c \
+        jdarith.c jdcolor.c jdhuff.c jdmain.c jdmaster.c jdmcu.c \
+        jdpipe.c jdsample.c jerror.c jfwddct.c jquant1.c jquant2.c \
+        jrdjfif.c jrdgif.c jrdppm.c jrevdct.c jutils.c jvirtmem.c \
+        jwrjfif.c jwrgif.c jwrppm.c egetopt.c
+DOCS= README architecture codingrules
+MAKEFILES= makefile.unix makefile.amiga \
+          makefile.mc5 makefile.mc6 makcjpeg.lnk makdjpeg.lnk \
+          makefile.pwc makcjpeg.cf makdjpeg.cf makljpeg.cf
+TESTFILES= testorig.jpg testimg.ppm testimg.jpg
+DISTFILES= $(DOCS) $(MAKEFILES) ansi2knr.c $(SOURCES) $(INCLUDES) $(TESTFILES)
+
+# compression objectfiles
+COBJECTS = jcmain.o jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \
+          jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \
+          jrdgif.o jrdppm.o jwrjfif.o \
+          jutils.o jvirtmem.o jerror.o
+# decompression objectfiles
+DOBJECTS = jdmain.o jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
+          jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \
+          jrdjfif.o jwrgif.o jwrppm.o \
+          jutils.o jvirtmem.o jerror.o
+# These objectfiles are included in libjpeg.a (all but jcmain.o, jdmain.o)
+LIBOBJECTS = jcmaster.o jcdeflts.o jcarith.o jccolor.o jcexpand.o \
+            jchuff.o jcmcu.o jcpipe.o jcsample.o jfwddct.o \
+            jrdgif.o jrdppm.o jwrjfif.o \
+            jdmaster.o jbsmooth.o jdarith.o jdcolor.o jdhuff.o \
+            jdmcu.o jdpipe.o jdsample.o jquant1.o jquant2.o jrevdct.o \
+            jrdjfif.o jwrgif.o jwrppm.o \
+            jutils.o jvirtmem.o jerror.o
+
+
+all: cjpeg djpeg
+# By default, libjpeg.a is not built unless you explicitly request it.
+
+
+# If you have a C compiler that doesn't understand function prototypes,
+# uncomment the 5 lines below and make sure PROTO is not defined by jconfig.h.
+# Then say "make ansi2knr" before "make".
+
+#.c.o:
+#      ./ansi2knr $*.c tmpansi.c
+#      $(CC) $(CFLAGS) -c tmpansi.c
+#      mv tmpansi.o $*.o
+#      $(RM) tmpansi.c
+
+ansi2knr: ansi2knr.c
+       $(CC) -o ansi2knr ansi2knr.c
+# You may need to add one of -DBSD, -DVMS, or -DMSDOS to the line above.
+
+
+cjpeg: $(COBJECTS)
+       $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) $(LDLIBS)
+
+djpeg: $(DOBJECTS)
+       $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) $(LDLIBS)
+
+# libjpeg.a is useful if you are including the JPEG software in a larger
+# program; you'd include it in your link, rather than the individual modules.
+libjpeg.a: $(LIBOBJECTS)
+       $(RM) libjpeg.a
+       $(AR) libjpeg.a  $(LIBOBJECTS)
+       $(AR2) libjpeg.a
+
+clean:
+       $(RM) *.o cjpeg djpeg libjpeg.a ansi2knr core tmpansi.* testout.ppm testout.jpg
+
+distribute:
+       $(RM) jpegsrc.tar*
+       tar cvf jpegsrc.tar $(DISTFILES)
+       ls -l jpegsrc.tar
+       compress -v jpegsrc.tar
+       ls -l jpegsrc.tar*
+
+test: cjpeg djpeg
+       $(RM) testout.ppm testout.jpg
+       ./djpeg testorig.jpg >testout.ppm
+       ./cjpeg testimg.ppm >testout.jpg
+       cmp testimg.ppm testout.ppm
+       cmp testimg.jpg testout.jpg
+
+
+jbsmooth.o : jbsmooth.c jinclude.h jconfig.h jpegdata.h 
+jcarith.o : jcarith.c jinclude.h jconfig.h jpegdata.h 
+jccolor.o : jccolor.c jinclude.h jconfig.h jpegdata.h 
+jcdeflts.o : jcdeflts.c jinclude.h jconfig.h jpegdata.h 
+jcexpand.o : jcexpand.c jinclude.h jconfig.h jpegdata.h 
+jchuff.o : jchuff.c jinclude.h jconfig.h jpegdata.h 
+jcmain.o : jcmain.c jinclude.h jconfig.h jpegdata.h egetopt.c 
+jcmaster.o : jcmaster.c jinclude.h jconfig.h jpegdata.h 
+jcmcu.o : jcmcu.c jinclude.h jconfig.h jpegdata.h 
+jcpipe.o : jcpipe.c jinclude.h jconfig.h jpegdata.h 
+jcsample.o : jcsample.c jinclude.h jconfig.h jpegdata.h 
+jdarith.o : jdarith.c jinclude.h jconfig.h jpegdata.h 
+jdcolor.o : jdcolor.c jinclude.h jconfig.h jpegdata.h 
+jdhuff.o : jdhuff.c jinclude.h jconfig.h jpegdata.h 
+jdmain.o : jdmain.c jinclude.h jconfig.h jpegdata.h egetopt.c
+jdmaster.o : jdmaster.c jinclude.h jconfig.h jpegdata.h 
+jdmcu.o : jdmcu.c jinclude.h jconfig.h jpegdata.h 
+jdpipe.o : jdpipe.c jinclude.h jconfig.h jpegdata.h 
+jdsample.o : jdsample.c jinclude.h jconfig.h jpegdata.h 
+jerror.o : jerror.c jinclude.h jconfig.h jpegdata.h 
+jfwddct.o : jfwddct.c jinclude.h jconfig.h jpegdata.h 
+jquant1.o : jquant1.c jinclude.h jconfig.h jpegdata.h 
+jquant2.o : jquant2.c jinclude.h jconfig.h jpegdata.h 
+jrdjfif.o : jrdjfif.c jinclude.h jconfig.h jpegdata.h 
+jrdgif.o : jrdgif.c jinclude.h jconfig.h jpegdata.h 
+jrdppm.o : jrdppm.c jinclude.h jconfig.h jpegdata.h 
+jrevdct.o : jrevdct.c jinclude.h jconfig.h jpegdata.h 
+jutils.o : jutils.c jinclude.h jconfig.h jpegdata.h 
+jvirtmem.o : jvirtmem.c jinclude.h jconfig.h jpegdata.h 
+jwrjfif.o : jwrjfif.c jinclude.h jconfig.h jpegdata.h 
+jwrgif.o : jwrgif.c jinclude.h jconfig.h jpegdata.h 
+jwrppm.o : jwrppm.c jinclude.h jconfig.h jpegdata.h 
diff --git a/makljpeg.cf b/makljpeg.cf
new file mode 100644 (file)
index 0000000..3325bf4
--- /dev/null
@@ -0,0 +1,5 @@
+jbsmooth.mix,jcarith.mix,jccolor.mix,jcdeflts.mix,jcexpand.mix,jchuff.mix
+jcmaster.mix,jcmcu.mix,jcpipe.mix,jcsample.mix,jdarith.mix,jdcolor.mix
+jdhuff.mix,jdmaster.mix,jdmcu.mix,jdpipe.mix,jdsample.mix,jerror.mix
+jfwddct.mix,jquant1.mix,jquant2.mix,jrdgif.mix,jrdjfif.mix,jrdppm.mix
+jrevdct.mix,jutils.mix,jvirtmem.mix,jwrgif.mix,jwrjfif.mix,jwrppm.mix
diff --git a/testimg.jpg b/testimg.jpg
new file mode 100644 (file)
index 0000000..b6b68bc
Binary files /dev/null and b/testimg.jpg differ
diff --git a/testimg.ppm b/testimg.ppm
new file mode 100644 (file)
index 0000000..c7dab37
--- /dev/null
@@ -0,0 +1,9 @@
+P6
+128 128
+255
+»cUÒzlߦ\92ò¹¥Ô¼¢Âª\90¹©\92²\9bϪ\9a\91\81¬rd\9cbT\98YG¤eSÊ\8evò¶\9eßÅ®ÚÀ©Ó¹¢Ïµ\9eÔ¹¦Ù¾«×¼«Ï´£Ê® Ï³¥Ë¯£¸\9c\90¤\88}\9d\81\85\89\95\8f¯\9c\96³\9a\93«\92\8b¬\8c\8e\7f¯\8a\83\84\99\85±\8bx\9fyf³\92\81˪\99Â¥\97¹\9c\8eÂ\8c\80\8e\92\81\9b\80y\95zs\9c\8e\8e£\95\95\91\8b\8d{uwbXWQGF[JBfUMlVHhRD\7fM6\8cZC\9enW´\84\96\7fÏ¡\8aÒ¥\90Ó¦\91Ѧ\95Ѧ\95ѧ\97Ò¨\98Ѫ\9bÒ«\9cÒ­\9dÒ­\9dѵ§Ï³¥Ï²¤Í°¢Í¬\9dÌ«\9cͨ\98̧\97¿\94\83½\92\81¼\8d\88\81n¯|i¬weªuc¡uh\9dqd\97k^\91eX\8ecS\8ecS\90eT\91fU\92hR\8edN\88^F\82X@|R9sI0h>%_5\1cY<\1c]@ _E*_E*VC2S@/N@5OA6J;6G83N<8]KGqZTs\ViLFY<6½cSÕ{ká¨\94÷¾ªÛéɱ\97¿­\95Æ´\9cϪ\98¸\93\81®tf\9dcU\9bZH§fTÈ\8crì°\96ؾ§Õ»¤Ð¶\9fÊ°\99ʯ\9cγ Ò·¦Ó¸§È¬\9eͱ£É­¡¹\9d\91¨\8c\81¡\85\8a\7f­\91\86«\98\92²\9f\99\9d\96¬\93\8c¬\8c\8d\88\82o§~j¿\96\82³\8dz¡{h³\92\81ɨ\97Á¤\96¹\9c\8e²~h±}g¶\8c\8az\95zs\9c\81\9e\9e°¤¤«¥§\8a\84\86f\ZTJHbPFm[QnWGdM=\81O8\91_H§w`»\8b\99\82Π\89Ò¥\90Õ¨\93Ò§\96Ó¨\97Ó©\99Ôª\9aÓ¬\9dÔ­\9eÕ° Õ° Ò¶¨Ñµ§Ñ´¦Ï²¤Ï®\9fέ\9eϪ\9aΩ\99Ç\9c\8bÄ\99\88Á\92\80»\8c\85\81n³~l²}k«\7fr§{n¢vi\9dqd\9bp`\9cqa\9esb\9ftc\9et^\9apZ\94jR\8feM\89_F\80V=vL3mC*_@!cD%cH-bG,XC2T?.O>4P?5G83C4/H62UC?hQKlUOeJCW<5º^OÑufÜ¢\8có¹£ÚÀ¥Ê°\95®\95ɵ\9cΨ\95»\95\82±vf\9ecS\9dZG¨eRÄ\86má£\8aÑ· Í³\9cɯ\98Ī\93Á¦\93§\94É®\9dе¤É­\9f˯¡É­¡½¡\95­\91\86¥\89\8f\84µ\99\8e°\9d\97¸¥\9f»¢\9b¯\96\8f¬\8c\89\85\7fl\9fvb½\94\80\90\7f\92\81Æ¥\94¾¡\93¸\9b\8d¥u_®~h·\90\81±\8a{\99\80\9b\96ɽ¿Å¹»²©¬\89\80\83`UQRGCeQFq]RqVEfK:\86T=\9biR´\84\96\7fË\9d\86Í\9f\88Ò¥\90Ø«\96Ô©\98Õª\99Õ«\9b×­\9dÖ¯ Ø±¢Ø³£Ù´¤Õ¹«Ô¸ªÔ·©Òµ§Ò±¢Ñ°¡Ò­\9dѬ\9cÐ¥\94Ë \8fÇ\98\86¿\90\8a\88\87\88\8a\87\84\81\80\81\83\85\82m«~i¦yb¡t]\9cpW\94hO\8a^E\82V=kH*nK-lL3hH/ZC3U>.O=3O=3E61?0+@.*I73[D>bKE`E>W<5²UCÃfTÊ\8evߣ\8bÈ­\90½¢\85º¥\8aî\93Ë¢\8e¼\93\7f³vd\9fbP\9dYD¨dO¿\7f\94xƬ\95¾¤\8d»¡\8aÀ¦\8fŪ\97Ū\97Æ«\9aʯ\9eβ¤Í±£Ê®¢Â¦\9a²\96\8b¦\8a\7f¬\90\85¹\9d\92µ¢\9c¾«¥Á¨¡²\99\92«\8b\86\83p£~k\9br^¼\93\7f¸\92\7f§\81\92\81Ä£\92¼\9f\91·\9a\8c©zh´\85\95\88\90\83ª\92\8eζ²ØÌÎÁµ·\90\87\88nefSF@NA;dM?mVHqU@mQ<\8f]F¦t]Á\91zР\89Ï¡\8aÌ\9e\87Ò¥\90Ú­\98Ö«\9a׬\9bØ®\9eÚ° Ù²£Û´¥Ü·§Ý¸¨Ø¼®×»­×º¬Õ¸ªÕ´¥Ó²£Õ° Ô¯\9fÖ«\9aÐ¥\94Ê\9b\89Â\93\81À\8d\8d\8e\90\8e\82½\8d\81»\8b\7fº\8a\8a\8c\8f\7f¿\90\80¹\8a\86\83\7fh©{c¡s[\98jR\90bJ|S7}T8wS;oK3_C5W;-N:1N:1G51@.*;)%@.*P93XA;Y@9V=6«L8¶WC³vZÅ\88\94\90\97{»£\87Ç\9d\87¼\92|µvd aO¡[B¬fM»z\È\87\97\80¥\8b\8dv¼¢\8bÏ´¡Ñ¶£Í²¡Î³¢Õ¹«Ï³¥Ì°¤Æª\9e´\98\8d¤\88\8d\82¹\9d\92¸¥\9f¯©Ç®§¶\9d\96«\8b\84\81n¢}j wc¾\95\81¸\92\7f§\81\94\83Æ¥\94»\9e\90´\97\89´\89\8b\94\8a´\92\88®\99\96ʵ²¿µ¶\94\8a\8bnefWNON?8QB;bH7eK:qQ:zZC\9cjS²\80\9a\83Õ¥\8eÑ£\8cÍ\9f\88Ѥ\8fÙ¬\97׬\9bØ­\9cÙ¯\9fÛ±¡Û´¥Þ·¨ßºªßºªÚ¾°Ù½¯Ø»­Ö¹«×¶§Õ´¥Ö±¡Ö±¡×¬\9bѦ\95Ì\9d\8bÄ\95\83Ã\90\90\91\7fÈ\93\81À\8e\83¿\8d\82¿\8d\82¿\8d\82À\8f\81Á\90\82Â\91\82Ã\92\83¼\8c\89\85\82\7fh¨xa\9foX\98hQ\8f]D\8e\C\83YCxN8dB6Z8,N5.N5.J73B/+:'#;($D0)M92S<4S<4ªJ4²R<®mQ¾}aª\8b\88\91\9d\7fÆ\99\82¿\92{»xe§dQ§_F³kR½{[Â\80\87p\95{d\9c\82\9d\86Ë°\9dͲ\9fÏ´£Ö»ª×»­Ï³¥Ë¯£È¬ ¶\9a\8f¢\86\8b\80»\9f\94º§¡Æ³­Ë²«¹ \99¬\8c\83\81\7f\83\9b\87·\91\7f\96\85Ê©\98¼\9f\91°\93\85º\92\86±\89\90\88±\93\8b©\95\94µ¡ \9d\92\96peii_`UKLQ@8WF>dG5dG5uQ7\87cI«yb»\89\9c\85Ô¤\8dÒ¤\8dÏ¡\8aѤ\8fÖ©\94Ö«\9a׬\9bØ®\9eÛ±¡Üµ¦Þ·¨à»«à»«Ú¾°Ù½¯Ø»­Ö¹«×¶§Õ´¥Ö±¡Ö±¡Ö«\9aÒ§\96Î\9f\8dÈ\99\87Ç\94\81Æ\93\80È\93\81É\94\82Ã\8f\84Ã\8f\84Ã\8f\84Ä\90\85Ä\90\83Ä\90\83Å\91\83Å\91\83¿\8c\89\86\84\82k®|e¦t]\9fmV hQ\9deN\8e^J\80P<hB7\6+N3,N3,K63C.+9&"6#\1f<(!C/(J3+L5-³P9¼YB¸w[Ì\8b\99\94\96\9d\7fÉ\9b\83Ä\96\80j¯mW²hOÀv]Æ\81\7f\8dv\9f\85\8a\9a\83µ\9a\87®\93\80º\9f\8eÒ·¦Ô¸ªÉ­\9fÇ«\9fȬ ·\9b\90£\87\8c\81¿£\98º§¡Ç´®Í´­º¡\9a¬\8c\83\82\81\92~É \8cµ\8f|¢|i¹\98\87Ï®\9d½ \92¬\8f\81·\91\86¬\86\93\8d¼\9f\99¯\9d\9d°\9e\9e£\98\9c\8a\7f\83rhgUKJJ8.R@6hI5mN:\81\A\96qV¹\87\90\9a\83Ñ¡\8aÑ£\8cТ\8bѤ\8fÓ¦\91Õª\99Õª\99×­\9dÚ° Û´¥Þ·¨ßºªá¼¬Ù½¯Ø¼®Ø»­Ö¹«Öµ¦Ô³¤Ö±¡Õ° Ö«\9aÓ¨\97Ó¤\92Î\9f\8dÍ\9a\87Ë\98\85Ë\96\84Ë\96\84É\93\89É\93\89Ê\94\8aÊ\94\8aÊ\94\88É\93\87È\93\85Ç\92\84Ä\8f\8c\8a\88\87\82l­yc§s]¬oZ¨kV\97bP\86Q?lA8^3*N1+M0*H30A,)7$ 1\1e\1a\197$\1d=) ?+"ºW@ÆcLÈ\85\9c\7fά\89Ä¢\7f¹\9e\80¼¡\83Ì\9c\85É\99\82È\84m¶r[¹oTÈ~cÍ\86\81\9e\87²\98\81´\9a\83³\99\82\9e\83p\8cq^¡\86uŪ\99ϳ¥Ä¨\9aç\9bÇ«\9f¸\9c\91¤\88\8f\84Ĩ\9dº§¡Èµ¯Îµ®»¢\9b¬\8c\84\82\82\9b\87ͤ\90³\8dz zgº\99\88Ò± ¾¡\93ª\8d\7f²\8d\84©\84\9b\97ͱ­¼¬­¼¬­Á¶º¿´¸wmlOED<(\1fH4+hH3vVA\8egJ¤}`Á\8f\93\98\81Í\9d\86Т\8bÒ¤\8dУ\8eУ\8eÓ¨\97Ô©\98Ö¬\9cÙ¯\9fÛ´¥Þ·¨ßºªà»«Ø¼®×»­×º¬Õ¸ªÕ´¥Ô³¤Õ° Ô¯\9f׬\9bÕª\99Ö§\95Ó¤\92Ó \8dÐ\9d\8aÎ\99\87Í\98\86Î\98\8eÎ\98\8eÏ\99\8fÏ\99\8fÎ\98\8cÍ\97\8bË\96\88Ê\95\87È\93\81Å\90\8e\8d\8c\87\7fi¬xb²t_­oZ\9cdS\8aRAnB9_3*N/*M.)G/-@(&4!\1d.\e\17-\1a\130\1d\165!\187#\1aºG4Ó`MÖ\8evð¨\90ÛçØÀ¤¼¶\9e¬¦\8eÇ°\9e¹¢\90¾\8b\85\82\86\84\80\8cuÑ«\94̪\91¬\8aq\94za\8bqX\94~f³\9d\85¹£\8eÄ®\99Ò·¦Î³¢½\99\8d¨\84\87\99\8f¿¥¦È®¯Ë­«»\9d\9b²\8d\84­\88\7f¬\85\81\9e\8dΧ\96\9f{k\9f{k·\9b\8d½¡\93¿§\9b«\93\87\9fynÈ¢\97Ѹ±Ä«¤¾¹µ×ÒμÅÂ\90\99\96TYUBGCF:.PD8oJ8zUC\98bJªt\À\94\97\9a\81Ë\9f\86Τ\8cѧ\8fѨ\92Ò©\93Ï©\96Ñ«\98Ò¯\9cÕ²\9fØ´¤Ùµ¥Ø·¦Ø·¦Þ¸­Þ¸­ß·­Þ¶¬Ý³§Ú°¤Ø¬\9f׫\9eÒ¤\94Ñ£\93Ï \8eÌ\9d\8bÌ\9c\88Ê\9a\86Í\9a\87Í\9a\87È¡\92É¢\93Ë¡\93Ë¡\93Í\9f\90Ë\9d\8eÍ\99\8bË\97\89Ê\92\81É\91\80Ç\8c\88\83\7fm¼{i»zhµxY¯rS\9cfL\89S9kB0]4"N0%N0%>*#;' 3$\1d\19,\1d\16,\1d\16\17/!\18½J7Ï\IÎ\83\9e\87ؾ£Ù¿¤¿· ±©\92˱ ¿¥\94Â\8d\85\81\82\80_Æ}\·\91zÉ£\8c½\9b\82®\8c\95\98\7f­\97\7f¹£\8b¡\8b\9e\89Ë°\9fγ¢¾\9a\8e©\85\8a\80Å\9d\93¨©Ë±²Í¯­½\9f\9d´\8f\86®\89\80®\87\83\97\86È¡\90\9dyi¡}m¹\9d\8f½¡\93¾¦\9a«\93\87¸\96\8cƤ\9aË´¬Ò»³ËÆÿº·\8b\91\8f]caGID;=8C5*PB7rM:\84_L©sYÀ\8a\98\7fÆ\9a\81Ê\9e\85΢\89ѧ\8fÓ©\91Ô«\95Ô«\95Ï©\96Ñ«\98Ò¯\9cÖ³ Ø´¤Ú¶¦Ø·¦Ø·¦Þ¸­Þ¸­ß·­Þ¶¬Ý³§Ú°¤Ø¬\9fÖª\9dÒ¤\94Ñ£\93Ï \8eÍ\9e\8cÌ\9c\88Ë\9b\87Í\9a\87Î\9b\88È¡\92É¢\93Ë¡\93Ë¡\93Í\9f\90Ë\9d\8eÌ\98\8aË\97\89Ë\93\82É\91\80È\8d\89\83\7fm½|j»zh³vW­pQ\9adJ\86P6i@.[2 L.#L.#>*#;' 3$\1d\19,\1d\16,\1d\16-\1f\16\17¾I7ÅP>»pY×\8cuγ\98Õº\9f½µ\9e²ª\93γ¢Ã¨\97Ç\92\80»\86tÂ|cÀzaÃxXÂwW¶\90\90y ~e¡\7ff¿¥\8cϵ\9c½§\8f´\9e\86\93}h«\95\80É®\9dͲ¡º\96\8a¤\80\85\9b\91Å«¬Í³´Ï±¯¾ \9e´\8f\86¯\8a\81¯\88\84\8c\99\88\9avf£\7fo¼ \92½¡\93½¥\99¬\94\88Ç« Ê®£Íº´×ľ¾º·\94\90\8dcghLPQ?>:984G5)SA5tN9\8beP´\81\9b\9b\82Ê\9e\85Í¡\88Ò¦\8dÔª\92Ö¬\94Ö­\97×®\98Ñ«\98Ó­\9aÓ°\9dÖ³ Ø´¤Ú¶¦Ø·¦Ø·¦Ý·¬Ý·¬Þ¶¬Ýµ«Ý³§Ù¯£Ø¬\9fÖª\9dÒ¤\94Ñ£\93Ï \8eÍ\9e\8cÍ\9d\89Ì\9c\88Ï\9c\89Ï\9c\89É¢\93É¢\93Ë¡\93Ë¡\93Ì\9e\8fÊ\9c\8dË\97\89É\95\87Ë\93\82É\91\80È\8d\89\83\7fm½|j»zh¯rS©lM\96`F\83M3e<*W.\1cH*\1fH*\1f=)":&\1f2#\1c.\1f\18,\1d\16,\1d\16-\1f\16\17¿G6¼D3ª^GÈ|eŧ\8dΰ\96»¯\99´¨\92Í° Å¨\98Ë\93\82»\83r»s[µmUºnN»oO¶\90\85n\8cjQ\8elS·\9d\84δ\9bº¤\8c«\95}\9e\88\9d\88γ¢Ë°\9f³\8f\83\9bwk¦~t½\95\8bÅ«¬Í³´Í¯­»\9d\9b±\8c\83¬\87\85\82\84\92\81\98td¨\84tÁ¥\97½¡\93½¥\99±\99\8dÁ­¤Ï»²ÕÈÂɼ¶ \9c\9b\7f{zooqqqsA<9@;8O9,WA4uM4\8efM¶\84\9b\9d\84Ë\9f\86΢\89Ò¦\8dÔª\92Ö¬\94Ö­\97Ö­\97Ò¬\99Ô®\9bÕ²\9f×´¡Ùµ¥Ú¶¦Ø·¦×¶¥Ü¶«Ý·¬Ýµ«Ü´ªÜ²¦Ù¯£×«\9eÕ©\9cÒ¤\94Т\92Ï \8eÍ\9e\8cÎ\9e\8aÍ\9d\89Ð\9d\8aÑ\9e\8bÉ¢\93É¢\93Ë¡\93Ê \92Ë\9d\8eÈ\9a\8bÊ\96\88È\94\86Ê\92\81È\90\7fÇ\8c\88\82p½~l¼{iºyg¬oP¥hI\92\B\7fI/a8&S*\18E'\1cD&\e<(!9%\1e1"\e-\1e\17+\1c\15+\1c\15,\1e\15-\1f\16ÅL;½D3ªYDÊydÅ¥\8cË«\92º«\96¸©\94Ë«\9cƦ\97Î\93\83»\80pµjS¬aJ²cD¶gH·\91\86o\88fM\7f]D\9d\83\98\7f¦\90\8b\98\83½§\92Ï´£Ç¬\9b°\8c\80\9bwk©\81\9a\90Ī«Ë±²É«©¶\98\96¬\87\82\81\7f\82\90\7f\99ue­\89yƪ\9c¿£\95À¨\9c¹¡\95½°¨ÐûÏÅ÷­« \9b\9f\9b\96\9a\8e\89\8dzuyA64D97T:-[A4yR5\96oRº\88\99\9d\84Ë\9f\86΢\89Ò¦\8dÓ©\91Ôª\92Ô«\95Ô«\95Ô®\9bÖ°\9dÖ³ Øµ¢Ú¶¦Ú¶¦×¶¥×¶¥Ü¶«Ü¶«Ýµ«Ü´ªÛ±¥Ø®¢Öª\9dÔ¨\9bÑ£\93Т\92С\8fÎ\9f\8dÏ\9f\8bÏ\9f\8bÒ\9f\8cÓ \8dÉ¢\93É¢\93Ë¡\93É\9f\91Ê\9c\8dÇ\99\8aÈ\94\86Æ\92\84Ç\8f\8e\89\85s¿\80n»|j¹xf¸we©lM£fG\90Z@|F,_6$Q(\16B$\19B$\19<(!9%\1e0!\1a-\1e\17*\e\14*\e\14+\1d\14,\1e\15ÍRBÅJ:µcNÖ\84o̪\91Ë©\90º©\95¼«\97Ê©\9aȧ\98Ò\94\85½\7fp³eO§YC®]?¶eGª\84\80i\83aHoM4|bI\8apW\88rZ\90zb´\9e\89½§\92ʯ\9eŪ\99µ\91\85¦\82\8d\83̤\9aĪ«Ê°±Èª¨³\95\93©\84\80\7fp¤}n®\87\92\81\9dyi´\90\80˯¡Á¥\97Å­¡Ã«\9fÄ¿¹Ç¼¼¸·³¯®¾¹¿¿ºÀ\93\89\91VLT<,,A11R5'_B4\85\>©\80\98nÏ vÊ\9e\85Ì \87Ï£\8aÒ¦\8dÓ©\91Ôª\92Óª\94Óª\94Ö°\9dز\9fص¢Ù¶£Ú¶¦Ú¶¦×¶¥×¶¥ÛµªÛµªÜ´ªÛ³©Ú°¤×­¡Õ©\9cÔ¨\9bÑ£\93Т\92С\8fÏ \8eÏ\9f\8bР\8cÔ¡\8eÕ¢\8fÊ£\94É¢\93Ë¡\93É\9f\91É\9b\8cÅ\97\88Æ\92\84Ä\90\82Ä\8c\8a\86\81o»|j·xfµtb´sa¨kL¢eF\8fY?{E+^5#P'\15A#\18A#\18;' 8$\1d0!\1a,\1d\16)\1a\13)\1a\13*\1c\13+\1d\14ÎPAÉK<¾iUà\8bwΪ\92Ä \88² \8c¸¦\92Í©\9bΪ\9cØ\99\8aÂ\83t³eO¦XB±^@»hJ¡{d¥\7fh\88fMqO6u[B~dK~hP\8at\¶ \8b»¥\90Æ«\9aÆ«\9a¿\9b\8f²\8e\82º\92\88É¡\97Ç­®Ì²³É«©´\96\94©\84\80\80q¥~oµ\8e\97\86¢~nº\96\86ϳ¥Ã§\99ʲ¦Íµ©ÆÇÁ»¼¶¶¶¶¿¿¿ÈÃɯª°xmuE:B?+,D01U5&gG8\96kI¾\93qÓ¤xСu΢\89Ф\8bÓ§\8eÖª\91Ö¬\94×­\95Ö­\97Ö­\97ز\9fÙ³ Ù¶£Ú·¤Ú¶¦Ú¶¦×¶¥Öµ¤Ú´©ÛµªÛ³©Ú²¨Ú°¤×­¡Õ©\9cÓ§\9aÑ£\93Т\92С\8fÏ \8eР\8cÑ¡\8dÕ¢\8fÖ£\90Ê£\94Ê£\94Ê \92É\9f\91É\9b\8cÄ\96\87Å\91\83Â\8e\80À\88\86\82p¹~l·xf³tb²q_°o]¨kL¢eF\8fY?|F,^5#P'\15A#\18A#\18:&\1f7#\1c\19+\1c\15)\1a\13)\1a\13*\1c\13+\1d\14ÇI:ÆH9¿jVá\8cxÉ¥\8dº\96\94\80¯\9d\89Ï«\9dÑ­\9fÜ\9d\8eÆ\87x·fQªYD³`B¿lN«\85\8dv\9by`\86dK\88nU\8et[\8dw_\99\83k¸¢\8d¼¦\91Æ«\9aʯ\9eÆ¢\96\92\86\8e\84¾\96\8c˱²Ïµ¶Ë­«¶\98\96«\86\82\82\81\94\83Â\9b\8a¥\81\99\89Ò¶¨Ä¨\9a͵©Ó»¯¼Á»³¸²½¾ÀÌÍÏ»¶½\83~\85_R[XKTH24K57[:)nM< uSÈ\9d{רzÌ\9doÒ¦\8dÓ§\8eÖª\91Ù­\94Ù¯\97Ú°\98د\99Ù°\9aز\9fÚ´¡Ú·¤Ú·¤Û·§Ú¶¦×¶¥Öµ¤Ú´©Ú´©Û³©Ú²¨Ù¯£Ö¬ Ô¨\9bÓ§\9aТ\92Т\92С\8fÏ \8eÑ¡\8dÒ¢\8eÖ£\90פ\91Ê£\94Ê£\94Ê \92È\9e\90È\9a\8bÄ\96\87Ä\90\82Â\8e\80¾\86\84\80n¶{iµvd±r`¯n\®m[©lM¢eF\8fY?|F,^5#P'\15B$\19A#\18:&\1f7#\1c\19+\1c\15)\1a\13)\1a\13*\1c\13+\1d\14¼N-ºL+µ`AÍxY¿\90\8e\98}´ \85µ¤\8aÅ´\9aÈ \87®\86m¶lS£Y@²P7ÉgN®\82\8bnÅ \86Á\9c\82©\8a\97\83Á§\98·\9d\8eí Ê´§Î·©Å® ·\9a\88«\8e\94\7fÀ \8bì¤È±©Ä©\9e±\96\8b¥\88\89\8c\8e\7fÀ£\95\99\8b©\90\89±\98\91¿°­ÐÁ¾É½¿½±³¸·¿¹¸ÀÀ»Á¶±·\93\87\89eY[[HBdQKO3'F*\1e[6#\85`M±\87\9b\83Т\88Ö¨\8eÓª\94Óª\94Õ¬\96Ö­\97Ö°\9b×±\9cײ\9fس Öµ¤×¶¥×·¨Ø¸©×·ªÖ¶©Ó¶¨Òµ§ß´¤Þ³£Ý²¢Ü±¡Ù®\9eÕª\9aѦ\96Ϥ\94Ó¨\98Ò§\97Ð¥\95Ϥ\94Σ\93Ϥ\94Ð¥\95Ð¥\95Ò\9a\89Ñ\99\88Î\97\83Ë\94\80É\90\8c\8a\89\87\84m¿\7ff¹y`µsY²pV°nT¯mS¤hC\9c`;\8bT5{D%d4 U%\11C\1d\14=\17\ e=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17¾K,¸E&­T6ÀgI´\81\87\9a\7fº¥\8a·§\8eÇ·\9eÉ¥\8b°\8cr¸v\§eKµ]BÌtYÂ\96\96yÊ¥\8bÊ¥\8b»\9c\88È©\95˱¢¸\9e\8f¬\96\89­\97\8a´\9d\8f¹¢\94³\96\84§\8a\8fz¿\9f\8a«£È±©Æ« ³\98\8d§\8a\89\8b\8a{½ \92·\9a\8c®\95\8eµ\9c\95¾¯¬Ë¼¹Ç»½À´¶º¹ÁÃÂʵ°¶\92\8d\93\8c\80\82\91\85\87}jdR?9P4(N2&hC0\90kX¹\8f\9f\87Т\88Õ§\8dÕ¬\96Õ¬\96Ö­\97د\99ز\9dÙ³\9eÙ´¡Ù´¡×¶¥Ø·¦×·¨Ø¸©×·ªÖ¶©Ó¶¨Òµ§Û° Û° Ú¯\9fÙ®\9e׬\9cÔ©\99Ò§\97Ð¥\95Ó¨\98Ò§\97Ð¥\95Ϥ\94Ϥ\94Ϥ\94Ð¥\95Ϥ\94Ñ\99\88Ð\98\87Í\96\82Ê\93\7fÈ\8f\8b\89\87\84m¿\81j¼|c·w^³qW°nT­kQ­kQ£gB\9c`;\8bT5zC$d4 V&\12D\1e\15>\18\ f=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17¿G,¸@%©K1¹[A±ybÀ\88\9f\88Å«\94¹©\92ɹ¢Èª\90³\95\85f«vW·mPÍ\83\98\8e\96\98\8f\94\80ª\90\81\8fuf\8buh\83m`\90yk¨\91\83°\93\81£\86\8au¿\9f\8aÁª¢É²ªÈ­¢·\9c\91ª\8d\7f¦\89\88\86\9b\8d´\97\89¯\96\8f¹ \99À±®Éº·Å¹»Ã·¹¾½Åº¹Á¦¡§\92\8d\93¢\96\98­¡£\86smE2,N2&W;/yTA¡|iÃ\99\81Τ\8cÒ¤\8aÓ¥\8bد\99د\99Ù°\9aÛ²\9cÛµ Ü¶¡Ü·¤Ü·¤Ø·¦Ù¸§Ù¹ªÙ¹ªØ¸«Ö¶©Òµ§Ñ´¦×¬\9cÖ«\9bÕª\9aÕª\9aÔ©\99Ó¨\98Ò§\97Ò§\97Ò§\97Ò§\97Ѧ\96Ð¥\95Ϥ\94Ϥ\94Σ\93Σ\93Ð\98\87Ï\97\86Ì\95\81É\92\8d\89\86p¿\85\7fhº|e·w^²rY¯mS¬jPªhN©gM¡e@\9a^9\8aS4zC$e5!W'\13E\1f\16@\1a\11=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17¼B*¼B*²R:ÆfNÄ\87\98\85ɪ\96Í®\9a¸§\93È·£Æ¬\93´\9a\81º\8f\81a²wWÅ\8a\88kª~a«\86\82h\8akW\7f`LqWHY?0nXKdNAw`R\9e\87\94\82¤\87\8auÀ \8bÀ©¡È±©Ê¯¤¹\9e\93«\8e\80§\8a\87\83\99\8b¬\8f\81§\8e\87º¡\9aȹ¶ÏÀ½È¼¾Ä¸º¾½Å©¨°§¢¨ºµ»Áµ·\9b\8f\91lYSJ71I-!^B6\89dQ®\89vÊ \88Ó©\91Ö¨\8eÔ¦\8cÛ²\9cÛ²\9cܳ\9dÞµ\9fÝ·¢ß¹¤ßº§ßº§Ú¹¨Ûº©Úº«Úº«Ø¸«Ö¶©Òµ§Ñ´¦Ó¨\98Ó¨\98Ѧ\96Ѧ\96Ѧ\96Ò§\97Ó¨\98Ó¨\98Ò§\97Ò§\97Ò§\97Ò§\97Ð¥\95Ϥ\94Í¢\92Ì¡\91Ï\97\86Í\95\84Ê\93\7fÆ\8f\8aw¿\86\83\81k·ybµw`²rY®nU«iO¨fL¦dJ¦dJ\9fc>\98\7\88Q2zC$e5!X(\14G!\18B\1c\13=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17²@&»I/½aJÖzcÛ\9e\8cë®\9c׶¥Ð¯\9e·¢\91Dz¡Å«\94\9c\85º\93\81d¦tS³\81`¡uX¢vY®\89\82hwXD]>*T:+J0!_I<]G:v_Q\9f\88\98\86¬\8f\90{À \8b¿¨ Ç°¨É®£¹\9e\93¬\8f\81§\8a\88\84\99\8b¤\87y\9e\85~º¡\9aÐÁ¾×ÈÅË¿Á¶¸µ´¼µ´¼Á¼ÂÆÁDZ¥§\7fsu_LFS@:G+\1ffJ>\97r_·\92\7fÍ£\8bÔª\92ت\90ש\8fܳ\9dÝ´\9eÞµ\9f߶ ß¹¤àº¥à»¨á¼©Ü»ªÜ»ªÜ¼­Û»¬Ù¹¬×·ªÒµ§Ð³¥Ò§\97Ѧ\96Ϥ\94Ϥ\94Ϥ\94Ѧ\96Ó¨\98Õª\9aÒ§\97Ó¨\98Ó¨\98Ó¨\98Ѧ\96Ϥ\94Ë \90É\9e\8eÎ\96\85Ì\94\83É\92\8d\87\83\80j¸~h³u^°r[¯oVªjQ§eK¥cI¤bH¤bH\9da<\96Z5\87P1yB#e5!Y)\15I#\1aD\1e\15=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17¤A$°M0¶dLÏ}eÛ¢\91ﶥ۹­Î¬ µ\9e\90Ư¡Æª\95¹\9d\88¼\92y¥{b\9aeF¡lM\8daD\9anQ´\8f\8bquVBS4 Q7(U;,\F9kUH\89rd¨\91\83¹\9c\8a\99\87¸\98\83½\9d\88¾§\9fƯ§Ç¬¡¶\9b\90ª\8d\7f¨\8b\8b\89\99\8b£\86\87\80¿¦\9fÓÄÁÔÅÂƺ¼Áµ·±°¸ÏÎÖÐËÑ£\9e¤\85y{{oqp]WTA;Q5)vZN§\82\99\86Ë¡\89ѧ\8fت\90ت\90Ý´\9eÝ´\9eÞµ\9f߶ ß¹¤àº¥á¼©á¼©Þ½¬Þ½¬Ý½®Ü¼­Úº­×·ªÒµ§Ð³¥Ô©\99Ó¨\98Ð¥\95Σ\93Σ\93Ѧ\96Ô©\99Ö«\9bÒ§\97Ó¨\98Õª\9aÕª\9aÒ§\97Σ\93Ê\9f\8fÇ\9c\8cÍ\95\84Ê\92\81Ç\90\8b\85\80m¶|f´zd°r[®pY¬lS¨hO¦dJ¤bH£aG£aG\9a^9\95Y4\86O0yB#f6"[+\17K%\1cG!\18=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17\97B#\9fJ+\9eV=®fM¿\8c{Ü©\98Õ³§Ê¨\9c¸\9c\91Ê®£Í©\99Á\9d\8dÂ\92|£s]\8eU:\8fV;\87[>\96jM¶\91\91wyZFS4 R8)[A2`J=\82l_¤\8d\7f³\9c\8e»\9e\8c½ \8e½\9d\88·\97\82½¦\9eÄ­¥Ä©\9e²\97\8c¨\8b\8c\8f\80¯\8f\80´\97\89ª\8d\7f¯\96\8fʱªÎ¿¼Ã´±»¯±Â¶¸¿¾ÆÅÄ̲­³\8a\85\8b\83wy\89}\7fxe_Q>8eI=\8cpdº\95\82Å \8dÈ\9e\86Í£\8bש\8fÙ«\91ܳ\9dܳ\9dÝ´\9e߶ Þ¸£ß¹¤à»¨à»¨ß¾­ß¾­Þ¾¯Ý½®Úº­×·ªÒµ§Ð³¥Ø­\9dÕª\9aÒ§\97Ϥ\94Σ\93Ѧ\96Ô©\99׬\9cÒ§\97Ó¨\98Õª\9aÖ«\9bÓ¨\98Σ\93É\9e\8eÅ\9a\8aÌ\94\83É\91\80Æ\8f\89\83p·~k´zd²xb¯qZ­oX«kR¨hO¦dJ¤bH£aG£aG\99]8\93W2\85N/yB#f6"\,\18L&\1dH"\19=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17\8fD$\90E%\86F+\8eN3¡r`È\99\87̬¡Ç§\9c¼\9b\92Ï®¥Òª\9eÇ\9f\93Ç\93~¤p[\89K2\86H/\93gJ\9erU½\98\98~\82cOY:&T:+Z@1dNA\92|o¶\9f\91¹¢\94º\9d\8bÁ¤\92À \8b±\91|½¦\9eì¤Á¦\9b°\95\8a¦\89\8c\91\82³\93\84±\94\86±\94\86¿¦\9fÓº³È¹¶´¥¢±¥§Ä¸ºÑÐØ£¢ª\85\80\86\90\8b\91¥\99\9b\92\86\88n[UO<6uYM\9d\81uÆ¡\8eÊ¥\92Æ\9c\84Ê \88Õ§\8dت\90Û²\9cÛ²\9cܳ\9dÞµ\9fÞ¸£ß¹¤ßº§ßº§à¿®à¿®ß¿°Ý½®Úº­×·ªÒµ§Ð³¥Û° Ø­\9dÔ©\99Ð¥\95Ϥ\94Ѧ\96Ô©\99׬\9cÒ§\97Ô©\99Ö«\9bÖ«\9bÓ¨\98Σ\93È\9d\8dÅ\9a\8aË\93\82É\91\80Å\8ez¿\88\82o¶}j²xb°v`®pY¬nW«kR¨hO¦dJ¤bH¤bH¤bH\98\7\92V1\84M.yB#f6"\,\18M'\1eI#\1a=!\1e:\1e\e-\1e\e)\1a\17"\e\15!\1a\14\1e\1e\16\1f\1f\17\82VS\83WT\84YR\89^W\97p_­\86\97\81Á\9d\87¼\98\80Æ¢\8aÒ¯\9bÒ¯\9bº\96\88\9avh\87e[\89g]\9dwj¡{n©\83\8f\82\9cxj_;-U4%\89hY\8dp`\9d\80\86u\9c\81\8d|À¦\95é\98´\9a\89¿¥¦È®¯Ê®­½¡ ´\95\90µ\96\91¸\9a\92·\99\91¢\89\84¾¥ Å³±·¥£«¢¥º±´¾½Ã¹¸¾\9c\99¤\9f\9c§ª\9f¥¾³¹Ç¯­\92zxkI?mKA\96j]£wj¶\85\8c\8d\7fÂ\91\83Ë\9b\8fÕ¥\99Ö©\94Ø«\96Ù¯\99Þ´\9e߶¢à·£Þ¸¥Þ¸¥â½­ã¾®á½¯à¼®Üº®Ù·«Õµ¨Ó³¦Ø­\9dÖ«\9bÔ©\99Ó¨\98Ò§\97Ò§\97Ó¨\98Ô©\99Ö«\9bÔ©\99Ò§\97Ð¥\95Ì¡\91Ê\9f\8fÇ\9c\8cÆ\9b\8bÆ\8e\8c\8a\86\80mµ|i³yc±wa°r[¯qZ°pW­mT«iO©gM§eK¦dJ\9fZ;\99T5\8eM1\86E)x@'n6\1d[.\eS&\13E#\17?\1d\11/\18\10,\15\r'\18\15)\1a\17'\e\e&\1a\1a©\7f\80©\7f\80¨\7f\7f\87\8e\93\93\90\9a\81ʧ\93Ϋ\97¾\9a\8c¨\84v ~t§\85\83\86\8c\7f¼\96\89¨\84vrN@jI:\9ayj­\90\80®\91\81 \85t\92wf\9e\84s½£\92ɯ\9eÀ¦\95½£¤Æ¬­È¬«»\9f\9e´\95\90µ\96\91¹\9b\93¹\9b\93¾¥ ²\99\94©\97\95·¥£Á¸»Ãº½´³¹ª©¯\9a\97¢¶³¾Ã¸¾¹®´°\98\96\86nljH>iG=\9bob£wj®}n°\7f\7f\84\91\85Í\9d\91Õ¨\93Ö©\94Ø«\96Û®\99ܱ\9eൢḦ仩޹©Þ¹©Ý¹«Ý¹«Ø¶ªÖ´¨Ó±¥Ñ¯£Ø­\9d׬\9cÕª\9aÓ¨\98Ò§\97Ó¨\98Ó¨\98Ô©\99Ö«\9bÕª\9aÓ¨\98Ð¥\95Í¢\92Ê\9f\8fÈ\9d\8dÇ\9c\8cÇ\8f\8d\8b\87\81n¶}j´zd²xb²t]±s\±qX¯oV­kQªhN¨fL§eK\9fZ;\99T5\8eM1\87F*yA(p8\1f]0\1dU(\15F$\18?\1d\11/\18\10,\15\r'\18\15)\1a\17&\1a\1a&\1a\1aЩ¬Ï¨«Ï©¦Î¨¥Ê¦\9aÃ\9f\93¼\9c\87º\9a\85·\94\99\83Æ£\8fʧ\93À\9c\8c´\90\80·\93\87Ä \94¾\98\8b¾\98\8b¼\96\89Á\9b\8e²\8e\80\86bT|[L¤\83t½ \90µ\98\88¡\86u\95zi¥\8bzé\98˱ À¦\95»¡¢Äª«Æª©º\9e\9d³\94\8f\97\92»\9d\95¼\9e\96¿¦¡­\94\8f¬\9a\98˹·ÑÈ˼³¶£¢¨£¢¨ª§²ÍÊÕÌÁǤ\99\9f\90xvx`^rPFzXN§{n¨|o«zk¦uf¢qc¦ug±\81\8d\81Í\9e\8aÍ\9e\8aΡ\8cÒ¥\90Õª\97Û°\9d߶¤â¹§Ù²£Ú³¤Ú´§Ù³¦×³§Õ±¥Ñ¯£Ï­¡Ù®\9e׬\9cÕª\9aÔ©\99Ó¨\98Ó¨\98Ô©\99Õª\9aÖ«\9bÕª\9aÓ¨\98Ð¥\95Í¢\92Ë \90È\9d\8dÇ\9c\8cÉ\91\80Ç\8f\8d\89\83\7fl¶|f´zdµw`´v_´t[±qX®lR«iO©gM¨fL [<\9aU6\8fN2\88G+{C*r:!`3 Y,\19G%\19A\1f\130\19\11-\16\ e'\18\15)\1a\17&\1a\1a&\1a\1aÚ»ÁÙºÀܼ½Þ¾¿Ù»±Ð²¨Î¯\9dÒ³¡Ë«\96Ȩ\93˨\94ʧ\93À\9b\8b·\92\82½\97\8aʤ\97Ï©\9cͧ\9aÃ\9d\90À\9a\8d¸\94\86\97se\89hY¥\84\8b\88x\9f\84\89x»¡\90ϵ¤È®\9d³\99\88º ¡Â¨©Ä¨§·\9b\9a±\92\8d\97\92¼\9e\96¾ \98©\90\8b»¢\9dÒÀ¾ÞÌÊú½¦\9d \9f\9e¤²±·ÆÃÎÈÅа¥«\8b\80\86\84ljv^\\81_U\9czp¸\8c\7f\8a\83t«zk¢qc\9fn`¢rf¨xl»\8b\90\96\82Î\9e\8aÔ¥\93Ú«\99Ú¯\9eܱ Ø® Ù¯¡Ø°¤Ù±¥×±¦Ö°¥Ô®£Ó­¢Ù®\9eØ­\9dÖ«\9bÔ©\99Ô©\99Ô©\99Õª\9aÕª\9a׬\9cÖ«\9bÔ©\99Ѧ\96Σ\93Ë \90É\9e\8eÈ\9d\8dË\93\82É\91\80Æ\8f\8b\85\81n¸~h¶|f·yb¶xa¶v]²rY°nT¬jPªhN¨fL [<\9aU6\90O3\8aI-}E,v>%d7$]0\1dI'\e\142\e\13.\17\ f(\19\16)\1a\17&\1a\1a%\19\19Ù¿ÊÕ»ÆؽÂÞÃÈÚ¿¸Ðµ®Ó¸§Þòڻ¦Ò³\9eΫ\97ɦ\92¿\9a\8aµ\90\80»\93\87Ç\9f\93Ô®¡Ò¬\9fÃ\9d\90¾\98\8bÂ\9e\90¯\8b}\9e}n®\8d~\90sc\91td\96{jª\8f~Å«\9aÔº©É¯\9eµ\9b\8aº ¡Â¨©Â¦¥µ\99\98¯\90\8b´\95\90»\9d\95¾ \98²\99\94ÓºµßÍËȶ´¥\9c\9f¥\9c\9f³²¸ÂÁÇËÈÓ«¨³\8d\82\88\8d\82\88\9d\85\83\83ki\89g]®\8c\82Å\99\8cÄ\98\8bÄ\93\84»\8a{¯~p£rd\9aj^\97g[¬yfµ\82\8e\9c\89Ö¥\94Ú©\98Ú«\9bÙª\9a׫\9eج\9fÙ¯£Û±¥Ù±§Ø°¦×¯¥Ö®¤Ú¯\9fÙ®\9e׬\9cÕª\9aÔ©\99Õª\9aÕª\9aÖ«\9bØ­\9d׬\9cÕª\9aÒ§\97Ϥ\94Ì¡\91Ê\9f\8fÉ\9e\8eÎ\96\85Ì\94\83É\92\8d\88\84\80\7fi¸zc·yb¶v]²rY¯mS¬jP©gM§eK [<\9bV7\91P4\8cK/\80H/yA(h;(b5"K)\1dD"\163\1c\14.\17\ f(\19\16*\e\18&\1a\1a%\19\19ÙÄÓÒ½ÌÕÀÉÙÄÍѹµÀ¨¤Ã©\9cÒ¸«×¸¤Î¯\9bȨ\93Ĥ\8f¿\9a\88\91\7f»\94\85Æ\9f\90Ñ«\9eЪ\9dÀ\9a\8d½\97\8aΪ\9cȤ\96µ\94\85¸\97\88\8eqa\8co_\91ve¥\8ay¿¥\94ж¥Î´£Æ¬\9b¼¢£Ã©ªÂ¦¥³\97\96­\8e\89²\93\8eº\9c\94½\9f\97Õ¼·ÙÀ»Á¯­¡\8f\8d\9b\92\95º±´ÇÆÌÁÀƶ³¾\96\93\9e\8a\7f\85¤\99\9f¹¡\9f\8dus\84bXª\88\9d\90Ê\9e\91Í\9c\8dÇ\96\87»\8a|ªyk\9aj^\91aU\9fjX©tb·\82\92\80Ñ\9e\8dפ\93צ\97צ\97Ö¨\9bש\9cج¡Ú®£Û¯¦Û¯¦Ú¯¦Ù®¥Û° Ù®\9eØ­\9dÖ«\9bÕª\9aÕª\9aÖ«\9b׬\9cÙ®\9eØ­\9dÕª\9aÓ¨\98Ϥ\94Í¢\92Ê\9f\8fÉ\9e\8eÐ\98\87Î\96\85Ë\94\80Ç\90\8aw¿\86\83\81k¸zc¶xaµu\±qX®lRªhN¦dJ¥cI [<\9bV7\92Q5\8eM1\83K2}E,m@-f9&M+\1fF$\185\1e\16/\18\10)\1a\17*\e\18&\1a\1a$\18\18ØÇÚÑÀÓÖÄÐÚÈÔ̸·®\9a\99¬\94\88¸ \94Í°\9eŨ\96â\8f¡\8eÀ\99\88·\90\7fº\90\80Â\98\88Ñ«\9eÑ«\9e½\97\8a¹\93\86Ï«\9dΪ\9c\95\86­\8c}\96yi\95xh\9b\80\92\81Á§\96̲¡Î´£Í³¢¿¥¦Å«¬Ã§¦²\96\95«\8c\87¯\90\8b¸\9a\92»\9d\95Ø¿ºÄ«¦¨\96\94¥\93\91³ª­Ç¾Á¿¾Ä²±·¢\9fª¢\9fª¨\9d£±¦¬¯\97\95\82jh\7f]S¦\84\97\8aÄ\98\8bÉ\98\89Æ\95\86¾\8d\7f°\7fq pd\96fZ\92ZI\98`O¢jY¯wfº\85\91\81Í\99\8bÒ\9e\90Ò¢\96Ó£\97Õ¦\9cØ©\9fج£Ù­¤Ù­¤Ø¬£Û° Ú¯\9fØ­\9dÖ«\9bÖ«\9bÖ«\9b׬\9c׬\9cÙ®\9eØ­\9dÖ«\9bÓ¨\98Ð¥\95Σ\93Ë \90Ê\9f\8fÒ\9a\89Ð\98\87Í\96\82É\92\8c\88u¿\85\83m·ybµw`´t[¯oV¬jP§eK¤bH¢`F [<\9cW8\93R6\8fN2\85M4\7fG.pC0i<)N, G%\196\1f\170\19\11)\1a\17*\e\18&\1a\1a$\18\18ÓÆÚÎÁÕØÈÕßÏÜÍ»»§\95\95\9e\88\93\86Ê­\9bÂ¥\93Á \8dÁ \8d¿\98\87´\8d\8a\90\80Ô®¡Ó­ ¼\96\89´\8e\81Ç£\95Ç£\95§\86w\97vg\99|l\9d\80\8f~¿¤\93̲¡Í³¢É¯\9eƬ\9bÁ§¨Æ¬­Ã§¦²\96\95ª\8b\86®\8f\8a\98\90¹\9b\93¼£\9e«\92\8d©\97\95ȶ´ÒÉ̹¼¨§­¤£©\9e\9b¦¼¹ÄźÀ¬¡§\91ywnVT~\R«\89\7f¼\90\83¼\90\83Á\90\81À\8f\80¼\8b\81s¥ui\9dma\85M<\87O>\8cTC\96^M¢m]²}mÀ\8c\95\87Î\9c\91Ð\9e\93Ò¢\98Õ¥\9bר Ø©¡Öª¡Öª¡Ü±¡Ú¯\9fØ­\9d׬\9cÖ«\9bÖ«\9b׬\9cØ­\9dÙ®\9eØ­\9dÖ«\9bÓ¨\98Ð¥\95Σ\93Ë \90Ê\9f\8fÓ\9b\8aÑ\99\88Î\97\83Ê\93\7fÆ\8d\89\86\84n¶xa´v_³sZ®nUªhN¦dJ¢`F ^D [<\9cW8\94S7\90O3\86N5\81I0rE2k>+O-!G%\19\180\19\11)\1a\17*\e\18&\1a\1a$\18\18×ÆÐÑÀÊÖÁÆÜÇÌѽ¶¹¥\9e±\97\8a²\98\8bǪ\98æ\94Ê©\98Ñ°\9fÏ©\9e¿\99\8e½\95\8dÄ\9c\94×µ´Ø¶µÇ¦¡´\93\8e½\9d\8eʪ\9b¬\8dxz[F\9d\7f\89\97\82ä\8fÊ«\99Ê«\99Ʀ\99¢\95½¡\95¦\9a¿¤\99´\99\8e«\94\8c¯\98\90¯\9c\96­\9a\94§\99\98­\9f\9eÀ¶·ÐÆǾ¸¼¢\9c £\9e¤»¶¼¹´ÊÁ¼Ò¸ª¹\8e\80\8f~af\82ej\99nh\9drlÂ\89\88\84\80r¿|lºwg¶qb³n_\92YR\8dTM\86J@\82F<\8bM> bS¼\7f\93\81Í\94\83Ñ\98\87Ñ \92Ô£\95Ϥ\9dÐ¥\9eЫ¥Ó®¨Ø¨\9cק\9bÖ¦\9aÖ¦\9aÖ¦\9aק\9bÙ©\9dÚª\9eÖ¦\9aÖ¦\9aÖ¦\9aÖ¦\9aÔ¤\98Ò¢\96Ï\9f\93Î\9e\92Ñ\99\88Ï\97\86Ì\95\81Ç\90\8aw¿\86\82\81k¹{d¶xa³sZ­mT©gM¥cI¢`F¡_E\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$Z1\eP'\119\1f\101\17\b#\18\12$\19\13 \1c\e!\1d\1cÚÉÓÔÃÍØÃÈÜÇÌÕÁºÅ±ªÃ©\9cƬ\9fÈ«\99Á¤\92Æ¥\94ͬ\9bΨ\9dÁ\9b\90¼\94\8c¿\97\8fÔ²±Ù·¶Í¬§»\9a\95¢\93ѱ¢»\9c\87\92s^§\89\90\9b\86Ä¥\90Ê«\99Ê«\99ǧ\9aĤ\97¦\9aƪ\9eÁ¦\9b³\98\8d©\92\8a­\96\8e®\9b\95­\9a\94¶¨§É»ºÎÄż²³ \9a\9e\9e\98\9c±¬²ÆÁÇÇÂÖ«¦º\99\8b\9a\8d\7f\8e\8cot\82ej\99nh±\86\80º\81vµ|qµvg³te¶td¶td´pc°l_\97`[\90YT\87LD~C;\81C6\8fQD£fT³vdÄ\89\90\9b\8dÔ \92Ϥ\9bÐ¥\9cϨ¡Ò«¤×§\9bק\9bÖ¦\9aÖ¦\9aÖ¦\9aק\9bب\9cب\9cÓ£\97Ô¤\98Ó£\97Ò¢\96Ñ¡\95Ï\9f\93Í\9d\91Ì\9c\90Ï\97\86Í\95\84Ê\93\7fÆ\8f\89\84\81\7fi¸zc´v_±qXªjQ¦dJ¡_E\9e\B\9d[A\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$Z1\eQ(\129\1f\101\17\b#\18\12$\19\13 \1c\e \1c\eÝÌÖØÇÑÙÄÉÜÇÌÚƿѽ¶Ñ·ªÔº­È«\99À£\91Á \8fÊ©\98Ъ\9fÈ¢\97À\98\90¼\94\8cЮ­Û¹¸Õ´¯Å¤\9fǧ\98Ö¶§Í®\99´\95\80\98\80º\9c\84À¡\8cŦ\91ɪ\98Ê«\99É©\9cȨ\9bÅ©\9dÉ­¡Ã¨\9d\9b\90¯\98\90¸¡\99½ª¤¾«¥Ê¼»ÒÄÿµ¶\9e\94\95\96\90\94²¬°ÅÀÆþļµÇ\8f\88\9a\87w\84\9e\8e\9b¦\89\8d\88ko\9aoiÁ\96\90\80t«ui¢gY¡fX©k^¯qd¬na§i\\98ea\91^Z\8bRK\7fF?{@2\80E7\8eQ?\98[I´yg¿\84\93\83Ò\9d\8dÑ¢\98Ò£\99Í¥\9dΦ\9eצ\98צ\98צ\98צ\98צ\98צ\98צ\98צ\98Ò¡\93Ò¡\93Ð\9f\91Ï\9e\90Î\9d\8fÌ\9b\8dË\9a\8cÊ\99\8bÍ\95\84Ë\93\82È\91\8d\87\83\80\7fi·yb³u^¯oV¨hO£aG\9e\B\9bY?\99W=\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$\3\1dR)\13\112\18    #\18\12$\19\13 \1c\e \1c\eÛÊÔØÇÑÚÅÊÛÆËÙžѽ¶Í³¦È®¡Â¥\93»\9e\8c¼\9b\8aÄ£\92Ñ« Ðª\9fÇ\9f\97¾\96\8eά«Ý»ºÝ¼·Í¬§È¨\99Ô´¥Ö·¢Ì­\98ƨ\90ƨ\90Ƨ\92Ǩ\93È©\97Ê«\99Ë«\9e̬\9fÅ©\9dÉ­¡Åª\9f½¢\97»¤\9cɲªÔÁ»Øſ˽¼¹«ª\9d\93\94\98\8e\8f¯©­ÌÆÊÆÁÇ®©¯\99\93¡\87\81\8f\99\89\93¶¦°´\97\99\8bnp\96mg»\92\8c·\85z¦ti\98`S\95]P h[ªre¨od¢i^\9cji\99gf\95`\\8aUQ\86LA\84J?\8bM>\91SD¥jX²weÂ\8a\97\86Р\92Ñ¡\93Í¡\96΢\97×£\95×£\95×£\95ؤ\96×£\95Ö¢\94Õ¡\93Ô \92Ò\9e\90Ñ\9d\8fÏ\9b\8dÍ\99\8bË\97\89Ê\96\88Ê\96\88Ê\96\88Ë\93\82É\91\80Æ\8f\8c\87\83\80\7fi·yb´v_°pW©iP£aG\9e\B\9aX>\99W=\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$^5\1fT+\15<"\133\19
+$\19\13%\1a\14 \1c\e \1c\eÖÅÏ×ÆÐÛÆËÙÄÉÖ»ʶ¯½£\96­\93\86µ\98\86²\95\83µ\94\83¼\9b\8aË¥\9aЪ\9fÈ \98¼\94\8cÍ«ªÞ¼»áÀ»Ñ°«Æ¦\97Í­\9eÔµ Ôµ Ñ³\9bϱ\99Ì­\98Ê«\96ɪ\98Ê«\99Í­ Î®¡Ç«\9fÌ°¤È­¢¿¤\99½¦\9e̵­ÖýÚÇÁ´¦¥¡\93\92\9b\91\92´ª«Å¿Ã¾¸¼«¦¬¢\9d£\93\8b\96¦\9e©¾¯´·¨­\9e\82\7f\80da\8fi`§\81x«{o\9aj^\8bWJ\8bWJ\99g\¨vk«yp©wnª|~ª|~©xt ok\9bbY\91XO\8fTD\8fTD\9b^KªmZ»\82\92\7fÏ\9c\8bÑ\9e\8dÎ\9e\90Î\9e\90Ó\9e\8cÔ\9f\8dÕ \8eÖ¡\8fÕ \8eÓ\9e\8cÐ\9b\89Î\99\87Ï\9a\88Î\99\87Ë\96\84È\93\81Æ\91\7fÆ\91\7fÇ\92\80È\93\81È\90\7fÆ\8e\8d\89\85\82\7fi¸~h¸zcµw`±qXªjQ¥cI ^D\9d[A\9cZ@\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$`7!V-\17=#\144\1a\v%\1a\14%\1a\14 \1c\e\1f\e\1aÔÃÍØÇÑÜÇÌØÃÈÕÁºË·°¸\9e\91 \86\91\7f±\94\82\95\84¸\97\86Ä\9e\93ʤ\99Å\9d\95¹\91\89Ë©¨Û¹¸áÀ»Ó²­Å¥\96ǧ\98Ï°\9bÓ´\9fÖ¸ Ô¶\9eб\9cÌ­\98ˬ\9aˬ\9aÍ­ Î®¡Ì°¤Ð´¨Ê¯¤½¢\97\9f\97¿¨ Ä±«Å²¬£\95\94§\99\98¹¯°ÍÃÄ»µ¹\9a\94\98\96\91\97¬§­²¨°Ç½Åɹ¼\9d\8d\90|`\tXT\87bY\91lc\8b_R\7fSFwG;|L@\8d^V qi©|v­\80\8c\90¹\8f\93¾\8e\8e\86\86¬un\9ce^\93XJ\8dRD\95XE¤gT¶|hÆ\8c\95\84Ñ\99\88Î\9d\8cÎ\9d\8cÐ\99\85Ò\9b\87Ó\9c\88Ô\9d\89Ó\9c\88Ï\98\84Ì\95\81É\92\93\7fÇ\90\8d\89u¿\88t¿\88\8a\8b\88w¿\87\86\83\7flµ|i´zd²xb¶xa³u^°pWªjQ¦dJ¢`F ^D\9f]C\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$a8"W.\18?%\165\e\f%\1a\14%\1a\14 \1c\e\1f\e\1aÖÅÏÛÊÔÝÈÍØÃÈÚÆ¿Ö»ǭ ®\94\87¸\9b\89Á¤\92ȧ\96â\91Æ \95Ë¥\9aÇ\9f\97¼\94\8cȦ¥Ö´³Ý¼·Ô³®È¨\99ǧ\98Í®\99Ò³\9e×¹¡Õ·\9fÒ³\9eί\9aÍ®\9cÍ®\9cÍ­ Î®¡Ì°¤Ñµ©Ë°¥¾£\98´\9d\95¸¡\99¹¦ ·¤\9e¶¨§¾°¯Á·¸¹¯°¤\9e¢\9b\95\99¨£©½¸¾Ç¾ÃÀ·¼©\99\99\83ssw^Y{b]\85`W}XOpF:j@4e9.i=2uJC\87\U\93jd\9brl±\88\8e·\8e\94À\94\95½\91\92·\82|¤oi\99^P\91VH\94WD¢eRµxcÄ\87\91\96\82Ð\9b\89Ò\9d\8bÌ\93\80Î\95\82Ð\97\84Ñ\98\85Ð\97\84Ë\92\7fÇ\8e\8a\88\85\80mµ|i´{hµ|i·~k¹\80m¶~mµ}l³|h°ye¯vc¬s`«q[ªpZ°r[®pY«kR§gN¤bH¢`F ^D ^D\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$c:$X/\19@&\176\1c\r&\e\15%\1a\14 \1c\e\1f\e\1aÚÉÓÞÍ×ÞÉÎØÃÈÞÊÃâÎÇÙ¿²Â¨\9bÈ«\99Õ¸¦Ü»ªÒ± Î¨\9dЪ\9fÍ¥\9dÃ\9b\93Ƥ£Ò°¯Ú¹´Ô³®Ì¬\9dʪ\9bί\9aÓ´\9fÖ¸ Õ·\9fÓ´\9fб\9cί\9dÍ®\9cÍ­ Í­ Ê®¢Ï³§Ì±¦À¥\9a¸¡\99»¤\9c¼©£¹¦ ÖÈÇÍ¿¾®¤¥\91\87\88\97\91\95¹³·ËÆÌÆÁÇÆ»¿¤\99\9d\84ttzjj\8brk\8fvo\86bVpL@f<0b8,]3']3'a82mD>yTN\82]W x\80ª\82\8aº\8d\90½\90\93¹\87\80©wp fX\98^P\95XE¡dQ³vaÂ\85\8f\95\81Ò\9b\87Ô\9d\89Ê\90\92\95\81Ð\96\82Î\94\80É\8f\8a\86\80l·}i²xd­s_¬r^­s_°vb²xd¯wf®ve«t`©r^¨o\¥lY¤jT£iS«mV©kT§gN¤dK¢`F ^D\9f]C\9f]C\96Y<\92U8\8fR3\8cO0\8aO/\86K+yF)tA$d;%Y0\1aA'\186\1c\r&\e\15%\1a\14 \1c\e\1f\e\1aÏÂÌØËÕÞÏÖÙÊÑØÅÉÖÃÇѹ·Å­«Õº³àžܿ±Çª\9cŤ\93Ï®\9dͪ\96»\98\84º\8a\86Ì\9c\98Ö­§Õ¬¦Ç§\9cƦ\9bɯ Ïµ¦Ë¶£Í¸¥Ï¹¤Ì¶¡Í±\9bͱ\9bÓ³\9eÖ¶¡×·ªË«\9eĬ¢É±§¹ª§¬\9d\9a¹°µØÏÔ¿¼Ã\92\8f\96~{\82\9b\98\9f½·»½·»¸¯²»²µ­£¤\8a\80\81\8f|x´¡\9dȦ\9a¥\83w\95gW\99k[\8d^N\82SCrJ@pH>cEE\>>ZAGbIOsYX\87ml¦\80\8b\88\81y¬wo®l^¬j\¥]N­eV·vdÅ\84\91\80Ñ\98\87Í\9c\8bÍ\9c\8bË\99\96\92\91\8f\8a\80h»ya¶ua¯nZ£fS\9eaN\98dN\9afP\96fP\95eO\8dcS\8edT\8eeS\8eeS\8ecP\8caN\8c_J\8b^I\95eO\95eO\96dM\94bK\92^F\90\D\8f\A\8e[@\8aS>\89R=\87O8\82J3|F*v@$l=\1fi:\1c[8\1aT1\13?)\115\1f\a$\1d
+#\1c     \1f \10!"\12ÐÃÍ×ÊÔÛÌÓØÉÐÚÇËØÅÉÏ·µ¾¦¤¿¤\9dѶ¯Ø»­Ë® É¨\97έ\9cɦ\92·\94\80³\83\7fÇ\97\93Ô«¥Õ¬¦Ç§\9cĤ\99ɯ Ò¸©Í¸¥Î¹¦Ðº¥Í·¢Í±\9bͱ\9bÓ³\9e×·¢Ø¸«Ò²¥Ä¬¢Á©\9fô±ÏÀ½ÍÄÉÈ¿Ä\96\93\9a\8a\87\8e\94\91\98´±¸ËÅÉ¿¹½ª¡¤\9e\95\98\9b\8f\91¡\95\97²\9d\9a¹¤¡À\9e\92´\92\86³\85\80p¢sc\95fV\86[R\81VMpPQgGHcJPjQWoUT\7fed\9atq¡{x§rj kc¦dV¦dV©aR±iZºygÇ\86\91\80Ï\96\85É\98\87É\98\87Ë\99\96\90\8e\8b\85l¾|f·u_­lX¥dP\96\H\8fUA\87T?\86S>\80S>~Q<tNAuOBvQAxSCzSBzSB|SA|SA\82WD\83XE\87XD\88YE\89YC\89YC\89YB\89YB\89R=\89R=\88R:\84N6~H,xB&l=\1fi:\1c[8\1cT1\15@*\125\1f\a%\1c
+%\1c
+!\1f\12#!\14ÒÅÏÕÈÒ×ÈÏÖÇÎÝÊÎÛÈÌÌ´²µ\9d\9b£\88\81½¢\9bг¥Í°¢Ëª\99˪\99Ä¡\8d´\91}¬|xÃ\93\8fÕ¬¦Ù°ªÈ¨\9dÁ¡\96È®\9fÖ¼­Í¸¥Ïº§Ðº¥Í·¢Í±\9bÌ°\9aÒ²\9dÕµ Ò²¥×·ªÌ´ªÆ®¤ÒÃÀåÖÓÊÁÆ¡\98\9d|y\80\99\96\9dº·¾ÅÂɺ´¸¥\9f£\9c\93\96\9a\91\94\99\8d\8f¾²´Ò½º¸£ ¶\92\86Ã\9f\93Î\9f\8f¿\90\80·\86w©xi\96kb\8fd[}[\sQRmRYtY`u[Z~dc\91kh\93mj\9ae]\95`X ^P¢`R¬dU´l]½|jÉ\88\92\81Î\95\84Ç\96\85Æ\95\84Ì\97\93\8d\8a\85l¼~eµt`­lX\9e_M\95VD\84M9{D0o@,l=)c:$`7!V5,W6-X8-[;0_=1a?3d@2eA3jE5lG7pI8sL;zO>{P?}R?}R?\80M8\82O:\84P:\83O9~K0wD)l?"h;\1e\7\1dU0\16C*\14
+)\1d\r(\1c\f#\1f\14\15ÔÇÑÔÇÑÔÅÌÕÆÍßÌÐÞËÏ˳±±\99\97\95zs®\93\8cŨ\9aÈ«\9dÆ¥\94Ť\93À\9d\89\93\7f­}yÃ\93\8fد©à·±Í­¢À \95Å«\9cؾ¯Ë¶£Ì·¤Í·¢Ê´\9fÊ®\98Ȭ\96ή\99ѱ\9cÍ­ ×·ª×¿µØÀ¶ÖÇÄÐÁ¾© ¥\84{\80\93\90\97¸µ¼ÍÊѶ³º\93\8d\91\8a\84\88¡\98\9b¸¯²´¤§Ë»¾Íµ³¯\97\95²\8c\81Ç¡\96Ó¢\93Á\90\81À\8c~±}o\9cpg\94h_\84`b{WYwYa\7fai\89on\8crq\95ol\91kh\95`X\91\T\9d[M ^PªbS³k\½|jÊ\89\94\83Ð\97\86É\98\87Ç\96\85Ì\94\90\8a\85j¼~i³u`¨iW aO\8dR@\84I7s@-j7$]4 Z1\1dR/\eO,\18E*#E*#F)!H+#K-%N0(R1(T3*W5)Z8,`<.eA3jE5kF6lE6lE6pA-sD0xH2zJ4zH/vD+m?%i;![5\1eV0\19E*\17<!\ e.\1e\11,\1c\ f&\1d\16'\1e\17ÕÈÒÔÇÑÓÄËÔÅÌßÌÐßÌÐζ´´\9c\9a\9c\81\91\8a¼\9f\91¾¡\93¿\9e\8d¿\9e\8d¾\9b\87º\97\83²\82\94\90Ù°ªæ½·Ó³¨Á¡\96¨\99Õ»¬É´¡Êµ¢Ê´\9fDZ\9cƪ\94Ĩ\92É©\94Í­\98Ö¶©Õµ¨×¿µÝŻƷ´ª\9b\98\98\8f\94\9c\93\98¿¼Ã¾»Â¯¬³\96\93\9a\90\8a\8e \9a\9e¹°³Å¼¿Ì¹½¸¥©¨\8c\8b¢\86\85¹\91\87É¡\97Ð\9c\8eÄ\90\82¿\8a|±|n oh\9aib\8ceh\87`c\85fn\8fpx\9d\83\82\9b\81\80\9exu\94nk\95`X\90[S\99WI\9aXJ¥]N¯gX»zhË\8a\97\86Ô\9b\8aÍ\9c\8bË\9a\89Ë\93\8e\85p»~i´uc©jX\9c_M\92UC\7fF5w>-f7%_0\1eU2\1eT1\1dM1\1cJ.\19G,%F+$E( E( G)!H*"M,#O.%S1%V4(]9+a=/d?/c>.c<-a:+`5"d9&k<(o@,rB+qA*m?'j<$[5 V0\eG*\1c?"\141\1f\15.\1c\12)\e\18)\e\18ÕÈÒÖÉÓÖÇÎÕÆÍÝÊÎÞËÏÓ»¹¿§¥±\96\8f³\98\91·\9a\8c¸\9b\8d¼\9b\8a¼\9b\8a¼\99\85¹\96\82²\82\8d\89Ѩ¢å¼¶Ù¹®Æ¦\9b¨\99Ñ·¨É´¡Êµ¢Ê´\9fÆ°\9bÅ©\93ç\91Ȩ\93Ë«\96âµӳ¦Ë³©Íµ«´¥¢\9f\90\8d© ¥ÉÀÅÉÆͤ¡¨\85\82\89\8d\8a\91µ¯³ÌÆÊż¿±¨«Ç²·\9e\89\8e\8doo \82\82Æ\9b\92Í¢\99Ð\9b\8dÍ\98\8aÁ\89|³{n¢pi\9fmf\94ko\93jn\94s| \7f\88¦\8c\8b¢\88\87£}z\99sp\99d\\91\T\96TF\93QC£[L®fW¼{iÍ\8c\9a\89Ö\9d\8cÏ\9e\8dÍ\9c\8bÌ\92\8bu¿\82o¶yf­n] aP\91SD\87I:r=-k6&Z1\1fV-\eP1\1dR3\1fL6!J4\1fP/&O.%L,!K+ L*\1eN, T0"W3%\7'`;+f?.jC2nC2lA0h=*f;(]4"_6$b7$d9&h;&i<'h;&h;&]4"X/\1dJ*\1fC#\186\1e\1a2\1a\16-\e\e,\1a\1aÔÇÑØËÕÙÊÑÕÆÍÚÇËÜÉÍÙÁ¿Ì´²Ç¬¥½¢\9b¸\9b\8d¹\9c\8e¿\9e\8d½\9c\8b¸\95\81²\8f{«{w¯\7f\99\93߶°Ý½²Êª\9fé\9aϵ¦Í¸¥Î¹¦Î¸£Ê´\9fȬ\96ƪ\94Ë«\96ή\99Ù¹¬Ï¯¢À¨\9e¾¦\9c¶§¤¸©¦½´¹Æ½Â¥¢©\8c\89\90\89\86\8d©¦­ÊÄÈÆÀIJ©¬£\9a\9d¯\98\9e\9b\84\8a\9c|}¯\8f\90Í¡\98Ï£\9aÓ\9b\8eÒ\9a\8dÁ\87{³ym¤oi¡lf\97mq\98nr\9cx\82©\85\8f§\8d\8c¤\8a\89§\81~ zw£nf\99d\\9aXJ\94RD¦^O±iZ¾}kÏ\8e\9b\8aÕ\9c\8bÌ\9b\8aÉ\98\87Í\90\89\80n²uc¦hY\98ZK\87L>|A3i5'c/!R+\1aO(\17I.\eL1\1eF5!E4 U/"S- Q,\1cQ,\1cT-\1cX1 _6$c:(k@-oD1xI5}N:\80P:~N8zJ3wG0c>,b=+b9'`7%b5 c6!c6!e8#\2"Y/\1fL* F$\1a\1c4\e\17.\1a\1c-\19\eÔÇÑÚÍ×ÜÍÔÖÇÎ×ÄÈÛÈÌÝÅÃÕ½»Ô¹²Ä©¢º\9d\8f¼\9f\91Ä£\92À\9f\8eµ\92\87s£so£so¶\8d\87Ù°ªÞ¾³Î®£Äª\9bͳ¤Ñ¼©Ò½ªÒ¼§Í·¢Ì°\9aÉ­\97ή\99ѱ\9cƦ\99ʪ\9d½¥\9b¹¡\97ĵ²×ÈŹ¾¡\98\9d~{\82\89\86\8d«¨¯ËÈÏÁ»¿\9c\96\9a\95\8c\8f¨\9f¢\9c\85\8b¦\8f\95º\9a\9bÁ¡¢Î¢\99Í¡\98Ò\9a\8dÎ\96\89¿\83x±uj¡lf\9eic\94jn\95ko\9av\80¨\84\8e¨\8e\8d¦\8c\8b¬\86\83¨\82\7f®yq¤og¢`R\99WIªbSµm^Â\81\90\9a\89Ó\9a\89É\98\87Å\94\83Ì\8f\89w»~l°sa£eV\94VG\82G9x=/b1#\+\1dM(\18J%\15D+\17G.\1aA2\1d@1\1cU+\eS)\19S*\18S*\18X-\1a_4!h;&l?*vF0{K5\84R;\8aXA\8f[C\8eZB\8aW<\87T9lH8iE5d=,^7&]2\1f]2\1f_2\1fb5"\2"Y/\1fM+"F$\e;\1f\1e7\e\1a/\19\1c-\17\1aÙÍÏÙÍÏÚËÐÙÊÏÙÅÎÖÂËÖ½ÃÔ»Á¬\8f\91¦\89\8b¼\9e\94Ú¼²×·¢´\94\7f©\87\97\86~©tl°~uÓ¡\98ß°¦Ò£\99̤\98ݵ©Ü¼­ß¿°Ü±׽¬Í¸¥Ç²\9fñ\9dIJ\9eÕµ¨Â¢\95·\9f\95ζ¬ÝÎËÑ¿¡\98\9d|sx\88\85\8cª§®ÄÁȶ³º\97\91\95\8a\84\88¡\98\9b»²µ¸±§º³©Ì­¨È©¤Ö\9d\96Ô\9b\94Û\9d\92Ý\9f\94Á\8e\86u«zk o`¢c\¡b[­]`¯_b®ne´tk»{r¿\7f\80v·{q­sh§mb¬shµ|qÁ\8b\7fÎ\98\8cÔ \93Ô \93Ï\9b\8eË\97\8aÑ\8c\83s·xf©jX\94`K\85Q<nD.d:$X2\1fU/\1cQ*\19M&\15N$\16O%\17S'\1aV*\1dU1\19O+\13T+\19^5#i9/m=3yD>\85PJ\80J@\81KA\85P@\8eYI\93aH\93aH\8e]=\8aY9\85V<\82S9}K4uC,k8%b/\1cY*\1aU&\16Q*\eQ*\eG- D*\1d6)\19/"\12$\1e\10 \1a\fÙÍÏÙÍÏÛÌÑÚËÐÚÆÏ×ÃÌØ¿Åֽë\8e\90\9f\82\84®\90\86в¨Ù¹¤À \8b³\91\9a\8a\81§ulªxoÈ\96\8dÑ¥\9aÇ\9b\90Æ\9e\92Ø°¤×¶§Ûº«Ù¾­×¼«Ï¸¦Ê³¡É´¡É´¡Ð°£Æ¦\99Æ®¤ÙÁ·Ì½º«\9c\99\8f\86\8b\8d\84\89\9b\98\9f´±¸«¨¯\85\82\89\85\7f\83¯©­ËÂŹ¼Ëĺü²Ê«¦Æ§¢Ù \99Ú¡\9aÜ\9e\93Ø\9a\8fÆ\93\82¿\8c\82r¥vf¤h`\9fc[©Z]¨Y\¨h_«kb°pgµul¶zp¸|r·}r·}r·~s¿\86\94\88Õ\9f\93ؤ\97Õ¡\94Ï\9b\8eÊ\96\89Í\88\7fo²sa£dR\8eZE\7fK6i?)_5\1fS-\1aQ+\18O(\17N'\16Q'\19T*\1cW+\1eZ.!\8"^:$lE4~WF\88\S\83WN\83RM\86UP\8cZQ\89WN\88TF\89UG\8d[D\8f]F\8e]?\8d\>\86W=\83T:}M6uE.n;(e2\1f[,\1cW(\18L%\16M&\17D(\1cC'\e7'\182"\13\13%\1d\10ÚÎÐÚÎÐÜÍÒÛÌÑÜÈÑÙÅÎÚÁÇØ¿Å°\93\95\9d\80\82¥\87}Ç©\9fÛ»¦Ì¬\97À\9e\82 \84Å\95\8b®~tª{qÁ\92\88Ë\9f\94Ä\98\8dÂ\9c\8fÒ¬\9fÑ°¡Öµ¦×ºª×ºªÒ¸§Î´£Ë´¢Ìµ£Ì¬\9fȨ\9bʲ¨Ð¸®¯ \9d\8d~{\8e\85\8a¬£¨\9f\9c£\9e\9b¢\8c\89\90\7f|\83\99\93\97¼ÀÎÅÈ»²µËÁ¸½³ªÀ\9d\99À\9d\99Ú\9f\99à¥\9fß¡\96Ø\9a\8fÎ\9b\8aÈ\95\84»\8d\82r¬qi£h`¦\]£YZ `W¡aX¤d[ªja®rh·{q¾\84\89\8a\7fÊ\91\86Ó\9d\91ܦ\9aܨ\9b×£\96Ï\9b\8eÉ\95\88É\84t¿zj«lZ\9b\J\86R=wC.c9#Y/\19N(\15O)\16P)\18R+\1aW-\1fY/!\0#^2%`;)e@.wQD\8dgZ\98ph\95me\92ic\94ke\9bnh\92e_\89[N\83UH\85UA\87WC\89Z@\8a[A\83W<\81U:~P8wI1p@,g7#_0 [,\1cI"\13J#\14B$\19A#\188&\184"\14,"\16)\1f\13ÙÍÏÚÎÐÜÍÒÛÌÑÜÈÑÚÆÏÛÂÈÚÁǽ ¢¬\8f\91¯\91\87Ȫ Ù¹¤Ï¯\9aȦ\8aË©\8d΢\97¹\8d\82µ\89\9b\90Ш\9cÉ¡\95Å\9f\92ͧ\9aÏ®\9fÔ³¤Ù¹ªÙ¹ªÓ¶¦Ï²¢Ì± Ì± Ë«\9eȨ\9b½¥\9b³\9b\91\9f\90\8d\9d\8e\8b¦\9d¢¸¯´\8d\8a\91zw~\86\83\8a²¯¶Ä¾Â¬¦ª \97\9a© £­\9e\97¦\97\90´\8e\8b»\95\92×\9a\95à£\9eâ¢\98Þ\9e\94Ñ \8fÎ\9d\8cÃ\98\87»\90\7f·\81w­wm°hi«cd¢bY¢bY¥e\ªja­qgµyo¼\82\87\8f\84Ï\96\8bס\95ß©\9dÞª\9dؤ\97Ï\9b\8eÉ\95\88Æ\81qºue¥fT\93TB~J5q=(_5\1fW-\17O)\16R,\19V/\1eZ3"^4&^4&^2%]1$[5(\6)gB9|WN\89fb\8flh\96tr ~|\9bxr\91nh\88`V~VL\80RB\7fQA\81Q;\80P:}T8|S7|P7wK2rC/j;'d5%`1!N$\16N$\16E%\1aC#\187$\164!\13\15,\1e\13×ËÍØÌÎÚËÐÚËÐÜÈÑÚÆÏÜÃÉÚÁÇ̯±¿¢¤À¢\98Ë­£Ò²\9dÉ©\94ɧ\8bѯ\93Ш\9c¿\97\8b¼\94\88Í¥\99ز¥Ðª\9dÅ\9f\92Ä\9e\91Ò® ×³¥Ûº«Ú¹ªÔ´¥Î®\9fʪ\9bȨ\99Ȩ\9bÉ©\9c\9e\94©\91\87¯ \9dŶ³´«°\94\8b\90\82\7f\86\85\82\89£ §ÄÁÈ»µ¹\92\8c\90\8e\85\88§\9e¡\97\86\7f\9e\8d\86¸\8f\8dÁ\98\96Ø\99\94Ü\9d\98à \96á¡\97Ó¢\91Ñ \8fÉ \8eÅ\9c\8aÆ\92\87¾\8a\7fÁ}|½yx´tk¶vm¸xo¹yp¹}s»\7f\82\82\8f\84Ï\96\8bס\95Þ¨\9cÞª\9dؤ\97Ï\9b\8eÉ\95\88Â}mµp`\9f`N\8dN<xD/m9$^4\1eX.\18U/\1cY3 _8'd=,g=/d:,_3&\0#U.'U.'[:5nMHw[X{_\~fd\88pn\8aqm\83jf\80]WxUO{OBvJ=tC4o>/pK.qL/tL2rJ0rE0l?*f8(c5%V,\1eT*\1cJ(\1eE#\199!\155\1d\11/\1d\13-\e\11ÔÈÊÕÉËØÉÎØÉÎÚÆÏØÄÍÚÁÇÙÀÆÒµ·Æ©«Â¤\9aĦ\9cȨ\93Ĥ\8fɧ\8bѯ\93Ï«\9dÀ\9c\8e¼\98\8a˧\99׳¥Ð¬\9eÂ\9e\90¹\95\87Ь\9eÖ²¤Ü¸ªÜ¸ªÖ²¤Ï«\9dʦ\98Ȥ\96Ʀ\99Ë«\9eÁ©\9f¿§\9dɺ·ÏÀ½£\9a\9flch\8e\8b\92¯¬³º·¾\9c\99 \8b\85\89\98\92\96¯¦©´«®£\8e\89­\98\93È\9a\9aÍ\9f\9fÚ\99\95Ù\98\94Ü\9c\92ß\9f\95Ò¡\90Ò¡\90ʤ\91È¢\8fÌ\9c\90È\98\8cÏ\8f\8dÍ\8d\8bË\8b\82Ë\8b\82Ê\8a\81É\89\80Ä\88\87\88\87\91\86Ñ\98\8dØ¢\96Þ¨\9cÞª\9dÖ¢\95Í\99\8cÆ\92\85¼wg®iY\96WE\85F4r>)i5 ]3\1dY/\19X2\1f_9&hA0oH7qG9kA3d8+^2%Z20]53dECuVTq[]gQS\LM\LMsa_n\ZoSOkOKpH@iA9h6+a/$`? cB#hE)kH,nD.kA+i;+e7'\2$Y/!P+"J%\1c>"\17:\1e\134\1d\153\1c\14ÑÅÇÒÆÈÕÆËÕÆËØÄÍÖÂËÙÀÆØ¿ÅË®°¹\9c\9e­\8f\85°\92\88¾\9e\89Å¥\90ʨ\8c̪\8eÒ±¢Â¡\92¹\98\89â\93Я Î­\9eÃ\9f\91¸\94\86ʦ\98Ñ­\9fÚ´§Ü¶©Ø²¥Ò¬\9fͧ\9aË¥\98ϯ¢Ì¬\9f͵«ØÀ¶È¹¶ª\9b\98\87~\83zqv\9c\99 ¯¬³¢\9f¦\7f|\83\87\81\85³­±Ç¾Á·®±¿¦¢½¤ Ë\9b\9bË\9b\9bÛ\97\94Þ\9a\97ß\9c\93ß\9c\93Ñ¢\90С\8fÈ£\90Ç¢\8fÌ\9e\91Ì\9e\91Ó\98\94Ó\98\94Õ\95\8cÑ\91\88Ë\8b\82Æ\86\86\88\8d\82Ê\90\85Ò\99\8eØ\9f\94ݧ\9bá«\9fÞª\9dÔ \93É\95\88Á\8d\80³n^¥`P\8cM;|=+j6!d0\eZ0\1aX.\18X2\1f`:'mF5vO>zPBuK=mA4f:-lEFjCDkMOtVXgWXYIJJABI@A]QQYMM\DBYA?b;6^72_-&Z(!P3\13U8\18^< dB&kB,jA+j<,g9)]1$Z.!Q+"L&\1dB$\1a@"\18;"\e;"\eÏÃÅÐÄÆÓÄÉÔÅÊÖÂËÕÁÊ×¾ÄÖ½ÃÂ¥§©\8c\8e\97yo\9e\80\99\84É©\94̪\8eÇ¥\89Ù¹ªÇ§\98º\99\8aÀ\9f\90ͬ\9dЯ È¤\96¾\9a\8cÄ \92̨\9a×±¤Ûµ¨Ú²¦Õ­¡Ñ©\9dШ\9cÚº­Ë«\9eи®áÉ¿¶§¤|mjxot§\9e£\9f\9c£\88\85\8cxu|\86\83\8a®¨¬ÇÁÅÁ¸»­¤§Îµ±¿¦¢Ã\91\92À\8e\8fÙ\93\91â\9c\9aã \97ß\9c\93Ñ¢\90Ï \8eÇ¢\8fÅ \8dÈ\9c\8fÉ\9d\90Ô\99\95Õ\9a\96Ò\92\89Ë\8b\82Á\81x»{r·{q¿\83\8f\84Ð\96\8bÚ¡\96à§\9c㭡寣߫\9eÓ\9f\92Æ\92\85¾\8a}¬gW\9eYI\85F4u6$d0\ea-\18X.\18W-\17U/\1c_9&nG6zSB\80VH|RDtH;l@3}VYsLOeHLeHLWHKPADJFGRNORIJMDEO:9K65V0-V0-[($Y&"H+\vN1\11V7\1a_@#gA*gA*h=,e:)\0#Y- Q+"L&\1dF%\1cF%\1cC(!C(!ØÄÆØÄÆ×ÄÈ×ÄÈÔÅÌÔÅÌÔÅÌÔÅÌϺ¿§\92\97\8ank\8cpm²\8c\83ʤ\9bФ\97Ê\9e\91د\9dͤ\92¾\94\86¼\92\84É¡\99Ö®¦Ì¥\9e¹\92\8bƤ\98̪\9eÒ³\9fÔµ¡Ò´\98ϱ\95˱\8e̲\8fÀ® ×Å·ÙÈÀ´£\9b\8d}~\89yz\97\87\92¢\92\9d\8a|\8brds\82v\84½±¿ÖÌ×»±¼¢\9b¢¦\9f¦Î³¬Ã¨¡È\97\92È\97\92ß\98\92ã\9c\96à\9a\8eÙ\93\87Ò\9e\89Ò\9e\89Ë¡\8bÊ \8aÏ\9b\8dÌ\98\8aÔ\91\8bÒ\8f\89É\84\83\81\81u¿\86\7fÄ\8b\84Ä\93\8eÈ\97\92Ù¬¦Ú­§Ü°¥Ý±¦Û¬\9aÎ\9f\8d¾\8bv°}h\9ceQ\8aS?qA+g7!d:"f<$a<"]8\1ed?%c>$pF.\82X@\90`J\8c\F\8eWC\8fXD\96cP\8f\I|VKrLA`LMaMNYS]\V`iis]]gQKM?9;>+$:' A'\18C)\1a6!\f:%\10E*\15L1\1cX4$[7'`6*a7+a2*_0(Z.%V*!O) M'\1eI'\1dJ(\1eØÄÆØÄÆ×ÄÈ×ÄÈÔÅÌÔÅÌÔÅÌÔÅÌÌ·¼³\9e£¢\86\83£\87\84¼\96\8dË¥\9cÏ£\96Ë\9f\92×®\9cϦ\94Â\98\8a¼\92\84Ä\9c\94Ш Ë¤\9d½\96\8fÅ£\97ʨ\9cб\9dÓ´ Ñ³\97ΰ\94˱\8e˱\8eǵ§Ë¹«¼«££\92\8a\9a\8a\8b£\93\94\9d\8d\98\8az\85pbq\91\83\92²¦´º®¼§\9d¨\97\8d\98\9b\94\9b«¤«¼¡\9a·\9c\95Á\90\8bÄ\93\8eÛ\94\8eß\98\92ß\99\8dÜ\96\8aÓ\9f\8aÓ\9f\8aË¡\8bÉ\9f\89Ì\98\8aÈ\94\86Ï\8c\86Ì\89\83È\83\83\82\83\8a\83Ê\91\8aË\9a\95Ï\9e\99Ù¬¦Û®¨ß°¦ß°¦Ú©\98Ê\99\88¸\85p©va\96_K\87P<q>)h5 f9"h;$b=#_: d?%c>$rE.\86YB\96cN\94aL\95^J\97`L\9djW\97dQ\86^T}UKlWVmXWh^fkaipmvdajWNQE<?@-&9&\1f>$\15?%\169$\ f<'\12D)\16J/\1cU1#Y5'_5)`6*`1'^/%Z.%W+"Q+ P*\1fL*\1eL*\1e×ÃÅ×ÃÅÖÃÇÖÃÇÓÄËÓÄËÓÄËÓÄËϺ¿Å°µ¿£ ¼ \9dʤ\9bÑ«¢Ô¨\9bФ\97Óª\98Ѩ\96Æ\9c\8e»\91\83º\92\8aÄ\9c\94Æ\9f\98Á\9a\93 \94Ȧ\9aί\9bÒ³\9fв\96ΰ\94˱\8e̲\8fÍ»­º¨\9a¢\91\89\9f\8e\86®\9e\9fµ¥¦\9a\8a\95vfqwix¬\9e­Â¶Ä\9f\93¡\81w\82\90\86\91ª£ª´­´©\8e\87ª\8f\88¼\8b\86À\8f\8aÕ\8e\88Ù\92\8cÝ\97\8bÝ\97\8bÓ\9f\8aÓ\9f\8aÊ \8aÈ\9e\88Ê\96\88Æ\92\84Ì\89\83Ê\87\81É\87\87\87\89\90\89Ï\98\91Ñ¢\9cÖ§¡Ü¯©Ý°ªà±§Þ¯¥Ù¦\95Æ\93\82²{g¡jV\8eUB\82I6p<'j6!f9"i<%f>%c;"h@'g?&tG0\88[D\9afQ\9bgR\9ddQ gT£p_\9ekZ\91f]\8caX\7fcb\82fe~ms\82qw~syrgmcUUPBBE1*<(!>"\16=!\15<'\16=(\17B'\16E*\19O+\1dT0"\2&^4(\-#\-#Y-"X,!S- S- O.\1fO.\1f×ÃÅ×ÃÅÖÃÇÖÃÇÓÄËÓÄËÓÄËÓÄËÔ¿Äι¾Ç«¨À¤¡Í§\9e×±¨Ú®¡Ó§\9aÌ£\91Ϧ\94Ç\9d\8f¹\8f\81°\88\80¸\90\88Á\9a\93Ä\9d\96¿\9d\91Å£\97Ì­\99Ѳ\9eв\96ΰ\94̲\8fͳ\90˹«®\9c\8e¤\93\8bº©¡À°±¦\96\97\87w\82|lw¡\93¢©\9bª\97\8b\99}q\7f\89\7f\8a´ªµÂ»Â³¬³¡\86\7f§\8c\85¼\8b\86À\8f\8aÐ\89\83Ô\8d\87Ù\93\87Ý\97\8bÑ\9d\88Ñ\9d\88Ê \8aÉ\9f\89Í\99\8bÊ\96\88Ñ\8e\88Ï\8c\86Ï\92\80Î\91\7fÊ\90\82Ë\91\83Ë\96\8eÒ\9d\95Õ¦ Ùª¤á´®à³­ä²©ß­¤Ö¡\91Á\8c|ªq^\99`M\86K9~C1q:&n7#j:$m='i?'h>&mC+kA)xH2\8aZD\9ceQ\9ceQ\9ecQ¡fT¡m_\9fk]\95i^\94h]\8dki\92pn\91yy\95}}\89vx\7flno[Z\HGO61C*%?#\18\15;%\17;%\17>"\16?#\17H$\18M)\1dW,#Z/&X)\1fX)\1fW+\1eX,\1fT/\1dT/\1dP/\1cP/\1cÖÂÄÖÂÄÕÂÆÕÂÆÒÃÊÒÃÊÒÃÊÒÃÊÔ¿Äȳ¸¸\9c\99«\8f\8c½\97\8eÑ«¢Ø¬\9f΢\95Ä\9b\89Ë¢\90Ç\9d\8f·\8d\7f«\83\8a\82½\96\8fÄ\9d\96½\9b\8fÄ¢\96Ì­\99Ѳ\9eѳ\97в\96ϵ\92ж\93IJ¤°\9e\90¾­¥ÝÌÄó´\84tuscn\93\83\8e¯¡°\90\82\91uiw\80t\82©\9fªÆ¼Çº³º¡\9a¡©\8e\87­\92\8bÀ\8f\8aÁ\90\8bÏ\88\82Ñ\8a\84Ö\90\84Ú\94\88Î\9a\85Ï\9b\86Ê \8aË¡\8bÒ\9e\90Ñ\9d\8fÛ\98\92Ú\97\91×\9e\8bÕ\9c\89Ï\9a\8aÎ\99\89Í\9b\92Ò \97Ó¦ ×ª¤ç¸²äµ¯ä¯§Ü§\9fÑ\97\89»\81s¦iW\95XF\82E3}@.t;(r9&o<'q>)m@)m@)tG0qD-{H3\8cYD\9aaN\9aaN\9c_M cQ\9bgZ\9afY\96f\\96f\\92kd\97pi\99wu\9d{y\8ero\86jgv]YeLHW<5J/(C&\1e?"\1a8"\177!\16;\1e\16<\1f\17\18J%\1dS(\1fW,#V(\eW)\1cX-\1dZ/\1fV1\1eV1\1eQ1\1aP0\19ÕÁÃÕÁÃÔÁÅÔÁÅÑÂÉÑÂÉÑÂÉÑÂÉι¾À«°©\8d\8a\93wt¥\7f\9b\92Ï£\96Æ\9a\8dÀ\97\85È\9f\8dÇ\9d\8f¹\8f\81®\86\8d\85À\99\92Æ\9f\98½\9b\8fÄ¢\96Í®\9aÓ´ Ô¶\9aÔ¶\9aÓ¹\96Õ»\98ñ£Á¯¡ÓºßÎƳ£¤xhiuep\9e\8e\99\8d\7f\8e}o~\81u\83¡\95£µ«¶­£®\9a\93\9a\93\8c\93¸\9d\96µ\9a\93Á\90\8b¿\8e\89Î\87\81Ñ\8a\84Ô\8e\82Ö\90\84Ì\98\83Í\99\84É\9f\89Ì¢\8cÕ¡\93Ö¢\94à\9d\97ß\9c\96Ü¥\91Ù¢\8eÓ \8fÑ\9e\8dÍ\9e\94Ñ¢\98Ó¦ ×ª¤ç¸²á²¬Ý¦\9fÑ\9a\93Ç\89|³uh ^N\91O?\7f@/~?.y>,x=+t@+t@+qC,qC,yK4uG0~J5\8dYD\9b`N\9a_M\9d^M¢cR\9be[\9adZ\94bY\93aX\92c[\94e]\92ic\94ke\88c]\83^XuTOiHCY:5N/*E("A$\1e5\1e\186\1f\19;\1e\18>!\eH#\1dM("U*#W,%Z,\1f\.!]2!_4#\8 [7\1fU6\1aS4\18ÔÀÂÔÀÂÓÀÄÓÀÄÐÁÈÐÁÈÐÁÈÐÁÈ͸½Ç²·²\96\93\92vs\98ri³\8d\84É\9d\90Ç\9b\8eÀ\97\85É \8eÊ \92¿\95\87·\8f\87¿\97\8fÇ \99Ê£\9c¾\9c\90Å£\97Ï°\9cÕ¶¢×¹\9d×¹\9d×½\9aÙ¿\9c˹«ØƸÕļ¹¨ \99\89\8a\8e~\7f\90\80\8b\92\82\8dpbq\80r\81\9b\8f\9d­¡¯¤\9a¥\92\88\93\91\8a\91¡\9a¡Â§ ¸\9d\96½\8c\87º\89\84Î\87\81Ô\8d\87Õ\8f\83Ô\8e\82Ì\98\83Í\99\84É\9f\89Ë¡\8bÓ\9f\91Ó\9f\91Ý\9a\94Ü\99\93Ø¥\90Ö£\8eÑ \8fÐ\9f\8eС\97Ô¥\9bת¤Û®¨ä³®Ûª¥Ó\9a\93Å\8c\85¹ym§g[\98SD\8cG8\81?/\82@0\80C1\7fB0yB.xA-sC-tD.|L6wG1\82K7\91ZF cQ¢eS¦dT«iY¢kd\9fha\98c[\92]U\8cZQ\89WN\86VL\85UKzOHwLElG?d?7W61N-(D'#@#\1f5\1d\e7\1f\1d@#\1fF)%Q+(U/,[0)\1*c5(e7*g<)i>+eA'b>$[<\1fY:\1dÔÀÂÔÀÂÓÀÄÓÀÄÐÁÈÐÁÈÐÁÈÐÁÈѼÁÕÀÅÅ©¦\9e\82\7f\97qh®\88\7fÉ\9d\90΢\95Ã\9a\88Ë¢\90Í£\95Å\9b\8dÀ\98\90È \98Χ Î§ ¿\9d\91Ƥ\98б\9dÖ·£Øº\9eÙ»\9fÙ¿\9cÛÁ\9eÔ´é×ÉÌ»³\8f~v\85uv¬\9c\9dª\9a¥\80p{oap\8b}\8c¢\96¤\9f\93¡\8e\84\8f\8d\83\8e¡\9a¡¹²¹Ç¬¥¸\9d\96·\86\81µ\84\7fÍ\86\80Ö\8f\89×\91\85Ô\8e\82Í\99\84Î\9a\85É\9f\89Ê \8aÐ\9c\8eÏ\9b\8dØ\95\8f×\94\8eÕ¢\8dÓ \8bÎ\9f\8dÏ \8eÏ£\98Õ©\9eÛ®¨à³­ß®©Õ¤\9fË\92\8bº\81z°nb ^R\91L=\87B3\81?/\84B2\83F4\82E3{D0yB.vC.wD/~K6yF1\82K7\93\H¤gU¨kY®l\³qa©rk¥ng\9df_\93\U\89SI\82LB{G<yE:o@6n?5d=6^70S2-K*%B$"?!\1f6\1e\1c:" E'%L.,X2/\63`5.a6/j</l>1nC0pE2lI-hE)`A"]>\1fؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄϺ¿É´¹Æ­©¿¦¢·\97\8c­\8d\82·\92\82Å \90æ\96À£\93Ť\95Ä£\94¾\98\8b¹\93\86Å\9f\94Ö°¥·\92\89À\9b\92ƪ\9eͱ¥Ë¸©Ñ¾¯ØË»àÓÃÔÖÕÕ×Ö¥¡¢\84\80\81®¢¦¹­±\92}\84t_f\83lt\9d\86\8e\97\82\89vahwhm©\9a\9fɽÁÇ»¿®\85\83µ\8c\8a¾\91\8b¾\91\8bÁ\8b\7fÁ\8b\7fË\90\80Ñ\96\86Ñ\94\82Ó\96\84Ó\98\88Ö\9b\8bÕ\9d\90Õ\9d\90Ò\9e\93Ò\9e\93Þ \91Ú\9c\8dÕ\9b\8fØ\9e\92ק\9dÝ­£Ý±¨Þ²©á±¥Ô¤\98È\90\81µ}n­jW\9e[H\96K4\8eC,\81D/\84G2\87J5\87J5\82E0\80C.\80C.\82E0\84G2\87J5\8cO:\90S>\94WB\9b^I¥hS­p[ºvmµqh«h_ ]T\90TI\85I>xC5t?1rC3m>.b9']4"X3 U0\1dN.\19J*\15L(\1aL(\1aO*\1aS.\1e]3#g=-sF3yL9}M7|L6}K2\7fM4\82L2}G-v>#o7\1cؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄѼÁDz·Á¨¤¸\9f\9b´\94\89®\8e\83½\98\88Ω\99Â¥\95À£\93Ť\95Ť\95Á\9b\90¼\96\8bÅ\9f\94Õ¯¤µ\93\89Á\9f\95Ë°¥×¼±ÖƹÛ˾ÜÓÄáØÉÔÖÕÂÄ맨¥¡¢²¦ª\9d\91\95\81lswbi\98\81\89\8bt|\83nu\91|\83ª\9b ¹ª¯­¡¥\9a\8e\92«\82\80®\85\83µ\88\82\89\83¾\88\8c\80Ì\91\81Ñ\96\86Ó\96\84Ô\97\85Ô\99\89×\9c\8cÖ\9e\91×\9f\92Ô \95Ó\9f\94Þ \91Û\9d\8eÕ\9d\90Ø \93ئ\9dÝ«¢Ý®¦Ý®¦Ô¤\98Ç\97\8bº\82s§o`¡^K\94Q>\8dE-\87?'\83F1\86I4\88K6\86I4\82E0\7fB-\7fB-\81D/\87J5\8bN9\8fR=\93VA\96YD\9eaL¨kV¯r]ºvk¸ti¯oc¨h\\9b`R\91VH\87O@\82J;yH7tC2j?,f;(a;&_9$Z7!V3\1dW0!V/ U.\1dX1 b7&lA0xK6~Q<\81Q:\7fO8\7fM4\80N5\80M2{H-t>"n8\1cؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄÔ¿ÄÉ´¹¿¦¢¯\96\92¤\84y\9f\7f\91\81ͨ\98Ä¥\93ä\92Ȥ\96˧\99Æ \95¾\98\8dÃ\9e\95Ы¢µ\94\8b¡\98Í´­ÝĽÝÐÇàÓÊÞØÌßÙÍÚÜÛ¶¸·¼¸¹ÌÈÉ°¤¨~rvxcj\83nu\94}\85zck\82mt²\9d¤Å¶»©\9a\9f\88|\80\81uy¸\8f\8d´\8b\89³\86\80³\86\80¾\88\8e\82Ì\91\81Í\92\82Ô\97\85Ö\99\87Ö\9b\8bÙ\9e\8eØ \93Ù¡\94Ö¢\97Õ¡\96Ú¡\90Ø\9f\8eÖ\9e\91Ù¡\94Ú¥\9dÞ©¡Û©¢Ù§ Ë\97\8c¾\8a\7f®tf\9cbT\95T@\8cK7\88E+\84A'\85H3\87J5\89L7\86I4\81D/}@+~A,\81D/\8aM8\8eQ<\92U@\95XC\99\G cN©lW±t_¹wk¹wk·wk´th«pb£hZ\98`Q\93[L\87TC\81N=xI7tE3pE2nC0i@,f=)f;*c8'a6#a6#i<'rE0~P9\85W@\86V?\83S<\82P7\81O6\80M2zG,s=#m7\1dؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄÓ¾Ãι¾Å¬¨«\92\8e\91qf\87g\¤\7foÆ¡\91˪\99ɨ\97̨\98Ϊ\9aÉ£\98À\9a\8fÀ\9b\93ɤ\9c»\9c\97Ä¥ É¶°Öý×ÎÇÚÑÊÕÕÍÕÕÍâäã¾À¿ÑÍÎØÔÕ\9f\93\97rfj\83nu\8fz\81t]e|em\9c\87\8e»¦­¨\99\9e\80qv}qu\9a\8e\92ͤ¢Â\99\97º\8d\87\89\83Á\8b\7fÅ\8f\83É\8e\8c\99\87×\9a\88Ø\9d\8dÚ\9f\8fÚ¢\95Ú¢\95×£\98×£\98Ö¡\8fÕ \8eÕ \92Ø£\95Û¦\9eÛ¦\9eÙ¢\9dÕ\9e\99É\90\87»\82y©n`\98]O\91S>\8cN9\8bK0\88H-\87J5\88K6\89L7\85H3\7fB-|?*~A,\81D/\8bN9\8eQ<\92U@\95XC\98[F\9fbM¨kV¯r]´ud¶wfº{j¼}l¶{i°uc¨o\£jW\96bM\90\G\88U@\82O:}M7yI3tF/pB+uE.qA*m=&k;$o?(xH1\84R;\8aXA\8cZA\88V=\84R9\80N5\7fK3xD,p="j7\1cؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄÌ·¼Ñ¼ÁѸ´µ\9c\98\92rg\82bW¤\7foͨ\98Ó²\9fέ\9aÏ«\9bЬ\9cË¥\9aÀ\9a\8f¼\9a\91 \97É­©Ë¯«È¹¶Î¿¼ÍÉÆÒÎËÎÒÑÎÒÑÞàßÌÎÍÖÒÓ¿»¼\87{\7fxlp\93~\85\8ey\80lU]\8bt|§\92\99£\8e\95\83tyzkp\96\8a\8e¼°´Ì£¡Â\99\97¹\8c\86µ\88\82À\8a\8e\82È\8d\8b\99\87×\9a\88Ø\9d\8dÚ\9f\8fÚ¢\95Ú¢\95×£\98×£\98Ò£\8fÑ¢\8eÕ¡\93Ù¥\97Ü¥\9eÚ£\9cÖ\9b\97Ñ\96\92Ç\88\81º{t§i\\98ZM\90S>\8cO:\8aN2\88L0\87J5\88K6\87J5\83F1~A,}@+\80C.\83F1\8aM8\8dP;\91T?\93VA\96YD\9c_J¥hS¬oZ¯r_³vc¸{h¼\7f\7fl·zg°vb¬r^§nZ gS\96_J\8eWB\89R=\83L7{G1vB,\82L0~H,yC'wA%yC)\7fI/\85R7\8aW<\8f\A\8aW<\84P8\7fK3{I0uC*n<#h6\1dؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄȳ¸Ïº¿×¾ºÅ¬¨«\8b\80\9b{p·\92\82س£Øµ¡Ñ®\9aΩ\99Ы\9b̦\9bÄ\9e\93¿\9e\97Ť\9dÑ·¶Ð¶µÇ»»Ë¿¿ÉÊÌÏÐÒÉÓÕÈÒÔÏÑÐÍÏÎÄÀÁ\9c\98\99\81uy\8a~\82\95\80\87~ip\83lt\92{\83\92}\84\86qx\85v{\9f\90\95³§«·«¯¶\8d\8b±\88\86±\84\83\86\8c\80Ê\8f\7fË\90\80Ô\97\85Ö\99\87Ö\9b\8bÙ\9e\8eØ \93Ù¡\94Ö¢\97Õ¡\96Τ\8eΤ\8eÕ¤\95ا\98Þ¥\9eÙ \99Ô\94\92Í\8d\8bÁ~x¶sm£cW\96VJ\8cR<\88N8\84M/\82K-\86I4\86I4\85H3\81D/~A,~A,\83F1\87J5\8bN9\8eQ<\92U@\93VA\95XC\9b^I¤gR«nY¯r]²u`¶yd¹|g¹|g·ze³va±t_±waªpZ fP\98^H\92XB\8cR<\85K5\80F0\8dR2\8aO/\87L.\84I+\83J,\86M/\89Q6\8cT9\8fY?\8aT:\81M5|H0xF-sA(k;$f6\1fؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄι¾Í¸½Óº¶Ï¶²È¨\9dº\9a\8fÃ\9e\8eЫ\9bÖ²\9cÍ©\93È£\91˦\94˧\9bÉ¥\99ȧ¢Ð¯ªÊ²²É±±Â¹¼ÉÀÃÈÍÑÌÑÕÁÐÕ½ÌÑÀÂÁÄÆŪ¦§\8e\8a\8b\9d\91\95¢\96\9a\8bv}nY`\90y\81\86ow{fm\83nu\9f\90\95º«°¯£§\94\88\8c¨\7f\82\80±\84\85\7f»\85y¿\89\8e\93\83Ó\96\84Ô\97\85Ô\99\89×\9c\8cÖ\9e\91×\9f\92Ô \95Ó\9f\94Ì£\8dͤ\8eÕ¦\96Ø©\99ߤ\9eÙ\9e\98Ó\8f\8eÊ\86\85½xs´oj¥cW\9aXL\8dU>\87O8\7fL-{H)\84G2\84G2\83F1\80C.~A,\80C.\86I4\8bN9\8eQ<\91T?\95XC\96YD\98[F\9d`K¦iT¬oZ°v^±w_µya¶zb¶zbµya³w_³w_¶zb¯s[¨jS¢dM\9e`I\9a\E\96U?\91P:\97W4\96V3\94U4\93T3\90S4\90S4\8dT6\8dT6\8cV:\86P4}J/xE*uC,r@)j:#e5\1eؽÂؽÂÖ½ÃÕ¼ÂѽÆмÅͼÄͼÄÙÄÉ͸½Ì³¯Ñ¸´×·¬Ë« À\9b\8b»\96\86Ò®\98Ç£\8dÂ\9d\8bÈ£\91̨\9cΪ\9eίªØ¹´º¥¤¼§¦¹³·Å¿ÃÆÍÓÈÏÕ¹ÊѱÂɺ¼»¼¾½\9a\96\97\91\8d\8e½±µ´¨¬\82mtfQX\87pxv_gt_f\91|\83²£¨¸©®\99\8d\91xlpª\81\7f±\88\86º\8d\87º\8d\87½\87\87\8c\92\82Ñ\94\82Ó\96\84Ó\98\88Ö\9b\8bÕ\9d\90Õ\9d\90Ò\9e\93Ò\9e\93ʤ\8dË¥\8eÕ¦\96Ùª\9aߤ\9eØ\9d\97Ò\8c\8cÈ\82\82¿xt·pl©g[\9f]Q\91YB\8bS<\80O/{J*\82E0\82E0\81D/\7fB-}@+\81D/\88K6\8eQ<\92U@\94WB\98[F\99\G\9b^I cN¨kV¯r]´zb´zbµyaµya´x`´x`³w_´x`·yb±s\¬kU¨gQ§eO¥cM¡_I\9d[E\9d\6\9d\6\9d]9\9c\8\98\:\95Y7\92W9\90U7\8bS8\85M2zG,vC(sA*q?(i9#e5\1fÓ½¿Ó½¿Ñ¼ÁлÀ̽Ä˼ÃɼÅÈ»Ä;ÅÊ»Âк½Î¸»Æ¨¦²\94\92¯\8c\86²\8f\89Ë¢\86Óª\8eΫ\95Ä¡\8bµ\9f\92¸¢\95¯¥£­£¡¨¦©ÉÇÊÝÞãÑÒ×½¼Á¸·¼½¼ÁÀ¿Ä»¼À¼½Á¬§­´¯µË¾Ç¡\94\9du_k|frmUbkS`\89s\7f·¡­±¡«\86v\80uhq\89|\85Ä«¤º¡\9a·\92\89³\8e\85À\8c\7fÂ\8e\81Ê\88\84\8f\81Û\93\85Ü\9a\8cÝ\9b\8dÕ\9b\8fÔ\9a\8eÐ\9e\93Ò \95Ë\9e\99Ρ\9cÔ¤\9aÕ¥\9bÙ\9f\91Ò\98\8aÎ\8f\8by°oY«jT¡cN\98ZE\8cQA\84I9}E8zB5rA2sB3wD3yF5}H8\7fJ:\85J:\86K;\92SA\96WE\9f\I¢_L¦_K©bN°gT´kX¯td²wg¶{i¹~l¼\7fm¹|j¶xc´va³q[²pZ²nW¯kT®hO¬fMªdK©cJ¢_E¡^D\9f]C\9e\B\99[B\99[B\94ZB\93YA\89S;\86P8|L6uE/nA*j=&e;%d:$Ò¼¾Ñ»½Ð»ÀϺ¿Ê»ÂɺÁǺÃǺÃǸ¿Ê»ÂÒ¼¿Ê´·µ\97\95\9b}{\9awq£\80z¿\97~È \87Ä£\90¾\9d\8a´ \95¾ª\9f½³±¾´²ÔÒ×Á¿Ä´µº»¼Á¿¾Ãº¹¾»º¿ÃÂÇÆÇËÀÁÅ»¶¼»¶¼²¥®\83v\7fkUau_kkS`\87o|¢\8c\98¢\8c\98\8az\84\80pz\92\85\8e¬\9f¨È¯¨¾¥\9e·\92\89®\89\80¹\85x¿\8b\8e\80Õ\93\85Ú\92\84Ý\95\87Ü\9a\8cÛ\99\8bÒ\98\8cÒ\98\8cÎ\9c\91Ò \95Õ¨£Ö©¤Ù©\9fÖ¦\9cÔ\9a\8cÇ\8d\7f¾\7fm¶weªiS¥dN\9b]H\91S>\85J:~C3v>1t</n=.o>/s@/vC2zE5~I9\86K;\88M=\93TB\97XF ]J£`M§`LªcO±hUµlY±vf´yi·|jº\7f\7fmº}k·ydµwbµs]´r\³oX°lU¯iP­gN«eLªdK¡^D ]C\9e\B\9cZ@\96X?\94V=\8fU=\8eT<\85O7\82L4xH2qA+j=&f9"a7!`6 Ï¹»Ï¹»Í¸½Ì·¼È¹ÀǸ¿Å¸ÁÄ·ÀÁ²¹ÉºÁÔ¾Áɳ¶¯\91\8f\93us\95rl£\80zÅ¢\8cͪ\94Ë°\9fǬ\9b±©Ï¾¶ÑÉÇÓËÉÛÚß³²·¢£¨¸¹¾ÄÃÈ·¶»º¸»ÏÍÐÅÆÊ¿ÀÄÊÅË»¶¼\91\84\8dpcls]it^jrZg\95}\8a\9c\86\92\80jvueo\98\88\92·ª³½°¹¯\96\8f®\95\8e´\8f\86±\8c\83»\87\8c\7fÒ\90\82Ù\97\89Ý\95\87Þ\96\88Ú\98\8aØ\96\88Î\94\88Ð\96\8aÏ\9d\92Ô¢\97Û®©Û®©Ý­£×§\9dÐ\96\88¿\85w±r`¦gU¡`J\9d\F\93U@\89K6}B2u:*o7*l4'i8)j9*m:)p=,vA1}H8\87L<\8aO?\94UC\99ZH¢_L¥bO©bN¬eQ²iV·n[µzj·|l¹~l»\80\80n»~l¹{f·yd·u_¶t^µqZ²nW°jQ®hO«eLªdK¡^D ]C\9d[A\99W=\93U<\8fQ8\8aP8\88N6\7fI1|F.rB,l<&e8!a4\1d]3\1d\2\1cÍ·¹Í·¹Ë¶»ÊµºÆ·¾Å¶½Ã¶¿Âµ¾Â³ºÇ¸¿Ñ»¾Î¸»¾ \9e¨\8a\88ª\87\81µ\92\8cα\9fÙ¼ªÛĶ×À²Ï¼ÖÉÃÒÎÏÏËÌ´µº®¯´¹º¿ËÌÑÉÇÌ·µº½»¾ÓÑÔ´µ¹½¾ÂÐËÑ®©¯|ox\82u~\96\80\8cu_k~fs\84lyxbnq[g\8d}\87¾®¸À³¼£\96\9f\88oh\96}v±\8c\83»\96\8dÆ\92\85Ã\8f\82Î\8c\8d\7fÙ\91\83Ú\92\84Ö\94\86Ô\92\84Í\93\87Ñ\97\8bÓ¡\96Ú¨\9dܯªÝ°«ß¯¥Ø¨\9eÑ\97\89¾\84v¯p^¤eS\9bZD\97V@\8dO:\84F1y>.q6&k3&i1$e4%e4%f3"j7&r=-{F6\88M=\8eSC\97XF\9b\J¤aN§dQ«dP®gSµlY¹p]¹~nº\7f\80\81\80\7fmº|g¹{f¹wa·u_¶r[²nW±kR®hO«eLªdK£`F¡^D\9d[A\98V<\91S:\8cN5\86L4\84J2{E-yC+o?)i9#c6\1f_2\e[1\eZ0\1a̶¸Ì¶¸ÊµºÊµºÅ¶½Äµ¼Âµ¾Á´½Ì½ÄǸ¿Ì¶¹Ï¹¼Ï±¯À¢ ¼\99\93¾\9b\95ȱ£Õ¾°ÛÉ¿ÙǽÏÅÃÏÅÃÄÂżº½««³¼¼ÄËÌÑÊËÐÆÄÇÃÁÄÅÁÂÄÀÁ­®²ÃÄÈÐËÑ \9b¡\7fr{¥\98¡°\9a¦mWc}errZgnXd\87q}©\99£¹©³¡\94\9d\81t}\8aqj\98\7f\8e\85½\98\8fÇ\93\86Â\8e\81Ê\88\88\8b\8d\7fÒ\90\82Ò\90\82Í\93\87Ô\9a\8e×¥\9aß­¢á´¯à³®à°¦×§\9dÍ\93\85º\80r«lZ\9f`N\97V@\94S=\8bM8\83E0y>.s8(n6)l4'd3$b1"b/\1ee2!n9)zE5\89N>\91VF\99ZH\9e_M§dQ©fS®gS±jV·n[¼s`»\80\80\80\80\7fmº}kº|g¹{f¹wa¸v`¶r[²nW°jQ¬fM©cJ¨bI¢_E¡^D\9cZ@\97U;\8fQ8\8aL3\84J2\82H0yC+v@(m='h8"a4\1d^1\1a[1\eZ0\1aÍ·¹Í·¹Ë¶»ÊµºÅ¶½Å¶½Âµ¾Âµ¾ÐÁÈÆ·¾Ç±´Ëµ¸Ï±¯Á£¡¹\96\90µ\92\8cñ§ÒÀ¶ÙÌÆ×ÊÄÎÈÈÍÇÇÃÄÉ»¼ÁÉÌÓÊÍÔÂÃÈ·¸½À¾ÁÎÌÏÉÃó­­º»¿ÎÏÓÌÇÍ£\9e¤\9b\8e\97¶©²§\91\9daKWpXet\i\89s\7f¥\8f\9b¤\94\9e\8f\7f\89\7fr{\82u~°\97\90±\98\91¹\94\8b\91\88¾\8a\8a\8b\8f\81Ï\87\8a\8f\81Ó\91\83Ï\95\89Ô\9a\8eÖ¤\99Ý« ã¶±ß²­Úª Í\9d\93Á\87y­se\9f`N\94UC\93R<\90O9\89K6\83E0{@0v;+r:-q9,e4%b1"a.\1dc0\1fl7'yD4\8bP@\93XH\9c]K aO©fS¬iV°iU³lXºq^¾ub¼\81\80\7fm¹~l¹|j¸{i¸ze¸ze¸v`¶t^´pY°lU®hO©cJ¦`G¥_F\9e[A\9cY?\97U;\93Q7\8bM4\86H/\80F.~D,u?'s=%i9#e5\1f_2\e\/\18Y/\19Y/\19θºÎ¸ºÌ·¼Ì·¼Ç¸¿Æ·¾Ä·Àö¿Æ·¾Á²¹Å¯²Ç±´Å§¥µ\97\95°\8d\87±\8e\88È»µÓÆÀÕËÉÏÅÃÄÂÅÆÄÇÁÄË»¾ÅÍÑÚÁÅλ»ÃººÂÁ¼À½ÁÁ»»Á»»ÍÎÒÎÏÓÀ»Á¶±·Ã¶¿°£¬\85o{dNZlTa\7fgt\99\83\8f¢\8c\98\8b{\85yis\85x\81¢\95\9eÀ§ ¸\9f\98¸\93\8a³\8e\85¿\8b\8f\82Ð\8e\80Ò\90\82Ð\88\8c\92\84Ö\94\86Ð\96\8aÒ\98\8cÐ\9e\93Õ£\98Ô§¢Ï¢\9dÈ\98\8eº\8a\80°vh\9feW\95VD\8dN<\8dL6\8bJ4\85G2\82D/{@0y>.v>1u=0i8)d3$a.\1db/\1ej5%xC3\8cQA\95ZJ\9d^L¢cQ«hU®kX²kWµnZ»r_Àwd»\80\7fo¸}k¶{i¶ygµxf¶xc¶xc·u_µs]²nW®jS«eL¦`G£]D¡[B\96S9\94Q7\90N4\8cJ0\85G.\81C*z@(y?'o9!m7\1fd4\1e`0\1aZ-\16X+\14U+\15U+\15Ϲ»Ï¹»Í¸½Í¸½È¹ÀǸ¿Å¸ÁÄ·À¸©°º«²Ä®±Å¯²¾ \9e­\8f\8d¯\8c\86·\94\8eËÀ¼ÐÅÁËÃÁ¾¶´±°µ´³¸²¶¿¯³¼¯³¼®²»ÀÃÊÐÓÚÄÀÁ¨¤¥¹±¯áÙ××ØÜÆÇ˳®´ÇÂÈáÔݤ\97 jT`pZfrZg\84ly\90z\86\88r~yis\84t~¢\95\9e¾±º±\98\91¬\93\8c²\8d\84\91\88É\95\88Ì\98\8bÒ\90\82Ì\8a\8c\90\82Ø\96\88Ù\97\89Ð\96\8aÏ\95\89Ë\99\8eÍ\9b\90¿\92\8d»\8e\89µ\85{ªzp¤j\\99_Q\94UC\8fP>\89H2\87F0\82D/\80B-{@0y>.w?2w?2k:+f5&b/\1eb/\1ej5%xC3\8cQA\96[K\9e_M£dR¬iV¯lY³lX¶o[¼s`Áxe»\80\7fo·|j´yg´we³vd´vaµwbµs]³q[±mV¬hQ©cJ¤^E¡[B\9fY@\8fL2\8eK1\89G-\86D*\7fA(|>%v<$u;#k5\1di3\e`0\1a\,\16V)\12T'\10Q'\11Q'\11ø¼Â·»ÄµºÃ´¹È±¹É²ºÏ±»Ð²¼É©´Î®¹Ð²¼Ï±»Ä­µ½¦®¶¥«´£©ÔÐÑÐÌÍÊÆÇÄÀÁÀ¼½½¹º¼¸¹¼¸¹ÉÅÆÊÆÇÅÁ»·¸³¯°º¶·ÍÉÊÞÚÛÒ×ÚÊÏÒ¿¾Ãàß亰¸tjr\89y\83wgqzfq\83oz{jtrak\81v~¤\99¡ª ¨\97\8d\95\86ri\94\80\89\83À\93\8dÒ\8d\86Ò\8d\86Ô\8e\82Ø\92\86× \8cÏ\98\84Ä\94\80Ç\97\83Ô\98\8dÓ\97\8cÔ\89\86Ê\7f\7fnÀwf´m[§`N\9aUE\92M=\8cJ<\8aH:\7fD6|A3w?2u=0r>1s?2sB4uD6iE9^:.Y.\1eY.\1em9$|H3\8eP9\93U>¤bH©gM®lT±oW±p^³r`µwhº|m¾zc¾zc¾zc½yb»w`¸t]µqZ³oX´pY¯kT©eN¥aJ£_H\9f[D\99U>\94P9\8dF*\8bD(\88B(\84>$}=$y9 p8!o7 b/\1aa.\19Y.\1dW,\eR+\1aP)\18L(\18K'\17÷»Â¶ºÄ³¹Ã²¸É¯¸Ê°¹Î°ºÏ±»Ë«¶Ë«¶Ç¬µÈ­¶Å°·È³ºÇ¶¼È·½ÍÉÊÊÆÇÅÁ¾¿Á½¾Ã¿ÀÇÃÄÊÆÇ·³´¿»¼ÇÃÄÊÆÇÈÄÅÈÄÅÍÉÊÒÎÏÉÎÑÅÊÍÁÀÅÎÍÒ\9f\95\9dvlt\95\85\8fueo\84p{ualm\f\7fnx\95\8a\92\9c\91\99\8c\82\8azpx\9d\89\80£\8f\86¹\8c\86½\90\8aÎ\8b\83Ñ\8e\86Õ\91\84Ø\94\87Ò\9b\87Ï\98\84È\99\85Í\9e\8aØ\9e\92Ò\98\8cÍ\83\80¿ur¬hU§cP\9e[J\94Q@\88I8\7f@/w<,t9)q<,o:*j9*h7(g9*j<-k?2mA4fB6[7+V+\eW,\1cl8#|H3\8fQ:\94V?¥cIªhN®lT°nV°o]²q_´vg¸zk½yb½yb¼xa»w`¹u^¶r[³oX²nW°lU«gP¥aJ¡]F\9f[D\9bW@\95Q:\90L5\8bF)\89D'\84A&\81>#y;"v8\1fo7 n6\1f_/\e^.\1aY.\1dW,\eP+\eN)\19L(\1aK'\19³¸Á²·Ã°¶Â¯µÆ¬µÇ­¶Ì¬·Í­¸Ò´¾Ë­·Á§°Ã©²É¶¼ÓÀÆÒÆÊÓÇ˾º»¸´µ®ª«¤ ¡\9f\9b\9c\9f\9b\9c¢\9e\9f¥¡¢·³´¾º»ÇÃÄÎÊËÐÌÍÍÉÊÈÄÅÄÀÁÅÊÍÃÈËÉÈͼ»À\88~\86\89\7f\87®\9e¨rblt`kjVawfp\99\88\92\9d\92\9a\86{\83xnv\7fu}·¥\9b±\9f\95»\90\89¹\8e\87Ë\8b\82Ð\90\87Ö\92\85Ø\94\87Ì\98\83Í\99\84Í \8bÔ§\92Ý¥\98Ò\9a\8dÈ\81}¸qm\94WD\90S@\87L:~C1s;*k3"c0\1f`-\1c_0 ^/\1fY/\1fY/\1fY4$]8(`<.c?1`<0V2&R'\17T)\19k7"}I4\91S<\96XA¦dJªhN®lT°nV®m[¯n\±sdµwhºv_ºv_ºv_¹u^¶r[³oX°lU¯kTªfO¥aJ\9f[D\9cXA\9aV?\96R;\90L5\8bG0\88B(\87A'\81?%~<"v:"r6\1el5 j3\1e].\1a\-\19W-\1dU+\eN*\1cL(\1aH&\1aG%\19¯µÁ®´Â«³Áª²Æ¨²Ç©³É©´Êªµ×¹Ãͯ¹Áª²Å®¶Í¾ÃÖÇÌÒÇËÍÂÆÏËÌÇÃÄ»·¸°¬­«§¨¬¨©°¬­´°±ÉÅÆÆÂÃÄÀÁÅÁÂÇÃÄÅÁÂÀ¼½¼¸¹ÉÎÑÄÉÌÒÑÖµ´¹\8c\82\8a¯¥­Ä´¾m]gT@Ko[f\94\83\8d¥\94\9e\8b\80\88qfn\82x\80¨\9e¦À¯¥¶¥\9bº\92\8a·\8f\87Í\8e\85Ò\93\8aÔ\95\86Ò\93\84Ë\98\83Î\9b\86Τ\8eÕ«\95ݨ\9aÔ\9f\91Î\89\84Â}x\99bN\90YE\81L:s>,e4#^-\1cZ,\1cY+\eP)\18P)\18N*\1aO+\eO/ T4%W:,Z=/Z6*Q-!P%\15U*\1an:%\81M8\95W@\9a\E¨fL«iO®lT¯mU¬kY¬kY¬n_°rc¶r[¶r[¶r[µqZ³oX¯kT­iR«gP§cL¢^G\9cXA\98T=\96R;\92N7\8cH1\87C,\83@&\82?%}=$y9 q7!m3\1dg3\1ee1\1c[-\1dZ,\1cS,\1dQ*\eK)\1dH&\1aF&\eE%\1aÁª²À©±Â§°Á¦¯Ä¤¯Å¥°Æ¦±Ç§²Í¯¹Èª´Á¬³Ë¶½ÒÇË×ÌÐÍÇÉľÀÁ½¾½¹º·³´µ±²¹µ¶Â¾¿ÌÈÉÔÐÑÆÂÃÄÀÁÿÀÄÀÁÅÁ¾¿¼¸¹·³´ËÐÓÃÈËÓÒ×´³¸¤\9a¢ÐÆÎó½fV`UALzfq\96\85\8f\90\7f\89ujrvks\96\8c\94¸®¶¸ª\9f°¢\97º\94\8bº\94\8bÐ\94\8aÒ\96\8cÓ\95\86Ï\91\82Ì\9c\86Î\9e\88ͤ\8eѨ\92Ú¦\98Ö¢\94Ú\97\91Ô\91\8b®yi k[\87VErA0a2"[,\1cX-\1dZ/\1fN)\19M(\18J(\1cK)\1dK. O2$S7+V:.S/#N*\1eQ&\16\1!vB-\89U@\9c^G bKªhN­kQ¯mU®lTªiW©hV¨j[«m^²nW²nW²nW±mV¯kT«gP©eN§cL¥aJ \E\9aV?\96R;\94P9\90L5\8aF/\85A*~>%|<#x:#t6\1fm4 i0\1cb/\1ca.\eW,\1cV+\eQ+\1eN(\eH(\1dF&\eB$\1aA#\19Á¦¯À¥®Á£­À¢¬Â¡¬Ã¢­Ä£®Å¤¯» ©¾£¬Â¯µÑ¾ÄÖÍÐÙÐÓÌÊËÄÂí©ªª¦§¦¢£¤ ¡¨¤¥°¬­¸´µ¾º»²®¯º¶·ÅÁÂÎÊËÎÊËÈÄÅ¿»¼¹µ¶ÆËοÄÇÎÍÒ´³¸¿µ½ÚÐب\98¢gWa{gr\7fkvzisrakujr\8b\80\88\9f\95\9d¦\9c¤®¢\96¬ \94º\98\8e¼\9a\90Ð\96\8bÑ\97\8cÑ\96\86Ï\94\84Ë\9e\87Ì\9f\88É£\8cË¥\8eÓ¢\93Ô£\94Þ\9d\97Þ\9d\97Â\8a}²zm\97bT}H:g6(^-\1f[- ]/"S+!R* N) M(\1fK+ N.#O1'Q3)N*\1eM)\1dV+\ef;+\82N9\94`K¤fO¥gP«iO®lR¯mU­kS§fT¥dR¤fW¦hY®jS®jS®jS­iR«gP¨dM¥aJ£_H¡]F\9cXA\96R;\93O8\90L5\8dI2\87C,\82>'y;$w9"t7"p3\1ei2\1ee.\1a],\e\+\1aU+\1dT*\1cL*\1eJ(\1cE'\1dB$\1a@#\e?"\1aÁ£­¿¡«¿\9fª¾\9e©Á\9d©Â\9eªÁ «Ã¢­» ©Ã¨±É¸¾ÕÄÊÔÎÐÓÍÏÈÊÉÄÆÅÿÀÀ¼½»·¸·³´¶²³¹µ¶¼¸¹¾º»µ±²À¼½ËÇÈÏËÌËÇÈÆÂÃÅÁÂÇÃÄÂÇÊÃÈËÏÎÓ¸·¼ÔÊÒÒÈÐ\87w\81zjt\96\82\8d|hskZdyhr\88}\85\92\87\8f\9b\91\99§\9d¥¬¢\96­£\97¿\9d\93¾\9c\92Ì\93\88Í\94\89Ò\99\88Ö\9d\8cÉ\9c\85Ë\9e\87Ȥ\8cÉ¥\8dÏ \90Î\9f\8fÙ\9a\93Ù\9a\93Ì\90\85¿\83x¨nc\91WLyC9l6,b0'`.%Z.%X,#Q)!N&\1eK&\1eL'\1fL)#M*$K'\eN*\1e\1!qF6\8eZE\9fkV«mVªlU­kQ¯mS¯mU¬jR¦eS£bP¡cT£eV«gP«gP«gPªfO¨dM¥aJ¢^G \E\9cXA\97S<\91M6\8dI2\8bG0\87C,\81=&|8!v8#u7"o5!l2\1ed/\1da,\1aZ+\eX)\19R*\1eP(\1cK)\1fI'\1dB%\1d@#\e>#\1c="\eÀ «¿\9fª¿\9e©¾\9d¨À\9c¨Á\9d©À\9fªÁ «Ç¬µÏ´½ÓÂÈÙÈÎÏËÌÊÆÇÂÄÃÀÂÁ¼¸¹¼¸¹¼¸¹½¹ºÀ¼½ÅÁÂÊÆÇÌÈÉÌÈÉÐÌÍÏËÌÇÃļ¸¹½¹ºÉÅÆ×ÓÔÂÇÊÊÏÒÕÔÙ¾½Âá×ßȾÆtdn\8f\7f\89\95\81\8cwcntcm\95\84\8e\9a\8f\97\8a\7f\87\98\8e\96À¶¾°¦\9a³©\9dã\98½\9d\92È\8f\84É\90\85Ó\9a\89ݤ\93Ã\99\81È\9e\86Ȥ\8cÉ¥\8dÎ\9f\8fÊ\9b\8bÑ\92\8bÑ\92\8bÑ\91\88È\88\7f·xo£d[\8cQI{@8k4-e.'_.)],'U(#P#\1eJ!\1dJ!\1dJ#\1eJ#\1eJ&\1aN*\1e`5%wL<\96bM¦r]°r[­oX­kQ¯mS°nV¬jR¥dR¢aO\9faR¡cTªfOªfO©eN¨dM¦bK£_H \E\9f[D\97S<\92N7\8cH1\89E.\87C,\83?(}9"x4\1dt7$s6#n3!j/\1dc.\1c_*\18X*\eV(\19Q)\1dP(\1cI(\1fG&\1dB%\1d@#\e;"\e:!\1aÈ\9f­È\9f­Æ¢®Ç£¯Å¥°Å¥°¼¥­»¤¬Ç¶¼ÒÁÇØÏÒÚÑÔÒÎÏÉÅÆÁÁÁÀÀÀ»¶¼ºµ»¹´º¼·½À»Á½ÃÀ»Á½¸¾µ°¶·²¸ºµ»¿ºÀþÄÇÂÈÊÅËËÆÌËÉÎËÉνÃÏÊÐÔÏÕ\9a\95\9b\85{\83º°¸¡\96\9ek`hm`i\98\8b\94\9c\8c\96\8b{\85\97\87\91¬\9c¦Îµ¹Ì³·Ä¥£´\95\93¸\90\88Â\9a\92Ð\9f\90Ð\9f\90Ô\9c\8bÌ\94\83Ê\92\81Ï\97\86Ï\9a\8cÊ\95\87É\95\88Ï\9b\8eÐ\8e\8bu¾}i§fR\91WC\89O;{F4p;)f7'Y*\1aN$\16P&\18M'\1aI#\16E#\17J(\1cb'\17n3#\80E3\8fTB\9c_M¤gU¬nY°r]±oY¯mW¬hQ¨dM§aH¥_F£]D£]D¨cD¥`A£^A¤_B£`E¡^C\9cZ@\97U;\93U<\91S:\8cP8\87K3\7fE/y?)u;'s9%l5!k4 d1\1eb/\1c[-\1dZ,\1cU.\1fU.\1fN.!H(\eD) H-$@,%7#\1c5"\1c;("Å\9f¬Æ ­Æ¢®Æ¢®Á£­Á£­¾§¯Áª²Ê»ÀÒÃÈ×ÎÑØÏÒÎÌÍÈÆÇÃÃÃÂÂÂÁ¼Â»¶¼¶±·µ°¶¸³¹¼·½½¸¾½¸¾¸³¹Á¼ÂÎÉÏØÓÙÙÔÚÑÌÒÅÀƽ¸¾ÊÈÍÓÑÖÌÇÍÍÈÎËÆÌ \9b¡\98\8e\96É¿Ç\99\8e\96h]em`i\98\8b\94\98\88\92\7foy\93\83\8d¼¬¶È²µÉ³¶Ç©§»\9d\9b¿\97\8fÅ\9d\95Ï\9e\8fË\9a\8bÑ\99\88É\91\80Ç\8e\95\84Í\98\8aÉ\94\86É\93\87Ï\99\8dÖ\93\80Ó\90\84o«mX\97\J\90UC\85M<zB1i8)[*\eP$\17R&\19R*\1eP(\1cQ-\1fX4&t9)~C3\8cQ?\97\J\9fbP£fT©kV«mX±oY®lV¬hQ¨dM¦`G¥_F£]D£]D¦aB£^?¡\?¢]@ ]B\9f\A\99W=\94R8\90R9\8eP7\8aN6\85I1}C-x>(t:&r8$l5!j3\1fd1\1ea.\e[-\1dZ,\1cT-\1eT-\1eP0#I)\1cB'\1eC(\1f:&\1f3\1f\185"\1c>+%Ã\9dªÆ ­Ä£®Á «º\9f¨¼¡ªÁ¬³Êµ¼ÎÂÆÒÆÊÓÍÏÓÍÏÌÌÌÈÈÈÅÇÆÅÇÆÆÁǾ¹¿µ°¶°«±±¬²¶±·¹´º»¶¼ÉÄÊÆÁÇÄ¿ÅÁ¼Â½ÃÅÀÆÈÃÉËÆÌÆÄÉÚØÝ×ÒØÉÄÊÁ¼Â®©¯²¨°ÒÈÐ\84y\81j_gpcl\8c\7f\88\88x\82rbl\8f\7f\89Ç·ÁÄ°²È´¶Ë¯¬Á¥¢Æ \97È¢\99Í\9e\8eÆ\97\87Ï\97\86Æ\8e\8a\91\81Ð\96\8aÍ\93\87Ì\93\88Ð\97\8cØ\97\85Ö\95\83Ç\88w±ra\9fdR\9a_M\90XG\86N=t@2f2$Y)\e\,\1e^2%_3&d:,nD6\8aO?\92WG\9b`N¡fT£fT£fT¥gR¦hS¯mW­kU«gP§cL¦`G¤^E£]D£]D£^? [<\9eY<\9eY<\9dZ?\9bX=\95S9\90N4\8dO6\8aL3\86J2\81E-z@*u;%q7#o5!l5!j3\1fd1\1ea.\eZ,\1cY+\eT-\1eT-\1eN.!H(\eA&\1dA&\1d9%\1e5!\1a;("I60¿\9e©Â¡¬Ã£®¿\9fª¸\9e§½£¬Ç´ºÓÀÆÓÈÌÔÉÍÐÌÍÐÌÍÊÌËÉËÊÆÊÉÆÊÉÉÄʽù´º³®´´¯µµ°¶¶±·¶±·Ã¾Ä¿ºÀ¹´º¶±·¹´ºÁ¼ÂÌÇÍÓÎÔÄÂÇ×ÕÚØÓÙÆÁÇÀ»Á½ÃÅ»ÃƼÄmbj{px|oxsfop`jtdn\93\83\8d¿¯¹Ã³´È¸¹Ê²®À¨¤Æ¡\98È£\9aÍ\9e\8eÆ\97\87Ñ\98\87Å\8c\86\8e\7fÑ\95\8aÏ\93\88Î\92\88Ñ\95\8bÖ\97\88×\98\89Ì\8d~»|m¬qa¨m]¡gY\97]O\88SCyD4l8*m9+n=.p?0wH8\81RB\97\L\9caQ£hV¥jX¤gU¢eS£eP¤fQ­kU¬jT©eN¦bK¥_F¤^E¤^E¤^E¡\=\9eY:\9bV9\9aU8\99V;\96S8\90N4\8bI/\89K2\87I0\82F.~B*w='s9#o5!n4 k4 i2\1ec0\1d`-\1aZ,\1cX*\1aS,\1dS,\1dI)\1cF&\19B'\1eE*!=)"9%\1eA.(O<6À «Á¡¬Á£­¾ ªº£«Â«³Í¼ÂÙÈÎÖÍÐÕÌÏÍÍÍÌÌÌÉÍÌÉÍÌÈÎÌÇÍËÉÄÊÄ¿Å¿ºÀ¼·½¼·½¹´ºµ°¶±¬²«¦¬¶±·ÇÂÈÔÏÕ×ÒØÐËÑÆÁǽ¸¾ÅÃÈÍËÐÐËÑÆÁÇÅÀÆÓÎÔÌÂʪ ¨k`h\9d\92\9a\90\83\8c^QZfV`\88x\82\9e\8e\98­\9d§Å¹¹Ç»»Ç´®º§¡À \95ã\98Í\9e\8eÇ\98\88Ï\96\85Á\88w¿\80\89\91\87Ï\8f\85Ì\8c\83Í\8d\84Ò\94\89×\99\8eÔ\96\8bÉ\8b\80Â\84\83x¹~p¯tf¡gY\91WI\82J9\80H7\81I8\80H7\84O=\8dXF\98]M\9dbR¢gU£hV£fT¡dR£eP¥gR«iSªhR¨dM¥aJ¥_F¤^E¤^E¤^E\9fZ;\9cW8\99T7\98S6\96S8\93P5\8cJ0\87E+\86H/\84F-\80D,|@(v<&r8"o5!m3\1fj3\1fh1\1db/\1c_,\19Y+\eX*\1aR+\1cR+\1cF&\19F&\19E*!G,#;' 3\1f\188%\1fF3-¤®À¢¬»¡ª½£¬Á¬³Í¸¿ÒÆÊÙÍÑÖÐÒÓÍÏÌÎÍÌÎÍËÑÏÌÒÐÇÐÍÄÍÊÈÃÉÅÀÆÁ¼Â¿ºÀ¿ºÀ»¶¼µ°¶¯ª°±¬²¸³¹Â½ÃÊÅËÌÇÍÇÂÈ¿ºÀºµ»ËÉÎÅÃÈÌÇÍËÆÌÈÃÉÖÑ×ȾÆ\93\89\91\86{\83½²º\9c\8f\98YLUrbl \90\9a¡\91\9b\9b\8b\95º¸Ä¼ºÅ´­¸§ ½\9f\94¿¡\96Ê\9c\8cÄ\96\86Å\8c{¶}l´rd¼zlÆ\82\81x¿zs¾yrÈ\89\82Ò\93\8c×\98\91Õ\96\8fÕ\96\8dÖ\97\8eÏ\91\86Å\87|°ue eU\92WE\8fTB\8dR@\8aO=\8cR>\94ZF\95ZJ\99^N\9ecQ eS¡dR¡dR¤fQ§iTªhR¨fP¦bK¤`I¤^E¤^E¤^E¤^E\9fZ;\9cW8\99T7\97R5\95R7\92O4\8bI/\85C)\85G.\83E,\7fC+|@(v<&r8"p6"n4 i2\1eh1\1da.\e_,\19X*\1aW)\19R+\1cR+\1cH(\eH(\eF+"E*!5!\1a-\19\124!\eD1+Ä©²½¢«¸\9e§¿¥®Ê·½ÙÆÌÙÍÑÚÎÒÖÒÓÓÏÐÌÎÍÏÑÐÍÖÓÍÖÓÇÒÎÁÌÈÊÅËĿŽ¸¾¹´º¹´º¸³¹µ°¶²­³¾¹¿ºµ»µ°¶³®´¶±·½¸¾ÆÁÇÌÇÍÔÒ×ÃÁÆÎÉÏÒÍÓÅÀÆÌÇÍÁ·¿\8c\82\8a¬¡©È½Å\92\85\8e]PY\89y\83¦\96 \90\80\8a\8b{\85¹´±¿º·Äµ®º«¤À¢\97¿¡\96Å\97\87»\8d}¶{k¥jZ¡]P©eX³me±kcªc]¦_Y¯rm¾\81\8f\8aÔ\95\90Ù\9a\93Ü\9d\96Õ\97\8cÉ\8b\80³uf¤fW\9a[J\98YH\96XC\91S>\93R>\98WC\95ZJ\99^N\9dbP\9fdR cQ¡dR¥gR©kV¨fP§eO¥aJ¤`I¤^E¤^E¤^E¥_F [<\9dX9\9aU8\98S6\95R7\91N3\8aH.\85C)\85G.\83E,\80D,|@(w='s9#q7#o5!i2\1eg0\1ca.\e^+\18X*\1aV(\18Q*\eQ*\eK+\1eI)\1cE*!D) 8$\1d:&\1fM:4fSMǬµ½¢«µ\9e¦¿¨°Ñ¾ÄáÎÔÝÒÖÙÎÒÖÒÓÒÎÏËÏÎÎÒÑÐÙÖÏØÕÆÒοËÇËÆÌþĸ³¹²­³±¬²´¯µµ°¶µ°¶®©¯µ°¶¾¹¿ÉÄÊÏÊÐÒÍÓÑÌÒÐËÑÛÙÞÅÃÈÔÏÕØÓÙÀ»ÁÀ»Á¼²º\8e\84\8cźÂĹÁ\80s|`S\\98\88\92 \90\9a{ku\80pz±­ªº¶³Å¸°¾±©Ä¨\9c¿£\97Á\93\83³\85uªo_\97\L\92NA\99UH¥\U£ZS\9aQK\95LF\99\Y¬olÁ\82\8d\88Ô\95\8eØ\99\92Ð\92\87Ä\86{°qb¢cT\9bZH\9bZH\9bXE\95R?\94R<\98V@\97\L\9b`P\9ecQ\9fdR cQ¡dR¥gR©kV§eO¦dN¥aJ£_H¤^E¤^E¤^E¥_F¡\=\9eY:\9aU8\98S6\95R7\92O4\8aH.\85C)\85G.\84F-\80D,}A)x>(t:$r8$p6"h1\1dg0\1ca.\e^+\18W)\19V(\18Q*\eQ*\eJ*\1dH(\eD) E*!A-&N:3p]W\92\7f\96 º\9c¦Â¨±Ð¶¿ÚÅÌßÊÑÙÊÏÕÆËÖÐÒ×ÑÓÔÒÓÓÑÒÐÒÑÍÏÎÈÎÌÇÍ˽ÃÁ¼Â¾¹¿ºµ»µ°¶±¬²­¨®¬§­±¬²·²¸¿ºÀÅÀÆÇÂÈÆÁǽÿºÀÎÌÍÇÅÆÆÂÃÆÂü¸¹©¥¦¡\98\9b \97\9aãØÜ©\9e¢mae{os \91\96}nsdUZ\8e\7f\84¶­¾³ª»¶¥­·¦®Ä£\9e¾\9d\98½\8c\82q¯p^ aO¨^Q¹ob»lh£TP\8e>A\8a:=\96F?\9dMF¨XQ·g`¿rhÁtj¹pg³ja\96RE\97SF\95VE\97XG\94YG\95ZH\97\J\97\J\94^F\96`H\97aG\96`F\96^E\97_F\9ddI¡hM¡dG¢eH¤eF\9f`A\9bZ:\99X8\9aY9\9d\<\99\@\98[?\97Z>\93V:\8dT9\88O4\82J1\80H/{E-zD,uA,s?*n;&l9$j7$h5"\2$[1#Y.\1eW,\1cX*\1aW)\19V*\1dV*\1dM(\1fT/&J0/?%$:+2ZKR\80u\83\9b\90\9e¹\9f¨À¦¯Ê³»Õ¾ÆÙÆÌÛÈÎÕÉÍÔÈÌÖÐÒ×ÑÓÔÒÓÓÑÒÐÒÑÍÏÎÈÎÌÇÍËÇÂÈÄ¿Å¿ºÀ¹´º´¯µ°«±®©¯­¨®¹´º´¯µ­¨®«¦¬±¬²¾¹¿ÍÈÎ×ÒØÉÇÈÆÄÅÊÆÇËÇÈÿÀ¶²³·®±½´·ØÍÑ\9a\8f\93}qu\99\8d\91\9e\8f\94o`egX]\94\85\8a³ª»¸¯À±¹¾­µÀ\9f\9a\95\90º\89\86u»|j´uc»qdÃylÅvr·hd¦VY\9dMP\9090\91:1\93?5\99E;\9cLC\9bKB\91G<\8bA6\89E:\89E:\84I;\87L>\88PC\8cTG\8fZL\91\N\8cV>\90ZB\94^F\96`H\97_F\9abI gL¤kP cG¢eI£cG `D\9bZ:\98W7\9aY9\9c[;\98[?\98[?\96Y=\93V:\8cS8\88O4\82J1\80H/{E-zD,uA,s?*n;&l9$j7$h5"]3%[1#Z/\1fX-\1dX*\1aX*\1aV*\1dV*\1dD\1f\16L'\1eE+*@&%=.5TELi^lujx¼§®Ç²¹ÔÁÇÚÇÍÖÇÌÔÅÊÓÈÌ×ÌÐÖÐÒ×ÑÓÔÒÓÓÑÒÐÒÑÍÏÎÉÍÌÈÌËÅÀÆÁ¼Âºµ»´¯µ²­³±¬²³®´´¯µ®©¯±¬²¶±·¼·½Â½ÃÇÂÈËÆÌÍÈÎÀ¾¿Á¿ÀÇÃÄÇÃĽ¹º³¯°¼³¶ÊÁÄÊ¿Ã\88}\81\96\8a\8e¶º\99\8a\8f\MRo`e\9f\90\95¬£´¸¯ÀɸÀòº¾\9d\98¯\8e\89¸\87\8a\84\89\84wÈ~qÊ{wÉzv¿or²be\9e@4\9a<0\938-\916+\8c8-\8a6+\803)z-#v3+u2*n3+p5-p>7wE>}LG\82QL\88Q<\8dVA\93\G\96_J\97_H\98`I\9dcK fN\9fbF¡dH£cG `D\9bZ<\98W9\99X:\9bZ<\97Z>\96Y=\95X<\92U9\8cS8\88O4\82J1\80H/{E-zD,uA,s?*n;&l9$j7$h5"]3%\2$Z/\1fX-\1dX*\1aX*\1aV*\1dW+\1eH#\1aH#\1a\1f8\1e\1d=.5SDK]R`^Saº«°È¹¾ÔÈÌØÌÐÒÇËÏÄÈÓÊÍÚÑÔÕÑÒÖÒÓÓÓÓÒÒÒÐÒÑÍÏÎËÍÌÊÌ˽¸¾¹´º³®´®©¯®©¯±¬²¶±·¹´º«¦¬²­³»¶¼Ã¾ÄÆÁÇÅÀÆÁ¼Â¾¹¿ÄÂÃÅÃÄÉÅÆÅÁµ±²©¥¦¶­°ÉÀ÷»\81vz­¡¥ÝÑÕ\8d~\83RCH\7fpu¨\99\9e\9e\95¦¬£´Á°¸À¯·¿\9e\99²\91\8c¹\88\89\82\8f\8b~Å{nÄuqÍ~zË{~¼lo»[M³SE¥I>\9eB7\94@6\90<2\87:2\836.q0*n-'f,(e+'d3/k:6oAAuGG\85N:\8aS?\90YE\93\H\93ZF\92YE\95[E\97]G\9d_F\9faH£cH `E\9c[?\98W;\98W;\99X<\95X<\95X<\94W;\91T8\8bR7\87N3\83K2\80H/{E-zD,uA,s?*n;&l9$j7$h5"^4&\2$[0 Y.\1eY+\eY+\eW+\1eW+\1eX3*L'\1e4\1a\193\19\18D5<eV]odrmbp·®±Ä»¾ÏÉËÓÍÏÎÈÊÍÇÉÒÎÏÚÖ×ÓÑÒÔÒÓÓÓÓÒÒÒÑÑÑÎÎÎËÍÌÊÌË¿ºÀºµ»²­³¬§­©¤ªª¥«®©¯°«±ºµ»³®´ª¥«¥ ¦©¤ªµ°¶Ä¿ÅÎÉÏÍËÌÍËÌÐÌÍÊÆǸ´µ­©ªº±´ÍÄǾ³·\89~\82¿³·ÞÒÖ\80qv[LQ\93\84\89§\98\9d\8a\81\92\97\8e\9f°\9f§º©±Æ¥ ¼\9b\96¼\8b\84s½~lÎ\8f\8b~Äzm¿plÉzvÌ|\7fÄtwÐslÇjc¸\W¬PK\9dJD\96C=\8a<8\8573|85w30k0,g,(c-+f0.h65m;:x@1}E6\84L;\88P?\8bR?\8dTA\92XD\96\H\9b]H\9e`K¢aK¡`J\9cZB\97U=\96T:\97U;\93V:\93V:\92U9\91T8\8bR7\87N3\83K2\81I0{E-zD,uA,s?*n;&l9$j7$h5"_5']3%\1!Z/\1fZ,\1cZ,\1cX,\1fX,\1fY4+M(\1f\1fE+*`QX\83t{\86{\89|q\7f¹·¸ÂÀÁÊÊÊÎÎÎÎÌÍÎÌÍÒÐÑ×ÕÖÒÒÒÓÓÓÓÓÓÒÒÒÑÑÑÎÎÎÌÌÌËËËÉÄÊþĺµ»°«±¨£©£\9e¤¢\9d£¡\9c¢¯ª°®©¯¬§­¯ª°·²¸Â½ÃÎÉÏÕÐÖÆÄÅÅÃÄÈÄÅÆÂú¶·²®¯¾µ¸ÎÅÈ»°´\9f\94\98ɽÁʾÂ{lqyjo§\98\9d\96\87\8ctk|\87~\8f§\96\9e»ª²Ì«¦Â¡\9c¾\8d\82\81\8d\8c\7fÊ\80sÂsoÃtpÊz}Í}\80à\8b\8eØ\83\86Éwy½km¯aa£UU\93IH\8a@?\80:8{53q0,j)%b% a$\1f`%\1fb'!h0#m5(s;,x@1\7fF5\86M<\90UC\98]K\99ZH\9d^L¢aM¡`L\9cZD\97U?\95S;\95S;\91T8\91T8\91T8\90S7\8aQ6\87N3\83K2\81I0{E-zD,uA,s?*n;&l9$j7$h5"_5'^4&]2"Z/\1f[-\1dZ,\1cY- Y- K&\1dJ%\1cG-,^DC|mt\93\84\8b\83x\86j_mÄÈÇÇËÊÊÎÍÍÑÐÑÓÒÑÓÒÒÒÒÒÒÒÒÒÒÓÓÓÓÓÓÒÒÒÑÑÑÎÎÎÍËÌÌÊËÉÄÊÅÀƾ¹¿¶±·®©¯§¢¨¤\9f¥¢\9d£ \9b¡¦¡§±¬²¼·½Ä¿ÅÇÂÈÈÃÉÇÂÈÄÂÿ½¾Á½¾Ã¿À¾º»·³´¾µ¸ÉÀõª®·¬°ÐÄȲ¦ª\7fpu\9f\90\95µ¦«yjobYj\81x\89®\9d¥Å´¼Ð¯ªÁ \9b½\8c\85\83\88\8a\88{Æws»lhÃsvÒ\82\85ß\95¤Û\91 ×\8e\99Ò\89\94Ê\81\88¾u|¯gj¥]`\90IE\8cEA\86@8\7f91y1%t, q)\eo'\19g/"i1$k3&l4'p6(x>0\84I9\8dRB\97XG\9c]L¢aO¡`N\9d[E\97U?\94R<\93Q;\90S7\90S7\90S7\8fR6\8aQ6\87N3\83K2\81I0{E-zD,uA,s?*n;&l9$j7$h5"`6(_5']2"[0 [-\1d[-\1dY- Z.!H#\1aJ%\1cI/.`FEvgn\82szh]kH=KÐÖÔÎÔÒÍÓÑÏÕÓÓ×ÖÒÖÕÑÓÒÍÏÎÑÓÒÒÔÓÓÓÓÒÒÒÒÐÑÏÍÎÍËÌÌÊËÁ¼ÂÀ»Á½¸¾ºµ»¶±·±¬²¯ª°­¨®«¦¬¥ ¦\9d\98\9e\9a\95\9b\9f\9a «¦¬ºµ»Ä¿ÅÓÑÒËÉÊÊÆÇÍÉÊÊÆǾ¿Ä»¾ÊÁį¤¨Ç¼ÀÓÇË£\97\9b\85v{¹ª¯¼­²dUZWN_\81x\89¹¨°Ï¾ÆÒ±¬¼\9b\96¼\8b\89\83\82\86\8b~Èyu´ea»knÓ\83\86Ð\8d¡Ñ\8e¢Õ\92¤Ù\96¨Ú\97¡Ò\8f\99Ç\80\84¾w{°fc­c`«^T¤WM\9dP@\97J:\92D0\8fA-q8-p7,l4'g/"e+\1di/!t9)|A1\96WF\9b\K¢aO¡`N\9dZG\97TA\93P=\93P=\8fR6\8fR6\8fR6\8fR6\8aQ6\87N3\83K2\82J1{E-zD,uA,s?*n;&l9$j7$h5"`6(_5']2"[0 [-\1d[-\1dY- Z.!Q,#N) D*)O54]NUgX_NCQ1&4ÕÕÕÎÎÎÐÐÐÜÜÜÜÜÜÐÐÐÎÎÎÕÕÕÓÓÓÒÒÒÐÐÐÒÒÒÔÔÔÒÒÒÌÌÌÇÇÇÿÀÿÀ½ÿºÀº´Â³­»¬¥·¨¡³¶¯Á¶¯Áµ¯½´®¼´¯µºµ»ÄÀÁÌÈÉËÇÈÆÂý¹º·³´µ±²¹µ¶¿»¼Ã¿À¾¿ÉÅÆìèé±­®\83\7f\80ÿÀÿÀzvwUGT\82t\81¢\8e\99µ¡¬×¼ÃؽÄÆ\9f ³\8c\8d»\8a\85½\8c\87É\8d\82Ë\8f\84Ì\89yÀ}mµl[«bQÊmpÌorÌu{Ô}\83Õ\8a\91Ú\8f\96Ò\90\9aÏ\8d\97Ã\84\8d¾\7f\88¿}\81À~\82½stª`a¡QP PO\93>;\92=:\8d:4\885/\7f2*\7f2*~8,\83=1\87H6\8cM;\91WA\98^H\95bG\93`E\8cZ?\89W<\91W?\8dS;\88P7\87O6\87Q9\86P8\80L6}I3\80M:|I6uD3rA0pA/n?-h:*d6&g4!f3 b1"`/ [/"Y- U.'U.'O0->\1f\1c9 #R9<ePUbMRP<EE1:ÖÖÖÏÏÏÐÐÐØØØØØØÐÐÐÏÏÏÖÖÖÕÕÕÓÓÓÑÑÑÒÒÒÓÓÓÑÑÑËËËÆÆÆÆÂÃÆÂÃÅÀƽý·Åµ¯½¯¨º«¤¶¥\9e°¤\9d¯¢\9cª\9f\99§\9f\9a ¦¡§±­®»·¸¸´µÄÀÁÏËÌÏËÌÄÀÁ¹µ¶µ±²µ±²ÔÐÑÅÁÂÇÃÄ\97\93\94\9b\97\98ÜØÙ¾º»oklwiv\90\82\8f\9f\8b\96¨\94\9fÄ©°Ë°·¾\9a\9a¯\8b\8b»\8a\85»\8a\85Ä\8a\8d\81Í\8a\81q¶o]ªcQ»][º\Z¹a`ÀhgÄuzÌ}\82Ê\83\89Ê\83\89Ë\89\8dÄ\82\86Ã}\7fÁ{}½ok«]Y¢RK¢RK\97D@\97D@\93C<\8f?8\8a=5\8b>6\8bE9\90J>\8bL:\8fP>\93[D\98`I\98bH\95_E\8cZ?\89W<\92X@\8eT<\89Q8\88P7\88R:\87Q9\82N8~J4\7fL9{H5tC2rA0pA/n?-h:*d6&i6#f3 _0 \-\1dY- Z.!X3+Z5-@!\1eH)&\CF}dg\84otq\aSBJE4<ØØØÒÒÒÑÑÑÕÕÕÕÕÕÑÑÑÒÒÒØØØÖÖÖÔÔÔÑÑÑÑÑÑÑÑÑÏÏÏÊÊÊÄÄÄÉÅÆÈÄÅÇÂÈÄ¿Å¿¹Ç¸²À²«½®§¹ª£µ§ ²¢\9cª\9d\97¥\9d\98\9e¥ ¦³¯°½¹ºÂ¾¿ËÇÈÍÉʾ¿³¯°±­®À¼½ÐÌÍÆÂþ¿·³´\95\91\92º¶·ãßঢ£njk¢\96¢\98\8c\98\90\7f\89\96\85\8f\9d£Ç®´Å¡¡´\90\90½\8e\88¹\8a\84¿\85\89\8b\84t¶r_¦bO°RH­OE©NF­RJ³_]¿kiÃuuÆxxÃyxºpo´id±faª\P\9aL@\95C5\98F8\94E@\95FA\95H@\93F>\8fF=\92I@\95QD\9bWJ\8fR?\93VC\96^G\99aJ\99cI\95_E\8e[@\8aW<\93YA\8fU=\8aR9\8aR9\89S;\88R:\83O9\7fK5~K8zG4sB1p?.o@.m>,g9)b4$g7#c3\1f^/\1f[,\1cV,\1eY/!W5,Z8/I,(dGC\84np\98\82\84\86sw`MQ?075&-ÚÚÚ×××ÔÔÔÔÔÔÔÔÔÔÔÔ×××ÚÚÚ×××ÔÔÔÐÐÐÏÏÏÏÏÏÍÍÍÉÉÉÄÄÄÈÄÅÈÄÅÇÂÈÄ¿Å¿¹Ç¸²À±ª¼­¦¸·°Â³¬¾¬¦´¦ ®¥ ¦®©¯½¹ºÉÅÆÇÃÄÉÅÆÄÀÁ¸´µ¯«¬µ±²ËÇÈßÛܤ ¡ÅÁÂÉÅÆ­©ªËÇÈÉÅÆ\85\81\82\83\7f\80À¶Á\90\86\91xhr\8az\84³\9c¢Ð¹¿Ñ²°µ\96\94À\93\8dº\8d\87¾\86\8a\8c\86uµr_¤aN±VD«P>¢H:¡G9¦OH²[T¸ea½jf²a]¨WS RH\9dOE\96I7\8a=+\87;$\8dA*\88?8\8bB;\8cF<\8dG=\8cH=\90LA\94UF\99ZK\93VC\96YF\97_H\9abK\99cI\95_E\8e[@\8bX=\94ZB\90V>\8bS:\8aR9\8aT<\89S;\84P:\80L6}J7xE2rA0o>-m>,k<*e7'a3#b3\1f`1\1d^0 \.\1eT-\1eT-\1eN-$N-$K/+kOK\85qr\84pq`PS<,/- '3&-ÙÙÙÚÚÚ×××ÓÓÓÓÓÓ×××ÚÚÚÙÙÙ×××ÒÒÒÎÎÎÌÌÌÍÍÍÌÌÌÉÉÉÆÆÆÆÂÃÆÂÃÅÀƽý·Å¶°¾¯¨º«¤¶²«½®§¹§¡¯ \9a¨\9f\9a §¢¨¶²³Á½¾»·¸Á½¾ÈÄÅËÇÈÉÅÆÅÁÂÁ½¾¿»¼ª¦§ÊÆÇËÇȳ¯°ËÇȲ®¯xtu£\9f ËÃÎ~v\81aV^\82w\7f°\9b Í¸½Ì®¬¢\84\82Ã\98\91½\92\8bÀ\8c\8e\80Ê\8d\86t¶ua§fR®\F¥S=\9bE4\95?.\97@7\9dF= KF£NI¤QK\9aGA\91C7\92D8\8cD.\85='\85?%\8cF,~>4\82B8\86F:\88H<\88J=\8bM@\91SD\96XI\92XD\94ZF\97_H\99aJ\99aH\95]D\91[A\8eX>\93YA\8fU=\8aR9\8aR9\89S;\88R:\83O9\7fK5{H5wD1p?.m<+l=+j;)d6&_1!\/\1a^1\1c\3!\3!U0 O*\1aC%\e\163\1c\16R;5hVVaOO>24, "1&,?4:ÓÓÓ×××ÖÖÖÐÐÐÐÐÐÖÖÖ×××ÓÓÓÔÔÔÐÐÐËËËÊÊÊÌÌÌÍÍÍËËËÉÉÉÆÂÃÆÂÃÅÀƽü¶Äµ¯½¯¨º«¤¶©¢´¦\9f± \9a¨\9a\94¢\99\94\9a \9b¡¬¨©¶²³ÊÆÇÈÄÅÆÂÃÄÀÁ¾¿¿»¼»·¸·³´ÒÎÏÉÅÆ´°±¦¢£Ã¿À®ª«\84\80\81¾¿ÉÃÍrlv^T\\85{\83¡\8e\92³ ¤´\98\95\87kh½\95\8d¼\94\8cÃ\92\83Ä\93\84É\8e\87u»}h³u`«cK¢ZB\98M:\8fD1\8c<3\8b;2\8a73\8851\90?;\8762\806+\84:/\7f>(z9#y=!\81E)|B6\81G;\85K=\87M?\87M?\88N@\8dTC\91XG\8fVB\91XD\94\E\96^G\96^E\94\C\92ZA\91Y@\91W?\8dS;\88P7\88P7\87Q9\86P8\81M7}I3zG4uB/o>-l;*j;)h9'b4$^0 Z0\1a[1\eZ4!Y3 R1 L+\1aA%\1a=!\16A-&VB;^NNP@@4*+* !,#(1(-ÈÈÈÐÐÐÒÒÒÊÊÊÊÊÊÒÒÒÐÐÐÈÈÈÑÑÑÍÍÍÉÉÉÈÈÈËËËÎÎÎÎÎÎÌÌÌÈÄÅÈÄÅÇÂÈÄ¿Å¿¹Ç¸²À±ª¼®§¹¨¡³§ ²£\9d«\9e\98¦\9c\97\9d¡\9c¢«§¨´°±ËÇÈÈÄž¿¹µ¶³¯°µ±²À¼½ÉÅÆÝÙÚ½¹º°¬­°¬­Ã¿Àª¦§\92\8e\8fÚÖ׿¼Ånktndl\94\8a\92\92\82\85\95\85\88£\8a\86\84kg±\8b\82·\91\88Å\96\86Ç\98\88É\90\8c\89\89tµya®rZ§dS\9e[J\9bPJ\92GA\8c<;\8554\8385|1.v3*{8/u<(p7#k< rC'{F8\80K=\84O?\85P@\85M>\84L=\87O>\8aRA\8bT?\8dVA\90XA\93[D\94\C\94\C\93[B\92ZA\8fU=\8bQ9\86N5\85M4\85O7\84N6~J4zF0yF3tA.m<+k:)i:(g8&a3#]/\1f]4\1e\3\1dV1\1eT/\1cO.\1dO.\1dK0%L1&s_Xt`Y`RQE761'(/%&*$(%\1f#¿¿¿ÊÊÊÍÍÍÆÆÆÆÆÆÍÍÍÊÊÊ¿¿¿ÏÏÏËËËÇÇÇÇÇÇÊÊÊÎÎÎÏÏÏÎÎÎËÇÈËÇÈÊÅËÇÂȼʻµÃ´­¿°©»¦\9f±¦\9f±¤\9e¬\9f\99§\9d\98\9e¡\9c¢©¥¦±­®¡\9d\9eµ±²ÊÆÇÏËÌÆÂý¹º¾º»ÅÁÂÇÃÄ°¬­Â¾¿ÏËÌÇÃÄ \9c\9d\96\92\93éå涳¼olu}v} \99 \8b|\7f\86wz¤\8b\87\95|x¦\81\8c\83Æ\97\87É\9a\8aË\92\7fÈ\8f\92\99\84Ç\90\8a\7fp¶xi²kg¥^Z\9bOQ\91EG\8bAB\85;<~?8\83D={H5tA.lD*qI/yE7}I;\80M<\81N=\7fJ:}H8\80H7\82J9\88Q<\8aS>\8dU>\91YB\92ZA\93[B\94ZB\94ZB\8dS;\89O7\84L3\83K2\83M5\82L4}I3yE/xE2tA.m<+j9(i:(g8&a3#\.\1e`:#[5\1eS.\eO*\17K,\1aR3!V;0\A6\90}v~kdVHG4&%*!":12?9=:48ǾÁéàã«¢¥Â¹¼ìã涭°º±´à×ÚÒÉ̶­°à×ÚÏÆÉÁ¸»ØÏÒǾÁÚÑÔÑÒÔ¶·¹°¯´ÆÅÊÐÏÔ½¼Á«¨±«¨±\9a\92\9f¡\99¦¦\9b«\9f\94¤\95\88\9a\93\86\98\9e\91£¬\9f±¿ºÀÉÄÊÐËÑÊÅ˽¸¾¹´ºÃ¾ÄÐËÑ­¨®Â½ÃÚÕÛÉÄÊ\9b\96\9c\92\8d\93µ°¶ÒÍÓ¦\94\92wecÀ®®Ã±±q^`\8bxz½¨§®\99\98\81b_¹\9a\97Á\95\8aÆ\9a\8f×\9e\8bÎ\95\82Þ\9e\85Ø\98\7fÊ¢\98Ë£\99Ë \97Ç\9c\93À\91\87´\85{¬xm¤pe\99aT\91YL\8aOA\84I;\89J;\8cM>\8fM?\8fM?\8fL9\8cI6\89F3\86C0\84C/\85D0\84F1\86H3\85K5\86L6\87O8\89Q:\8aT<\8dW?\8eX@\8fYA\87Q9\83M5\7fI1\7fI1~J4~J4yF3vC0q@/n=,i:*e6&b4%b4%a6&a6&^#\ed)!\/)T'!:#\1d;$\1e=82LGAstnOPJ4/)2-'C2+C2+F-&G.'ÓÊÍ¿¶¹´«®ÒÉÌÊÁı¨«È¿ÂÔËξµ¸Ä»¾×ÎÑƽÀú½ÓÊÍÉÀÃÌÃÆ·¸ºÍÎÐÒÑÖ¾½Âµ´¹½¼Á·´½¤¡ª \98¥£\9b¨¥\9aª\9f\94¤\9a\8d\9f\9a\8d\9f£\96¨­ ²¯ª°ºµ»ÅÀÆÆÁÇÀ»Á¾¹¿Ä¿ÅÌÇÍ«¦¬ÑÌÒ½Ã\98\93\99\99\94\9a¬§­¹´ºËÆÌ¡\8f\8d\8f}{ÕÂĽª¬iVX\8e{}¿©««\95\97\81b_·\98\95¿\93\8aÄ\98\8f×\9e\8dÏ\96\85á \8aÛ\9a\84Ñ©\9fÓ«¡Ö«¢Ô© Ñ¢\98È\99\8fÃ\8f\84½\89\83v³{n©n` eW\9d^O\99ZK\96TF\93QC\93P=\91N;\8cI6\89F3\86E1\85D0\84F1\85G2\82H2\83I3\84L5\86N7\86P8\88R:\8aT<\8aT<\82L4\7fI1{D/zC.yE0yE0tA.q>+l=+i:(e7'b4$^3#^3#_3&`4'c-#c-#V.&M%\1d6"\e8$\1d92,E>8NMI651'"\1e+&"<+$;*#<#\1e<#\1eÒÉÌ\97\8e\91ż¿×ÎѤ\9b\9e´«®ÐÇʹ¼¯¦©ÓÊÍż¿À·ºÉÀÃǾÁÌÃƹ¼»¼¾ÏÐÒÒÑÖ¾½Âµ´¹½¼Á¸µ¾£ © \98¥\9d\95¢\9a\8f\9f\96\8b\9b\98\8b\9d\9b\8e ¡\94¦¥\98ª«¦¬µ°¶Â½ÃÊÅËËÆÌÇÂÈÅÀÆÅÀÆÇÂÈÒÍÓ®©¯\9b\96\9cºµ»»¶¼¯ª°ÉÄÊ\9a\8a\8a¯\9f\9féÙÚ¬\9c\9d^NQ\96\86\89¾ª¬\9e\8a\8c\86hf¹\9b\99½\92\89Á\96\8dÖ\9e\8dÑ\99\88ã¥\90Ý\9f\8aÕ­£Ø°¦Ü±¨Þ³ªß°¦Û¬¢Ú¦\9bÖ¢\97Õ\9d\90Í\95\88Å\8a\80rµvg¬m^¤bT\9d[M\9bXE\98UB\93P=\8dJ7\89H4\87F2\85G2\86H3\80F0\81G1\81I2\82J3\82L4\83M5\84N6\85O7{G1xD.t@+s?*s@-r?,l;*h7&f8(d6&`5%^3#]1$]1$]3']3'b3)\-#K) F$\e:'!?,&?74F>;40/($#&\1e\1c-%#7(#3$\1f0\1c\15.\1a\13¶­°\98\8f\92ÖÍÐÁ¸»\98\8f\92ż¿Ä»¾°§ª¸¯²ÙÐÓ±¨«Ä»¾ÔËθ¯²ÍÄÇËÂÅÕÖغ»½³²·ÆÅÊÎÍÒ»º¿­ª³¯¬µ¥\9dª\9c\94¡\94\89\99\92\87\97\98\8b\9d\9e\91£¡\94¦¡\94¦©¤ª³®´Á¼ÂËÆÌÍÈÎÇÂȽ¸¾¶±·æáç°«±©¤ªÔÏÕÔÏÕ¥ ¦\9d\98\9e¿ºÀ\97\89\89Ⱥºîßâ\96\87\8aaRW©\9a\9f¹¦ª\85rv\95yxĨ§Á\98\92Â\99\93Ö¡\93Ñ\9c\8eä§\94Ý \8dÓ«¡Õ­£Û°§Ý²©à±§ß°¦à¬¡Þª\9fÕ\9d\90Ð\98\8bÍ\92\84Ç\8c\85vº{l±oa©gY¤aN¡^K\9aWD\93P=\8dL8\8aI5\87I4\87I4\82H2\82H2\82J3\82J3\81K3\82L4\82L4\82L4yF1uB-q>+p=*n=,l;*g8(c4$b7'a6&^4&^4&Z2&Z2&Z2(Z2(T2&K)\1d>!\19?"\1a@.*J84LBANDC0*,-')/%&2()7(%1"\1f-\1a\14(\15\ f\94\8b\8e¼³¶ÚÑÔ\9e\95\98§\9e¡×ÎÑ­¤§ª¡¤ÎÅÈÍÄǧ\9e¡ÏÆÉ×ÎÑ®¥¨ÍÄÇØÏÒÊËÍ·¸º·¶»ÉÈÍËÊϸ·¼³°¹¿¼Å®¦³¢\9a§\97\8c\9c\94\89\99\9b\8e ¢\95§¤\97©¢\95§\9e\99\9fª¥«¹´ºÆÁÇÉÄÊþĹ´º±¬²ÝØÞ\94\8f\95¶±·êåë´¯µ\8f\8a\90ª¥«®©¯\98\8c\90ÐÄÈÝÒØ\81v|shn¾³¹¬\9b¡kZ`¨\8e\8fÑ·¸È¡\9cÄ\9d\98Ö¢\95Ñ\9d\90â§\95Û \8eÒª Ô¬¢Ø­¤Ù®¥Ü­£Ú«¡Ü¨\9dÛ§\9cÓ\9b\8eÐ\98\8bÎ\93\85Ê\8f\81Ê\8b\82s¸vh°n`¬iV¨eR¡^K\9aWD\93R>\8eM9\8bM8\8bM8\87M7\87M7\86N7\85M6\84N6\83M5\83M5\83M5xG6tC2p?.n=,m>.k<,c8(_4$`6(`6(]5+]5+Z4)Y3(W1(V0'E. ;$\161\1d\14\17<-*F74H<@F:>-"(,!',!%+ $0"!1#",\1d\1a%\16\13\90\87\8aÛÒÕÈ¿Â\8e\85\88Á¸»ÔËÎ\9e\95\98°§ªØÏÒµ¬¯®¥¨ÓÊÍǾÁ´«®ÏÆÉÑÈ˧¨ªÉÊÌØ×ÜÁÀů®³¸·¼ÅÂËÃÀÉ«£°\9f\97¤\94\89\99\8e\83\93\92\85\97\97\8a\9c\9a\8d\9f\9a\8d\9f\9a\95\9b¨£©ºµ»ÈÃÉÍÈÎËÆÌÉÄÊÈÃÉÀ»Á«¦¬ÏÊÐËÆÌ\8e\89\8f¥ ¦ÏÊЩ¤ª\97\8c\92ÌÁÇȾÆ|rz\93\89\91ÐÆÎ\9e\8f\96_PW´\9b\9eÙÀÃÈ¥¡Á\9e\9aÓ¡\96Ï\9d\92à¨\97Ø \8fÔ¬¢Õ­£Ø­¤Ø­¤Ùª Ø©\9fÚ¦\9bÙ¥\9aÙ¡\94Õ\9d\90Ñ\96\88Í\92\84Ë\8c\83t¹wi±oa²o\®kX§dQ\9f\I\98WC\94S?\90R=\90R=\8cR<\8bQ;\89Q:\88P9\86P8\84N6\84N6\83M5xI9tE5n@0l>.j?/h=-a7)]3%\4*\4*[5,Z4+V1(S.%N,#L*!6)\190#\13*\1d\14,\1f\162$#7)(4'.1$+$\17 %\18!#\16\1d$\17\1e/!!8**3%$(\1a\19²©¬ÞÕا\9e¡\9c\93\96ÑÈ˺±´¢\99\9c¿¶¹ËÂÅ\9c\93\96ú½ÌÃƨ\9f¢Æ½ÀÔËᨫ³´¶ÊËÍÐÏÔ»º¿´³¸ÂÁÆÆÃÌ»¸Á­¥²£\9b¨\98\8d\9d\8f\84\94\8d\80\92\91\84\96\96\89\9b\99\8c\9e\99\94\9a©¤ª½¸¾ÆÁÇÇÂÈÆÁÇÍÈÎÓÎÔª¥«ÐËÑÏÊЧ¢¨¤\9f¥Ä¿ÅĿŦ¡§\94\8b\90Ä»À¼²º\87}\85´ª³ÚÐÙ\90\83\8cbU^µ\9f¢ÖÀÃÄ¡\9f¼\99\97Ï\9f\95Ì\9c\92à¨\99×\9f\90Ó«¡Ó«¡Õª¡Õª¡×¨\9eÖ§\9dÙ¥\9aؤ\99Ø \93Ô\9c\8fÏ\94\86Ê\8f\81È\89\82sºxj´rd¶s`²o\ªgT£`M\9c[G\98WC\95WB\94VA\8dS=\8dS=\8aR;\88P9\86P8\83M5\82L4\81K3vH8rD4m?0j<-h</e9,_5)[1%W1&W1&V1(T/&N,#I'\1eD!\eA\1e\18'$\13'$\13*#\19,%\e0$$1%%0!(-\1e%2"-3#.1!+3#-@46K?A?33*\1e\1eÖÍÐÒÉÌ\8d\84\87²©¬×ÎÑ \97\9a¬£¦ÌÃƹ°³\8c\83\86ÕÌϹ¼\8f\86\89ÖÍÐ×ÎÑ\93\8a\8dáâ䶷¹£¢§¼»ÀÕÔÙÌËй¶¿°­¶¼´Áµ­ºª\9f¯\9f\94¤\99\8c\9e\9b\8e ¢\95§¨\9b­\92\8d\93£\9e¤´¯µ¸³¹²­³°«±ºµ»ÅÀÆ\9e\99\9fÚÕÛµ°¶\97\92\98ÑÌÒÈÃÉ\8e\89\8f\99\94\9a\8f\88\8f½¶½·°¸\90\89\91Ç¿ÊÛÓÞ\8a}\86l_h±\9c¡Ñ¼Á¾\9c\9aµ\93\91Ë\9c\92Ê\9b\91Þ©\99Ö¡\91Φ\9cÍ¥\9bϤ\9bÐ¥\9cÔ¥\9bÓ¤\9a×£\98×£\98Ï\97\8aÊ\92\85Ç\8c\87\85\81r½{m¸vh·ta³p]¬iV¥bO\9e]I\9bZF\98ZE\97YD\8dS=\8cR<\8aR;\87O8\84N6\82L4\80J2\7fI1uG8pB3i>.f;+d:,b8*Z2&V."S-$S-$R-%P+#I& C \1a<\e\149\18\11\1e\1f\ f"#\13-)\1e1-"6,-6,-8(27'1L:FM;GH8BK;EXLP`TXKA@-#"¸¶·¶´µ¯«¬¼¸¹ÇÃÄ¥¡¢¢\99\9cÓÊÍ\9b\90\94¡\96\9aã×Û\9c\90\94Á²·Ê»À®\9f¤ÏÀÅÌÇͳ®´Ã¾ÄÑÌÒ¶±·´¯µËÆÌÅÀÆÕÐÖÁ¼Â§¢¨\93\8e\94\8c\87\8d\8a\85\8b\89\84\8a\88\83\89\8f\84\95\90\85\96\96\8b\9c©\9e¯Ä¹ÉÒÇ×ɾ̸­»\9f\95 íãî¤\9a¢É¿Çǽŵ«³¥\9c¡\96\8d\92¦¤©À¾Ã¥£¨\9a\98\9däßæÅÀÇi^d\91\86\8c͹º¯\9b\9c\94riÁ\9f\96С\8fº\8byã«\94Ò\9a\83ݤ\9bÛ¢\99Ù \97×\9e\95Ö\9c\91Ö\9c\91×\9b\90×\9b\90Ì\8d\8b\87\83sÁ~m½ziºwf¸udµmW³kU®gQ©bL¡_I\9cZD\95WB\93U@\90UC\8cQ?\83N<\82M;\81N=\7fL;xI7tE3r=-n9)g6'c2#]1$Z.!P, M)\1dP4)Q5*D0)7#\1c.!\e3& ,#\1e"\19\14&\1a\1e, $/#'."&."&5)-?37G;?xlpxlpZNRC7;QEIUIMB6:9-1³±²\9a\98\99·³´ÓÏд°±\9f\9b\9c¼³¶ÓÊÍ\8f\84\88ø¼Ë¿Ã\99\8d\91ÕÆË·¨­¬\9d¢ßÐÕ®©¯©¤ªÍÈν¸¾´¯µÎÉÏÄ¿ÅþĠ\9b¡«¦¬³®´¨£©\93\8e\94\86\81\87\8c\87\8d\98\93\99\7ft\85\8e\83\94¤\99ªº¯ÀɾÎËÀп´Â²§µÙÏÚº°»\9e\94\9cá×ß³©±¡\97\9f¸¯´ÊÁÆ«¦¬¤\9f¥\81\7f\84\8d\8b\90áÜ㿺Áj`h£\99¡Ó¿À\9c\88\89}\U±\90\89È\9a\8b¹\8b|ߨ\94Í\96\82Õ\9c\93Ô\9b\92Ò\99\90Ð\97\8eÐ\96\8bÏ\95\8aÏ\93\88Ð\94\89È\89\87\83sÀ~n½zi¹ve¶sb´q`°iS®gQ¨dO£_J\9c[G\97VB\90S@\8eQ>\8aQ>\85L9}J7{H5zI8xG6rD4n@0vB4o;-c3%]-\1fW-!X."U3)V4*A&\1d?$\e5"\1c.\e\15#\15\12#\15\12&\1c\1a-#!0$(4(,6*.=15PDHbVZ\PTK?CnbfthlXLP:.2<04=157+/=15ª¨©\9d\9b\9cÐÌÍÔÐÑ\96\92\93­©ªÜÓÖ´«®\8f\84\88æÛߧ\9b\9f \94\98åÖÛ\9f\90\95¸©®åÖÛ\95\90\96¯ª°ÏÊЬ§­¸³¹ÛÖܺµ»ºµ»ª¥«·²¸À»Áµ°¶\9d\98\9e\88\83\89\82}\83\86\81\87\84y\8a\94\89\9aª\9f°¹®¿¼±Á·¬¼´©·³¨¶íãî\8e\84\8f²¨°æÜä\98\8e\96«¡©ÌÃÈ×ÎÓ\9b\96\9a\8e\89\8d~y\7f\98\93\99ÚÕÜ®©°qgoÅ»ÃÛÈÊ\86sujMI¦\89\85À\96\8a\8c\80Ö£\92Ç\94\83Ì\93\8aË\92\89Ê\91\88É\90\87È\8e\83Ç\8d\82Ç\8b\80Æ\8a\7fÂ\83\82s¿}m»yi¸ud´q`±n]¯l[¨fP¦dN¢aM\9d\H\95VD\90Q?\89P=\86M:\80K9|G5uD3sB1qC3oA1i>.e:*i=0f:-`6*[1%R-$O*!J,$J,$=$\1f;"\1d=+)D204)''\1c\1a0&'G=>UIMTHLI=AG;?dX\\83w{xlpVJNVJNbVZL@D-!%'\e\1f'\e\1f0$(G;?ª¨©ÄÂÃßÛܶ²³\92\8e\8fÌÈÉà×Ú\8a\81\84ª\9f£êßã\8c\80\84¹­±ÝÎÓ\8f\80\85ÕÆËÏÀÅ\96\91\97ÈÃɹ´º®©¯ÆÁÇĿźµ»´¯µØÓÙËÆ̺µ»°«±ª¥«\9d\98\9e\88\83\89vqw\9d\92£\9b\90¡\9c\91¢\9e\93¤\9e\93£ \95¥®£±¾³ÁÁ·Â\90\86\91ÙÏ×ĺÂ\91\87\8fÕËÓÈ¿Ä© ¥\8f\89\8d\99\93\97 \9b¡©¤ªÈÃÊ \9b¢\80y\81áÚâ×ÈÍyjou[Z¯\95\94\91\88«\86\9a\8d¿\91\84Æ\8d\84Æ\8d\84Æ\8d\84Å\8c\83Ä\8a\7fÂ\88\85\84\7fp¼}n»yi·ue´q`¯l[¬iXªgV¢dO bM\9b^K\96YF\8eUB\89P=\82M;\80K9xG6tC2k@/j?.g@/e>-`;+\7'T0$X4(Y7-X6,O1)F( ;"\1d\e=('C.-ZJKueffZ^E9=A8=WNS\7fsw\7fswg[_L@DVJNwkoxlp_SW:.2G;?8,0#\17\e$\18\1c%\19\1d0$(L@D¿½¾×ÕÖÅÁ¦¢£¼¸¹ÙÕÖÀ·º\90\87\8aÎÃÇÏÄÈ\87{\7f×ËÏ¿°µ\94\85\8aðáæª\9b ¤\9f¥ÙÔÚ\99\94\9a»¶¼ÔÏÕ¦¡§ÇÂÈ»¶¼ÌÇÍÀ»Áµ°¶´¯µ·²¸°«±\9c\97\9d\8a\85\8b \95¦\90\85\96\87|\8d\8a\7f\90\91\86\96\9a\8f\9f¯¤²ÅºÈ\9f\95 ¨\9e©åÛã\9c\92\9aª ¨ìâê¨\9f¤\95\8c\91­¤§³ª­©¤¨\95\90\94©¦­£ §\97\91\9bãÝçÄ·¾qdk\93}\7fÁ«­¥\84\7f\97vq°\8a\81¯\89\80Á\88\7fÂ\89\80Ã\8a\81Ã\8a\81Â\88}¿\85\81\80u¹zk¸yj¶td²p`¯l[«hW§dS¦cR\9baM\99_K\93\H\8eWC\87R@\82M;{J9yH7pE4lA0e>-c<+a=-_;+Y8)U4%H+#K.&L1*J/(E.(G0*L76S>=@01N>?uho\9d\90\97\95\8a\92i^fQGPXNW\80tx\8c\80\84~rvYMQH<@VJN_SWYMQ/#'5)-)\1d!"\16\1a."&, $, $?37ÕÓÔÁ¿À¥¡¢»·¸åáâÈÄŧ\9e¡¿¶¹ÜÑÕ±¦ª\9b\8f\93ã×Û¢\93\98«\9c¡îßä\98\89\8e³®´ÎÉÏ\94\8f\95À»ÁÏÊУ\9e¤ÐËÑþī¦¬¹´ºÇÂÈÈÃɺµ»¨£©\9c\97\9d\98\93\99\8b\80\91\80u\86\80u\86\90\85\96\99\8e\9e\9c\91¡« ®Á¶Ä¢\98£¯¥°ÏÅÍ\8f\85\8dËÁÉÖÌÔ\8f\86\8b¹°µÕÌ͸¯°\92\8c\90tnr\92\8f\96ª§®£\9d§ÕÏÙ«¡ªmcl³ ¤Íº¾\8dqp\84hg\9f~y \7f\7f\81\82\83\82w¸~sµyn³wl²sd°qb¯m]«iY¨eT£`O ]L\9f\K\90[I\8eYG\8aWD\85R?|M;wH6qF5nC2hA0d=,\;*Z9(Y9*W7(P4&L0"F2+C/(<)#7$\1e<*(R@>p`a\88xyVJNaUY\82v\80¨\9c¦« ®\8b\80\8embrbWg`TXsgkznrfZ^L@DA59B6:E9=2&*2&*%\19\1d%\19\1d6*.-!%"\16\1a-!%ÒÐÑ°®¯¶²³ØÔÕÒÎϵ±²¼³¶ØÏÒʿã\98\9cº®²×ËÏ\97\88\8dȹ¾Í¾Ã¥\96\9bĿŵ°¶ºµ»·²¸³®´À»ÁÁ¼Â¸³¹¶±·Á¼ÂÊÅËÇÂȺµ»ª¥« \9b¡\9d\98\9e\89~\8f\86{\8c\8f\84\95\9e\93¤\9a\8f\9f\90\85\95\9f\94¢»°¾\9b\91\9c¡\97¢¾´¼\97\8d\95ÐÆζ¬´\9a\91\96ÛÒ×ÍÃĦ\9c\9d\8d\87\8b\83}\81\95\92\9b\9b\98¡\95\92\9dÐÍØ\9f\97¢nfqÊ»ÂÏÀÇ|cf\81hk\9f\81\81\9c~~«ri­tk¯vm±xo°vk¬rg©mb¦j_©j[§hY¦dT¢`P\9f\K\9aWF\97TC\95RA\85UA\83S?~O=yJ8sE5n@0e>-c<+_;+[7'T4%R2#O3%N2$H.!D*\1d=0*</)9+(7)&>22ZNN\7fsw\9b\8f\93pemmbjshv\86{\89\98\8d\9d\98\8d\9d\83z\8dpgzVJNVJN[OS_SWRFJ<041%)4(,1%)/#'#\17\e&\1a\1e5)-)\1d!\1d\11\15+\1f#À¾¿´²³ãßàäàá¢\9e\9f°¬­äÛÞÎÅȱ¦ª£\98\9cÑÅÉƺ¾\97\88\8dÜÍÒ¬\9d¢º«°ÓÎÔ¢\9d£æá笧­\97\92\98ÝØÞª¥«¥ ¦ÓÎÔÀ»Á±¬²²­³¿ºÀĿźµ»«¦¬\9a\8f \9a\8f ¡\96§¤\99ª\90\85\95}r\82\92\87\95¸­»\7fu\80\91\87\92¸À \96\9eÀ¶¾©\9f§¶­²ÜÓؤ\9a\99\90\86\85£\9d\9f°ª¬¥¢«\82\7f\88\81~\89ÙÖá\9f\99¥tnz×ÊÓÐÃÌu_b\87qt©\8c\8e \83\85¡h_£ja¦md§ne§mb£i^\9fcX\9b_T¢cT¡bS\9f]M\9bYI\98UD\94Q@\90M<\8fL;}N<{L:wJ7rE2j?.e:)^9'[6$X7(T3$M0"K. I/ H.\1fA*\1c=&\18/$ 7,(?42E:8KAB]STwlr\8b\80\86wmvf\eSHXVK[qhy\8b\82\93\88\7f\92sj}eY]I=A=15L@DOCG;/3, $-!%(\1c )\1d\14\18$\18\1c0$(%\19\1d \14\186*.
\ No newline at end of file
diff --git a/testorig.jpg b/testorig.jpg
new file mode 100644 (file)
index 0000000..1a628fc
Binary files /dev/null and b/testorig.jpg differ