The Independent JPEG Group's JPEG software v6b
diff --git a/README b/README
index fa69a18..86cc206 100644
--- a/README
+++ b/README
@@ -1,8 +1,8 @@
 The Independent JPEG Group's JPEG software
 ==========================================
 
-README for release 6a of 7-Feb-96
-=================================
+README for release 6b of 27-Mar-1998
+====================================
 
 This distribution contains the sixth public release of the Independent JPEG
 Group's free JPEG software.  You are welcome to redistribute this software and
@@ -13,9 +13,10 @@
 our electronic mailing list.  Mailing list members are notified of updates
 and have a chance to participate in technical discussions, etc.
 
-This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim
-Boucher, Lee Crocker, Julian Minguillon, George Phillips, Davide Rossi,
-Ge' Weijers, and other members of the Independent JPEG Group.
+This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
+Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
+Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
+Group.
 
 IJG is not affiliated with the official ISO JPEG standards committee.
 
@@ -126,7 +127,7 @@
 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-1996, Thomas G. Lane.
+This software is copyright (C) 1991-1998, Thomas G. Lane.
 All Rights Reserved except as specified below.
 
 Permission is hereby granted to use, copy, modify, and distribute this
@@ -166,8 +167,11 @@
 of any program generated from the IJG code, this does not limit you more than
 the foregoing paragraphs do.
 
-The configuration script "configure" was produced with GNU Autoconf.  It
-is copyright by the Free Software Foundation but is freely distributable.
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltconfig, ltmain.sh).  Another support script, install-sh, is copyright
+by M.I.T. but is also freely distributable.
 
 It appears that the arithmetic coding option of the JPEG spec is covered by
 patents owned by IBM, AT&T, and Mitsubishi.  Hence arithmetic coding cannot
@@ -178,13 +182,12 @@
 So far as we are aware, there are no patent restrictions on the remaining
 code.
 
-WARNING: Unisys has begun to enforce their patent on LZW compression against
-GIF encoders and decoders.  You will need a license from Unisys to use the
-included rdgif.c or wrgif.c files in a commercial or shareware application.
-At this time, Unisys is not enforcing their patent against freeware, so
-distribution of this package remains legal.  However, we intend to remove
-GIF support from the IJG package as soon as a suitable replacement format
-becomes reasonably popular.
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs".  This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
 
 We are required to state that
     "The Graphics Interchange Format(c) is the Copyright property of
@@ -203,21 +206,21 @@
 	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.)  If you don't have the CACM issue
-handy, a PostScript file containing a revised version of Wallace's article
-is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz.  The file (actually
+handy, a PostScript file containing a revised version of Wallace's article is
+available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz.  The file (actually
 a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
 omits the sample images that appeared in CACM, but it includes corrections
-and some added material.  Note: the Wallace article is copyright ACM and
-IEEE, and it may not be used for commercial purposes.
+and some added material.  Note: the Wallace article is copyright ACM and IEEE,
+and it may not be used for commercial purposes.
 
 A somewhat less technical, more leisurely introduction to JPEG can be found in
-"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood
-City, CA), 1991, ISBN 1-55851-216-0.  This book provides good explanations and
-example C code for a multitude of compression methods including JPEG.  It is
-an excellent source if you are comfortable reading C code but don't know much
-about data compression in general.  The book's JPEG sample code is far from
-industrial-strength, but when you are ready to look at a full implementation,
-you've got one here...
+"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
+M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1.  This book provides
+good explanations and example C code for a multitude of compression methods
+including JPEG.  It is an excellent source if you are comfortable reading C
+code but don't know much about data compression in general.  The book's JPEG
+sample code is far from industrial-strength, but when you are ready to look
+at a full implementation, you've got one here...
 
 The best full description of JPEG is the textbook "JPEG Still Image Data
 Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
@@ -242,10 +245,9 @@
 Continuous-tone Still Images, Part 2: Compliance testing" and has document
 numbers ISO/IEC IS 10918-2, ITU-T T.83.
 
-Extensions to the original JPEG standard are defined in JPEG Part 3, a new ISO
-document.  Part 3 is undergoing ISO balloting and is expected to be approved
-by the end of 1995; it will have document numbers ISO/IEC IS 10918-3, ITU-T
-T.84.  IJG currently does not support any Part 3 extensions.
+Some extensions to the original JPEG standard are defined in JPEG Part 3,
+a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84.  IJG
+currently does not support any Part 3 extensions.
 
 The JPEG standard does not specify all details of an interchangeable file
 format.  For the omitted details we follow the "JFIF" conventions, revision
@@ -255,24 +257,22 @@
 	1778 McCarthy Blvd.
 	Milpitas, CA 95035
 	phone (408) 944-6300,  fax (408) 944-6314
-A PostScript version of this document is available at ftp.uu.net, file
-graphics/jpeg/jfif.ps.gz.  It can also be obtained by e-mail from the C-Cube
-mail server, netlib@c3.pla.ca.us.  Send the message "send jfif_ps from jpeg"
-to the server to obtain the JFIF document; send the message "help" if you have
-trouble.
+A PostScript version of this document is available by FTP at
+ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz.  There is also a plain text
+version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
+the figures.
 
-The TIFF 6.0 file format specification can be obtained by FTP from sgi.com
-(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed
-copy from Aldus Corp. at (206) 628-6593.  The JPEG incorporation scheme
+The TIFF 6.0 file format specification can be obtained by FTP from
+ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz.  The JPEG incorporation scheme
 found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
 IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
 Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
-(Compression tag 7).  Copies of this Note can be obtained from sgi.com or
-from ftp.uu.net:/graphics/jpeg/.  It is expected that the next revision of
-the TIFF spec will replace the 6.0 JPEG design with the Note's design.
+(Compression tag 7).  Copies of this Note can be obtained from ftp.sgi.com or
+from ftp://ftp.uu.net/graphics/jpeg/.  It is expected that the next revision
+of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
 Although IJG's own code does not support TIFF/JPEG, the free libtiff library
 uses our library to implement TIFF/JPEG per the Note.  libtiff is available
-from sgi.com:/graphics/tiff/.
+from ftp://ftp.sgi.com/graphics/tiff/.
 
 
 ARCHIVE LOCATIONS
@@ -281,26 +281,27 @@
 The "official" archive site for this software is ftp.uu.net (Internet
 address 192.48.96.9).  The most recent released version can always be found
 there in directory graphics/jpeg.  This particular version will be archived
-as graphics/jpeg/jpegsrc.v6a.tar.gz.  If you are on the Internet, you
-can retrieve files from ftp.uu.net by standard anonymous FTP.  If you don't
-have FTP access, UUNET's archives are also available via UUCP; contact
+as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz.  If you don't have
+direct Internet access, UUNET's archives are also available via UUCP; contact
 help@uunet.uu.net for information on retrieving files that way.
 
 Numerous Internet sites maintain copies of the UUNET files.  However, only
 ftp.uu.net is guaranteed to have the latest official version.
 
 You can also obtain this software in DOS-compatible "zip" archive format from
-the SimTel archives (ftp.coast.net:/SimTel/msdos/graphics/), or on CompuServe
-in the Graphics Support forum (GO CIS:GRAPHSUP), library 12 "JPEG Tools".
-Again, these versions may sometimes lag behind the ftp.uu.net release.
+the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
+on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
+"JPEG Tools".  Again, these versions may sometimes lag behind the ftp.uu.net
+release.
 
 The JPEG FAQ (Frequently Asked Questions) article is a useful source of
 general information about JPEG.  It is updated constantly and therefore is
 not included in this distribution.  The FAQ is posted every two weeks to
 Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
-You can always obtain the latest version from the news.answers archive at
-rtfm.mit.edu.  By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and
-.../part2.  If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu
+It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
+and other news.answers archive sites, including the official news.answers
+archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
+If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
 with body
 	send usenet/news.answers/jpeg-faq/part1
 	send usenet/news.answers/jpeg-faq/part2
@@ -315,21 +316,20 @@
 obtain them on Internet.
 
 If you are on a Unix machine, we highly recommend Jef Poskanzer's free
-PBMPLUS image software, which 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 obtain this package by FTP from ftp.x.org
-(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z).  There is also
-a newer update of this package called NETPBM, available from
-wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/.
-Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software
-is; you are likely to have difficulty making it work on any non-Unix machine.
+PBMPLUS software, which 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, thus making cjpeg/djpeg considerably more useful.  The latest
+version is distributed by the NetPBM group, and is available from numerous
+sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
+Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
+you are likely to have difficulty making it work on any non-Unix machine.
 
 A different free JPEG implementation, written by the PVRG group at Stanford,
-is available from havefun.stanford.edu in directory pub/jpeg.  This program
+is available from ftp://havefun.stanford.edu/pub/jpeg/.  This program
 is designed for research and experimentation rather than production use;
 it is slower, harder to use, and less portable than the IJG code, but it
 is easier to read and modify.  Also, the PVRG code supports lossless JPEG,
-which we do not.
+which we do not.  (On the other hand, it doesn't do progressive JPEG.)
 
 
 FILE FORMAT WARS
@@ -370,14 +370,16 @@
 TO DO
 =====
 
+The major thrust for v7 will probably be improvement of visual quality.
+The current method for scaling the quantization tables is known not to be
+very good at low Q values.  We also intend to investigate block boundary
+smoothing, "poor man's variable quantization", and other means of improving
+quality-vs-file-size performance without sacrificing compatibility.
+
 In future versions, we are considering supporting some of the upcoming JPEG
 Part 3 extensions --- principally, variable quantization and the SPIFF file
 format.
 
-Tuning the software for better behavior at low quality/high compression
-settings is also of interest.  The current method for scaling the
-quantization tables is known not to be very good at low Q values.
-
-As always, speeding things up is high on our priority list.
+As always, speeding things up is of great interest.
 
 Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
diff --git a/cderror.h b/cderror.h
index 41a29cd..70435e1 100644
--- a/cderror.h
+++ b/cderror.h
@@ -1,7 +1,7 @@
 /*
  * cderror.h
  *
- * Copyright (C) 1994, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -72,7 +72,7 @@
 #ifdef PPM_SUPPORTED
 JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
 JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
-JMESSAGE(JERR_PPM_NOT, "Not a PPM file")
+JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
 JMESSAGE(JTRC_PGM, "%ux%u PGM image")
 JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
 JMESSAGE(JTRC_PPM, "%ux%u PPM image")
diff --git a/cdjpeg.c b/cdjpeg.c
index a3d6e06..b6250ff 100644
--- a/cdjpeg.c
+++ b/cdjpeg.c
@@ -1,7 +1,7 @@
 /*
  * cdjpeg.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -47,7 +47,9 @@
 enable_signal_catcher (j_common_ptr cinfo)
 {
   sig_cinfo = cinfo;
+#ifdef SIGINT			/* not all systems have SIGINT */
   signal(SIGINT, signal_catcher);
+#endif
 #ifdef SIGTERM			/* not all systems have SIGTERM */
   signal(SIGTERM, signal_catcher);
 #endif
diff --git a/cdjpeg.h b/cdjpeg.h
index cc0d600..2b387b6 100644
--- a/cdjpeg.h
+++ b/cdjpeg.h
@@ -1,7 +1,7 @@
 /*
  * cdjpeg.h
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -156,9 +156,14 @@
 #define READ_BINARY	"r"
 #define WRITE_BINARY	"w"
 #else
+#ifdef VMS			/* VMS is very nonstandard */
+#define READ_BINARY	"rb", "ctx=stm"
+#define WRITE_BINARY	"wb", "ctx=stm"
+#else				/* standard ANSI-compliant case */
 #define READ_BINARY	"rb"
 #define WRITE_BINARY	"wb"
 #endif
+#endif
 
 #ifndef EXIT_FAILURE		/* define exit() codes if not provided */
 #define EXIT_FAILURE  1
diff --git a/change.log b/change.log
index 231650e..74102c0 100644
--- a/change.log
+++ b/change.log
@@ -1,6 +1,71 @@
 CHANGE LOG for Independent JPEG Group's JPEG software
 
 
+Version 6b  27-Mar-1998
+-----------------------
+
+jpegtran has new features for lossless image transformations (rotation
+and flipping) as well as "lossless" reduction to grayscale.
+
+jpegtran now copies comments by default; it has a -copy switch to enable
+copying all APPn blocks as well, or to suppress comments.  (Formerly it
+always suppressed comments and APPn blocks.)  jpegtran now also preserves
+JFIF version and resolution information.
+
+New decompressor library feature: COM and APPn markers found in the input
+file can be saved in memory for later use by the application.  (Before,
+you had to code this up yourself with a custom marker processor.)
+
+There is an unused field "void * client_data" now in compress and decompress
+parameter structs; this may be useful in some applications.
+
+JFIF version number information is now saved by the decoder and accepted by
+the encoder.  jpegtran uses this to copy the source file's version number,
+to ensure "jpegtran -copy all" won't create bogus files that contain JFXX
+extensions but claim to be version 1.01.  Applications that generate their
+own JFXX extension markers also (finally) have a supported way to cause the
+encoder to emit JFIF version number 1.02.
+
+djpeg's trace mode reports JFIF 1.02 thumbnail images as such, rather
+than as unknown APP0 markers.
+
+In -verbose mode, djpeg and rdjpgcom will try to print the contents of
+APP12 markers as text.  Some digital cameras store useful text information
+in APP12 markers.
+
+Handling of truncated data streams is more robust: blocks beyond the one in
+which the error occurs will be output as uniform gray, or left unchanged
+if decoding a progressive JPEG.  The appearance no longer depends on the
+Huffman tables being used.
+
+Huffman tables are checked for validity much more carefully than before.
+
+To avoid the Unisys LZW patent, djpeg's GIF output capability has been
+changed to produce "uncompressed GIFs", and cjpeg's GIF input capability
+has been removed altogether.  We're not happy about it either, but there
+seems to be no good alternative.
+
+The configure script now supports building libjpeg as a shared library
+on many flavors of Unix (all the ones that GNU libtool knows how to
+build shared libraries for).  Use "./configure --enable-shared" to
+try this out.
+
+New jconfig file and makefiles for Microsoft Visual C++ and Developer Studio.
+Also, a jconfig file and a build script for Metrowerks CodeWarrior
+on Apple Macintosh.  makefile.dj has been updated for DJGPP v2, and there
+are miscellaneous other minor improvements in the makefiles.
+
+jmemmac.c now knows how to create temporary files following Mac System 7
+conventions.
+
+djpeg's -map switch is now able to read raw-format PPM files reliably.
+
+cjpeg -progressive -restart no longer generates any unnecessary DRI markers.
+
+Multiple calls to jpeg_simple_progression for a single JPEG object
+no longer leak memory.
+
+
 Version 6a  7-Feb-96
 --------------------
 
diff --git a/cjpeg.1 b/cjpeg.1
index 4dfce00..d175a96 100644
--- a/cjpeg.1
+++ b/cjpeg.1
@@ -1,4 +1,4 @@
-.TH CJPEG 1 "15 June 1995"
+.TH CJPEG 1 "20 March 1998"
 .SH NAME
 cjpeg \- compress an image file to a JPEG file
 .SH SYNOPSIS
@@ -16,7 +16,7 @@
 compresses the named image file, or the standard input if no file is
 named, and produces a JPEG/JFIF file on the standard output.
 The currently supported input file formats are: PPM (PBMPLUS color
-format), PGM (PBMPLUS gray-scale format), BMP, GIF, Targa, and RLE (Utah Raster
+format), PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster
 Toolkit format).  (RLE is supported only if the URT library is available.)
 .SH OPTIONS
 All switch names may be abbreviated; for example,
@@ -27,9 +27,9 @@
 .BR \-gr .
 Most of the "basic" switches can be abbreviated to as little as one letter.
 Upper and lower case are equivalent (thus
-.B \-GIF
+.B \-BMP
 is the same as
-.BR \-gif ).
+.BR \-bmp ).
 British spellings are also accepted (e.g.,
 .BR \-greyscale ),
 though for brevity these are not mentioned below.
@@ -42,9 +42,9 @@
 .TP
 .B \-grayscale
 Create monochrome JPEG file from color input.  Be sure to use this switch when
-compressing a grayscale GIF file, because
+compressing a grayscale BMP file, because
 .B cjpeg
-isn't bright enough to notice whether a GIF file uses only shades of gray.
+isn't bright enough to notice whether a BMP file uses only shades of gray.
 By saying
 .BR \-grayscale ,
 you'll get a smaller JPEG file that takes less time to process.
@@ -180,16 +180,22 @@
 The
 .B \-smooth
 option filters the input to eliminate fine-scale noise.  This is often useful
-when converting GIF files to JPEG: a moderate smoothing factor of 10 to 50
-gets rid of dithering patterns in the input file, resulting in a smaller JPEG
-file and a better-looking image.  Too large a smoothing factor will visibly
-blur the image, however.
+when converting dithered images to JPEG: a moderate smoothing factor of 10 to
+50 gets rid of dithering patterns in the input file, resulting in a smaller
+JPEG file and a better-looking image.  Too large a smoothing factor will
+visibly blur the image, however.
 .PP
 Switches for wizards:
 .TP
 .B \-baseline
-Force a baseline JPEG file to be generated.  This clamps quantization values
-to 8 bits even at low quality settings.
+Force baseline-compatible quantization tables to be generated.  This clamps
+quantization values to 8 bits even at low quality settings.  (This switch is
+poorly named, since it does not ensure that the output is actually baseline
+JPEG.  For example, you can use
+.B \-baseline
+and
+.B \-progressive
+together.)
 .TP
 .BI \-qtables " file"
 Use the quantization tables given in the specified text file.
@@ -272,6 +278,10 @@
 .SH BUGS
 Arithmetic coding is not supported for legal reasons.
 .PP
+GIF input files are no longer supported, to avoid the Unisys LZW patent.
+Use a Unisys-licensed program if you need to read a GIF file.  (Conversion
+of GIF files to JPEG is usually a bad idea anyway.)
+.PP
 Not all variants of BMP and Targa file formats are supported.
 .PP
 The
diff --git a/cjpeg.c b/cjpeg.c
index 194d93b..f2a929f 100644
--- a/cjpeg.c
+++ b/cjpeg.c
@@ -1,7 +1,7 @@
 /*
  * cjpeg.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -184,7 +184,7 @@
 #ifdef C_ARITH_CODING_SUPPORTED
   fprintf(stderr, "  -arithmetic    Use arithmetic coding\n");
 #endif
-  fprintf(stderr, "  -baseline      Force baseline output\n");
+  fprintf(stderr, "  -baseline      Force baseline quantization tables\n");
   fprintf(stderr, "  -qtables file  Use quantization tables given in file\n");
   fprintf(stderr, "  -qslots N[,...]    Set component quantization tables\n");
   fprintf(stderr, "  -sample HxV[,...]  Set component sampling factors\n");
@@ -255,7 +255,7 @@
 #endif
 
     } else if (keymatch(arg, "baseline", 1)) {
-      /* Force baseline output (8-bit quantizer values). */
+      /* Force baseline-compatible output (8-bit quantizer values). */
       force_baseline = TRUE;
 
     } else if (keymatch(arg, "dct", 2)) {
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000..413ed41
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,883 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	cat <<EOF >dummy.s
+	.globl main
+	.ent main
+main:
+	.frame \$30,0,\$26,0
+	.prologue 0
+	.long 0x47e03d80 # implver $0
+	lda \$2,259
+	.long 0x47e20c21 # amask $2,$1
+	srl \$1,8,\$2
+	sll \$2,2,\$2
+	sll \$0,3,\$0
+	addl \$1,\$0,\$0
+	addl \$2,\$0,\$0
+	ret \$31,(\$26),1
+	.end main
+EOF
+	${CC-cc} dummy.s -o dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		./dummy
+		case "$?" in
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
+				UNAME_MACHINE="alphaev5"
+				;;
+			14)
+				UNAME_MACHINE="alphaev56"
+				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
+		esac
+	fi
+	rm -f dummy.s dummy
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-cbm-sysv4
+	exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc64:OpenBSD:*:*)
+	echo mips64el-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hkmips:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    arm32:NetBSD:*:*)
+	echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:NetBSD:*:*)
+	echo m68k-atari-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3*:NetBSD:*:*)
+	echo m68k-sun-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:NetBSD:*:*)
+	echo m68k-apple-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	sed 's/^	//' << EOF >dummy.c
+	int main (argc, argv) int argc; char **argv; {
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	${CC-cc} dummy.c -o dummy \
+	  && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm dummy.c dummy && exit 0
+	rm -f dummy.c dummy
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+	if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+	     -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		sed 's/^		//' << EOF >dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+		rm -f dummy.c dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:4)
+	if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=4.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[3478]??:HP-UX:*:*)
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
+	    9000/8?? )            HP_ARCH=hppa1.0 ;;
+	esac
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	sed 's/^	//' << EOF >dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+	rm -f dummy.c dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i?86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+	echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY-2:*:*:*)
+	echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+	echo m68k-hp-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    i?86:BSD/386:*:* | *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:NetBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo i386-pc-cygwin32
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo i386-pc-mingw32
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin32
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us.
+	ld_help_string=`ld --help 2>&1`
+	ld_supported_emulations=`echo $ld_help_string \
+			 | sed -ne '/supported emulations:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported emulations: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_emulations" in
+	  i?86linux)  echo "${UNAME_MACHINE}-pc-linux-gnuaout"      ; exit 0 ;;
+	  i?86coff)   echo "${UNAME_MACHINE}-pc-linux-gnucoff"      ; exit 0 ;;
+	  sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  m68klinux)  echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  elf32ppc)   echo "powerpc-unknown-linux-gnu"              ; exit 0 ;;
+	esac
+
+	if test "${UNAME_MACHINE}" = "alpha" ; then
+		sed 's/^	//'  <<EOF >dummy.s
+		.globl main
+		.ent main
+	main:
+		.frame \$30,0,\$26,0
+		.prologue 0
+		.long 0x47e03d80 # implver $0
+		lda \$2,259
+		.long 0x47e20c21 # amask $2,$1
+		srl \$1,8,\$2
+		sll \$2,2,\$2
+		sll \$0,3,\$0
+		addl \$1,\$0,\$0
+		addl \$2,\$0,\$0
+		ret \$31,(\$26),1
+		.end main
+EOF
+		LIBC=""
+		${CC-cc} dummy.s -o dummy 2>/dev/null
+		if test "$?" = 0 ; then
+			./dummy
+			case "$?" in
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
+				UNAME_MACHINE="alphaev5"
+				;;
+			14)
+				UNAME_MACHINE="alphaev56"
+				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
+			esac	
+
+			objdump --private-headers dummy | \
+			  grep ld.so.1 > /dev/null
+			if test "$?" = 0 ; then
+				LIBC="libc1"
+			fi
+		fi	
+		rm -f dummy.s dummy
+		echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+	elif test "${UNAME_MACHINE}" = "mips" ; then
+	  cat >dummy.c <<EOF
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	  ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+	  rm -f dummy.c dummy
+	else
+	  # Either a pre-BFD a.out linker (linux-gnuoldld)
+	  # or one that does not give us useful --help.
+	  # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+	  # If ld does not provide *any* "supported emulations:"
+	  # that means it is gnuoldld.
+	  echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+	  test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+	  case "${UNAME_MACHINE}" in
+	  i?86)
+	    VENDOR=pc;
+	    ;;
+	  *)
+	    VENDOR=unknown;
+	    ;;
+	  esac
+	  # Determine whether the default compiler is a.out or elf
+	  cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	  ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+	  rm -f dummy.c dummy
+	fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+	fi
+	exit 0 ;;
+    i?86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i?86:LynxOS:2.*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:*:6*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000..213a6d4
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,954 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+	echo Configuration name missing. 1>&2
+	echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+	echo "or     $0 ALIAS" 1>&2
+	echo where ALIAS is a recognized configuration type. 1>&2
+	exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+	*local*)
+		echo $1
+		exit 0
+		;;
+	*)
+	;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple)
+		os=
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+		| arme[lb] | pyramid | mn10200 | mn10300 \
+		| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+		| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+		| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+		| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+		| mipstx39 | mipstx39el \
+		| sparc | sparclet | sparclite | sparc64 | v850)
+		basic_machine=$basic_machine-unknown
+		;;
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i[3456]86)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+	      | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+	      | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
+	      | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+	      | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+	      | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+	      | sparc64-* | mips64-* | mipsel-* \
+	      | mips64el-* | mips64orion-* | mips64orionel-*  \
+	      | mipstx39-* | mipstx39el-* \
+	      | f301-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-cbm
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-cbm
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-cbm
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	cray2)
+		basic_machine=cray2-cray
+		os=-unicos
+		;;
+	[ctj]90-cray)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i[3456]86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i[3456]86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i[3456]86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i[3456]86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	mipsel*-linux*)
+		basic_machine=mipsel-unknown
+		os=-linux-gnu
+		;;
+	mips*-linux*)
+		basic_machine=mips-unknown
+		os=-linux-gnu
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5)
+		basic_machine=i586-intel
+		;;
+	pentiumpro | p6)
+		basic_machine=i686-intel
+		;;
+	pentium-* | p5-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	k5)
+		# We don't have specific support for AMD's K5 yet, so just call it a Pentium
+		basic_machine=i586-amd
+		;;
+	nexen)
+		# We don't have specific support for Nexgen yet, so just call it a Pentium
+		basic_machine=i586-nexgen
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=rs6000-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	xmp)
+		basic_machine=xmp-cray
+		os=-unicos
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	mips)
+		if [ x$os = x-linux-gnu ]; then
+			basic_machine=mips-unknown
+		else
+			basic_machine=mips-mips
+		fi
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sparc)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f301-fujitsu)
+		os=-uxpv
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
diff --git a/configure b/configure
index 146c43a..35c9db5 100755
--- a/configure
+++ b/configure
@@ -1,8 +1,8 @@
 #! /bin/sh
 
 # Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.7 
-# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+# Generated automatically using autoconf version 2.12 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
 #
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
@@ -12,6 +12,10 @@
 ac_default_prefix=/usr/local
 # Any additions from configure.in:
 ac_help="$ac_help
+  --enable-shared         build shared library using GNU libtool"
+ac_help="$ac_help
+  --enable-static         build static library using GNU libtool"
+ac_help="$ac_help
   --enable-maxmem[=N]     enable use of temp files, set max mem usage to N MB"
 ac_help="$ac_help
 "
@@ -53,6 +57,8 @@
 # Initialize some other variables.
 subdirs=
 MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
 
 ac_prev=
 for ac_option
@@ -334,7 +340,7 @@
     verbose=yes ;;
 
   -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.7"
+    echo "configure generated by autoconf version 2.12"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -447,11 +453,14 @@
 done
 
 # NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
 if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
 rm -rf conftest* confdefs.h
@@ -503,12 +512,10 @@
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='echo $CPP $CPPFLAGS 1>&5;
-$CPP $CPPFLAGS'
-ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
-${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
-ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
-${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
 
 if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
@@ -527,6 +534,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:538: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -542,7 +550,6 @@
     fi
   done
   IFS="$ac_save_ifs"
-  test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc"
 fi
 fi
 CC="$ac_cv_prog_CC"
@@ -552,8 +559,98 @@
   echo "$ac_t""no" 1>&6
 fi
 
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:567: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  ac_prog_rejected=no
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:615: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 625 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:649: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:654: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -562,41 +659,25 @@
   yes;
 #endif
 EOF
-if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:663: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
 fi
 fi
+
 echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
 if test $ac_cv_prog_gcc = yes; then
   GCC=yes
+  test "${CFLAGS+set}" = set || CFLAGS="-O2"
 else
   GCC=
-fi
-if test "${CFLAGS+set}" != set; then
-  echo $ac_n "checking whether ${CC-cc} accepts -O""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_prog_cc_o'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  echo 'int f(){ return 0; }' > conftest.c
-if test -z "`${CC-cc} -O -c conftest.c 2>&1`"; then
-  ac_cv_prog_cc_o=yes
-else
-  ac_cv_prog_cc_o=no
-fi
-rm -f conftest*
-
-fi
-  echo "$ac_t""$ac_cv_prog_cc_o" 1>&6
-  if test $ac_cv_prog_cc_o = yes; then
-    CFLAGS="-O"
-  else
-    CFLAGS=""
-  fi
+  test "${CFLAGS+set}" = set || CFLAGS="-O"
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:681: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -611,31 +692,37 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 615 "configure"
+#line 696 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 629 "configure"
+#line 713 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:719: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   CPP=/lib/cpp
 fi
@@ -650,38 +737,13 @@
 fi
 echo "$ac_t""$CPP" 1>&6
 
-# If we cannot run a trivial program, we must be cross compiling.
-echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_c_cross=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 663 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_c_cross=no
-else
-  ac_cv_c_cross=yes
-fi
-fi
-rm -fr conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
-
 echo $ac_n "checking for function prototypes""... $ac_c" 1>&6
+echo "configure:742: checking for function prototypes" >&5
 if eval "test \"`echo '$''{'ijg_cv_have_prototypes'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 685 "configure"
+#line 747 "configure"
 #include "confdefs.h"
 
 int testfunction (int arg1, int * arg2); /* check prototypes */
@@ -695,21 +757,22 @@
 int test2function (void)	/* check void arg list */
 { return 0; }
 
-int main() { return 0; }
-int t() {
+int main() {
  
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:765: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ijg_cv_have_prototypes=yes
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   ijg_cv_have_prototypes=no
 fi
 rm -f conftest*
-
 fi
+
 echo "$ac_t""$ijg_cv_have_prototypes" 1>&6
 if test $ijg_cv_have_prototypes = yes; then
   cat >> confdefs.h <<\EOF
@@ -723,23 +786,27 @@
   echo "   ./configure  CC='cc -switch'"
   echo where -switch is the proper switch.
 fi
-ac_safe=`echo "stddef.h" | tr './\055' '___'`
+ac_safe=`echo "stddef.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for stddef.h""... $ac_c" 1>&6
+echo "configure:792: checking for stddef.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 733 "configure"
+#line 797 "configure"
 #include "confdefs.h"
 #include <stddef.h>
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:802: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=yes"
 else
   echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=no"
 fi
@@ -755,23 +822,27 @@
   echo "$ac_t""no" 1>&6
 fi
 
-ac_safe=`echo "stdlib.h" | tr './\055' '___'`
+ac_safe=`echo "stdlib.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for stdlib.h""... $ac_c" 1>&6
+echo "configure:828: checking for stdlib.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 765 "configure"
+#line 833 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:838: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=yes"
 else
   echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=no"
 fi
@@ -787,23 +858,27 @@
   echo "$ac_t""no" 1>&6
 fi
 
-ac_safe=`echo "string.h" | tr './\055' '___'`
+ac_safe=`echo "string.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for string.h""... $ac_c" 1>&6
+echo "configure:864: checking for string.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 797 "configure"
+#line 869 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:874: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=yes"
 else
   echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=no"
 fi
@@ -821,8 +896,9 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:900: checking for size_t" >&5
 cat > conftest.$ac_ext <<EOF
-#line 826 "configure"
+#line 902 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_STDDEF_H
@@ -839,39 +915,43 @@
 #endif
 typedef size_t my_size_t;
 
-int main() { return 0; }
-int t() {
+int main() {
  my_size_t foovar; 
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:923: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ijg_size_t_ok=yes
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   ijg_size_t_ok="not ANSI, perhaps it is in sys/types.h"
 fi
 rm -f conftest*
-
 echo "$ac_t""$ijg_size_t_ok" 1>&6
 if test "$ijg_size_t_ok" != yes; then
-ac_safe=`echo "sys/types.h" | tr './\055' '___'`
+ac_safe=`echo "sys/types.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sys/types.h""... $ac_c" 1>&6
+echo "configure:937: checking for sys/types.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 865 "configure"
+#line 942 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:947: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=yes"
 else
   echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_header_$ac_safe=no"
 fi
@@ -884,7 +964,7 @@
 EOF
 
 cat > conftest.$ac_ext <<EOF
-#line 888 "configure"
+#line 968 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 EOF
@@ -910,16 +990,16 @@
 fi
 fi
 echo $ac_n "checking for type unsigned char""... $ac_c" 1>&6
+echo "configure:994: checking for type unsigned char" >&5
 cat > conftest.$ac_ext <<EOF
-#line 915 "configure"
+#line 996 "configure"
 #include "confdefs.h"
 
-int main() { return 0; }
-int t() {
+int main() {
  unsigned char un_char; 
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1003: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 cat >> confdefs.h <<\EOF
@@ -927,21 +1007,23 @@
 EOF
 
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   echo "$ac_t""no" 1>&6
 fi
 rm -f conftest*
 echo $ac_n "checking for type unsigned short""... $ac_c" 1>&6
+echo "configure:1018: checking for type unsigned short" >&5
 cat > conftest.$ac_ext <<EOF
-#line 937 "configure"
+#line 1020 "configure"
 #include "confdefs.h"
 
-int main() { return 0; }
-int t() {
+int main() {
  unsigned short un_short; 
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1027: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 cat >> confdefs.h <<\EOF
@@ -949,13 +1031,16 @@
 EOF
 
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   echo "$ac_t""no" 1>&6
 fi
 rm -f conftest*
 echo $ac_n "checking for type void""... $ac_c" 1>&6
+echo "configure:1042: checking for type void" >&5
 cat > conftest.$ac_ext <<EOF
-#line 959 "configure"
+#line 1044 "configure"
 #include "confdefs.h"
 
 /* Caution: a C++ compiler will insist on valid prototypes */
@@ -979,15 +1064,16 @@
   (*arg2) (1, 2);		/* check call of fcn returning void */
 }
 
-int main() { return 0; }
-int t() {
+int main() {
  
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1072: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   echo "$ac_t""no" 1>&6
 cat >> confdefs.h <<\EOF
@@ -996,16 +1082,17 @@
 
 fi
 rm -f conftest*
+
 echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1088: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1005 "configure"
+#line 1093 "configure"
 #include "confdefs.h"
 
-int main() { return 0; }
-int t() {
+int main() {
 
 /* Ultrix mips cc rejects this.  */
 typedef int charset[2]; const charset x;
@@ -1051,15 +1138,16 @@
 
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1142: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   ac_cv_c_const=no
 fi
 rm -f conftest*
-
 fi
 
 echo "$ac_t""$ac_cv_c_const" 1>&6
@@ -1071,76 +1159,82 @@
 fi
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1163: checking for inline" >&5
 ijg_cv_inline=""
 cat > conftest.$ac_ext <<EOF
-#line 1077 "configure"
+#line 1166 "configure"
 #include "confdefs.h"
 
-int main() { return 0; }
-int t() {
-} inline int foo() { return 0; }
-int bar() { return foo();
-; return 0; }
-EOF
-if eval $ac_compile; then
-  rm -rf conftest*
-  ijg_cv_inline="inline"
-else
-  rm -rf conftest*
-  cat > conftest.$ac_ext <<EOF
-#line 1092 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
+int main() {
 } __inline__ int foo() { return 0; }
 int bar() { return foo();
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1174: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ijg_cv_inline="__inline__"
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   cat > conftest.$ac_ext <<EOF
-#line 1107 "configure"
+#line 1182 "configure"
 #include "confdefs.h"
 
-int main() { return 0; }
-int t() {
+int main() {
 } __inline int foo() { return 0; }
 int bar() { return foo();
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1190: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ijg_cv_inline="__inline"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat > conftest.$ac_ext <<EOF
+#line 1198 "configure"
+#include "confdefs.h"
+
+int main() {
+} inline int foo() { return 0; }
+int bar() { return foo();
+; return 0; }
+EOF
+if { (eval echo configure:1206: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ijg_cv_inline="inline"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
 fi
 rm -f conftest*
-
 fi
 rm -f conftest*
-
 fi
 rm -f conftest*
 echo "$ac_t""$ijg_cv_inline" 1>&6
 cat >> confdefs.h <<EOF
 #define INLINE $ijg_cv_inline
 EOF
+
 echo $ac_n "checking for broken incomplete types""... $ac_c" 1>&6
+echo "configure:1224: checking for broken incomplete types" >&5
 cat > conftest.$ac_ext <<EOF
-#line 1133 "configure"
+#line 1226 "configure"
 #include "confdefs.h"
  typedef struct undefined_structure * undef_struct_ptr; 
-int main() { return 0; }
-int t() {
+int main() {
 
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1233: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   echo "$ac_t""ok" 1>&6
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   echo "$ac_t""broken" 1>&6
 cat >> confdefs.h <<\EOF
@@ -1150,22 +1244,24 @@
 fi
 rm -f conftest*
 echo $ac_n "checking for short external names""... $ac_c" 1>&6
+echo "configure:1248: checking for short external names" >&5
 cat > conftest.$ac_ext <<EOF
-#line 1155 "configure"
+#line 1250 "configure"
 #include "confdefs.h"
 
 int possibly_duplicate_function () { return 0; }
 int possibly_dupli_function () { return 1; }
 
-int main() { return 0; }
-int t() {
+int main() {
  
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1260: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""ok" 1>&6
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   echo "$ac_t""short" 1>&6
 cat >> confdefs.h <<\EOF
@@ -1174,15 +1270,15 @@
 
 fi
 rm -f conftest*
-
 echo $ac_n "checking to see if char is signed""... $ac_c" 1>&6
+echo "configure:1275: checking to see if char is signed" >&5
 if test "$cross_compiling" = yes; then
   echo Assuming that char is signed on target machine.
 echo If it is unsigned, this will be a little bit inefficient.
 
 else
-cat > conftest.$ac_ext <<EOF
-#line 1186 "configure"
+  cat > conftest.$ac_ext <<EOF
+#line 1282 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_PROTOTYPES
@@ -1206,24 +1302,29 @@
   exit(is_char_signed((int) signed_char_check));
 }
 EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
   echo "$ac_t""no" 1>&6
 cat >> confdefs.h <<\EOF
 #define CHAR_IS_UNSIGNED 
 EOF
 
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
   echo "$ac_t""yes" 1>&6
 fi
-fi
 rm -fr conftest*
+fi
+
 echo $ac_n "checking to see if right shift is signed""... $ac_c" 1>&6
+echo "configure:1323: checking to see if right shift is signed" >&5
 if test "$cross_compiling" = yes; then
   echo "$ac_t""Assuming that right shift is signed on target machine." 1>&6
 else
-cat > conftest.$ac_ext <<EOF
-#line 1227 "configure"
+  cat > conftest.$ac_ext <<EOF
+#line 1328 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_PROTOTYPES
@@ -1253,24 +1354,29 @@
   exit(is_shifting_signed(-0x7F7E80B1L));
 }
 EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
   echo "$ac_t""no" 1>&6
 cat >> confdefs.h <<\EOF
 #define RIGHT_SHIFT_IS_UNSIGNED 
 EOF
 
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
   echo "$ac_t""yes" 1>&6
 fi
-fi
 rm -fr conftest*
+fi
+
 echo $ac_n "checking to see if fopen accepts b spec""... $ac_c" 1>&6
+echo "configure:1375: checking to see if fopen accepts b spec" >&5
 if test "$cross_compiling" = yes; then
   echo "$ac_t""Assuming that it does." 1>&6
 else
-cat > conftest.$ac_ext <<EOF
-#line 1274 "configure"
+  cat > conftest.$ac_ext <<EOF
+#line 1380 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -1280,18 +1386,40 @@
   exit(1);
 }
 EOF
-eval $ac_link
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
   echo "$ac_t""yes" 1>&6
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
   echo "$ac_t""no" 1>&6
 cat >> confdefs.h <<\EOF
 #define DONT_USE_B_MODE 
 EOF
 
 fi
-fi
 rm -fr conftest*
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -1304,11 +1432,12 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1436: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ijg_cv_path_install'+set}'`\" = set"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS="${IFS}:"
   for ac_dir in $PATH; do
     # Account for people who put trailing slashes in PATH elements.
     case "$ac_dir/" in
@@ -1323,7 +1452,7 @@
 	    # OSF/1 installbsd also uses dspmsg, but is usable.
 	    :
 	  else
-	    ijg_cv_path_install="$ac_dir/$ac_prog -c"
+	    ac_cv_path_install="$ac_dir/$ac_prog -c"
 	    break 2
 	  fi
 	fi
@@ -1331,11 +1460,18 @@
       ;;
     esac
   done
-  IFS="$ac_save_ifs"
-  # As a last resort, use cp
-  test -z "$ijg_cv_path_install" && ijg_cv_path_install="cp"
+  IFS="$ac_save_IFS"
+
 fi
-  INSTALL="$ijg_cv_path_install"
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
 fi
 echo "$ac_t""$INSTALL" 1>&6
 
@@ -1343,17 +1479,12 @@
 # It thinks the first close brace ends the variable substitution.
 test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
-if test -z "$INSTALL_DATA"; then
-  if test "$INSTALL" = cp; then
-    INSTALL_DATA='${INSTALL}'
-  else
-    INSTALL_DATA='${INSTALL} -m 644'
-  fi
-fi
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1488: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1379,7 +1510,61 @@
   echo "$ac_t""no" 1>&6
 fi
 
-MEMORYMGR="jmemnobs.o"
+
+# Decide whether to use libtool,
+# and if so whether to build shared, static, or both flavors of library.
+LTSHARED="no"
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  LTSHARED="$enableval"
+fi
+
+LTSTATIC="no"
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  LTSTATIC="$enableval"
+fi
+
+if test "x$LTSHARED" != xno  -o  "x$LTSTATIC" != xno; then
+  USELIBTOOL="yes"
+  LIBTOOL="./libtool"
+  O="lo"
+  A="la"
+  LN='$(LIBTOOL) --mode=link $(CC)'
+  INSTALL_LIB='$(LIBTOOL) --mode=install ${INSTALL}'
+  INSTALL_PROGRAM="\$(LIBTOOL) --mode=install $INSTALL_PROGRAM"
+else
+  USELIBTOOL="no"
+  LIBTOOL=""
+  O="o"
+  A="a"
+  LN='$(CC)'
+  INSTALL_LIB="$INSTALL_DATA"
+fi
+
+
+
+
+
+
+# Configure libtool if needed.
+if test $USELIBTOOL = yes; then
+  disable_shared=
+  disable_static=
+  if test "x$LTSHARED" = xno; then
+    disable_shared="--disable-shared"
+  fi
+  if test "x$LTSTATIC" = xno; then
+    disable_static="--disable-static"
+  fi
+  $srcdir/ltconfig $disable_shared $disable_static $srcdir/ltmain.sh
+fi
+
+# Select memory manager depending on user input.
+# If no "-enable-maxmem", use jmemnobs
+MEMORYMGR='jmemnobs.$(O)'
 MAXMEM="no"
 # Check whether --enable-maxmem or --disable-maxmem was given.
 if test "${enable_maxmem+set}" = set; then
@@ -1407,40 +1592,45 @@
 EOF
 
 echo $ac_n "checking for 'tmpfile()'""... $ac_c" 1>&6
+echo "configure:1596: checking for 'tmpfile()'" >&5
 cat > conftest.$ac_ext <<EOF
-#line 1412 "configure"
+#line 1598 "configure"
 #include "confdefs.h"
 #include <stdio.h>
-int main() { return 0; }
-int t() {
+int main() {
  FILE * tfile = tmpfile(); 
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
-MEMORYMGR="jmemansi.o"
+MEMORYMGR='jmemansi.$(O)'
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   echo "$ac_t""no" 1>&6
-MEMORYMGR="jmemname.o"
+MEMORYMGR='jmemname.$(O)'
 cat >> confdefs.h <<\EOF
 #define NEED_SIGNAL_CATCHER 
 EOF
+
 echo $ac_n "checking for 'mktemp()'""... $ac_c" 1>&6
+echo "configure:1620: checking for 'mktemp()'" >&5
 cat > conftest.$ac_ext <<EOF
-#line 1433 "configure"
+#line 1622 "configure"
 #include "confdefs.h"
 
-int main() { return 0; }
-int t() {
+int main() {
  char fname[80]; mktemp(fname); 
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
   rm -rf conftest*
   echo "$ac_t""no" 1>&6
 cat >> confdefs.h <<\EOF
@@ -1449,32 +1639,55 @@
 
 fi
 rm -f conftest*
-
 fi
 rm -f conftest*
-
 fi
 
+
+# Extract the library version ID from jpeglib.h.
+echo $ac_n "checking libjpeg version number""... $ac_c" 1>&6
+echo "configure:1650: checking libjpeg version number" >&5
+JPEG_LIB_VERSION=`sed -e '/^#define JPEG_LIB_VERSION/!d' -e 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/' $srcdir/jpeglib.h`
+echo "$ac_t""$JPEG_LIB_VERSION" 1>&6
+
+
 # Prepare to massage makefile.cfg correctly.
 if test $ijg_cv_have_prototypes = yes; then
-  ANSI2KNR=""
-  ISANSICOM="# "
+  A2K_DEPS=""
+  COM_A2K="# "
 else
-  ANSI2KNR="ansi2knr"
-  ISANSICOM=""
+  A2K_DEPS="ansi2knr"
+  COM_A2K=""
 fi
+
+
 # ansi2knr needs -DBSD if string.h is missing
 if test $ac_cv_header_string_h = no; then
   ANSI2KNRFLAGS="-DBSD"
 else
   ANSI2KNRFLAGS=""
 fi
+
+# Substitutions to enable or disable libtool-related stuff
+if test $USELIBTOOL = yes -a $ijg_cv_have_prototypes = yes; then
+  COM_LT=""
+else
+  COM_LT="# "
+fi
+
+if test "x$LTSHARED" != xno; then
+  FORCE_INSTALL_LIB="install-lib"
+else
+  FORCE_INSTALL_LIB=""
+fi
+
 # Set up -I directives
 if test "x$srcdir" = x.; then
   INCLUDEFLAGS='-I$(srcdir)'
 else
   INCLUDEFLAGS='-I. -I$(srcdir)'
 fi
+
 trap '' 1 2 15
 
 trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
@@ -1519,7 +1732,7 @@
     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.7"
+    echo "$CONFIG_STATUS generated by autoconf version 2.12"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
@@ -1528,6 +1741,7 @@
 done
 
 ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
 
 trap 'rm -fr `echo "Makefile:makefile.cfg jconfig.h:jconfig.cfg" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
@@ -1561,32 +1775,75 @@
 s%@mandir@%$mandir%g
 s%@CC@%$CC%g
 s%@CPP@%$CPP%g
-s%@INSTALL@%$INSTALL%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@RANLIB@%$RANLIB%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@O@%$O%g
+s%@A@%$A%g
+s%@LN@%$LN%g
+s%@INSTALL_LIB@%$INSTALL_LIB%g
 s%@MEMORYMGR@%$MEMORYMGR%g
-s%@ANSI2KNR@%$ANSI2KNR%g
-s%@ISANSICOM@%$ISANSICOM%g
+s%@JPEG_LIB_VERSION@%$JPEG_LIB_VERSION%g
+s%@A2K_DEPS@%$A2K_DEPS%g
+s%@COM_A2K@%$COM_A2K%g
 s%@ANSI2KNRFLAGS@%$ANSI2KNRFLAGS%g
+s%@COM_LT@%$COM_LT%g
+s%@FORCE_INSTALL_LIB@%$FORCE_INSTALL_LIB%g
 s%@INCLUDEFLAGS@%$INCLUDEFLAGS%g
 
 CEOF
 EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
 cat >> $CONFIG_STATUS <<EOF
 
 CONFIG_FILES=\${CONFIG_FILES-"Makefile:makefile.cfg"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile]", defaulting infile="outfile.in".
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
        ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
   *) ac_file_in="${ac_file}.in" ;;
   esac
 
-  # Adjust relative srcdir, etc. for subdirectories.
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
 
   # Remove last slash and all that follows it.  Not all systems have dirname.
   ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
@@ -1610,6 +1867,11 @@
     top_srcdir="$ac_dots$ac_given_srcdir" ;;
   esac
 
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
   echo creating "$ac_file"
   rm -f "$ac_file"
   configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
@@ -1618,13 +1880,16 @@
 # $configure_input" ;;
   *) ac_comsub= ;;
   esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
   sed -e "$ac_comsub
 s%@configure_input@%$configure_input%g
 s%@srcdir@%$srcdir%g
 s%@top_srcdir@%$top_srcdir%g
-" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
 fi; done
-rm -f conftest.subs
+rm -f conftest.s*
 
 # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
 # NAME is the cpp macro being defined and VALUE is the value it is being given.
@@ -1645,11 +1910,17 @@
 ac_eC=' '
 ac_eD='%g'
 
-CONFIG_HEADERS=${CONFIG_HEADERS-"jconfig.h:jconfig.cfg"}
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="jconfig.h:jconfig.cfg"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
 for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile]", defaulting infile="outfile.in".
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
        ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
   *) ac_file_in="${ac_file}.in" ;;
   esac
@@ -1657,7 +1928,8 @@
   echo creating $ac_file
 
   rm -f conftest.frag conftest.in conftest.out
-  cp $ac_given_srcdir/$ac_file_in conftest.in
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
 
 EOF
 
@@ -1669,7 +1941,7 @@
 cat > conftest.hdr <<\EOF
 s/[\\&%]/\\&/g
 s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
 s%ac_d%ac_u%gp
 s%ac_u%ac_e%gp
 EOF
@@ -1684,8 +1956,6 @@
 
 # Break up conftest.vals because some shells have a limit on
 # the size of here documents, and old seds have small limits too.
-# Maximum number of lines to put in a single here document.
-ac_max_here_lines=12
 
 rm -f conftest.tail
 while :
@@ -1716,12 +1986,22 @@
     echo "$ac_file is unchanged"
     rm -f conftest.h
   else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
     rm -f $ac_file
     mv conftest.h $ac_file
   fi
 fi; done
 
+EOF
+cat >> $CONFIG_STATUS <<EOF
 
+EOF
+cat >> $CONFIG_STATUS <<\EOF
 
 exit 0
 EOF
diff --git a/djpeg.1 b/djpeg.1
index 8efa5cd..11beb6a 100644
--- a/djpeg.1
+++ b/djpeg.1
@@ -1,4 +1,4 @@
-.TH DJPEG 1 "15 June 1995"
+.TH DJPEG 1 "22 August 1997"
 .SH NAME
 djpeg \- decompress a JPEG file to an image file
 .SH SYNOPSIS
@@ -26,9 +26,9 @@
 .BR \-gr .
 Most of the "basic" switches can be abbreviated to as little as one letter.
 Upper and lower case are equivalent (thus
-.B \-GIF
+.B \-BMP
 is the same as
-.BR \-gif ).
+.BR \-bmp ).
 British spellings are also accepted (e.g.,
 .BR \-greyscale ),
 though for brevity these are not mentioned below.
@@ -182,13 +182,13 @@
 .BR \-verbose .
 .SH EXAMPLES
 .LP
-This example decompresses the JPEG file foo.jpg, automatically quantizes to
-256 colors, and saves the output in GIF format in foo.gif:
+This example decompresses the JPEG file foo.jpg, quantizes it to
+256 colors, and saves the output in 8-bit BMP format in foo.bmp:
 .IP
-.B djpeg \-gif
+.B djpeg \-colors 256 \-bmp
 .I foo.jpg
 .B >
-.I foo.gif
+.I foo.bmp
 .SH HINTS
 To get a quick preview of an image, use the
 .B \-grayscale
@@ -245,4 +245,9 @@
 .SH BUGS
 Arithmetic coding is not supported for legal reasons.
 .PP
+To avoid the Unisys LZW patent,
+.B djpeg
+produces uncompressed GIF files.  These are larger than they should be, but
+are readable by standard GIF decoders.
+.PP
 Still not as fast as we'd like.
diff --git a/djpeg.c b/djpeg.c
index 5465994..e099e90 100644
--- a/djpeg.c
+++ b/djpeg.c
@@ -1,7 +1,7 @@
 /*
  * djpeg.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -344,9 +344,9 @@
 
 
 /*
- * Marker processor for COM markers.
+ * Marker processor for COM and interesting APPn markers.
  * This replaces the library's built-in processor, which just skips the marker.
- * We want to print out the marker as text, if possible.
+ * We want to print out the marker as text, to the extent possible.
  * Note this code relies on a non-suspending data source.
  */
 
@@ -366,7 +366,7 @@
 
 
 METHODDEF(boolean)
-COM_handler (j_decompress_ptr cinfo)
+print_text_marker (j_decompress_ptr cinfo)
 {
   boolean traceit = (cinfo->err->trace_level >= 1);
   INT32 length;
@@ -377,8 +377,13 @@
   length += jpeg_getc(cinfo);
   length -= 2;			/* discount the length word itself */
 
-  if (traceit)
-    fprintf(stderr, "Comment, length %ld:\n", (long) length);
+  if (traceit) {
+    if (cinfo->unread_marker == JPEG_COM)
+      fprintf(stderr, "Comment, length %ld:\n", (long) length);
+    else			/* assume it is an APPn otherwise */
+      fprintf(stderr, "APP%d, length %ld:\n",
+	      cinfo->unread_marker - JPEG_APP0, (long) length);
+  }
 
   while (--length >= 0) {
     ch = jpeg_getc(cinfo);
@@ -445,8 +450,15 @@
   jerr.addon_message_table = cdjpeg_message_table;
   jerr.first_addon_message = JMSG_FIRSTADDONCODE;
   jerr.last_addon_message = JMSG_LASTADDONCODE;
-  /* Insert custom COM marker processor. */
-  jpeg_set_marker_processor(&cinfo, JPEG_COM, COM_handler);
+
+  /* Insert custom marker processor for COM and APP12.
+   * APP12 is used by some digital camera makers for textual info,
+   * so we provide the ability to display it as text.
+   * If you like, additional APPn marker types can be selected for display,
+   * but don't try to override APP0 or APP14 this way (see libjpeg.doc).
+   */
+  jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
+  jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);
 
   /* Now safe to enable signal catcher. */
 #ifdef NEED_SIGNAL_CATCHER
diff --git a/filelist.doc b/filelist.doc
index 707dc1c..e14982c 100644
--- a/filelist.doc
+++ b/filelist.doc
@@ -1,6 +1,6 @@
 IJG JPEG LIBRARY:  FILE LIST
 
-Copyright (C) 1994-1996, Thomas G. Lane.
+Copyright (C) 1994-1998, 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.
 
@@ -113,8 +113,8 @@
 jmemnobs.c	"No backing store": assumes adequate virtual memory exists.
 jmemansi.c	Makes temporary files with ANSI-standard routine tmpfile().
 jmemname.c	Makes temporary files with program-generated file names.
-jmemdos.c	Custom implementation for MS-DOS: knows about extended and
-		expanded memory as well as temporary files.
+jmemdos.c	Custom implementation for MS-DOS (16-bit environment only):
+		can use extended and expanded memory as well as temp files.
 jmemmac.c	Custom implementation for Apple Macintosh.
 
 Exactly one of the system-dependent modules should be configured into an
@@ -134,8 +134,9 @@
 
 Include files:
 
-cdjpeg.h	Declarations shared by cjpeg/djpeg modules.
-cderror.h	Additional error and trace message codes for cjpeg/djpeg.
+cdjpeg.h	Declarations shared by cjpeg/djpeg/jpegtran modules.
+cderror.h	Additional error and trace message codes for cjpeg et al.
+transupp.h	Declarations for jpegtran support routines in transupp.c.
 
 C source code files:
 
@@ -146,11 +147,12 @@
 rdcolmap.c	Code to read a colormap file for djpeg's "-map" switch.
 rdswitch.c	Code to process some of cjpeg's more complex switches.
 		Also used by jpegtran.
+transupp.c	Support code for jpegtran: lossless image manipulations.
 
 Image file reader modules for cjpeg:
 
 rdbmp.c		BMP file input.
-rdgif.c		GIF file input.
+rdgif.c		GIF file input (now just a stub).
 rdppm.c		PPM/PGM file input.
 rdrle.c		Utah RLE file input.
 rdtarga.c	Targa file input.
@@ -158,7 +160,7 @@
 Image file writer modules for djpeg:
 
 wrbmp.c		BMP file output.
-wrgif.c		GIF file output.
+wrgif.c		GIF file output (a mere shadow of its former self).
 wrppm.c		PPM/PGM file output.
 wrrle.c		Utah RLE file output.
 wrtarga.c	Targa file output.
@@ -190,6 +192,11 @@
 Configuration/installation files and programs (see install.doc for more info):
 
 configure	Unix shell script to perform automatic configuration.
+ltconfig	Support scripts for configure (from GNU libtool).
+ltmain.sh
+config.guess
+config.sub
+install-sh	Install shell script for those Unix systems lacking one.
 ckconfig.c	Program to generate jconfig.h on non-Unix systems.
 jconfig.doc	Template for making jconfig.h by hand.
 makefile.*	Sample makefiles for particular systems.
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..e843669
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,250 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/install.doc b/install.doc
index 585b29b..3702b98 100644
--- a/install.doc
+++ b/install.doc
@@ -1,6 +1,6 @@
 INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
 
-Copyright (C) 1991-1996, Thomas G. Lane.
+Copyright (C) 1991-1998, 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.
 
@@ -94,6 +94,19 @@
 for GNU configure scripts.  It makes a few assumptions that you may want to
 override.  You can do this by providing optional switches to configure:
 
+* If you want to build libjpeg as a shared library, say
+	./configure --enable-shared
+To get both shared and static libraries, say
+	./configure --enable-shared --enable-static
+Note that these switches invoke GNU libtool to take care of system-dependent
+shared library building methods.  If things don't work this way, please try
+running configure without either switch; that should build a static library
+without using libtool.  If that works, your problem is probably with libtool
+not with the IJG code.  libtool is fairly new and doesn't support all flavors
+of Unix yet.  (You might be able to find a newer version of libtool than the
+one included with libjpeg; see ftp.gnu.org.  Report libtool problems to
+bug-libtool@gnu.org.)
+
 * Configure will use gcc (GNU C compiler) if it's available, otherwise cc.
 To force a particular compiler to be selected, use the CC option, for example
 	./configure CC='cc'
@@ -102,8 +115,10 @@
 	./configure CC='cc -Aa'
 to get HP's compiler to run in ANSI mode.
 
-* The default CFLAGS setting is "-O".  You can override this by saying,
-for example, ./configure CFLAGS='-O2'.
+* The default CFLAGS setting is "-O" for non-gcc compilers, "-O2" for gcc.
+You can override this by saying, for example,
+	./configure CFLAGS='-g'
+if you want to compile with debugging support.
 
 * Configure will set up the makefile so that "make install" will install files
 into /usr/local/bin, /usr/local/man, etc.  You can specify an installation
@@ -131,17 +146,20 @@
 
 makefile.manx	jconfig.manx	Amiga, Manx Aztec C
 makefile.sas	jconfig.sas	Amiga, SAS C
+makeproj.mac	jconfig.mac	Apple Macintosh, Metrowerks CodeWarrior
 mak*jpeg.st	jconfig.st	Atari ST/STE/TT, Pure C or Turbo C
 makefile.bcc	jconfig.bcc	MS-DOS or OS/2, Borland C
 makefile.dj	jconfig.dj	MS-DOS, DJGPP (Delorie's port of GNU C)
-makefile.mc6	jconfig.mc6	MS-DOS, Microsoft C version 6.x and up
+makefile.mc6	jconfig.mc6	MS-DOS, Microsoft C (16-bit only)
 makefile.wat	jconfig.wat	MS-DOS, OS/2, or Windows NT, Watcom C
+makefile.vc	jconfig.vc	Windows NT/95, MS Visual C++
+make*.ds	jconfig.vc	Windows NT/95, MS Developer Studio
 makefile.mms	jconfig.vms	Digital VMS, with MMS software
 makefile.vms	jconfig.vms	Digital VMS, without MMS software
 
-Copy the proper jconfig file to jconfig.h and the makefile to Makefile
-(or whatever your system uses as the standard makefile name).  For the
-Atari, we provide four project files; see the Atari hints below.
+Copy the proper jconfig file to jconfig.h and the makefile to Makefile (or
+whatever your system uses as the standard makefile name).  For more info see
+the appropriate system-specific hints section near the end of this file.
 
 
 Configuring the software by hand
@@ -303,7 +321,7 @@
 several forms:
 	testorig.jpg	Starting point for the djpeg tests.
 	testimg.ppm	The output of djpeg testorig.jpg
-	testimg.gif	The output of djpeg -gif testorig.jpg
+	testimg.bmp	The output of djpeg -bmp -colors 256 testorig.jpg
 	testimg.jpg	The output of cjpeg testimg.ppm
 	testprog.jpg	Progressive-mode equivalent of testorig.jpg.
 	testimgp.jpg	The output of cjpeg -progressive -optimize testimg.ppm
@@ -339,10 +357,10 @@
 If it still doesn't work, better use two-file style.
 
 If you chose a memory manager other than jmemnobs.c, you should test that
-temporary-file usage works.  Try "djpeg -gif -max 0 testorig.jpg" and make
-sure its output matches testimg.gif.  If you have any really large images
-handy, try compressing them with -optimize and/or decompressing with -gif to
-make sure your DEFAULT_MAX_MEM setting is not too large.
+temporary-file usage works.  Try "djpeg -bmp -colors 256 -max 0 testorig.jpg"
+and make sure its output matches testimg.bmp.  If you have any really large
+images handy, try compressing them with -optimize and/or decompressing with
+-colors 256 to make sure your DEFAULT_MAX_MEM setting is not too large.
 
 NOTE: this is far from an exhaustive test of the JPEG software; some modules,
 such as 1-pass color quantization, are not exercised at all.  It's just a
@@ -357,7 +375,7 @@
 copying the executable files (cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom)
 to wherever you normally install programs.  On Unix systems, you'll also want
 to put the man pages (cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1)
-in the man-page directory.  The canned makefiles don't support this step
+in the man-page directory.  The pre-fab makefiles don't support this step
 since there's such a wide variety of installation procedures on different
 systems.
 
@@ -370,8 +388,13 @@
 the Makefile, particularly if your system's conventions for man page
 filenames don't match what configure expects.
 
-If you want to install the library file libjpeg.a and the include files j*.h
-(for use in compiling other programs besides the IJG ones), then say
+If you want to install the IJG library itself, for use in compiling other
+programs besides ours, then you need to put the four include files
+	jpeglib.h jerror.h jconfig.h jmorecfg.h
+into your include-file directory, and put the library file libjpeg.a
+(extension may vary depending on system) wherever library files go.
+If you generated a Makefile with "configure", it will do what it thinks
+is the right thing if you say
 	make install-lib
 
 
@@ -426,8 +449,8 @@
 binary-format PPM and PGM files.  Binary-format PPM/PGM files which have a
 maxval greater than 255 are assumed to use 2 bytes per sample, LSB first
 (little-endian order).  As of early 1995, 2-byte binary format is not
-officially supported by the PBMPLUS library, but it is expected that the
-next release of PBMPLUS will support it.  Note that the PPM reader will
+officially supported by the PBMPLUS library, but it is expected that a
+future release of PBMPLUS will support it.  Note that the PPM reader will
 read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming
 data is automatically rescaled to either maxval=255 or maxval=4095 as
 appropriate for the cjpeg bit depth.
@@ -568,19 +591,19 @@
 Copy the project files makcjpeg.st, makdjpeg.st, maktjpeg.st, and makljpeg.st
 to cjpeg.prj, djpeg.prj, jpegtran.prj, and libjpeg.prj respectively.  The
 project files should work as-is with Pure C.  For Turbo C, change library
-filenames "PC..." to "TC..." in each project file.  Note that libjpeg.prj
+filenames "pc..." to "tc..." in each project file.  Note that libjpeg.prj
 selects jmemansi.c as the recommended memory manager.  You'll probably want to
 adjust the DEFAULT_MAX_MEM setting --- you want it to be a couple hundred K
 less than your normal free memory.  Put "#define DEFAULT_MAX_MEM nnnn" into
 jconfig.h to do this.
 
 To use the 68881/68882 coprocessor for the floating point DCT, add the
-compiler option "-8" to the project files and replace PCFLTLIB.LIB with
-PC881LIB.LIB in cjpeg.prj and djpeg.prj.  Or if you don't have a
+compiler option "-8" to the project files and replace pcfltlib.lib with
+pc881lib.lib in cjpeg.prj and djpeg.prj.  Or if you don't have a
 coprocessor, you may prefer to remove the float DCT code by undefining
 DCT_FLOAT_SUPPORTED in jmorecfg.h (since without a coprocessor, the float
 code will be too slow to be useful).  In that case, you can delete
-PCFLTLIB.LIB from the project files.
+pcfltlib.lib from the project files.
 
 Note that you must make libjpeg.lib before making cjpeg.ttp, djpeg.ttp,
 or jpegtran.ttp.  You'll have to perform the self-test by hand.
@@ -637,49 +660,62 @@
 the Mac by means of the ccommand() library routine provided by Metrowerks
 CodeWarrior or Think C.  This is only appropriate for testing the library,
 however; to make a user-friendly equivalent of cjpeg/djpeg you'd really want
-to develop a Mac-style user interface.  Such an interface exists for pre-v5
-IJG libraries (see the Think C entry, below) but at this writing it has not
-been updated to work with the current release.
+to develop a Mac-style user interface.  There isn't a complete example
+available at the moment, but there are some helpful starting points:
+1. Sam Bushell's free "To JPEG" applet provides drag-and-drop conversion to
+JPEG under System 7 and later.  This only illustrates how to use the
+compression half of the library, but it does a very nice job of that part.
+The CodeWarrior source code is available from http://www.pobox.com/~jsam.
+2. Jim Brunner prepared a Mac-style user interface for both compression and
+decompression.  Unfortunately, it hasn't been updated since IJG v4, and
+the library's API has changed considerably since then.  Still it may be of
+some help, particularly as a guide to compiling the IJG code under Think C.
+Jim's code is available from the Info-Mac archives, at sumex-aim.stanford.edu
+or mirrors thereof; see file /info-mac/dev/src/jpeg-convert-c.hqx.
 
-We recommend replacing "malloc" and "free" by "NewPtr" and "DisposePtr" in
-whichever memory manager back end you use, because Mac C libraries often
-have inferior implementations of malloc/free.  jmemmac.c is recommended;
-it is a customized version of jmemansi.c with this change and a Mac-specific
-implementation of jpeg_mem_available().  You can also use jmemnobs.c if you
-don't care about handling images larger than available memory.
+jmemmac.c is the recommended memory manager back end for Macintosh.  It uses
+NewPtr/DisposePtr instead of malloc/free, and has a Mac-specific
+implementation of jpeg_mem_available().  It also creates temporary files that
+follow Mac conventions.  (That part of the code relies on System-7-or-later OS
+functions.  See the comments in jmemmac.c if you need to run it on System 6.)
+NOTE that USE_MAC_MEMMGR must be defined in jconfig.h to use jmemmac.c.
 
-
-Macintosh, MPW:
-
-We don't directly support MPW in the current release, but Larry Rosenstein
-ported an earlier version of the IJG code without very much trouble.  There's
-useful notes and conversion scripts in his kit for porting PBMPLUS to MPW.
-You can obtain the kit by FTP to ftp.apple.com, files /pub/lsr/pbmplus-port*.
+You can also use jmemnobs.c, if you don't care about handling images larger
+than available memory.  If you use any memory manager back end other than
+jmemmac.c, we recommend replacing "malloc" and "free" by "NewPtr" and
+"DisposePtr", because Mac C libraries often have peculiar implementations of
+malloc/free.  (For instance, free() may not return the freed space to the
+Mac Memory Manager.  This is undesirable for the IJG code because jmemmgr.c
+already clumps space requests.)
 
 
 Macintosh, Metrowerks CodeWarrior:
 
-Metrowerks release DR2 has problems with the IJG code; don't use it.  Release
-DR3.5 or later should be OK.
-
 The Unix-command-line-style interface can be used by defining USE_CCOMMAND.
-You'll also need to define either TWO_FILE_COMMANDLINE (to avoid stdin/stdout)
-or USE_FDOPEN (to make stdin/stdout work in binary mode).  See the Think C
-entry for more details.
+You'll also need to define TWO_FILE_COMMANDLINE to avoid stdin/stdout.
+This means that when using the cjpeg/djpeg programs, you'll have to type the
+input and output file names in the "Arguments" text-edit box, rather than
+using the file radio buttons.  (Perhaps USE_FDOPEN or USE_SETMODE would
+eliminate the problem, but I haven't heard from anyone who's tried it.)
 
 On 680x0 Macs, Metrowerks defines type "double" as a 10-byte IEEE extended
 float.  jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power
 of 2.  Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
 
+The supplied configuration file jconfig.mac can be used for your jconfig.h;
+it includes all the recommended symbol definitions.  If you have AppleScript
+installed, you can run the supplied script makeproj.mac to create CodeWarrior
+project files for the library and the testbed applications, then build the
+library and applications.  (Thanks to Dan Sears and Don Agro for this nifty
+hack, which saves us from trying to maintain CodeWarrior project files as part
+of the IJG distribution...)
+
 
 Macintosh, Think C:
 
-Jim Brunner has prepared a Mac-style user interface for the IJG library.
-Unfortunately, the released version of it only works with pre-v5 libraries;
-still, it may be a useful starting point.  You can obtain Jim's additional
-source code from the Info-Mac archives, at sumex-aim.stanford.edu or mirrors
-thereof; see file /info-mac/dev/src/jpeg-convert-c.hqx.  Jim's documentation
-also includes more detailed build instructions for Think C.
+The documentation in Jim Brunner's "JPEG Convert" source code (see above)
+includes detailed build instructions for Think C; it's probably somewhat
+out of date for the current release, but may be helpful.
 
 If you want to build the minimal command line version, proceed as follows.
 You'll have to prepare project files for the programs; we don't include any
@@ -695,6 +731,9 @@
 jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power of 2.
 Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
 
+jconfig.mac should work as a jconfig.h configuration file for Think C,
+but the makeproj.mac AppleScript script is specific to CodeWarrior.  Sorry.
+
 
 MIPS R3000:
 
@@ -705,7 +744,7 @@
 
 MS-DOS, generic comments for 16-bit compilers:
 
-The IJG code is designed to be compiled in 80x86 "small" or "medium" memory
+The IJG code is designed to work well in 80x86 "small" or "medium" memory
 models (i.e., data pointers are 16 bits unless explicitly declared "far";
 code pointers can be either size).  You may be able to use small model to
 compile cjpeg or djpeg by itself, but you will probably have to use medium
@@ -721,7 +760,7 @@
 It needs some assembly-code routines which are in jmemdosa.asm; make sure
 your makefile assembles that file and includes it in the library.  If you
 don't have a suitable assembler, you can get pre-assembled object files for
-jmemdosa by FTP from ftp.uu.net: graphics/jpeg/jdosaobj.zip.  (DOS-oriented
+jmemdosa by FTP from ftp.uu.net:/graphics/jpeg/jdosaobj.zip.  (DOS-oriented
 distributions of the IJG source code often include these object files.)
 
 When using jmemdos.c, jconfig.h must define USE_MSDOS_MEMMGR and must set
@@ -778,31 +817,22 @@
 (fdopen does not work correctly.)
 
 
-MS-DOS, DJGPP:
-
-Use a recent version of DJGPP (1.11 or better).  If you prefer two-file
-command line style, change the supplied jconfig.dj to define
-TWO_FILE_COMMANDLINE.  makefile.dj is set up to generate only COFF files
-(cjpeg, djpeg, etc) when you say make.  After testing, say "make exe" to
-make executables with stub.exe, or "make standalone" if you want executables
-that include go32.  You will probably need to tweak the makefile's pointer to
-go32.exe to do "make standalone".
-
-
 MS-DOS, Microsoft C:
 
-makefile.mc6 works with Microsoft C, Visual C++, etc.  Note that this
-makefile assumes that the working copy of itself is called "makefile".
-If you want to call it something else, say "makefile.mak", be sure to adjust
-the dependency line that reads "$(RFILE) : makefile".  Otherwise the make
-will fail because it doesn't know how to create "makefile".  Worse, some
-releases of Microsoft's make utilities give an incorrect error message in
-this situation.
+makefile.mc6 works with Microsoft C, DOS Visual C++, etc.  It should only
+be used if you want to build a 16-bit (small or medium memory model) program.
 
 If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
 jconfig.mc6 already includes #define USE_SETMODE to make this work.
 (fdopen does not work correctly.)
 
+Note that this makefile assumes that the working copy of itself is called
+"makefile".  If you want to call it something else, say "makefile.mak",
+be sure to adjust the dependency line that reads "$(RFILE) : makefile".
+Otherwise the make will fail because it doesn't know how to create "makefile".
+Worse, some releases of Microsoft's make utilities give an incorrect error
+message in this situation.
+
 Old versions of MS C fail with an "out of macro expansion space" error
 because they can't cope with the macro TRACEMS8 (defined in jerror.h).
 If this happens to you, the easiest solution is to change TRACEMS8 to
@@ -813,11 +843,12 @@
 off optimization entirely (remove -O from CFLAGS).  6.00A is better, but it
 still generates bad code if you enable loop optimizations (-Ol or -Ox).
 
-MS C 8.0 reportedly fails to compile jquant1.c if optimization is turned off
-(yes, off).
+MS C 8.0 crashes when compiling jquant1.c with optimization switch /Oo ...
+which is on by default.  To work around this bug, compile that one file
+with /Oo-.
 
 
-Microsoft Windows (all versions):
+Microsoft Windows (all versions), generic comments:
 
 Some Windows system include files define typedef boolean as "unsigned char".
 The IJG code also defines typedef boolean, but we make it "int" by default.
@@ -825,45 +856,86 @@
 include files.  But if you use the JPEG library in your own program, and some
 of your program's files import one definition of boolean while some import the
 other, you can get all sorts of mysterious problems.  A good preventive step
-is to change jmorecfg.h to define boolean as unsigned char.  We recommend
-making that part of jmorecfg.h read like this:
+is to make the IJG library use "unsigned char" for boolean.  To do that,
+add something like this to your jconfig.h file:
+	/* Define "boolean" as unsigned char, not int, per Windows custom */
 	#ifndef __RPCNDR_H__	/* don't conflict if rpcndr.h already read */
 	typedef unsigned char boolean;
 	#endif
-In v6a and later, using incompatible definitions of boolean will usually lead
-to the failure message "JPEG parameter struct mismatch", rather than the
-difficult-to-diagnose bugs it caused with earlier versions.
+	#define HAVE_BOOLEAN	/* prevent jmorecfg.h from redefining it */
+(This is already in jconfig.vc, by the way.)
+
+windef.h contains the declarations
+	#define far
+	#define FAR far
+Since jmorecfg.h tries to define FAR as empty, you may get a compiler
+warning if you include both jpeglib.h and windef.h (which windows.h
+includes).  To suppress the warning, you can put "#ifndef FAR"/"#endif"
+around the line "#define FAR" in jmorecfg.h.
 
 When using the library in a Windows application, you will almost certainly
 want to modify or replace the error handler module jerror.c, since our
 default error handler does a couple of inappropriate things:
   1. it tries to write error and warning messages on stderr;
   2. in event of a fatal error, it exits by calling exit().
+
 A simple stopgap solution for problem 1 is to replace the line
 	fprintf(stderr, "%s\n", buffer);
-(in output_message in jerror.c) with something like
-	MessageBox(GetActiveWindow(),buffer,"JPEG Error",MB_OK);
+(in output_message in jerror.c) with
+	MessageBox(GetActiveWindow(),buffer,"JPEG Error",MB_OK|MB_ICONERROR);
 It's highly recommended that you at least do that much, since otherwise
-error messages will disappear into nowhere.
+error messages will disappear into nowhere.  (Beginning with IJG v6b, this
+code is already present in jerror.c; just define USE_WINDOWS_MESSAGEBOX in
+jconfig.h to enable it.)
+
 The proper solution for problem 2 is to return control to your calling
 application after a library error.  This can be done with the setjmp/longjmp
-technique discussed in libjpeg.doc and illustrated in example.c.
+technique discussed in libjpeg.doc and illustrated in example.c.  (NOTE:
+some older Windows C compilers provide versions of setjmp/longjmp that
+don't actually work under Windows.  You may need to use the Windows system
+functions Catch and Throw instead.)
+
+The recommended memory manager under Windows is jmemnobs.c; in other words,
+let Windows do any virtual memory management needed.  You should NOT use
+jmemdos.c nor jmemdosa.asm under Windows.
+
+For Windows 3.1, we recommend compiling in medium or large memory model;
+for newer Windows versions, use a 32-bit flat memory model.  (See the MS-DOS
+sections above for more info about memory models.)  In the 16-bit memory
+models only, you'll need to put
+	#define MAX_ALLOC_CHUNK 65520L	/* Maximum request to malloc() */
+into jconfig.h to limit allocation chunks to 64Kb.  (Without that, you'd
+have to use huge memory model, which slows things down unnecessarily.)
+jmemnobs.c works without modification in large or flat memory models, but to
+use medium model, you need to modify its jpeg_get_large and jpeg_free_large
+routines to allocate far memory.  In any case, you might like to replace
+its calls to malloc and free with direct calls on Windows memory allocation
+functions.
 
 You may also want to modify jdatasrc.c and jdatadst.c to use Windows file
 operations rather than fread/fwrite.  This is only necessary if your C
 compiler doesn't provide a competent implementation of C stdio functions.
 
+You might want to tweak the RGB_xxx macros in jmorecfg.h so that the library
+will accept or deliver color pixels in BGR sample order, not RGB; BGR order
+is usually more convenient under Windows.  Note that this change will break
+the sample applications cjpeg/djpeg, but the library itself works fine.
+
+
 Many people want to convert the IJG library into a DLL.  This is reasonably
 straightforward, but watch out for the following:
+
   1. Don't try to compile as a DLL in small or medium memory model; use
 large model, or even better, 32-bit flat model.  Many places in the IJG code
 assume the address of a local variable is an ordinary (not FAR) pointer;
 that isn't true in a medium-model DLL.
+
   2. Microsoft C cannot pass file pointers between applications and DLLs.
 (See Microsoft Knowledge Base, PSS ID Number Q50336.)  So jdatasrc.c and
 jdatadst.c don't work if you open a file in your application and then pass
 the pointer to the DLL.  One workaround is to make jdatasrc.c/jdatadst.c
 part of your main application rather than part of the DLL.
+
   3. You'll probably need to modify the macros GLOBAL() and EXTERN() to
 attach suitable linkage keywords to the exported routine names.  Similarly,
 you'll want to modify METHODDEF() and JMETHOD() to ensure function pointers
@@ -871,10 +943,13 @@
 the function pointers.  These macros are in jmorecfg.h.  Typical definitions
 for a 16-bit DLL are:
 	#define GLOBAL(type)		type _far _pascal _loadds _export
-	#define EXTERN(type)		extern type _far _pascal
+	#define EXTERN(type)		extern type _far _pascal _loadds
 	#define METHODDEF(type)		static type _far _pascal
 	#define JMETHOD(type,methodname,arglist)  \
 		type (_far _pascal *methodname) arglist
+For a 32-bit DLL you may want something like
+	#define GLOBAL(type)		__declspec(dllexport) type
+	#define EXTERN(type)		extern __declspec(dllexport) type
 Although not all the GLOBAL routines are actually intended to be called by
 the application, the performance cost of making them all DLL entry points is
 negligible.
@@ -888,6 +963,12 @@
 
 Microsoft Windows, Borland C:
 
+The provided jconfig.bcc should work OK in a 32-bit Windows environment,
+but you'll need to tweak it in a 16-bit environment (you'd need to define
+NEED_FAR_POINTERS and MAX_ALLOC_CHUNK).  Beware that makefile.bcc will need
+alteration if you want to use it for Windows --- in particular, you should
+use jmemnobs.c not jmemdos.c under Windows.
+
 Borland C++ 4.5 fails with an internal compiler error when trying to compile
 jdmerge.c in 32-bit mode.  If enough people complain, perhaps Borland will fix
 it.  In the meantime, the simplest known workaround is to add a redundant
@@ -902,6 +983,57 @@
 Recent reports suggest that this bug does not occur with "bcc32a" (the
 Pentium-optimized version of the compiler).
 
+Another report from a user of Borland C 4.5 was that incorrect code (leading
+to a color shift in processed images) was produced if any of the following
+optimization switch combinations were used: 
+	-Ot -Og
+	-Ot -Op
+	-Ot -Om
+So try backing off on optimization if you see such a problem.  (Are there
+several different releases all numbered "4.5"??)
+
+
+Microsoft Windows, Microsoft Visual C++:
+
+jconfig.vc should work OK with any Microsoft compiler for a 32-bit memory
+model.  makefile.vc is intended for command-line use.  (If you are using
+the Developer Studio environment, you may prefer the DevStudio project
+files; see below.)
+
+Some users feel that it's easier to call the library from C++ code if you
+force VC++ to treat the library as C++ code, which you can do by renaming
+all the *.c files to *.cpp (and adjusting the makefile to match).  This
+avoids the need to put extern "C" { ... } around #include "jpeglib.h" in
+your C++ application.
+
+
+Microsoft Windows, Microsoft Developer Studio:
+
+We include makefiles that should work as project files in DevStudio 4.2 or
+later.  There is a library makefile that builds the IJG library as a static
+Win32 library, and an application makefile that builds the sample applications
+as Win32 console applications.  (Even if you only want the library, we
+recommend building the applications so that you can run the self-test.)
+
+To use:
+1. Copy jconfig.vc to jconfig.h, makelib.ds to jpeg.mak, and
+   makeapps.ds to apps.mak.  (Note that the renaming is critical!)
+2. Click on the .mak files to construct project workspaces.
+   (If you are using DevStudio more recent than 4.2, you'll probably
+   get a message saying that the makefiles are being updated.)
+3. Build the library project, then the applications project.
+4. Move the application .exe files from `app`\Release to an
+   appropriate location on your path.
+5. To perform the self-test, execute the command line
+	NMAKE /f makefile.vc  test
+
+
+OS/2, Borland C++:
+
+Watch out for optimization bugs in older Borland compilers; you may need
+to back off the optimization switch settings.  See the comments in
+makefile.bcc.
+
 
 SGI:
 
diff --git a/jcapimin.c b/jcapimin.c
index 6d86457..54fb8c5 100644
--- a/jcapimin.c
+++ b/jcapimin.c
@@ -1,7 +1,7 @@
 /*
  * jcapimin.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1998, 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.
  *
@@ -39,13 +39,18 @@
     ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
 	     (int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
 
-  /* For debugging purposes, zero the whole master structure.
-   * But error manager pointer is already there, so save and restore it.
+  /* For debugging purposes, we zero the whole master structure.
+   * But the application has already set the err pointer, and may have set
+   * client_data, so we have to save and restore those fields.
+   * Note: if application hasn't set client_data, tools like Purify may
+   * complain here.
    */
   {
     struct jpeg_error_mgr * err = cinfo->err;
+    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
     MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
     cinfo->err = err;
+    cinfo->client_data = client_data;
   }
   cinfo->is_decompressor = FALSE;
 
@@ -66,6 +71,8 @@
     cinfo->ac_huff_tbl_ptrs[i] = NULL;
   }
 
+  cinfo->script_space = NULL;
+
   cinfo->input_gamma = 1.0;	/* in case application forgets */
 
   /* OK, I'm ready */
@@ -185,13 +192,40 @@
 jpeg_write_marker (j_compress_ptr cinfo, int marker,
 		   const JOCTET *dataptr, unsigned int datalen)
 {
+  JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
+
   if (cinfo->next_scanline != 0 ||
       (cinfo->global_state != CSTATE_SCANNING &&
        cinfo->global_state != CSTATE_RAW_OK &&
        cinfo->global_state != CSTATE_WRCOEFS))
     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 
-  (*cinfo->marker->write_any_marker) (cinfo, marker, dataptr, datalen);
+  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+  write_marker_byte = cinfo->marker->write_marker_byte;	/* copy for speed */
+  while (datalen--) {
+    (*write_marker_byte) (cinfo, *dataptr);
+    dataptr++;
+  }
+}
+
+/* Same, but piecemeal. */
+
+GLOBAL(void)
+jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+{
+  if (cinfo->next_scanline != 0 ||
+      (cinfo->global_state != CSTATE_SCANNING &&
+       cinfo->global_state != CSTATE_RAW_OK &&
+       cinfo->global_state != CSTATE_WRCOEFS))
+    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+  (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+}
+
+GLOBAL(void)
+jpeg_write_m_byte (j_compress_ptr cinfo, int val)
+{
+  (*cinfo->marker->write_marker_byte) (cinfo, val);
 }
 
 
@@ -231,6 +265,16 @@
   (*cinfo->marker->write_tables_only) (cinfo);
   /* And clean up. */
   (*cinfo->dest->term_destination) (cinfo);
-  /* We can use jpeg_abort to release memory. */
-  jpeg_abort((j_common_ptr) cinfo);
+  /*
+   * In library releases up through v6a, we called jpeg_abort() here to free
+   * any working memory allocated by the destination manager and marker
+   * writer.  Some applications had a problem with that: they allocated space
+   * of their own from the library memory manager, and didn't want it to go
+   * away during write_tables.  So now we do nothing.  This will cause a
+   * memory leak if an app calls write_tables repeatedly without doing a full
+   * compression cycle or otherwise resetting the JPEG object.  However, that
+   * seems less bad than unexpectedly freeing memory in the normal case.
+   * An app that prefers the old behavior can call jpeg_abort for itself after
+   * each call to jpeg_write_tables().
+   */
 }
diff --git a/jccoefct.c b/jccoefct.c
index d971ce5..1963ddb 100644
--- a/jccoefct.c
+++ b/jccoefct.c
@@ -1,7 +1,7 @@
 /*
  * jccoefct.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -135,8 +135,8 @@
  * per call, ie, v_samp_factor block rows for each component in the image.
  * Returns TRUE if the iMCU row is completed, FALSE if suspended.
  *
- * NB: input_buf contains a plane for each component in image.
- * For single pass, this is the same as the components in the scan.
+ * NB: input_buf contains a plane for each component in image,
+ * which we index according to the component's SOF position.
  */
 
 METHODDEF(boolean)
@@ -175,7 +175,8 @@
 	  if (coef->iMCU_row_num < last_iMCU_row ||
 	      yoffset+yindex < compptr->last_row_height) {
 	    (*cinfo->fdct->forward_DCT) (cinfo, compptr,
-					 input_buf[ci], coef->MCU_buffer[blkn],
+					 input_buf[compptr->component_index],
+					 coef->MCU_buffer[blkn],
 					 ypos, xpos, (JDIMENSION) blockcnt);
 	    if (blockcnt < compptr->MCU_width) {
 	      /* Create some dummy blocks at the right edge of the image. */
diff --git a/jchuff.c b/jchuff.c
index b3eec8a..f235250 100644
--- a/jchuff.c
+++ b/jchuff.c
@@ -1,7 +1,7 @@
 /*
  * jchuff.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -125,16 +125,14 @@
     compptr = cinfo->cur_comp_info[ci];
     dctbl = compptr->dc_tbl_no;
     actbl = compptr->ac_tbl_no;
-    /* Make sure requested tables are present */
-    /* (In gather mode, tables need not be allocated yet) */
-    if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS ||
-	(cinfo->dc_huff_tbl_ptrs[dctbl] == NULL && !gather_statistics))
-      ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
-    if (actbl < 0 || actbl >= NUM_HUFF_TBLS ||
-	(cinfo->ac_huff_tbl_ptrs[actbl] == NULL && !gather_statistics))
-      ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
     if (gather_statistics) {
 #ifdef ENTROPY_OPT_SUPPORTED
+      /* Check for invalid table indexes */
+      /* (make_c_derived_tbl does this in the other path) */
+      if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
+	ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
+      if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
+	ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
       /* Allocate and zero the statistics tables */
       /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
       if (entropy->dc_count_ptrs[dctbl] == NULL)
@@ -151,9 +149,9 @@
     } else {
       /* Compute derived values for Huffman tables */
       /* We may do this more than once for a table, but it's not expensive */
-      jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl],
+      jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
 			      & entropy->dc_derived_tbls[dctbl]);
-      jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl],
+      jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
 			      & entropy->ac_derived_tbls[actbl]);
     }
     /* Initialize DC predictions to 0 */
@@ -172,19 +170,34 @@
 
 /*
  * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
  * Note this is also used by jcphuff.c.
  */
 
 GLOBAL(void)
-jpeg_make_c_derived_tbl (j_compress_ptr cinfo, JHUFF_TBL * htbl,
+jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
 			 c_derived_tbl ** pdtbl)
 {
+  JHUFF_TBL *htbl;
   c_derived_tbl *dtbl;
-  int p, i, l, lastp, si;
+  int p, i, l, lastp, si, maxsymbol;
   char huffsize[257];
   unsigned int huffcode[257];
   unsigned int code;
 
+  /* Note that huffsize[] and huffcode[] are filled in code-length order,
+   * paralleling the order of the symbols themselves in htbl->huffval[].
+   */
+
+  /* Find the input Huffman table */
+  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+  htbl =
+    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+  if (htbl == NULL)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
   /* Allocate a workspace if we haven't already done so. */
   if (*pdtbl == NULL)
     *pdtbl = (c_derived_tbl *)
@@ -193,19 +206,21 @@
   dtbl = *pdtbl;
   
   /* Figure C.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 <= (int) htbl->bits[l]; i++)
+    i = (int) htbl->bits[l];
+    if (i < 0 || p + i > 256)	/* protect against table overrun */
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    while (i--)
       huffsize[p++] = (char) l;
   }
   huffsize[p] = 0;
   lastp = p;
   
   /* Figure C.2: generate the codes themselves */
-  /* Note that this is in code-length order. */
-  
+  /* We also validate that the counts represent a legal Huffman code tree. */
+
   code = 0;
   si = huffsize[0];
   p = 0;
@@ -214,6 +229,11 @@
       huffcode[p++] = code;
       code++;
     }
+    /* code is now 1 more than the last code used for codelength si; but
+     * it must still fit in si bits, since no code is allowed to be all ones.
+     */
+    if (((INT32) code) >= (((INT32) 1) << si))
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
     code <<= 1;
     si++;
   }
@@ -221,14 +241,25 @@
   /* Figure C.3: generate encoding tables */
   /* These are code and size indexed by symbol value */
 
-  /* Set any codeless symbols to have code length 0;
-   * this allows emit_bits to detect any attempt to emit such symbols.
+  /* Set all codeless symbols to have code length 0;
+   * this lets us detect duplicate VAL entries here, and later
+   * allows emit_bits to detect any attempt to emit such symbols.
    */
   MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
 
+  /* This is also a convenient place to check for out-of-range
+   * and duplicated VAL entries.  We allow 0..255 for AC symbols
+   * but only 0..15 for DC.  (We could constrain them further
+   * based on data depth and mode, but this seems enough.)
+   */
+  maxsymbol = isDC ? 15 : 255;
+
   for (p = 0; p < lastp; p++) {
-    dtbl->ehufco[htbl->huffval[p]] = huffcode[p];
-    dtbl->ehufsi[htbl->huffval[p]] = huffsize[p];
+    i = htbl->huffval[p];
+    if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    dtbl->ehufco[i] = huffcode[p];
+    dtbl->ehufsi[i] = huffsize[p];
   }
 }
 
@@ -343,6 +374,11 @@
     nbits++;
     temp >>= 1;
   }
+  /* Check for out-of-range coefficient values.
+   * Since we're encoding a difference, the range limit is twice as much.
+   */
+  if (nbits > MAX_COEF_BITS+1)
+    ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
   
   /* Emit the Huffman-coded symbol for the number of bits */
   if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
@@ -380,6 +416,9 @@
       nbits = 1;		/* there must be at least one 1 bit */
       while ((temp >>= 1))
 	nbits++;
+      /* Check for out-of-range coefficient values */
+      if (nbits > MAX_COEF_BITS)
+	ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
       
       /* Emit Huffman symbol for run length / number of bits */
       i = (r << 4) + nbits;
@@ -516,19 +555,12 @@
 /*
  * 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.
- *
- * The JPEG standard requires Huffman codes to be no more than 16 bits long.
- * If some symbols have a very small but nonzero probability, the Huffman tree
- * must be adjusted to meet the code length restriction.  We currently use
- * the adjustment method suggested in the JPEG spec.  This method is *not*
- * optimal; it may not choose the best possible limited-length code.  But
- * since the symbols involved are infrequently used, it's not clear that
- * going to extra trouble is worthwhile.
+ * 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 a Huffman coding tree for the observed counts.
+ * Symbols which are not needed at all for the particular image are not
+ * assigned any code, which saves space in the DHT marker as well as in
+ * the compressed data.
  */
 
 #ifdef ENTROPY_OPT_SUPPORTED
@@ -537,7 +569,7 @@
 /* Process a single block's worth of coefficients */
 
 LOCAL(void)
-htest_one_block (JCOEFPTR block, int last_dc_val,
+htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
 		 long dc_counts[], long ac_counts[])
 {
   register int temp;
@@ -556,6 +588,11 @@
     nbits++;
     temp >>= 1;
   }
+  /* Check for out-of-range coefficient values.
+   * Since we're encoding a difference, the range limit is twice as much.
+   */
+  if (nbits > MAX_COEF_BITS+1)
+    ERREXIT(cinfo, JERR_BAD_DCT_COEF);
 
   /* Count the Huffman symbol for the number of bits */
   dc_counts[nbits]++;
@@ -582,6 +619,9 @@
       nbits = 1;		/* there must be at least one 1 bit */
       while ((temp >>= 1))
 	nbits++;
+      /* Check for out-of-range coefficient values */
+      if (nbits > MAX_COEF_BITS)
+	ERREXIT(cinfo, JERR_BAD_DCT_COEF);
       
       /* Count Huffman symbol for run length / number of bits */
       ac_counts[(r << 4) + nbits]++;
@@ -623,7 +663,7 @@
   for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
     ci = cinfo->MCU_membership[blkn];
     compptr = cinfo->cur_comp_info[ci];
-    htest_one_block(MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
+    htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
 		    entropy->dc_count_ptrs[compptr->dc_tbl_no],
 		    entropy->ac_count_ptrs[compptr->ac_tbl_no]);
     entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
@@ -634,8 +674,31 @@
 
 
 /*
- * Generate the optimal coding for the given counts, fill htbl.
+ * Generate the best Huffman code table for the given counts, fill htbl.
  * Note this is also used by jcphuff.c.
+ *
+ * The JPEG standard requires that no symbol be assigned a codeword of all
+ * one bits (so that padding bits added at the end of a compressed segment
+ * can't look like a valid code).  Because of the canonical ordering of
+ * codewords, this just means that there must be an unused slot in the
+ * longest codeword length category.  Section K.2 of the JPEG spec suggests
+ * reserving such a slot by pretending that symbol 256 is a valid symbol
+ * with count 1.  In theory that's not optimal; giving it count zero but
+ * including it in the symbol set anyway should give a better Huffman code.
+ * But the theoretically better code actually seems to come out worse in
+ * practice, because it produces more all-ones bytes (which incur stuffed
+ * zero bytes in the final file).  In any case the difference is tiny.
+ *
+ * The JPEG standard requires Huffman codes to be no more than 16 bits long.
+ * If some symbols have a very small but nonzero probability, the Huffman tree
+ * must be adjusted to meet the code length restriction.  We currently use
+ * the adjustment method suggested in JPEG section K.2.  This method is *not*
+ * optimal; it may not choose the best possible limited-length code.  But
+ * typically only very-low-frequency symbols will be given less-than-optimal
+ * lengths, so the code is almost optimal.  Experimental comparisons against
+ * an optimal limited-length-code algorithm indicate that the difference is
+ * microscopic --- usually less than a hundredth of a percent of total size.
+ * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
  */
 
 GLOBAL(void)
@@ -656,10 +719,10 @@
   for (i = 0; i < 257; i++)
     others[i] = -1;		/* init links to empty */
   
-  freq[256] = 1;		/* make sure there is a nonzero count */
+  freq[256] = 1;		/* make sure 256 has 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.
+   * will be placed last in the largest codeword category.
    */
 
   /* Huffman's basic algorithm to assign optimal code lengths to symbols */
diff --git a/jchuff.h b/jchuff.h
index fa4643a..a9599fc 100644
--- a/jchuff.h
+++ b/jchuff.h
@@ -1,7 +1,7 @@
 /*
  * jchuff.h
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -10,6 +10,18 @@
  * progressive encoder (jcphuff.c).  No other modules need to see these.
  */
 
+/* The legal range of a DCT coefficient is
+ *  -1024 .. +1023  for 8-bit data;
+ * -16384 .. +16383 for 12-bit data.
+ * Hence the magnitude should always fit in 10 or 14 bits respectively.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MAX_COEF_BITS 10
+#else
+#define MAX_COEF_BITS 14
+#endif
+
 /* Derived data constructed for each Huffman table */
 
 typedef struct {
@@ -27,7 +39,8 @@
 
 /* Expand a Huffman table definition into the derived format */
 EXTERN(void) jpeg_make_c_derived_tbl
-	JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, c_derived_tbl ** pdtbl));
+	JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
+	     c_derived_tbl ** pdtbl));
 
 /* Generate an optimal table definition given the specified counts */
 EXTERN(void) jpeg_gen_optimal_table
diff --git a/jcinit.c b/jcinit.c
index d96bb37..5efffe3 100644
--- a/jcinit.c
+++ b/jcinit.c
@@ -1,7 +1,7 @@
 /*
  * jcinit.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -56,7 +56,7 @@
 
   /* Need a full-image coefficient buffer in any multi-pass mode. */
   jinit_c_coef_controller(cinfo,
-			  (cinfo->num_scans > 1 || cinfo->optimize_coding));
+		(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
   jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
 
   jinit_marker_writer(cinfo);
diff --git a/jcmarker.c b/jcmarker.c
index 0198954..3d1e6c6 100644
--- a/jcmarker.c
+++ b/jcmarker.c
@@ -1,7 +1,7 @@
 /*
  * jcmarker.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -81,6 +81,17 @@
 } JPEG_MARKER;
 
 
+/* Private state */
+
+typedef struct {
+  struct jpeg_marker_writer pub; /* public fields */
+
+  unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
+} my_marker_writer;
+
+typedef my_marker_writer * my_marker_ptr;
+
+
 /*
  * Basic output routines.
  *
@@ -158,8 +169,8 @@
       /* The table entries must be emitted in zigzag order. */
       unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
       if (prec)
-	emit_byte(cinfo, qval >> 8);
-      emit_byte(cinfo, qval & 0xFF);
+	emit_byte(cinfo, (int) (qval >> 8));
+      emit_byte(cinfo, (int) (qval & 0xFF));
     }
 
     qtbl->sent_table = TRUE;
@@ -342,7 +353,7 @@
    * 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)
+   * Version Major, Minor	(2 bytes - major first)
    * Units			(1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
    * Xdpu			(2 bytes - dots per unit horizontal)
    * Ydpu			(2 bytes - dots per unit vertical)
@@ -359,11 +370,8 @@
   emit_byte(cinfo, 0x49);
   emit_byte(cinfo, 0x46);
   emit_byte(cinfo, 0);
-  /* We currently emit version code 1.01 since we use no 1.02 features.
-   * This may avoid complaints from some older decoders.
-   */
-  emit_byte(cinfo, 1);		/* Major version */
-  emit_byte(cinfo, 1);		/* Minor version */
+  emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
+  emit_byte(cinfo, cinfo->JFIF_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);
@@ -419,28 +427,30 @@
 
 
 /*
- * This routine is exported for possible use by applications.
- * The intended use is to emit COM or APPn markers after calling
- * jpeg_start_compress() and before the first jpeg_write_scanlines() call
- * (hence, after write_file_header but before write_frame_header).
+ * These routines allow writing an arbitrary marker with parameters.
+ * The only intended use is to emit COM or APPn markers after calling
+ * write_file_header and before calling write_frame_header.
  * Other uses are not guaranteed to produce desirable results.
+ * Counting the parameter bytes properly is the caller's responsibility.
  */
 
 METHODDEF(void)
-write_any_marker (j_compress_ptr cinfo, int marker,
-		  const JOCTET *dataptr, unsigned int datalen)
-/* Emit an arbitrary marker with parameters */
+write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+/* Emit an arbitrary marker header */
 {
-  if (datalen <= (unsigned int) 65533) { /* safety check */
-    emit_marker(cinfo, (JPEG_MARKER) marker);
-  
-    emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
+  if (datalen > (unsigned int) 65533)		/* safety check */
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
 
-    while (datalen--) {
-      emit_byte(cinfo, *dataptr);
-      dataptr++;
-    }
-  }
+  emit_marker(cinfo, (JPEG_MARKER) marker);
+
+  emit_2bytes(cinfo, (int) (datalen + 2));	/* total length */
+}
+
+METHODDEF(void)
+write_marker_byte (j_compress_ptr cinfo, int val)
+/* Emit one byte of marker parameters following write_marker_header */
+{
+  emit_byte(cinfo, val);
 }
 
 
@@ -458,8 +468,13 @@
 METHODDEF(void)
 write_file_header (j_compress_ptr cinfo)
 {
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
   emit_marker(cinfo, M_SOI);	/* first the SOI */
 
+  /* SOI is defined to reset restart interval to 0 */
+  marker->last_restart_interval = 0;
+
   if (cinfo->write_JFIF_header)	/* next an optional JFIF APP0 */
     emit_jfif_app0(cinfo);
   if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
@@ -535,6 +550,7 @@
 METHODDEF(void)
 write_scan_header (j_compress_ptr cinfo)
 {
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
   int i;
   jpeg_component_info *compptr;
 
@@ -567,11 +583,12 @@
   }
 
   /* Emit DRI if required --- note that DRI value could change for each scan.
-   * If it doesn't, a tiny amount of space is wasted in multiple-scan files.
-   * We assume DRI will never be nonzero for one scan and zero for a later one.
+   * We avoid wasting space with unnecessary DRIs, however.
    */
-  if (cinfo->restart_interval)
+  if (cinfo->restart_interval != marker->last_restart_interval) {
     emit_dri(cinfo);
+    marker->last_restart_interval = cinfo->restart_interval;
+  }
 
   emit_sos(cinfo);
 }
@@ -627,15 +644,21 @@
 GLOBAL(void)
 jinit_marker_writer (j_compress_ptr cinfo)
 {
+  my_marker_ptr marker;
+
   /* Create the subobject */
-  cinfo->marker = (struct jpeg_marker_writer *)
+  marker = (my_marker_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				SIZEOF(struct jpeg_marker_writer));
+				SIZEOF(my_marker_writer));
+  cinfo->marker = (struct jpeg_marker_writer *) marker;
   /* Initialize method pointers */
-  cinfo->marker->write_any_marker = write_any_marker;
-  cinfo->marker->write_file_header = write_file_header;
-  cinfo->marker->write_frame_header = write_frame_header;
-  cinfo->marker->write_scan_header = write_scan_header;
-  cinfo->marker->write_file_trailer = write_file_trailer;
-  cinfo->marker->write_tables_only = write_tables_only;
+  marker->pub.write_file_header = write_file_header;
+  marker->pub.write_frame_header = write_frame_header;
+  marker->pub.write_scan_header = write_scan_header;
+  marker->pub.write_file_trailer = write_file_trailer;
+  marker->pub.write_tables_only = write_tables_only;
+  marker->pub.write_marker_header = write_marker_header;
+  marker->pub.write_marker_byte = write_marker_byte;
+  /* Initialize private state */
+  marker->last_restart_interval = 0;
 }
diff --git a/jcmaster.c b/jcmaster.c
index c3e1ef5..aab4020 100644
--- a/jcmaster.c
+++ b/jcmaster.c
@@ -1,7 +1,7 @@
 /*
  * jcmaster.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -185,8 +185,20 @@
     Al = scanptr->Al;
     if (cinfo->progressive_mode) {
 #ifdef C_PROGRESSIVE_SUPPORTED
+      /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
+       * seems wrong: the upper bound ought to depend on data precision.
+       * Perhaps they really meant 0..N+1 for N-bit precision.
+       * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
+       * out-of-range reconstructed DC values during the first DC scan,
+       * which might cause problems for some decoders.
+       */
+#if BITS_IN_JSAMPLE == 8
+#define MAX_AH_AL 10
+#else
+#define MAX_AH_AL 13
+#endif
       if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
-	  Ah < 0 || Ah > 13 || Al < 0 || Al > 13)
+	  Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
 	ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
       if (Ss == 0) {
 	if (Se != 0)		/* DC and AC together not OK */
diff --git a/jcomapi.c b/jcomapi.c
index b518ec6..9b1fa75 100644
--- a/jcomapi.c
+++ b/jcomapi.c
@@ -1,7 +1,7 @@
 /*
  * jcomapi.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -30,6 +30,10 @@
 {
   int pool;
 
+  /* Do nothing if called on a not-initialized or destroyed JPEG object. */
+  if (cinfo->mem == NULL)
+    return;
+
   /* Releasing pools in reverse order might help avoid fragmentation
    * with some (brain-damaged) malloc libraries.
    */
@@ -38,7 +42,15 @@
   }
 
   /* Reset overall state for possible reuse of object */
-  cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START);
+  if (cinfo->is_decompressor) {
+    cinfo->global_state = DSTATE_START;
+    /* Try to keep application from accessing now-deleted marker list.
+     * A bit kludgy to do it here, but this is the most central place.
+     */
+    ((j_decompress_ptr) cinfo)->marker_list = NULL;
+  } else {
+    cinfo->global_state = CSTATE_START;
+  }
 }
 
 
diff --git a/jconfig.mac b/jconfig.mac
new file mode 100644
index 0000000..0de3efe
--- /dev/null
+++ b/jconfig.mac
@@ -0,0 +1,43 @@
+/* jconfig.mac --- jconfig.h for CodeWarrior on Apple Macintosh */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#define USE_MAC_MEMMGR		/* Define this if you use jmemmac.c */
+
+#define ALIGN_TYPE long		/* Needed for 680x0 Macs */
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED		/* BMP image file format */
+#define GIF_SUPPORTED		/* GIF image file format */
+#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED		/* Utah RLE image file format */
+#define TARGA_SUPPORTED		/* Targa image file format */
+
+#define USE_CCOMMAND		/* Command line reader for Macintosh */
+#define TWO_FILE_COMMANDLINE	/* Binary I/O thru stdin/stdout doesn't work */
+
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT		/* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/jconfig.vc b/jconfig.vc
new file mode 100644
index 0000000..7e291c7
--- /dev/null
+++ b/jconfig.vc
@@ -0,0 +1,45 @@
+/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS	/* we presume a 32-bit flat memory model */
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+/* Define "boolean" as unsigned char, not int, per Windows custom */
+#ifndef __RPCNDR_H__		/* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#endif
+#define HAVE_BOOLEAN		/* prevent jmorecfg.h from redefining it */
+
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED		/* BMP image file format */
+#define GIF_SUPPORTED		/* GIF image file format */
+#define PPM_SUPPORTED		/* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED		/* Utah RLE image file format */
+#define TARGA_SUPPORTED		/* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE	/* optional */
+#define USE_SETMODE		/* Microsoft has setmode() */
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT		/* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/jcparam.c b/jcparam.c
index 54871d5..6fc48f5 100644
--- a/jcparam.c
+++ b/jcparam.c
@@ -1,7 +1,7 @@
 /*
  * jcparam.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -29,7 +29,7 @@
  * are limited to 1..255 for JPEG baseline compatibility.
  */
 {
-  JQUANT_TBL ** qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
+  JQUANT_TBL ** qtblptr;
   int i;
   long temp;
 
@@ -37,6 +37,11 @@
   if (cinfo->global_state != CSTATE_START)
     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
 
+  if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
+    ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
+
+  qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
+
   if (*qtblptr == NULL)
     *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
 
@@ -148,11 +153,25 @@
 		JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
 /* Define a Huffman table */
 {
+  int nsymbols, len;
+
   if (*htblptr == NULL)
     *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
-  
+
+  /* Copy the number-of-symbols-of-each-code-length counts */
   MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
-  MEMCOPY((*htblptr)->huffval, val, SIZEOF((*htblptr)->huffval));
+
+  /* Validate the counts.  We do this here mainly so we can copy the right
+   * number of symbols from the val[] array, without risking marching off
+   * the end of memory.  jchuff.c will do a more thorough test later.
+   */
+  nsymbols = 0;
+  for (len = 1; len <= 16; len++)
+    nsymbols += bits[len];
+  if (nsymbols < 1 || nsymbols > 256)
+    ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+  MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
 
   /* Initialize sent_table FALSE so table will be written to JPEG file. */
   (*htblptr)->sent_table = FALSE;
@@ -313,7 +332,15 @@
 
   /* Fill in default JFIF marker parameters.  Note that whether the marker
    * will actually be written is determined by jpeg_set_colorspace.
+   *
+   * By default, the library emits JFIF version code 1.01.
+   * An application that wants to emit JFIF 1.02 extension markers should set
+   * JFIF_minor_version to 2.  We could probably get away with just defaulting
+   * to 1.02, but there may still be some decoders in use that will complain
+   * about that; saying 1.01 should minimize compatibility problems.
    */
+  cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
+  cinfo->JFIF_minor_version = 1;
   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;
@@ -529,11 +556,20 @@
       nscans = 2 + 4 * ncomps;	/* 2 DC scans; 4 AC scans per component */
   }
 
-  /* Allocate space for script. */
-  /* We use permanent pool just in case application re-uses script. */
-  scanptr = (jpeg_scan_info *)
-    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
-				nscans * SIZEOF(jpeg_scan_info));
+  /* Allocate space for script.
+   * We need to put it in the permanent pool in case the application performs
+   * multiple compressions without changing the settings.  To avoid a memory
+   * leak if jpeg_simple_progression is called repeatedly for the same JPEG
+   * object, we try to re-use previously allocated space, and we allocate
+   * enough space to handle YCbCr even if initially asked for grayscale.
+   */
+  if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
+    cinfo->script_space_size = MAX(nscans, 10);
+    cinfo->script_space = (jpeg_scan_info *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+			cinfo->script_space_size * SIZEOF(jpeg_scan_info));
+  }
+  scanptr = cinfo->script_space;
   cinfo->scan_info = scanptr;
   cinfo->num_scans = nscans;
 
diff --git a/jcphuff.c b/jcphuff.c
index 9ace161..07f9178 100644
--- a/jcphuff.c
+++ b/jcphuff.c
@@ -1,7 +1,7 @@
 /*
  * jcphuff.c
  *
- * Copyright (C) 1995-1996, Thomas G. Lane.
+ * Copyright (C) 1995-1997, 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.
  *
@@ -147,22 +147,19 @@
     compptr = cinfo->cur_comp_info[ci];
     /* Initialize DC predictions to 0 */
     entropy->last_dc_val[ci] = 0;
-    /* Make sure requested tables are present */
-    /* (In gather mode, tables need not be allocated yet) */
+    /* Get table index */
     if (is_DC_band) {
       if (cinfo->Ah != 0)	/* DC refinement needs no table */
 	continue;
       tbl = compptr->dc_tbl_no;
-      if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
-	  (cinfo->dc_huff_tbl_ptrs[tbl] == NULL && !gather_statistics))
-	ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl);
     } else {
       entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
-      if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
-          (cinfo->ac_huff_tbl_ptrs[tbl] == NULL && !gather_statistics))
-        ERREXIT1(cinfo,JERR_NO_HUFF_TABLE, tbl);
     }
     if (gather_statistics) {
+      /* Check for invalid table index */
+      /* (make_c_derived_tbl does this in the other path) */
+      if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
+        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
       /* Allocate and zero the statistics tables */
       /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
       if (entropy->count_ptrs[tbl] == NULL)
@@ -171,14 +168,10 @@
 				      257 * SIZEOF(long));
       MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
     } else {
-      /* Compute derived values for Huffman tables */
+      /* Compute derived values for Huffman table */
       /* We may do this more than once for a table, but it's not expensive */
-      if (is_DC_band)
-        jpeg_make_c_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl],
-				& entropy->derived_tbls[tbl]);
-      else
-        jpeg_make_c_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl],
-				& entropy->derived_tbls[tbl]);
+      jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
+			      & entropy->derived_tbls[tbl]);
     }
   }
 
@@ -329,6 +322,9 @@
     nbits = 0;
     while ((temp >>= 1))
       nbits++;
+    /* safety check: shouldn't happen given limited correction-bit buffer */
+    if (nbits > 14)
+      ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
 
     emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
     if (nbits)
@@ -427,6 +423,11 @@
       nbits++;
       temp >>= 1;
     }
+    /* Check for out-of-range coefficient values.
+     * Since we're encoding a difference, the range limit is twice as much.
+     */
+    if (nbits > MAX_COEF_BITS+1)
+      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
     
     /* Count/emit the Huffman-coded symbol for the number of bits */
     emit_symbol(entropy, compptr->dc_tbl_no, nbits);
@@ -523,6 +524,9 @@
     nbits = 1;			/* there must be at least one 1 bit */
     while ((temp >>= 1))
       nbits++;
+    /* Check for out-of-range coefficient values */
+    if (nbits > MAX_COEF_BITS)
+      ERREXIT(cinfo, JERR_BAD_DCT_COEF);
 
     /* Count/emit Huffman symbol for run length / number of bits */
     emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
diff --git a/jctrans.c b/jctrans.c
index 4296048..0e6d707 100644
--- a/jctrans.c
+++ b/jctrans.c
@@ -1,7 +1,7 @@
 /*
  * jctrans.c
  *
- * Copyright (C) 1995-1996, Thomas G. Lane.
+ * Copyright (C) 1995-1998, 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.
  *
@@ -129,6 +129,23 @@
      * instead we rely on jpeg_set_colorspace to have made a suitable choice.
      */
   }
+  /* Also copy JFIF version and resolution information, if available.
+   * Strictly speaking this isn't "critical" info, but it's nearly
+   * always appropriate to copy it if available.  In particular,
+   * if the application chooses to copy JFIF 1.02 extension markers from
+   * the source file, we need to copy the version to make sure we don't
+   * emit a file that has 1.02 extensions but a claimed version of 1.01.
+   * We will *not*, however, copy version info from mislabeled "2.01" files.
+   */
+  if (srcinfo->saw_JFIF_marker) {
+    if (srcinfo->JFIF_major_version == 1) {
+      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
+      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
+    }
+    dstinfo->density_unit = srcinfo->density_unit;
+    dstinfo->X_density = srcinfo->X_density;
+    dstinfo->Y_density = srcinfo->Y_density;
+  }
 }
 
 
@@ -170,7 +187,7 @@
   /* We can now tell the memory manager to allocate virtual arrays. */
   (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
 
-  /* Write the datastream header (SOI) immediately.
+  /* Write the datastream header (SOI, JFIF) immediately.
    * Frame and scan headers are postponed till later.
    * This lets application insert special markers after the SOI.
    */
diff --git a/jdapimin.c b/jdapimin.c
index c702154..cadb59f 100644
--- a/jdapimin.c
+++ b/jdapimin.c
@@ -1,7 +1,7 @@
 /*
  * jdapimin.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1998, 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.
  *
@@ -39,13 +39,18 @@
     ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, 
 	     (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
 
-  /* For debugging purposes, zero the whole master structure.
-   * But error manager pointer is already there, so save and restore it.
+  /* For debugging purposes, we zero the whole master structure.
+   * But the application has already set the err pointer, and may have set
+   * client_data, so we have to save and restore those fields.
+   * Note: if application hasn't set client_data, tools like Purify may
+   * complain here.
    */
   {
     struct jpeg_error_mgr * err = cinfo->err;
+    void * client_data = cinfo->client_data; /* ignore Purify complaint here */
     MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
     cinfo->err = err;
+    cinfo->client_data = client_data;
   }
   cinfo->is_decompressor = TRUE;
 
@@ -67,6 +72,7 @@
   /* Initialize marker processor so application can override methods
    * for COM, APPn markers before calling jpeg_read_header.
    */
+  cinfo->marker_list = NULL;
   jinit_marker_reader(cinfo);
 
   /* And initialize the overall input controller. */
@@ -101,23 +107,6 @@
 
 
 /*
- * Install a special processing method for COM or APPn markers.
- */
-
-GLOBAL(void)
-jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
-			   jpeg_marker_parser_method routine)
-{
-  if (marker_code == JPEG_COM)
-    cinfo->marker->process_COM = routine;
-  else if (marker_code >= JPEG_APP0 && marker_code <= JPEG_APP0+15)
-    cinfo->marker->process_APPn[marker_code-JPEG_APP0] = routine;
-  else
-    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
-}
-
-
-/*
  * Set default decompression parameters.
  */
 
diff --git a/jdcoefct.c b/jdcoefct.c
index c0cd0bd..4938d20 100644
--- a/jdcoefct.c
+++ b/jdcoefct.c
@@ -1,7 +1,7 @@
 /*
  * jdcoefct.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -139,8 +139,8 @@
  * Input and output must run in lockstep since we have only a one-MCU buffer.
  * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
  *
- * NB: output_buf contains a plane for each component in image.
- * For single pass, this is the same as the components in the scan.
+ * NB: output_buf contains a plane for each component in image,
+ * which we index according to the component's SOF position.
  */
 
 METHODDEF(int)
@@ -186,7 +186,8 @@
 	inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
 	useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
 						    : compptr->last_col_width;
-	output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size;
+	output_ptr = output_buf[compptr->component_index] +
+	  yoffset * compptr->DCT_scaled_size;
 	start_col = MCU_col_num * compptr->MCU_sample_width;
 	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
 	  if (cinfo->input_iMCU_row < last_iMCU_row ||
diff --git a/jdcolor.c b/jdcolor.c
index 0269498..6c04dfe 100644
--- a/jdcolor.c
+++ b/jdcolor.c
@@ -1,7 +1,7 @@
 /*
  * jdcolor.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -208,6 +208,33 @@
 
 
 /*
+ * Convert grayscale to RGB: just duplicate the graylevel three times.
+ * This is provided to support applications that don't want to cope
+ * with grayscale as a separate case.
+ */
+
+METHODDEF(void)
+gray_rgb_convert (j_decompress_ptr cinfo,
+		  JSAMPIMAGE input_buf, JDIMENSION input_row,
+		  JSAMPARRAY output_buf, int num_rows)
+{
+  register JSAMPROW inptr, outptr;
+  register JDIMENSION col;
+  JDIMENSION num_cols = cinfo->output_width;
+
+  while (--num_rows >= 0) {
+    inptr = input_buf[0][input_row++];
+    outptr = *output_buf++;
+    for (col = 0; col < num_cols; col++) {
+      /* We can dispense with GETJSAMPLE() here */
+      outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
+      outptr += RGB_PIXELSIZE;
+    }
+  }
+}
+
+
+/*
  * Adobe-style YCCK->CMYK conversion.
  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
  * conversion as above, while passing K (black) unchanged.
@@ -333,6 +360,8 @@
     if (cinfo->jpeg_color_space == JCS_YCbCr) {
       cconvert->pub.color_convert = ycc_rgb_convert;
       build_ycc_rgb_table(cinfo);
+    } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
+      cconvert->pub.color_convert = gray_rgb_convert;
     } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
       cconvert->pub.color_convert = null_convert;
     } else
diff --git a/jdhuff.c b/jdhuff.c
index 5b5544b..b5ba39f 100644
--- a/jdhuff.c
+++ b/jdhuff.c
@@ -1,7 +1,7 @@
 /*
  * jdhuff.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -64,6 +64,15 @@
   /* Pointers to derived tables (these workspaces have image lifespan) */
   d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
   d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+
+  /* Precalculated info set up by start_pass for use in decode_mcu: */
+
+  /* Pointers to derived tables to be used for each block within an MCU */
+  d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+  d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+  /* Whether we care about the DC and AC coefficient values for each block */
+  boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
+  boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
 } huff_entropy_decoder;
 
 typedef huff_entropy_decoder * huff_entropy_ptr;
@@ -77,7 +86,7 @@
 start_pass_huff_decoder (j_decompress_ptr cinfo)
 {
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
-  int ci, dctbl, actbl;
+  int ci, blkn, dctbl, actbl;
   jpeg_component_info * compptr;
 
   /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
@@ -92,27 +101,37 @@
     compptr = cinfo->cur_comp_info[ci];
     dctbl = compptr->dc_tbl_no;
     actbl = compptr->ac_tbl_no;
-    /* Make sure requested tables are present */
-    if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS ||
-	cinfo->dc_huff_tbl_ptrs[dctbl] == NULL)
-      ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
-    if (actbl < 0 || actbl >= NUM_HUFF_TBLS ||
-	cinfo->ac_huff_tbl_ptrs[actbl] == NULL)
-      ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
     /* Compute derived values for Huffman tables */
     /* We may do this more than once for a table, but it's not expensive */
-    jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[dctbl],
+    jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
 			    & entropy->dc_derived_tbls[dctbl]);
-    jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[actbl],
+    jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
 			    & entropy->ac_derived_tbls[actbl]);
     /* Initialize DC predictions to 0 */
     entropy->saved.last_dc_val[ci] = 0;
   }
 
+  /* Precalculate decoding info for each block in an MCU of this scan */
+  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+    ci = cinfo->MCU_membership[blkn];
+    compptr = cinfo->cur_comp_info[ci];
+    /* Precalculate which table to use for each block */
+    entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
+    entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
+    /* Decide whether we really care about the coefficient values */
+    if (compptr->component_needed) {
+      entropy->dc_needed[blkn] = TRUE;
+      /* we don't need the ACs if producing a 1/8th-size image */
+      entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
+    } else {
+      entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
+    }
+  }
+
   /* Initialize bitread state variables */
   entropy->bitstate.bits_left = 0;
   entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
-  entropy->bitstate.printed_eod = FALSE;
+  entropy->pub.insufficient_data = FALSE;
 
   /* Initialize restart counter */
   entropy->restarts_to_go = cinfo->restart_interval;
@@ -121,20 +140,35 @@
 
 /*
  * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
  * Note this is also used by jdphuff.c.
  */
 
 GLOBAL(void)
-jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, JHUFF_TBL * htbl,
+jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
 			 d_derived_tbl ** pdtbl)
 {
+  JHUFF_TBL *htbl;
   d_derived_tbl *dtbl;
-  int p, i, l, si;
+  int p, i, l, si, numsymbols;
   int lookbits, ctr;
   char huffsize[257];
   unsigned int huffcode[257];
   unsigned int code;
 
+  /* Note that huffsize[] and huffcode[] are filled in code-length order,
+   * paralleling the order of the symbols themselves in htbl->huffval[].
+   */
+
+  /* Find the input Huffman table */
+  if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+  htbl =
+    isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+  if (htbl == NULL)
+    ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
   /* Allocate a workspace if we haven't already done so. */
   if (*pdtbl == NULL)
     *pdtbl = (d_derived_tbl *)
@@ -144,17 +178,20 @@
   dtbl->pub = htbl;		/* fill in back link */
   
   /* Figure C.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 <= (int) htbl->bits[l]; i++)
+    i = (int) htbl->bits[l];
+    if (i < 0 || p + i > 256)	/* protect against table overrun */
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    while (i--)
       huffsize[p++] = (char) l;
   }
   huffsize[p] = 0;
+  numsymbols = p;
   
   /* Figure C.2: generate the codes themselves */
-  /* Note that this is in code-length order. */
+  /* We also validate that the counts represent a legal Huffman code tree. */
   
   code = 0;
   si = huffsize[0];
@@ -164,6 +201,11 @@
       huffcode[p++] = code;
       code++;
     }
+    /* code is now 1 more than the last code used for codelength si; but
+     * it must still fit in si bits, since no code is allowed to be all ones.
+     */
+    if (((INT32) code) >= (((INT32) 1) << si))
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
     code <<= 1;
     si++;
   }
@@ -173,8 +215,10 @@
   p = 0;
   for (l = 1; l <= 16; l++) {
     if (htbl->bits[l]) {
-      dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
-      dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
+      /* valoffset[l] = huffval[] index of 1st symbol of code length l,
+       * minus the minimum code of length l
+       */
+      dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
       p += htbl->bits[l];
       dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
     } else {
@@ -205,6 +249,20 @@
       }
     }
   }
+
+  /* Validate symbols as being reasonable.
+   * For AC tables, we make no check, but accept all byte values 0..255.
+   * For DC tables, we require the symbols to be in range 0..15.
+   * (Tighter bounds could be applied depending on the data depth and mode,
+   * but this is sufficient to ensure safe decoding.)
+   */
+  if (isDC) {
+    for (i = 0; i < numsymbols; i++) {
+      int sym = htbl->huffval[i];
+      if (sym < 0 || sym > 15)
+	ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+    }
+  }
 }
 
 
@@ -239,68 +297,86 @@
   /* Copy heavily used state fields into locals (hopefully registers) */
   register const JOCTET * next_input_byte = state->next_input_byte;
   register size_t bytes_in_buffer = state->bytes_in_buffer;
-  register int c;
+  j_decompress_ptr cinfo = state->cinfo;
 
   /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
   /* (It is assumed that no request will be for more than that many bits.) */
+  /* We fail to do so only if we hit a marker or are forced to suspend. */
 
-  while (bits_left < MIN_GET_BITS) {
-    /* Attempt to read a byte */
-    if (state->unread_marker != 0)
-      goto no_more_data;	/* can't advance past a marker */
+  if (cinfo->unread_marker == 0) {	/* cannot advance past a marker */
+    while (bits_left < MIN_GET_BITS) {
+      register int c;
 
-    if (bytes_in_buffer == 0) {
-      if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo))
-	return FALSE;
-      next_input_byte = state->cinfo->src->next_input_byte;
-      bytes_in_buffer = state->cinfo->src->bytes_in_buffer;
-    }
-    bytes_in_buffer--;
-    c = GETJOCTET(*next_input_byte++);
-
-    /* If it's 0xFF, check and discard stuffed zero byte */
-    if (c == 0xFF) {
-      do {
-	if (bytes_in_buffer == 0) {
-	  if (! (*state->cinfo->src->fill_input_buffer) (state->cinfo))
-	    return FALSE;
-	  next_input_byte = state->cinfo->src->next_input_byte;
-	  bytes_in_buffer = state->cinfo->src->bytes_in_buffer;
-	}
-	bytes_in_buffer--;
-	c = GETJOCTET(*next_input_byte++);
-      } while (c == 0xFF);
-
-      if (c == 0) {
-	/* Found FF/00, which represents an FF data byte */
-	c = 0xFF;
-      } else {
-	/* Oops, it's actually a marker indicating end of compressed data. */
-	/* Better put it back for use later */
-	state->unread_marker = c;
-
-      no_more_data:
-	/* There should be enough bits still left in the data segment; */
-	/* if so, just break out of the outer while loop. */
-	if (bits_left >= nbits)
-	  break;
-	/* Uh-oh.  Report corrupted data to user and stuff zeroes into
-	 * the data stream, so that we can produce some kind of image.
-	 * Note that this code will be repeated for each byte demanded
-	 * for the rest of the segment.  We use a nonvolatile flag to ensure
-	 * that only one warning message appears.
-	 */
-	if (! *(state->printed_eod_ptr)) {
-	  WARNMS(state->cinfo, JWRN_HIT_MARKER);
-	  *(state->printed_eod_ptr) = TRUE;
-	}
-	c = 0;			/* insert a zero byte into bit buffer */
+      /* Attempt to read a byte */
+      if (bytes_in_buffer == 0) {
+	if (! (*cinfo->src->fill_input_buffer) (cinfo))
+	  return FALSE;
+	next_input_byte = cinfo->src->next_input_byte;
+	bytes_in_buffer = cinfo->src->bytes_in_buffer;
       }
-    }
+      bytes_in_buffer--;
+      c = GETJOCTET(*next_input_byte++);
 
-    /* OK, load c into get_buffer */
-    get_buffer = (get_buffer << 8) | c;
-    bits_left += 8;
+      /* If it's 0xFF, check and discard stuffed zero byte */
+      if (c == 0xFF) {
+	/* Loop here to discard any padding FF's on terminating marker,
+	 * so that we can save a valid unread_marker value.  NOTE: we will
+	 * accept multiple FF's followed by a 0 as meaning a single FF data
+	 * byte.  This data pattern is not valid according to the standard.
+	 */
+	do {
+	  if (bytes_in_buffer == 0) {
+	    if (! (*cinfo->src->fill_input_buffer) (cinfo))
+	      return FALSE;
+	    next_input_byte = cinfo->src->next_input_byte;
+	    bytes_in_buffer = cinfo->src->bytes_in_buffer;
+	  }
+	  bytes_in_buffer--;
+	  c = GETJOCTET(*next_input_byte++);
+	} while (c == 0xFF);
+
+	if (c == 0) {
+	  /* Found FF/00, which represents an FF data byte */
+	  c = 0xFF;
+	} else {
+	  /* Oops, it's actually a marker indicating end of compressed data.
+	   * Save the marker code for later use.
+	   * Fine point: it might appear that we should save the marker into
+	   * bitread working state, not straight into permanent state.  But
+	   * once we have hit a marker, we cannot need to suspend within the
+	   * current MCU, because we will read no more bytes from the data
+	   * source.  So it is OK to update permanent state right away.
+	   */
+	  cinfo->unread_marker = c;
+	  /* See if we need to insert some fake zero bits. */
+	  goto no_more_bytes;
+	}
+      }
+
+      /* OK, load c into get_buffer */
+      get_buffer = (get_buffer << 8) | c;
+      bits_left += 8;
+    } /* end while */
+  } else {
+  no_more_bytes:
+    /* We get here if we've read the marker that terminates the compressed
+     * data segment.  There should be enough bits in the buffer register
+     * to satisfy the request; if so, no problem.
+     */
+    if (nbits > bits_left) {
+      /* Uh-oh.  Report corrupted data to user and stuff zeroes into
+       * the data stream, so that we can produce some kind of image.
+       * We use a nonvolatile flag to ensure that only one warning message
+       * appears per data segment.
+       */
+      if (! cinfo->entropy->insufficient_data) {
+	WARNMS(cinfo, JWRN_HIT_MARKER);
+	cinfo->entropy->insufficient_data = TRUE;
+      }
+      /* Fill the buffer with zero bits */
+      get_buffer <<= MIN_GET_BITS - bits_left;
+      bits_left = MIN_GET_BITS;
+    }
   }
 
   /* Unload the local registers */
@@ -353,8 +429,7 @@
     return 0;			/* fake a zero as the safest result */
   }
 
-  return htbl->pub->huffval[ htbl->valptr[l] +
-			    ((int) (code - htbl->mincode[l])) ];
+  return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
 }
 
 
@@ -411,8 +486,13 @@
   /* Reset restart counter */
   entropy->restarts_to_go = cinfo->restart_interval;
 
-  /* Next segment can get another out-of-data warning */
-  entropy->bitstate.printed_eod = FALSE;
+  /* Reset out-of-data flag, unless read_restart_marker left us smack up
+   * against a marker.  In that case we will end up treating the next data
+   * segment as empty, and we can avoid producing bogus output pixels by
+   * leaving the flag set.
+   */
+  if (cinfo->unread_marker == 0)
+    entropy->pub.insufficient_data = FALSE;
 
   return TRUE;
 }
@@ -437,14 +517,9 @@
 decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
 {
   huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
-  register int s, k, r;
-  int blkn, ci;
-  JBLOCKROW block;
+  int blkn;
   BITREAD_STATE_VARS;
   savable_state state;
-  d_derived_tbl * dctbl;
-  d_derived_tbl * actbl;
-  jpeg_component_info * compptr;
 
   /* Process restart marker if needed; may have to suspend */
   if (cinfo->restart_interval) {
@@ -453,96 +528,98 @@
 	return FALSE;
   }
 
-  /* Load up working state */
-  BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
-  ASSIGN_STATE(state, entropy->saved);
+  /* If we've run out of data, just leave the MCU set to zeroes.
+   * This way, we return uniform gray for the remainder of the segment.
+   */
+  if (! entropy->pub.insufficient_data) {
 
-  /* Outer loop handles each block in the MCU */
+    /* Load up working state */
+    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(state, entropy->saved);
 
-  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
-    block = MCU_data[blkn];
-    ci = cinfo->MCU_membership[blkn];
-    compptr = cinfo->cur_comp_info[ci];
-    dctbl = entropy->dc_derived_tbls[compptr->dc_tbl_no];
-    actbl = entropy->ac_derived_tbls[compptr->ac_tbl_no];
+    /* Outer loop handles each block in the MCU */
 
-    /* Decode a single block's worth of coefficients */
+    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+      JBLOCKROW block = MCU_data[blkn];
+      d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
+      d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
+      register int s, k, r;
 
-    /* Section F.2.2.1: decode the DC coefficient difference */
-    HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
-    if (s) {
-      CHECK_BIT_BUFFER(br_state, s, return FALSE);
-      r = GET_BITS(s);
-      s = HUFF_EXTEND(r, s);
-    }
+      /* Decode a single block's worth of coefficients */
 
-    /* Shortcut if component's values are not interesting */
-    if (! compptr->component_needed)
-      goto skip_ACs;
-
-    /* Convert DC difference to actual value, update last_dc_val */
-    s += state.last_dc_val[ci];
-    state.last_dc_val[ci] = s;
-    /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
-    (*block)[0] = (JCOEF) s;
-
-    /* Do we need to decode the AC coefficients for this component? */
-    if (compptr->DCT_scaled_size > 1) {
-
-      /* Section F.2.2.2: decode the AC coefficients */
-      /* Since zeroes are skipped, output area must be cleared beforehand */
-      for (k = 1; k < DCTSIZE2; k++) {
-	HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
-      
-	r = s >> 4;
-	s &= 15;
-      
-	if (s) {
-	  k += r;
-	  CHECK_BIT_BUFFER(br_state, s, return FALSE);
-	  r = GET_BITS(s);
-	  s = HUFF_EXTEND(r, s);
-	  /* Output coefficient in natural (dezigzagged) order.
-	   * Note: the extra entries in jpeg_natural_order[] will save us
-	   * if k >= DCTSIZE2, which could happen if the data is corrupted.
-	   */
-	  (*block)[jpeg_natural_order[k]] = (JCOEF) s;
-	} else {
-	  if (r != 15)
-	    break;
-	  k += 15;
-	}
+      /* Section F.2.2.1: decode the DC coefficient difference */
+      HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
+      if (s) {
+	CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	r = GET_BITS(s);
+	s = HUFF_EXTEND(r, s);
       }
 
-    } else {
-skip_ACs:
-
-      /* Section F.2.2.2: decode the AC coefficients */
-      /* In this path we just discard the values */
-      for (k = 1; k < DCTSIZE2; k++) {
-	HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
-      
-	r = s >> 4;
-	s &= 15;
-      
-	if (s) {
-	  k += r;
-	  CHECK_BIT_BUFFER(br_state, s, return FALSE);
-	  DROP_BITS(s);
-	} else {
-	  if (r != 15)
-	    break;
-	  k += 15;
-	}
+      if (entropy->dc_needed[blkn]) {
+	/* Convert DC difference to actual value, update last_dc_val */
+	int ci = cinfo->MCU_membership[blkn];
+	s += state.last_dc_val[ci];
+	state.last_dc_val[ci] = s;
+	/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
+	(*block)[0] = (JCOEF) s;
       }
 
+      if (entropy->ac_needed[blkn]) {
+
+	/* Section F.2.2.2: decode the AC coefficients */
+	/* Since zeroes are skipped, output area must be cleared beforehand */
+	for (k = 1; k < DCTSIZE2; k++) {
+	  HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
+      
+	  r = s >> 4;
+	  s &= 15;
+      
+	  if (s) {
+	    k += r;
+	    CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	    r = GET_BITS(s);
+	    s = HUFF_EXTEND(r, s);
+	    /* Output coefficient in natural (dezigzagged) order.
+	     * Note: the extra entries in jpeg_natural_order[] will save us
+	     * if k >= DCTSIZE2, which could happen if the data is corrupted.
+	     */
+	    (*block)[jpeg_natural_order[k]] = (JCOEF) s;
+	  } else {
+	    if (r != 15)
+	      break;
+	    k += 15;
+	  }
+	}
+
+      } else {
+
+	/* Section F.2.2.2: decode the AC coefficients */
+	/* In this path we just discard the values */
+	for (k = 1; k < DCTSIZE2; k++) {
+	  HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
+      
+	  r = s >> 4;
+	  s &= 15;
+      
+	  if (s) {
+	    k += r;
+	    CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	    DROP_BITS(s);
+	  } else {
+	    if (r != 15)
+	      break;
+	    k += 15;
+	  }
+	}
+
+      }
     }
+
+    /* Completed MCU, so update state */
+    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(entropy->saved, state);
   }
 
-  /* Completed MCU, so update state */
-  BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
-  ASSIGN_STATE(entropy->saved, state);
-
   /* Account for restart interval (no-op if not using restarts) */
   entropy->restarts_to_go--;
 
diff --git a/jdhuff.h b/jdhuff.h
index bcc3ab1..ae19b6c 100644
--- a/jdhuff.h
+++ b/jdhuff.h
@@ -1,7 +1,7 @@
 /*
  * jdhuff.h
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -25,10 +25,13 @@
 
 typedef struct {
   /* Basic tables: (element [0] of each array is unused) */
-  INT32 mincode[17];		/* smallest code of length k */
   INT32 maxcode[18];		/* largest code of length k (-1 if none) */
   /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
-  int valptr[17];		/* huffval[] index of 1st symbol of length k */
+  INT32 valoffset[17];		/* huffval[] offset for codes of length k */
+  /* valoffset[k] = huffval[] index of 1st symbol of code length k, less
+   * the smallest code of length k; so given a code of length k, the
+   * corresponding symbol is huffval[code + valoffset[k]]
+   */
 
   /* Link to public Huffman table (needed only in jpeg_huff_decode) */
   JHUFF_TBL *pub;
@@ -43,8 +46,9 @@
 } d_derived_tbl;
 
 /* Expand a Huffman table definition into the derived format */
-EXTERN(void) jpeg_make_d_derived_tbl JPP((j_decompress_ptr cinfo,
-				JHUFF_TBL * htbl, d_derived_tbl ** pdtbl));
+EXTERN(void) jpeg_make_d_derived_tbl
+	JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
+	     d_derived_tbl ** pdtbl));
 
 
 /*
@@ -70,30 +74,28 @@
 
 /* If long is > 32 bits on your machine, and shifting/masking longs is
  * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
- * appropriately should be a win.  Unfortunately we can't do this with
- * something like  #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
+ * appropriately should be a win.  Unfortunately we can't define the size
+ * with something like  #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
  * because not all machines measure sizeof in 8-bit bytes.
  */
 
 typedef struct {		/* Bitreading state saved across MCUs */
   bit_buf_type get_buffer;	/* current bit-extraction buffer */
   int bits_left;		/* # of unused bits in it */
-  boolean printed_eod;		/* flag to suppress multiple warning msgs */
 } bitread_perm_state;
 
 typedef struct {		/* Bitreading working state within an MCU */
-  /* current data source state */
+  /* Current data source location */
+  /* We need a copy, rather than munging the original, in case of suspension */
   const JOCTET * next_input_byte; /* => next byte to read from source */
   size_t bytes_in_buffer;	/* # of bytes remaining in source buffer */
-  int unread_marker;		/* nonzero if we have hit a marker */
-  /* bit input buffer --- note these values are kept in register variables,
+  /* Bit input buffer --- note these values are kept in register variables,
    * not in this struct, inside the inner loops.
    */
   bit_buf_type get_buffer;	/* current bit-extraction buffer */
   int bits_left;		/* # of unused bits in it */
-  /* pointers needed by jpeg_fill_bit_buffer */
+  /* Pointer needed by jpeg_fill_bit_buffer. */
   j_decompress_ptr cinfo;	/* back link to decompress master record */
-  boolean * printed_eod_ptr;	/* => flag in permanent state */
 } bitread_working_state;
 
 /* Macros to declare and load/save bitread local variables. */
@@ -106,15 +108,12 @@
 	br_state.cinfo = cinfop; \
 	br_state.next_input_byte = cinfop->src->next_input_byte; \
 	br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
-	br_state.unread_marker = cinfop->unread_marker; \
 	get_buffer = permstate.get_buffer; \
-	bits_left = permstate.bits_left; \
-	br_state.printed_eod_ptr = & permstate.printed_eod
+	bits_left = permstate.bits_left;
 
 #define BITREAD_SAVE_STATE(cinfop,permstate)  \
 	cinfop->src->next_input_byte = br_state.next_input_byte; \
 	cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
-	cinfop->unread_marker = br_state.unread_marker; \
 	permstate.get_buffer = get_buffer; \
 	permstate.bits_left = bits_left
 
diff --git a/jdinput.c b/jdinput.c
index a8565c5..0c2ac8f 100644
--- a/jdinput.c
+++ b/jdinput.c
@@ -1,7 +1,7 @@
 /*
  * jdinput.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -301,7 +301,7 @@
       initial_setup(cinfo);
       inputctl->inheaders = FALSE;
       /* Note: start_input_pass must be called by jdmaster.c
-       * before any more input can be consumed.  jdapi.c is
+       * before any more input can be consumed.  jdapimin.c is
        * responsible for enforcing this sequencing.
        */
     } else {			/* 2nd or later SOS marker */
diff --git a/jdmarker.c b/jdmarker.c
index b79ec37..f4cca8c 100644
--- a/jdmarker.c
+++ b/jdmarker.c
@@ -1,7 +1,7 @@
 /*
  * jdmarker.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -85,6 +85,28 @@
 } JPEG_MARKER;
 
 
+/* Private state */
+
+typedef struct {
+  struct jpeg_marker_reader pub; /* public fields */
+
+  /* Application-overridable marker processing methods */
+  jpeg_marker_parser_method process_COM;
+  jpeg_marker_parser_method process_APPn[16];
+
+  /* Limit on marker data length to save for each marker type */
+  unsigned int length_limit_COM;
+  unsigned int length_limit_APPn[16];
+
+  /* Status of COM/APPn marker saving */
+  jpeg_saved_marker_ptr cur_marker;	/* NULL if not processing a marker */
+  unsigned int bytes_read;		/* data bytes read so far in marker */
+  /* Note: cur_marker is not linked into marker_list until it's all read. */
+} my_marker_reader;
+
+typedef my_marker_reader * my_marker_ptr;
+
+
 /*
  * Macros for fetching data from the data source module.
  *
@@ -104,7 +126,7 @@
 	( datasrc->next_input_byte = next_input_byte,  \
 	  datasrc->bytes_in_buffer = bytes_in_buffer )
 
-/* Reload the local copies --- seldom used except in MAKE_BYTE_AVAIL */
+/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
 #define INPUT_RELOAD(cinfo)  \
 	( next_input_byte = datasrc->next_input_byte,  \
 	  bytes_in_buffer = datasrc->bytes_in_buffer )
@@ -118,14 +140,14 @@
 	  if (! (*datasrc->fill_input_buffer) (cinfo))  \
 	    { action; }  \
 	  INPUT_RELOAD(cinfo);  \
-	}  \
-	bytes_in_buffer--
+	}
 
 /* Read a byte into variable V.
  * If must suspend, take the specified action (typically "return FALSE").
  */
 #define INPUT_BYTE(cinfo,V,action)  \
 	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+		  bytes_in_buffer--; \
 		  V = GETJOCTET(*next_input_byte++); )
 
 /* As above, but read two bytes interpreted as an unsigned 16-bit integer.
@@ -133,8 +155,10 @@
  */
 #define INPUT_2BYTES(cinfo,V,action)  \
 	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+		  bytes_in_buffer--; \
 		  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
 		  MAKE_BYTE_AVAIL(cinfo,action); \
+		  bytes_in_buffer--; \
 		  V += GETJOCTET(*next_input_byte++); )
 
 
@@ -150,11 +174,18 @@
  *   marker parameters; restart point has not been moved.  Same routine
  *   will be called again after application supplies more input data.
  *
- * This approach to suspension assumes that all of a marker's parameters can
- * fit into a single input bufferload.  This should hold for "normal"
- * markers.  Some COM/APPn markers might have large parameter segments,
- * but we use skip_input_data to get past those, and thereby put the problem
- * on the source manager's shoulders.
+ * This approach to suspension assumes that all of a marker's parameters
+ * can fit into a single input bufferload.  This should hold for "normal"
+ * markers.  Some COM/APPn markers might have large parameter segments
+ * that might not fit.  If we are simply dropping such a marker, we use
+ * skip_input_data to get past it, and thereby put the problem on the
+ * source manager's shoulders.  If we are saving the marker's contents
+ * into memory, we use a slightly different convention: when forced to
+ * suspend, the marker processor updates the restart point to the end of
+ * what it's consumed (ie, the end of the buffer) before returning FALSE.
+ * On resumption, cinfo->unread_marker still contains the marker code,
+ * but the data source will point to the next chunk of marker data.
+ * The marker processor must retain internal state to deal with this.
  *
  * Note that we don't bother to avoid duplicate trace messages if a
  * suspension occurs within marker parameters.  Other side effects
@@ -188,7 +219,9 @@
   cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
 
   cinfo->saw_JFIF_marker = FALSE;
-  cinfo->density_unit = 0;	/* set default JFIF APP0 values */
+  cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
+  cinfo->JFIF_minor_version = 1;
+  cinfo->density_unit = 0;
   cinfo->X_density = 1;
   cinfo->Y_density = 1;
   cinfo->saw_Adobe_marker = FALSE;
@@ -280,11 +313,11 @@
 
   INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
 
+  TRACEMS1(cinfo, 1, JTRC_SOS, n);
+
   if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
     ERREXIT(cinfo, JERR_BAD_LENGTH);
 
-  TRACEMS1(cinfo, 1, JTRC_SOS, n);
-
   cinfo->comps_in_scan = n;
 
   /* Collect the component-spec parameters */
@@ -334,111 +367,7 @@
 }
 
 
-METHODDEF(boolean)
-get_app0 (j_decompress_ptr cinfo)
-/* Process an APP0 marker */
-{
-#define JFIF_LEN 14
-  INT32 length;
-  UINT8 b[JFIF_LEN];
-  int buffp;
-  INPUT_VARS(cinfo);
-
-  INPUT_2BYTES(cinfo, length, return FALSE);
-  length -= 2;
-
-  /* See if a JFIF APP0 marker is present */
-
-  if (length >= JFIF_LEN) {
-    for (buffp = 0; buffp < JFIF_LEN; buffp++)
-      INPUT_BYTE(cinfo, b[buffp], return FALSE);
-    length -= JFIF_LEN;
-
-    if (b[0]==0x4A && b[1]==0x46 && b[2]==0x49 && b[3]==0x46 && b[4]==0) {
-      /* Found JFIF APP0 marker: check version */
-      /* Major version must be 1, anything else signals an incompatible change.
-       * We used to treat this as an error, but now it's a nonfatal warning,
-       * because some bozo at Hijaak couldn't read the spec.
-       * Minor version should be 0..2, but process anyway if newer.
-       */
-      if (b[5] != 1)
-	WARNMS2(cinfo, JWRN_JFIF_MAJOR, b[5], b[6]);
-      else if (b[6] > 2)
-	TRACEMS2(cinfo, 1, JTRC_JFIF_MINOR, b[5], b[6]);
-      /* Save info */
-      cinfo->saw_JFIF_marker = TRUE;
-      cinfo->density_unit = b[7];
-      cinfo->X_density = (b[8] << 8) + b[9];
-      cinfo->Y_density = (b[10] << 8) + b[11];
-      TRACEMS3(cinfo, 1, JTRC_JFIF,
-	       cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
-      if (b[12] | b[13])
-	TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, b[12], b[13]);
-      if (length != ((INT32) b[12] * (INT32) b[13] * (INT32) 3))
-	TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) length);
-    } else {
-      /* Start of APP0 does not match "JFIF" */
-      TRACEMS1(cinfo, 1, JTRC_APP0, (int) length + JFIF_LEN);
-    }
-  } else {
-    /* Too short to be JFIF marker */
-    TRACEMS1(cinfo, 1, JTRC_APP0, (int) length);
-  }
-
-  INPUT_SYNC(cinfo);
-  if (length > 0)		/* skip any remaining data -- could be lots */
-    (*cinfo->src->skip_input_data) (cinfo, (long) length);
-
-  return TRUE;
-}
-
-
-METHODDEF(boolean)
-get_app14 (j_decompress_ptr cinfo)
-/* Process an APP14 marker */
-{
-#define ADOBE_LEN 12
-  INT32 length;
-  UINT8 b[ADOBE_LEN];
-  int buffp;
-  unsigned int version, flags0, flags1, transform;
-  INPUT_VARS(cinfo);
-
-  INPUT_2BYTES(cinfo, length, return FALSE);
-  length -= 2;
-
-  /* See if an Adobe APP14 marker is present */
-
-  if (length >= ADOBE_LEN) {
-    for (buffp = 0; buffp < ADOBE_LEN; buffp++)
-      INPUT_BYTE(cinfo, b[buffp], return FALSE);
-    length -= ADOBE_LEN;
-
-    if (b[0]==0x41 && b[1]==0x64 && b[2]==0x6F && b[3]==0x62 && b[4]==0x65) {
-      /* Found Adobe APP14 marker */
-      version = (b[5] << 8) + b[6];
-      flags0 = (b[7] << 8) + b[8];
-      flags1 = (b[9] << 8) + b[10];
-      transform = b[11];
-      TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
-      cinfo->saw_Adobe_marker = TRUE;
-      cinfo->Adobe_transform = (UINT8) transform;
-    } else {
-      /* Start of APP14 does not match "Adobe" */
-      TRACEMS1(cinfo, 1, JTRC_APP14, (int) length + ADOBE_LEN);
-    }
-  } else {
-    /* Too short to be Adobe marker */
-    TRACEMS1(cinfo, 1, JTRC_APP14, (int) length);
-  }
-
-  INPUT_SYNC(cinfo);
-  if (length > 0)		/* skip any remaining data -- could be lots */
-    (*cinfo->src->skip_input_data) (cinfo, (long) length);
-
-  return TRUE;
-}
-
+#ifdef D_ARITH_CODING_SUPPORTED
 
 LOCAL(boolean)
 get_dac (j_decompress_ptr cinfo)
@@ -472,10 +401,19 @@
     }
   }
 
+  if (length != 0)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
   INPUT_SYNC(cinfo);
   return TRUE;
 }
 
+#else /* ! D_ARITH_CODING_SUPPORTED */
+
+#define get_dac(cinfo)  skip_variable(cinfo)
+
+#endif /* D_ARITH_CODING_SUPPORTED */
+
 
 LOCAL(boolean)
 get_dht (j_decompress_ptr cinfo)
@@ -491,7 +429,7 @@
   INPUT_2BYTES(cinfo, length, return FALSE);
   length -= 2;
   
-  while (length > 0) {
+  while (length > 16) {
     INPUT_BYTE(cinfo, index, return FALSE);
 
     TRACEMS1(cinfo, 1, JTRC_DHT, index);
@@ -512,8 +450,11 @@
 	     bits[9], bits[10], bits[11], bits[12],
 	     bits[13], bits[14], bits[15], bits[16]);
 
+    /* Here we just do minimal validation of the counts to avoid walking
+     * off the end of our table space.  jdhuff.c will check more carefully.
+     */
     if (count > 256 || ((INT32) count) > length)
-      ERREXIT(cinfo, JERR_DHT_COUNTS);
+      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 
     for (i = 0; i < count; i++)
       INPUT_BYTE(cinfo, huffval[i], return FALSE);
@@ -537,6 +478,9 @@
     MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
   }
 
+  if (length != 0)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
   INPUT_SYNC(cinfo);
   return TRUE;
 }
@@ -592,6 +536,9 @@
     if (prec) length -= DCTSIZE2;
   }
 
+  if (length != 0)
+    ERREXIT(cinfo, JERR_BAD_LENGTH);
+
   INPUT_SYNC(cinfo);
   return TRUE;
 }
@@ -621,6 +568,279 @@
 }
 
 
+/*
+ * Routines for processing APPn and COM markers.
+ * These are either saved in memory or discarded, per application request.
+ * APP0 and APP14 are specially checked to see if they are
+ * JFIF and Adobe markers, respectively.
+ */
+
+#define APP0_DATA_LEN	14	/* Length of interesting data in APP0 */
+#define APP14_DATA_LEN	12	/* Length of interesting data in APP14 */
+#define APPN_DATA_LEN	14	/* Must be the largest of the above!! */
+
+
+LOCAL(void)
+examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
+	      unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP0.
+ * Take appropriate action if it is a JFIF marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+  INT32 totallen = (INT32) datalen + remaining;
+
+  if (datalen >= APP0_DATA_LEN &&
+      GETJOCTET(data[0]) == 0x4A &&
+      GETJOCTET(data[1]) == 0x46 &&
+      GETJOCTET(data[2]) == 0x49 &&
+      GETJOCTET(data[3]) == 0x46 &&
+      GETJOCTET(data[4]) == 0) {
+    /* Found JFIF APP0 marker: save info */
+    cinfo->saw_JFIF_marker = TRUE;
+    cinfo->JFIF_major_version = GETJOCTET(data[5]);
+    cinfo->JFIF_minor_version = GETJOCTET(data[6]);
+    cinfo->density_unit = GETJOCTET(data[7]);
+    cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
+    cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
+    /* Check version.
+     * Major version must be 1, anything else signals an incompatible change.
+     * (We used to treat this as an error, but now it's a nonfatal warning,
+     * because some bozo at Hijaak couldn't read the spec.)
+     * Minor version should be 0..2, but process anyway if newer.
+     */
+    if (cinfo->JFIF_major_version != 1)
+      WARNMS2(cinfo, JWRN_JFIF_MAJOR,
+	      cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
+    /* Generate trace messages */
+    TRACEMS5(cinfo, 1, JTRC_JFIF,
+	     cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
+	     cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
+    /* Validate thumbnail dimensions and issue appropriate messages */
+    if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
+      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
+	       GETJOCTET(data[12]), GETJOCTET(data[13]));
+    totallen -= APP0_DATA_LEN;
+    if (totallen !=
+	((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
+      TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
+  } else if (datalen >= 6 &&
+      GETJOCTET(data[0]) == 0x4A &&
+      GETJOCTET(data[1]) == 0x46 &&
+      GETJOCTET(data[2]) == 0x58 &&
+      GETJOCTET(data[3]) == 0x58 &&
+      GETJOCTET(data[4]) == 0) {
+    /* Found JFIF "JFXX" extension APP0 marker */
+    /* The library doesn't actually do anything with these,
+     * but we try to produce a helpful trace message.
+     */
+    switch (GETJOCTET(data[5])) {
+    case 0x10:
+      TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
+      break;
+    case 0x11:
+      TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
+      break;
+    case 0x13:
+      TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
+      break;
+    default:
+      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
+	       GETJOCTET(data[5]), (int) totallen);
+      break;
+    }
+  } else {
+    /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
+    TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
+  }
+}
+
+
+LOCAL(void)
+examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
+	       unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP14.
+ * Take appropriate action if it is an Adobe marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+  unsigned int version, flags0, flags1, transform;
+
+  if (datalen >= APP14_DATA_LEN &&
+      GETJOCTET(data[0]) == 0x41 &&
+      GETJOCTET(data[1]) == 0x64 &&
+      GETJOCTET(data[2]) == 0x6F &&
+      GETJOCTET(data[3]) == 0x62 &&
+      GETJOCTET(data[4]) == 0x65) {
+    /* Found Adobe APP14 marker */
+    version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
+    flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
+    flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
+    transform = GETJOCTET(data[11]);
+    TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
+    cinfo->saw_Adobe_marker = TRUE;
+    cinfo->Adobe_transform = (UINT8) transform;
+  } else {
+    /* Start of APP14 does not match "Adobe", or too short */
+    TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
+  }
+}
+
+
+METHODDEF(boolean)
+get_interesting_appn (j_decompress_ptr cinfo)
+/* Process an APP0 or APP14 marker without saving it */
+{
+  INT32 length;
+  JOCTET b[APPN_DATA_LEN];
+  unsigned int i, numtoread;
+  INPUT_VARS(cinfo);
+
+  INPUT_2BYTES(cinfo, length, return FALSE);
+  length -= 2;
+
+  /* get the interesting part of the marker data */
+  if (length >= APPN_DATA_LEN)
+    numtoread = APPN_DATA_LEN;
+  else if (length > 0)
+    numtoread = (unsigned int) length;
+  else
+    numtoread = 0;
+  for (i = 0; i < numtoread; i++)
+    INPUT_BYTE(cinfo, b[i], return FALSE);
+  length -= numtoread;
+
+  /* process it */
+  switch (cinfo->unread_marker) {
+  case M_APP0:
+    examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
+    break;
+  case M_APP14:
+    examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
+    break;
+  default:
+    /* can't get here unless jpeg_save_markers chooses wrong processor */
+    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+    break;
+  }
+
+  /* skip any remaining data -- could be lots */
+  INPUT_SYNC(cinfo);
+  if (length > 0)
+    (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+  return TRUE;
+}
+
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+METHODDEF(boolean)
+save_marker (j_decompress_ptr cinfo)
+/* Save an APPn or COM marker into the marker list */
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+  jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
+  unsigned int bytes_read, data_length;
+  JOCTET FAR * data;
+  INT32 length = 0;
+  INPUT_VARS(cinfo);
+
+  if (cur_marker == NULL) {
+    /* begin reading a marker */
+    INPUT_2BYTES(cinfo, length, return FALSE);
+    length -= 2;
+    if (length >= 0) {		/* watch out for bogus length word */
+      /* figure out how much we want to save */
+      unsigned int limit;
+      if (cinfo->unread_marker == (int) M_COM)
+	limit = marker->length_limit_COM;
+      else
+	limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
+      if ((unsigned int) length < limit)
+	limit = (unsigned int) length;
+      /* allocate and initialize the marker item */
+      cur_marker = (jpeg_saved_marker_ptr)
+	(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+				    SIZEOF(struct jpeg_marker_struct) + limit);
+      cur_marker->next = NULL;
+      cur_marker->marker = (UINT8) cinfo->unread_marker;
+      cur_marker->original_length = (unsigned int) length;
+      cur_marker->data_length = limit;
+      /* data area is just beyond the jpeg_marker_struct */
+      data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
+      marker->cur_marker = cur_marker;
+      marker->bytes_read = 0;
+      bytes_read = 0;
+      data_length = limit;
+    } else {
+      /* deal with bogus length word */
+      bytes_read = data_length = 0;
+      data = NULL;
+    }
+  } else {
+    /* resume reading a marker */
+    bytes_read = marker->bytes_read;
+    data_length = cur_marker->data_length;
+    data = cur_marker->data + bytes_read;
+  }
+
+  while (bytes_read < data_length) {
+    INPUT_SYNC(cinfo);		/* move the restart point to here */
+    marker->bytes_read = bytes_read;
+    /* If there's not at least one byte in buffer, suspend */
+    MAKE_BYTE_AVAIL(cinfo, return FALSE);
+    /* Copy bytes with reasonable rapidity */
+    while (bytes_read < data_length && bytes_in_buffer > 0) {
+      *data++ = *next_input_byte++;
+      bytes_in_buffer--;
+      bytes_read++;
+    }
+  }
+
+  /* Done reading what we want to read */
+  if (cur_marker != NULL) {	/* will be NULL if bogus length word */
+    /* Add new marker to end of list */
+    if (cinfo->marker_list == NULL) {
+      cinfo->marker_list = cur_marker;
+    } else {
+      jpeg_saved_marker_ptr prev = cinfo->marker_list;
+      while (prev->next != NULL)
+	prev = prev->next;
+      prev->next = cur_marker;
+    }
+    /* Reset pointer & calc remaining data length */
+    data = cur_marker->data;
+    length = cur_marker->original_length - data_length;
+  }
+  /* Reset to initial state for next marker */
+  marker->cur_marker = NULL;
+
+  /* Process the marker if interesting; else just make a generic trace msg */
+  switch (cinfo->unread_marker) {
+  case M_APP0:
+    examine_app0(cinfo, data, data_length, length);
+    break;
+  case M_APP14:
+    examine_app14(cinfo, data, data_length, length);
+    break;
+  default:
+    TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
+	     (int) (data_length + length));
+    break;
+  }
+
+  /* skip any remaining data -- could be lots */
+  INPUT_SYNC(cinfo);		/* do before skip_input_data */
+  if (length > 0)
+    (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+  return TRUE;
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
 METHODDEF(boolean)
 skip_variable (j_decompress_ptr cinfo)
 /* Skip over an unknown or uninteresting variable-length marker */
@@ -629,11 +849,13 @@
   INPUT_VARS(cinfo);
 
   INPUT_2BYTES(cinfo, length, return FALSE);
+  length -= 2;
   
   TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
 
   INPUT_SYNC(cinfo);		/* do before skip_input_data */
-  (*cinfo->src->skip_input_data) (cinfo, (long) length - 2L);
+  if (length > 0)
+    (*cinfo->src->skip_input_data) (cinfo, (long) length);
 
   return TRUE;
 }
@@ -833,12 +1055,13 @@
     case M_APP13:
     case M_APP14:
     case M_APP15:
-      if (! (*cinfo->marker->process_APPn[cinfo->unread_marker - (int) M_APP0]) (cinfo))
+      if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
+		cinfo->unread_marker - (int) M_APP0]) (cinfo))
 	return JPEG_SUSPENDED;
       break;
       
     case M_COM:
-      if (! (*cinfo->marker->process_COM) (cinfo))
+      if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
 	return JPEG_SUSPENDED;
       break;
 
@@ -1018,12 +1241,15 @@
 METHODDEF(void)
 reset_marker_reader (j_decompress_ptr cinfo)
 {
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
   cinfo->comp_info = NULL;		/* until allocated by get_sof */
   cinfo->input_scan_number = 0;		/* no SOS seen yet */
   cinfo->unread_marker = 0;		/* no pending marker */
-  cinfo->marker->saw_SOI = FALSE;	/* set internal state too */
-  cinfo->marker->saw_SOF = FALSE;
-  cinfo->marker->discarded_bytes = 0;
+  marker->pub.saw_SOI = FALSE;		/* set internal state too */
+  marker->pub.saw_SOF = FALSE;
+  marker->pub.discarded_bytes = 0;
+  marker->cur_marker = NULL;
 }
 
 
@@ -1035,21 +1261,100 @@
 GLOBAL(void)
 jinit_marker_reader (j_decompress_ptr cinfo)
 {
+  my_marker_ptr marker;
   int i;
 
   /* Create subobject in permanent pool */
-  cinfo->marker = (struct jpeg_marker_reader *)
+  marker = (my_marker_ptr)
     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
-				SIZEOF(struct jpeg_marker_reader));
-  /* Initialize method pointers */
-  cinfo->marker->reset_marker_reader = reset_marker_reader;
-  cinfo->marker->read_markers = read_markers;
-  cinfo->marker->read_restart_marker = read_restart_marker;
-  cinfo->marker->process_COM = skip_variable;
-  for (i = 0; i < 16; i++)
-    cinfo->marker->process_APPn[i] = skip_variable;
-  cinfo->marker->process_APPn[0] = get_app0;
-  cinfo->marker->process_APPn[14] = get_app14;
+				SIZEOF(my_marker_reader));
+  cinfo->marker = (struct jpeg_marker_reader *) marker;
+  /* Initialize public method pointers */
+  marker->pub.reset_marker_reader = reset_marker_reader;
+  marker->pub.read_markers = read_markers;
+  marker->pub.read_restart_marker = read_restart_marker;
+  /* Initialize COM/APPn processing.
+   * By default, we examine and then discard APP0 and APP14,
+   * but simply discard COM and all other APPn.
+   */
+  marker->process_COM = skip_variable;
+  marker->length_limit_COM = 0;
+  for (i = 0; i < 16; i++) {
+    marker->process_APPn[i] = skip_variable;
+    marker->length_limit_APPn[i] = 0;
+  }
+  marker->process_APPn[0] = get_interesting_appn;
+  marker->process_APPn[14] = get_interesting_appn;
   /* Reset marker processing state */
   reset_marker_reader(cinfo);
 }
+
+
+/*
+ * Control saving of COM and APPn markers into marker_list.
+ */
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+GLOBAL(void)
+jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
+		   unsigned int length_limit)
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+  long maxlength;
+  jpeg_marker_parser_method processor;
+
+  /* Length limit mustn't be larger than what we can allocate
+   * (should only be a concern in a 16-bit environment).
+   */
+  maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
+  if (((long) length_limit) > maxlength)
+    length_limit = (unsigned int) maxlength;
+
+  /* Choose processor routine to use.
+   * APP0/APP14 have special requirements.
+   */
+  if (length_limit) {
+    processor = save_marker;
+    /* If saving APP0/APP14, save at least enough for our internal use. */
+    if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
+      length_limit = APP0_DATA_LEN;
+    else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
+      length_limit = APP14_DATA_LEN;
+  } else {
+    processor = skip_variable;
+    /* If discarding APP0/APP14, use our regular on-the-fly processor. */
+    if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
+      processor = get_interesting_appn;
+  }
+
+  if (marker_code == (int) M_COM) {
+    marker->process_COM = processor;
+    marker->length_limit_COM = length_limit;
+  } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
+    marker->process_APPn[marker_code - (int) M_APP0] = processor;
+    marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
+  } else
+    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
+/*
+ * Install a special processing method for COM or APPn markers.
+ */
+
+GLOBAL(void)
+jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
+			   jpeg_marker_parser_method routine)
+{
+  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+  if (marker_code == (int) M_COM)
+    marker->process_COM = routine;
+  else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
+    marker->process_APPn[marker_code - (int) M_APP0] = routine;
+  else
+    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
diff --git a/jdmaster.c b/jdmaster.c
index 6f3351e..2802c5b 100644
--- a/jdmaster.c
+++ b/jdmaster.c
@@ -1,7 +1,7 @@
 /*
  * jdmaster.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -84,8 +84,10 @@
 jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
 /* Do computations that are needed before master selection phase */
 {
+#ifdef IDCT_SCALING_SUPPORTED
   int ci;
   jpeg_component_info *compptr;
+#endif
 
   /* Prevent application from calling me at wrong times */
   if (cinfo->global_state != DSTATE_READY)
@@ -429,7 +431,7 @@
  * modules will be active during this pass and give them appropriate
  * start_pass calls.  We also set is_dummy_pass to indicate whether this
  * is a "real" output pass or a dummy pass for color quantization.
- * (In the latter case, jdapi.c will crank the pass to completion.)
+ * (In the latter case, jdapistd.c will crank the pass to completion.)
  */
 
 METHODDEF(void)
diff --git a/jdphuff.c b/jdphuff.c
index f6a89f3..2267809 100644
--- a/jdphuff.c
+++ b/jdphuff.c
@@ -1,7 +1,7 @@
 /*
  * jdphuff.c
  *
- * Copyright (C) 1995-1996, Thomas G. Lane.
+ * Copyright (C) 1995-1997, 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.
  *
@@ -119,6 +119,12 @@
   }
   if (cinfo->Al > 13)		/* need not check for < 0 */
     bad = TRUE;
+  /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
+   * but the spec doesn't say so, and we try to be liberal about what we
+   * accept.  Note: large Al values could result in out-of-range DC
+   * coefficients during early scans, leading to bizarre displays due to
+   * overflows in the IDCT math.  But we won't crash.
+   */
   if (bad)
     ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
 	     cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
@@ -160,18 +166,12 @@
     if (is_DC_band) {
       if (cinfo->Ah == 0) {	/* DC refinement needs no table */
 	tbl = compptr->dc_tbl_no;
-	if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
-	    cinfo->dc_huff_tbl_ptrs[tbl] == NULL)
-	  ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
-	jpeg_make_d_derived_tbl(cinfo, cinfo->dc_huff_tbl_ptrs[tbl],
+	jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
 				& entropy->derived_tbls[tbl]);
       }
     } else {
       tbl = compptr->ac_tbl_no;
-      if (tbl < 0 || tbl >= NUM_HUFF_TBLS ||
-          cinfo->ac_huff_tbl_ptrs[tbl] == NULL)
-        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
-      jpeg_make_d_derived_tbl(cinfo, cinfo->ac_huff_tbl_ptrs[tbl],
+      jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
 			      & entropy->derived_tbls[tbl]);
       /* remember the single active table */
       entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
@@ -183,7 +183,7 @@
   /* Initialize bitread state variables */
   entropy->bitstate.bits_left = 0;
   entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
-  entropy->bitstate.printed_eod = FALSE;
+  entropy->pub.insufficient_data = FALSE;
 
   /* Initialize private state variables */
   entropy->saved.EOBRUN = 0;
@@ -248,8 +248,13 @@
   /* Reset restart counter */
   entropy->restarts_to_go = cinfo->restart_interval;
 
-  /* Next segment can get another out-of-data warning */
-  entropy->bitstate.printed_eod = FALSE;
+  /* Reset out-of-data flag, unless read_restart_marker left us smack up
+   * against a marker.  In that case we will end up treating the next data
+   * segment as empty, and we can avoid producing bogus output pixels by
+   * leaving the flag set.
+   */
+  if (cinfo->unread_marker == 0)
+    entropy->pub.insufficient_data = FALSE;
 
   return TRUE;
 }
@@ -297,39 +302,45 @@
 	return FALSE;
   }
 
-  /* Load up working state */
-  BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
-  ASSIGN_STATE(state, entropy->saved);
+  /* If we've run out of data, just leave the MCU set to zeroes.
+   * This way, we return uniform gray for the remainder of the segment.
+   */
+  if (! entropy->pub.insufficient_data) {
 
-  /* Outer loop handles each block in the MCU */
+    /* Load up working state */
+    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(state, entropy->saved);
 
-  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
-    block = MCU_data[blkn];
-    ci = cinfo->MCU_membership[blkn];
-    compptr = cinfo->cur_comp_info[ci];
-    tbl = entropy->derived_tbls[compptr->dc_tbl_no];
+    /* Outer loop handles each block in the MCU */
 
-    /* Decode a single block's worth of coefficients */
+    for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+      block = MCU_data[blkn];
+      ci = cinfo->MCU_membership[blkn];
+      compptr = cinfo->cur_comp_info[ci];
+      tbl = entropy->derived_tbls[compptr->dc_tbl_no];
 
-    /* Section F.2.2.1: decode the DC coefficient difference */
-    HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
-    if (s) {
-      CHECK_BIT_BUFFER(br_state, s, return FALSE);
-      r = GET_BITS(s);
-      s = HUFF_EXTEND(r, s);
+      /* Decode a single block's worth of coefficients */
+
+      /* Section F.2.2.1: decode the DC coefficient difference */
+      HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
+      if (s) {
+	CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	r = GET_BITS(s);
+	s = HUFF_EXTEND(r, s);
+      }
+
+      /* Convert DC difference to actual value, update last_dc_val */
+      s += state.last_dc_val[ci];
+      state.last_dc_val[ci] = s;
+      /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
+      (*block)[0] = (JCOEF) (s << Al);
     }
 
-    /* Convert DC difference to actual value, update last_dc_val */
-    s += state.last_dc_val[ci];
-    state.last_dc_val[ci] = s;
-    /* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */
-    (*block)[0] = (JCOEF) (s << Al);
+    /* Completed MCU, so update state */
+    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    ASSIGN_STATE(entropy->saved, state);
   }
 
-  /* Completed MCU, so update state */
-  BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
-  ASSIGN_STATE(entropy->saved, state);
-
   /* Account for restart interval (no-op if not using restarts) */
   entropy->restarts_to_go--;
 
@@ -361,53 +372,59 @@
 	return FALSE;
   }
 
-  /* Load up working state.
-   * We can avoid loading/saving bitread state if in an EOB run.
+  /* If we've run out of data, just leave the MCU set to zeroes.
+   * This way, we return uniform gray for the remainder of the segment.
    */
-  EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */
+  if (! entropy->pub.insufficient_data) {
 
-  /* There is always only one block per MCU */
+    /* Load up working state.
+     * We can avoid loading/saving bitread state if in an EOB run.
+     */
+    EOBRUN = entropy->saved.EOBRUN;	/* only part of saved state we need */
 
-  if (EOBRUN > 0)		/* if it's a band of zeroes... */
-    EOBRUN--;			/* ...process it now (we do nothing) */
-  else {
-    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
-    block = MCU_data[0];
-    tbl = entropy->ac_derived_tbl;
+    /* There is always only one block per MCU */
 
-    for (k = cinfo->Ss; k <= Se; k++) {
-      HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
-      r = s >> 4;
-      s &= 15;
-      if (s) {
-        k += r;
-        CHECK_BIT_BUFFER(br_state, s, return FALSE);
-        r = GET_BITS(s);
-        s = HUFF_EXTEND(r, s);
-	/* Scale and output coefficient in natural (dezigzagged) order */
-        (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
-      } else {
-        if (r == 15) {		/* ZRL */
-          k += 15;		/* skip 15 zeroes in band */
-        } else {		/* EOBr, run length is 2^r + appended bits */
-          EOBRUN = 1 << r;
-          if (r) {		/* EOBr, r > 0 */
-	    CHECK_BIT_BUFFER(br_state, r, return FALSE);
-            r = GET_BITS(r);
-            EOBRUN += r;
-          }
-	  EOBRUN--;		/* this band is processed at this moment */
-	  break;		/* force end-of-band */
+    if (EOBRUN > 0)		/* if it's a band of zeroes... */
+      EOBRUN--;			/* ...process it now (we do nothing) */
+    else {
+      BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+      block = MCU_data[0];
+      tbl = entropy->ac_derived_tbl;
+
+      for (k = cinfo->Ss; k <= Se; k++) {
+	HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
+	r = s >> 4;
+	s &= 15;
+	if (s) {
+	  k += r;
+	  CHECK_BIT_BUFFER(br_state, s, return FALSE);
+	  r = GET_BITS(s);
+	  s = HUFF_EXTEND(r, s);
+	  /* Scale and output coefficient in natural (dezigzagged) order */
+	  (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
+	} else {
+	  if (r == 15) {	/* ZRL */
+	    k += 15;		/* skip 15 zeroes in band */
+	  } else {		/* EOBr, run length is 2^r + appended bits */
+	    EOBRUN = 1 << r;
+	    if (r) {		/* EOBr, r > 0 */
+	      CHECK_BIT_BUFFER(br_state, r, return FALSE);
+	      r = GET_BITS(r);
+	      EOBRUN += r;
+	    }
+	    EOBRUN--;		/* this band is processed at this moment */
+	    break;		/* force end-of-band */
+	  }
 	}
       }
+
+      BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
     }
 
-    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    /* Completed MCU, so update state */
+    entropy->saved.EOBRUN = EOBRUN;	/* only part of saved state we need */
   }
 
-  /* Completed MCU, so update state */
-  entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */
-
   /* Account for restart interval (no-op if not using restarts) */
   entropy->restarts_to_go--;
 
@@ -437,6 +454,10 @@
 	return FALSE;
   }
 
+  /* Not worth the cycles to check insufficient_data here,
+   * since we will not change the data anyway if we read zeroes.
+   */
+
   /* Load up working state */
   BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
 
@@ -489,55 +510,93 @@
 	return FALSE;
   }
 
-  /* Load up working state */
-  BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
-  EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we care about */
-
-  /* There is always only one block per MCU */
-  block = MCU_data[0];
-  tbl = entropy->ac_derived_tbl;
-
-  /* If we are forced to suspend, we must undo the assignments to any newly
-   * nonzero coefficients in the block, because otherwise we'd get confused
-   * next time about which coefficients were already nonzero.
-   * But we need not undo addition of bits to already-nonzero coefficients;
-   * instead, we can test the current bit position to see if we already did it.
+  /* If we've run out of data, don't modify the MCU.
    */
-  num_newnz = 0;
+  if (! entropy->pub.insufficient_data) {
 
-  /* initialize coefficient loop counter to start of band */
-  k = cinfo->Ss;
+    /* Load up working state */
+    BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+    EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
 
-  if (EOBRUN == 0) {
-    for (; k <= Se; k++) {
-      HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
-      r = s >> 4;
-      s &= 15;
-      if (s) {
-	if (s != 1)		/* size of new coef should always be 1 */
-	  WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
-        CHECK_BIT_BUFFER(br_state, 1, goto undoit);
-        if (GET_BITS(1))
-	  s = p1;		/* newly nonzero coef is positive */
-	else
-	  s = m1;		/* newly nonzero coef is negative */
-      } else {
-	if (r != 15) {
-	  EOBRUN = 1 << r;	/* EOBr, run length is 2^r + appended bits */
-	  if (r) {
-	    CHECK_BIT_BUFFER(br_state, r, goto undoit);
-	    r = GET_BITS(r);
-	    EOBRUN += r;
+    /* There is always only one block per MCU */
+    block = MCU_data[0];
+    tbl = entropy->ac_derived_tbl;
+
+    /* If we are forced to suspend, we must undo the assignments to any newly
+     * nonzero coefficients in the block, because otherwise we'd get confused
+     * next time about which coefficients were already nonzero.
+     * But we need not undo addition of bits to already-nonzero coefficients;
+     * instead, we can test the current bit to see if we already did it.
+     */
+    num_newnz = 0;
+
+    /* initialize coefficient loop counter to start of band */
+    k = cinfo->Ss;
+
+    if (EOBRUN == 0) {
+      for (; k <= Se; k++) {
+	HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
+	r = s >> 4;
+	s &= 15;
+	if (s) {
+	  if (s != 1)		/* size of new coef should always be 1 */
+	    WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
+	  CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+	  if (GET_BITS(1))
+	    s = p1;		/* newly nonzero coef is positive */
+	  else
+	    s = m1;		/* newly nonzero coef is negative */
+	} else {
+	  if (r != 15) {
+	    EOBRUN = 1 << r;	/* EOBr, run length is 2^r + appended bits */
+	    if (r) {
+	      CHECK_BIT_BUFFER(br_state, r, goto undoit);
+	      r = GET_BITS(r);
+	      EOBRUN += r;
+	    }
+	    break;		/* rest of block is handled by EOB logic */
 	  }
-	  break;		/* rest of block is handled by EOB logic */
+	  /* note s = 0 for processing ZRL */
 	}
-	/* note s = 0 for processing ZRL */
+	/* Advance over already-nonzero coefs and r still-zero coefs,
+	 * appending correction bits to the nonzeroes.  A correction bit is 1
+	 * if the absolute value of the coefficient must be increased.
+	 */
+	do {
+	  thiscoef = *block + jpeg_natural_order[k];
+	  if (*thiscoef != 0) {
+	    CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+	    if (GET_BITS(1)) {
+	      if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
+		if (*thiscoef >= 0)
+		  *thiscoef += p1;
+		else
+		  *thiscoef += m1;
+	      }
+	    }
+	  } else {
+	    if (--r < 0)
+	      break;		/* reached target zero coefficient */
+	  }
+	  k++;
+	} while (k <= Se);
+	if (s) {
+	  int pos = jpeg_natural_order[k];
+	  /* Output newly nonzero coefficient */
+	  (*block)[pos] = (JCOEF) s;
+	  /* Remember its position in case we have to suspend */
+	  newnz_pos[num_newnz++] = pos;
+	}
       }
-      /* Advance over already-nonzero coefs and r still-zero coefs,
-       * appending correction bits to the nonzeroes.  A correction bit is 1
+    }
+
+    if (EOBRUN > 0) {
+      /* Scan any remaining coefficient positions after the end-of-band
+       * (the last newly nonzero coefficient, if any).  Append a correction
+       * bit to each already-nonzero coefficient.  A correction bit is 1
        * if the absolute value of the coefficient must be increased.
        */
-      do {
+      for (; k <= Se; k++) {
 	thiscoef = *block + jpeg_natural_order[k];
 	if (*thiscoef != 0) {
 	  CHECK_BIT_BUFFER(br_state, 1, goto undoit);
@@ -549,49 +608,16 @@
 		*thiscoef += m1;
 	    }
 	  }
-	} else {
-	  if (--r < 0)
-	    break;		/* reached target zero coefficient */
-	}
-	k++;
-      } while (k <= Se);
-      if (s) {
-	int pos = jpeg_natural_order[k];
-	/* Output newly nonzero coefficient */
-	(*block)[pos] = (JCOEF) s;
-	/* Remember its position in case we have to suspend */
-	newnz_pos[num_newnz++] = pos;
-      }
-    }
-  }
-
-  if (EOBRUN > 0) {
-    /* Scan any remaining coefficient positions after the end-of-band
-     * (the last newly nonzero coefficient, if any).  Append a correction
-     * bit to each already-nonzero coefficient.  A correction bit is 1
-     * if the absolute value of the coefficient must be increased.
-     */
-    for (; k <= Se; k++) {
-      thiscoef = *block + jpeg_natural_order[k];
-      if (*thiscoef != 0) {
-	CHECK_BIT_BUFFER(br_state, 1, goto undoit);
-	if (GET_BITS(1)) {
-	  if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
-	    if (*thiscoef >= 0)
-	      *thiscoef += p1;
-	    else
-	      *thiscoef += m1;
-	  }
 	}
       }
+      /* Count one block completed in EOB run */
+      EOBRUN--;
     }
-    /* Count one block completed in EOB run */
-    EOBRUN--;
-  }
 
-  /* Completed MCU, so update state */
-  BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
-  entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we care about */
+    /* Completed MCU, so update state */
+    BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+    entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
+  }
 
   /* Account for restart interval (no-op if not using restarts) */
   entropy->restarts_to_go--;
diff --git a/jdtrans.c b/jdtrans.c
index db620bc..6c0ab71 100644
--- a/jdtrans.c
+++ b/jdtrans.c
@@ -1,7 +1,7 @@
 /*
  * jdtrans.c
  *
- * Copyright (C) 1995-1996, Thomas G. Lane.
+ * Copyright (C) 1995-1997, 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.
  *
@@ -30,6 +30,13 @@
  * To release the memory occupied by the virtual arrays, call
  * jpeg_finish_decompress() when done with the data.
  *
+ * An alternative usage is to simply obtain access to the coefficient arrays
+ * during a buffered-image-mode decompression operation.  This is allowed
+ * after any jpeg_finish_output() call.  The arrays can be accessed until
+ * jpeg_finish_decompress() is called.  (Note that any call to the library
+ * may reposition the arrays, so don't rely on access_virt_barray() results
+ * to stay valid across library calls.)
+ *
  * Returns NULL if suspended.  This case need be checked only if
  * a suspending data source is used.
  */
@@ -41,32 +48,43 @@
     /* First call: initialize active modules */
     transdecode_master_selection(cinfo);
     cinfo->global_state = DSTATE_RDCOEFS;
-  } else if (cinfo->global_state != DSTATE_RDCOEFS)
-    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
-  /* Absorb whole file into the coef buffer */
-  for (;;) {
-    int retcode;
-    /* Call progress monitor hook if present */
-    if (cinfo->progress != NULL)
-      (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
-    /* Absorb some more input */
-    retcode = (*cinfo->inputctl->consume_input) (cinfo);
-    if (retcode == JPEG_SUSPENDED)
-      return NULL;
-    if (retcode == JPEG_REACHED_EOI)
-      break;
-    /* Advance progress counter if appropriate */
-    if (cinfo->progress != NULL &&
-	(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
-      if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
-	/* startup underestimated number of scans; ratchet up one scan */
-	cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+  }
+  if (cinfo->global_state == DSTATE_RDCOEFS) {
+    /* Absorb whole file into the coef buffer */
+    for (;;) {
+      int retcode;
+      /* Call progress monitor hook if present */
+      if (cinfo->progress != NULL)
+	(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+      /* Absorb some more input */
+      retcode = (*cinfo->inputctl->consume_input) (cinfo);
+      if (retcode == JPEG_SUSPENDED)
+	return NULL;
+      if (retcode == JPEG_REACHED_EOI)
+	break;
+      /* Advance progress counter if appropriate */
+      if (cinfo->progress != NULL &&
+	  (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
+	if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
+	  /* startup underestimated number of scans; ratchet up one scan */
+	  cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+	}
       }
     }
+    /* Set state so that jpeg_finish_decompress does the right thing */
+    cinfo->global_state = DSTATE_STOPPING;
   }
-  /* Set state so that jpeg_finish_decompress does the right thing */
-  cinfo->global_state = DSTATE_STOPPING;
-  return cinfo->coef->coef_arrays;
+  /* At this point we should be in state DSTATE_STOPPING if being used
+   * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
+   * to the coefficients during a full buffered-image-mode decompression.
+   */
+  if ((cinfo->global_state == DSTATE_STOPPING ||
+       cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
+    return cinfo->coef->coef_arrays;
+  }
+  /* Oops, improper usage */
+  ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+  return NULL;			/* keep compiler happy */
 }
 
 
@@ -78,6 +96,9 @@
 LOCAL(void)
 transdecode_master_selection (j_decompress_ptr cinfo)
 {
+  /* This is effectively a buffered-image operation. */
+  cinfo->buffered_image = TRUE;
+
   /* Entropy decoding: either Huffman or arithmetic coding. */
   if (cinfo->arith_code) {
     ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
diff --git a/jerror.c b/jerror.c
index 8b89e39..3da7be8 100644
--- a/jerror.c
+++ b/jerror.c
@@ -1,7 +1,7 @@
 /*
  * jerror.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -10,6 +10,11 @@
  * stderr is the right thing to do.  Many applications will want to replace
  * some or all of these routines.
  *
+ * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
+ * you get a Windows-specific hack to display error messages in a dialog box.
+ * It ain't much, but it beats dropping error messages into the bit bucket,
+ * which is what happens to output to stderr under most Windows C compilers.
+ *
  * These routines are used by both the compression and decompression code.
  */
 
@@ -19,6 +24,10 @@
 #include "jversion.h"
 #include "jerror.h"
 
+#ifdef USE_WINDOWS_MESSAGEBOX
+#include <windows.h>
+#endif
+
 #ifndef EXIT_FAILURE		/* define exit() codes if not provided */
 #define EXIT_FAILURE  1
 #endif
@@ -74,6 +83,15 @@
  * Actual output of an error or trace message.
  * Applications may override this method to send JPEG messages somewhere
  * other than stderr.
+ *
+ * On Windows, printing to stderr is generally completely useless,
+ * so we provide optional code to produce an error-dialog popup.
+ * Most Windows applications will still prefer to override this routine,
+ * but if they don't, it'll do something at least marginally useful.
+ *
+ * NOTE: to use the library in an environment that doesn't support the
+ * C stdio library, you may have to delete the call to fprintf() entirely,
+ * not just not use this routine.
  */
 
 METHODDEF(void)
@@ -84,8 +102,14 @@
   /* Create the message */
   (*cinfo->err->format_message) (cinfo, buffer);
 
+#ifdef USE_WINDOWS_MESSAGEBOX
+  /* Display it in a message dialog box */
+  MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
+	     MB_OK | MB_ICONERROR);
+#else
   /* Send it to stderr, adding a newline */
   fprintf(stderr, "%s\n", buffer);
+#endif
 }
 
 
diff --git a/jerror.h b/jerror.h
index de82c8a..fc2fffe 100644
--- a/jerror.h
+++ b/jerror.h
@@ -1,7 +1,7 @@
 /*
  * jerror.h
  *
- * Copyright (C) 1994-1995, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -45,7 +45,9 @@
 JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
 JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
 JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
+JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
 JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
+JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
 JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
 JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
 JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
@@ -71,7 +73,6 @@
 JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
 JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
 JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
-JMESSAGE(JERR_DHT_COUNTS, "Bogus DHT counts")
 JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
 JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
 JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
@@ -134,12 +135,13 @@
 JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
 JMESSAGE(JTRC_EOI, "End Of Image")
 JMESSAGE(JTRC_HUFFBITS, "        %3d %3d %3d %3d %3d %3d %3d %3d")
-JMESSAGE(JTRC_JFIF, "JFIF APP0 marker, density %dx%d  %d")
+JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d  %d")
 JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
 	 "Warning: thumbnail image size does not match data length %u")
-JMESSAGE(JTRC_JFIF_MINOR, "Unknown JFIF minor revision number %d.%02d")
+JMESSAGE(JTRC_JFIF_EXTENSION,
+	 "JFIF extension marker: type 0x%02x, length %u")
 JMESSAGE(JTRC_JFIF_THUMBNAIL, "    with %d x %d thumbnail image")
-JMESSAGE(JTRC_MISC_MARKER, "Skipping marker 0x%02x, length %u")
+JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
 JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
 JMESSAGE(JTRC_QUANTVALS, "        %4u %4u %4u %4u %4u %4u %4u %4u")
 JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
@@ -157,6 +159,12 @@
 JMESSAGE(JTRC_SOS_PARAMS, "  Ss=%d, Se=%d, Ah=%d, Al=%d")
 JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
 JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
+JMESSAGE(JTRC_THUMB_JPEG,
+	 "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_PALETTE,
+	 "JFIF extension marker: palette thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_RGB,
+	 "JFIF extension marker: RGB thumbnail image, length %u")
 JMESSAGE(JTRC_UNKNOWN_IDS,
 	 "Unrecognized component IDs %d %d %d, assuming YCbCr")
 JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
@@ -263,6 +271,12 @@
 	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
 	   (cinfo)->err->msg_code = (code); \
 	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5)  \
+  MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+	   _mp[4] = (p5); \
+	   (cinfo)->err->msg_code = (code); \
+	   (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
 #define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8)  \
   MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
 	   _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
diff --git a/jidctflt.c b/jidctflt.c
index 1724a0b..0188ce3 100644
--- a/jidctflt.c
+++ b/jidctflt.c
@@ -1,7 +1,7 @@
 /*
  * jidctflt.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1998, 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.
  *
@@ -96,9 +96,10 @@
      * column DCT calculations can be simplified this way.
      */
     
-    if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
-	 inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
-	 inptr[DCTSIZE*7]) == 0) {
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+	inptr[DCTSIZE*7] == 0) {
       /* AC terms all zero */
       FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
       
diff --git a/jidctfst.c b/jidctfst.c
index c8661ba..dba4216 100644
--- a/jidctfst.c
+++ b/jidctfst.c
@@ -1,7 +1,7 @@
 /*
  * jidctfst.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1998, 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.
  *
@@ -197,9 +197,10 @@
      * column DCT calculations can be simplified this way.
      */
     
-    if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
-	 inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
-	 inptr[DCTSIZE*7]) == 0) {
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+	inptr[DCTSIZE*7] == 0) {
       /* AC terms all zero */
       int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
 
@@ -289,8 +290,8 @@
      */
     
 #ifndef NO_ZERO_ROW_TEST
-    if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
-	 wsptr[7]) == 0) {
+    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
       /* AC terms all zero */
       JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
 				  & RANGE_MASK];
diff --git a/jidctint.c b/jidctint.c
index 002dac2..a72b320 100644
--- a/jidctint.c
+++ b/jidctint.c
@@ -1,7 +1,7 @@
 /*
  * jidctint.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -178,9 +178,10 @@
      * column DCT calculations can be simplified this way.
      */
     
-    if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
-	 inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
-	 inptr[DCTSIZE*7]) == 0) {
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+	inptr[DCTSIZE*7] == 0) {
       /* AC terms all zero */
       int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
       
@@ -284,8 +285,8 @@
      */
     
 #ifndef NO_ZERO_ROW_TEST
-    if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
-	 wsptr[7]) == 0) {
+    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
       /* AC terms all zero */
       JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
 				  & RANGE_MASK];
diff --git a/jidctred.c b/jidctred.c
index 3ec649c..421f3c7 100644
--- a/jidctred.c
+++ b/jidctred.c
@@ -1,7 +1,7 @@
 /*
  * jidctred.c
  *
- * Copyright (C) 1994-1996, Thomas G. Lane.
+ * Copyright (C) 1994-1998, 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.
  *
@@ -139,8 +139,9 @@
     /* Don't bother to process column 4, because second pass won't use it */
     if (ctr == DCTSIZE-4)
       continue;
-    if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
-	 inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*7]) == 0) {
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+	inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
+	inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
       /* AC terms all zero; we need not examine term 4 for 4x4 output */
       int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
       
@@ -198,8 +199,8 @@
     /* It's not clear whether a zero row test is worthwhile here ... */
 
 #ifndef NO_ZERO_ROW_TEST
-    if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[5] | wsptr[6] |
-	 wsptr[7]) == 0) {
+    if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
+	wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
       /* AC terms all zero */
       JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
 				  & RANGE_MASK];
@@ -290,8 +291,8 @@
     /* Don't bother to process columns 2,4,6 */
     if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
       continue;
-    if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*3] |
-	 inptr[DCTSIZE*5] | inptr[DCTSIZE*7]) == 0) {
+    if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
+	inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
       /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
       int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
       
@@ -331,7 +332,7 @@
     /* It's not clear whether a zero row test is worthwhile here ... */
 
 #ifndef NO_ZERO_ROW_TEST
-    if ((wsptr[1] | wsptr[3] | wsptr[5] | wsptr[7]) == 0) {
+    if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
       /* AC terms all zero */
       JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
 				  & RANGE_MASK];
diff --git a/jmemdos.c b/jmemdos.c
index 77fb5ad..60b45c6 100644
--- a/jmemdos.c
+++ b/jmemdos.c
@@ -1,7 +1,7 @@
 /*
  * jmemdos.c
  *
- * Copyright (C) 1992-1996, Thomas G. Lane.
+ * Copyright (C) 1992-1997, 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.
  *
@@ -77,6 +77,10 @@
 #define READ_BINARY	"rb"
 #endif
 
+#ifndef USE_MSDOS_MEMMGR	/* make sure user got configuration right */
+  You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */
+#endif
+
 #if MAX_ALLOC_CHUNK >= 65535L	/* make sure jconfig.h got this right */
   MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */
 #endif
diff --git a/jmemmac.c b/jmemmac.c
index 41756cb..106f9be 100644
--- a/jmemmac.c
+++ b/jmemmac.c
@@ -1,13 +1,16 @@
 /*
  * jmemmac.c
  *
- * Copyright (C) 1992-1996, Thomas G. Lane.
+ * Copyright (C) 1992-1997, 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.
  *
  * jmemmac.c provides an Apple Macintosh implementation of the system-
  * dependent portion of the JPEG memory manager.
  *
+ * If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the
+ * JPEG_INTERNALS part of jconfig.h.
+ *
  * jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr
  * instead of malloc and free.  It accurately determines the amount of
  * memory available by using CompactMem.  Notice that if left to its
@@ -16,29 +19,57 @@
  * factor computed in jpeg_mem_available().  The application can ensure
  * that more space is left over by reducing max_memory_to_use.
  *
- * Large images are swapped to disk using temporary files created with
- * tmpfile(); that part of the module is the same as in jmemansi.c.
- * Metrowerks CodeWarrior's implementation of tmpfile() isn't quite what
- * we want: it puts the files in the local directory and makes them
- * user-visible -- and only deletes them when the application quits,
- * which means they stick around in the event of a crash.
- * It would be better to create the temp files in the system's temporary
- * items folder.  Perhaps someday we'll get around to doing that.
+ * Large images are swapped to disk using temporary files and System 7.0+'s
+ * temporary folder functionality.
  *
- * Contributed by Sam Bushell (jsam@iagu.on.net).
+ * Note that jmemmac.c depends on two features of MacOS that were first
+ * introduced in System 7: FindFolder and the FSSpec-based calls.
+ * If your application uses jmemmac.c and is run under System 6 or earlier,
+ * and the jpeg library decides it needs a temporary file, it will abort,
+ * printing error messages about requiring System 7.  (If no temporary files
+ * are created, it will run fine.)
+ *
+ * If you want to use jmemmac.c in an application that might be used with
+ * System 6 or earlier, then you should remove dependencies on FindFolder
+ * and the FSSpec calls.  You will need to replace FindFolder with some
+ * other mechanism for finding a place to put temporary files, and you
+ * should replace the FSSpec calls with their HFS equivalents:
+ *
+ *     FSpDelete     ->  HDelete
+ *     FSpGetFInfo   ->  HGetFInfo
+ *     FSpCreate     ->  HCreate
+ *     FSpOpenDF     ->  HOpen      *** Note: not HOpenDF ***
+ *     FSMakeFSSpec  ->  (fill in spec by hand.)
+ *
+ * (Use HOpen instead of HOpenDF.  HOpen is just a glue-interface to PBHOpen,
+ * which is on all HFS macs.  HOpenDF is a System 7 addition which avoids the
+ * ages-old problem of names starting with a period.)
+ *
+ * Contributed by Sam Bushell (jsam@iagu.on.net) and
+ * Dan Gildor (gyld@in-touch.com).
  */
 
 #define JPEG_INTERNALS
 #include "jinclude.h"
 #include "jpeglib.h"
-#include "jmemsys.h"		/* import the system-dependent declarations */
+#include "jmemsys.h"    /* import the system-dependent declarations */
 
-#include <Memory.h>		/* we use the MacOS memory manager */
-
-#ifndef SEEK_SET		/* pre-ANSI systems may not define this; */
-#define SEEK_SET  0		/* if not, assume 0 is correct */
+#ifndef USE_MAC_MEMMGR	/* make sure user got configuration right */
+  You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */
 #endif
 
+#include <Memory.h>     /* we use the MacOS memory manager */
+#include <Files.h>      /* we use the MacOS File stuff */
+#include <Folders.h>    /* we use the MacOS HFS stuff */
+#include <Script.h>     /* for smSystemScript */
+#include <Gestalt.h>    /* we use Gestalt to test for specific functionality */
+
+#ifndef TEMP_FILE_NAME		/* can override from jconfig.h or Makefile */
+#define TEMP_FILE_NAME  "JPG%03d.TMP"
+#endif
+
+static int next_file_num;	/* to distinguish among several temp files */
+
 
 /*
  * Memory allocation and freeing are controlled by the MacOS library
@@ -124,10 +155,15 @@
 		    void FAR * buffer_address,
 		    long file_offset, long byte_count)
 {
-  if (fseek(info->temp_file, file_offset, SEEK_SET))
+  long bytes = byte_count;
+  long retVal;
+
+  if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
     ERREXIT(cinfo, JERR_TFILE_SEEK);
-  if (JFREAD(info->temp_file, buffer_address, byte_count)
-      != (size_t) byte_count)
+
+  retVal = FSRead ( info->temp_file, &bytes,
+		    (unsigned char *) buffer_address );
+  if ( retVal != noErr || bytes != byte_count )
     ERREXIT(cinfo, JERR_TFILE_READ);
 }
 
@@ -137,10 +173,15 @@
 		     void FAR * buffer_address,
 		     long file_offset, long byte_count)
 {
-  if (fseek(info->temp_file, file_offset, SEEK_SET))
+  long bytes = byte_count;
+  long retVal;
+
+  if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
     ERREXIT(cinfo, JERR_TFILE_SEEK);
-  if (JFWRITE(info->temp_file, buffer_address, byte_count)
-      != (size_t) byte_count)
+
+  retVal = FSWrite ( info->temp_file, &bytes,
+		     (unsigned char *) buffer_address );
+  if ( retVal != noErr || bytes != byte_count )
     ERREXIT(cinfo, JERR_TFILE_WRITE);
 }
 
@@ -148,30 +189,77 @@
 METHODDEF(void)
 close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
 {
-  fclose(info->temp_file);
-  /* Since this implementation uses tmpfile() to create the file,
-   * no explicit file deletion is needed.
-   */
+  FSClose ( info->temp_file );
+  FSpDelete ( &(info->tempSpec) );
 }
 
 
 /*
  * Initial opening of a backing-store object.
  *
- * This version uses tmpfile(), which constructs a suitable file name
- * behind the scenes.  We don't have to use info->temp_name[] at all;
- * indeed, we can't even find out the actual name of the temp file.
+ * This version uses FindFolder to find the Temporary Items folder,
+ * and puts the temporary file in there.
  */
 
 GLOBAL(void)
 jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
 			 long total_bytes_needed)
 {
-  if ((info->temp_file = tmpfile()) == NULL)
-    ERREXITS(cinfo, JERR_TFILE_CREATE, "");
+  short         tmpRef, vRefNum;
+  long          dirID;
+  FInfo         finderInfo;
+  FSSpec        theSpec;
+  Str255        fName;
+  OSErr         osErr;
+  long          gestaltResponse = 0;
+
+  /* Check that FSSpec calls are available. */
+  osErr = Gestalt( gestaltFSAttr, &gestaltResponse );
+  if ( ( osErr != noErr )
+       || !( gestaltResponse & (1<<gestaltHasFSSpecCalls) ) )
+    ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required");
+  /* TO DO: add a proper error message to jerror.h. */
+
+  /* Check that FindFolder is available. */
+  osErr = Gestalt( gestaltFindFolderAttr, &gestaltResponse );
+  if ( ( osErr != noErr )
+       || !( gestaltResponse & (1<<gestaltFindFolderPresent) ) )
+    ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required.");
+  /* TO DO: add a proper error message to jerror.h. */
+
+  osErr = FindFolder ( kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
+                       &vRefNum, &dirID );
+  if ( osErr != noErr )
+    ERREXITS(cinfo, JERR_TFILE_CREATE, "- temporary items folder unavailable");
+  /* TO DO: Try putting the temp files somewhere else. */
+
+  /* Keep generating file names till we find one that's not in use */
+  for (;;) {
+    next_file_num++;		/* advance counter */
+
+    sprintf(info->temp_name, TEMP_FILE_NAME, next_file_num);
+    strcpy ( (Ptr)fName+1, info->temp_name );
+    *fName = strlen (info->temp_name);
+    osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec );
+
+    if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr )
+      break;
+  }
+
+  osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript );
+  if ( osErr != noErr )
+    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
+
+  osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) );
+  if ( osErr != noErr )
+    ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
+
+  info->tempSpec = theSpec;
+
   info->read_backing_store = read_backing_store;
   info->write_backing_store = write_backing_store;
   info->close_backing_store = close_backing_store;
+  TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
 }
 
 
@@ -183,6 +271,8 @@
 GLOBAL(long)
 jpeg_mem_init (j_common_ptr cinfo)
 {
+  next_file_num = 0;
+
   /* max_memory_to_use will be initialized to FreeMem()'s result;
    * the calling application might later reduce it, for example
    * to leave room to invoke multiple JPEG objects.
diff --git a/jmemmgr.c b/jmemmgr.c
index 5ea19ce..d801b32 100644
--- a/jmemmgr.c
+++ b/jmemmgr.c
@@ -1,7 +1,7 @@
 /*
  * jmemmgr.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -1076,6 +1076,9 @@
   mem->pub.free_pool = free_pool;
   mem->pub.self_destruct = self_destruct;
 
+  /* Make MAX_ALLOC_CHUNK accessible to other modules */
+  mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
+
   /* Initialize working state */
   mem->pub.max_memory_to_use = max_to_use;
 
diff --git a/jmemname.c b/jmemname.c
index d1b57e9..ed96dee 100644
--- a/jmemname.c
+++ b/jmemname.c
@@ -1,7 +1,7 @@
 /*
  * jmemname.c
  *
- * Copyright (C) 1992-1996, Thomas G. Lane.
+ * Copyright (C) 1992-1997, 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.
  *
@@ -30,9 +30,14 @@
 #define READ_BINARY	"r"
 #define RW_BINARY	"w+"
 #else
+#ifdef VMS			/* VMS is very nonstandard */
+#define READ_BINARY	"rb", "ctx=stm"
+#define RW_BINARY	"w+b", "ctx=stm"
+#else				/* standard ANSI-compliant case */
 #define READ_BINARY	"rb"
 #define RW_BINARY	"w+b"
 #endif
+#endif
 
 
 /*
diff --git a/jmemsys.h b/jmemsys.h
index 6d4c7f2..6c3c6d3 100644
--- a/jmemsys.h
+++ b/jmemsys.h
@@ -1,7 +1,7 @@
 /*
  * jmemsys.h
  *
- * Copyright (C) 1992-1996, Thomas G. Lane.
+ * Copyright (C) 1992-1997, 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.
  *
@@ -14,7 +14,8 @@
  * in the IJG distribution.  You may need to modify it if you write a
  * custom memory manager.  If system-dependent changes are needed in
  * this file, the best method is to #ifdef them based on a configuration
- * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR.
+ * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
+ * and USE_MAC_MEMMGR.
  */
 
 
@@ -114,6 +115,7 @@
 
 #define TEMP_NAME_LENGTH   64	/* max length of a temporary file's name */
 
+
 #ifdef USE_MSDOS_MEMMGR		/* DOS-specific junk */
 
 typedef unsigned short XMSH;	/* type of extended-memory handles */
@@ -127,6 +129,11 @@
 
 #endif /* USE_MSDOS_MEMMGR */
 
+#ifdef USE_MAC_MEMMGR		/* Mac-specific junk */
+#include <Files.h>
+#endif /* USE_MAC_MEMMGR */
+
+
 typedef struct backing_store_struct * backing_store_ptr;
 
 typedef struct backing_store_struct {
@@ -148,12 +155,20 @@
   handle_union handle;		/* reference to backing-store storage object */
   char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
 #else
+#ifdef USE_MAC_MEMMGR
+  /* For the Mac manager (jmemmac.c), we need: */
+  short temp_file;		/* file reference number to temp file */
+  FSSpec tempSpec;		/* the FSSpec for the temp file */
+  char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
+#else
   /* For a typical implementation with temp files, we need: */
   FILE * temp_file;		/* stdio reference to temp file */
   char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
 #endif
+#endif
 } backing_store_info;
 
+
 /*
  * Initial opening of a backing-store object.  This must fill in the
  * read/write/close pointers in the object.  The read/write routines
diff --git a/jmorecfg.h b/jmorecfg.h
index e43651b..54a7d1c 100644
--- a/jmorecfg.h
+++ b/jmorecfg.h
@@ -1,7 +1,7 @@
 /*
  * jmorecfg.h
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -285,6 +285,7 @@
 #undef  D_ARITH_CODING_SUPPORTED    /* Arithmetic coding back end? */
 #define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
 #define D_PROGRESSIVE_SUPPORTED	    /* Progressive JPEG? (Requires MULTISCAN)*/
+#define SAVE_MARKERS_SUPPORTED	    /* jpeg_save_markers() needed? */
 #define BLOCK_SMOOTHING_SUPPORTED   /* Block smoothing? (Progressive only) */
 #define IDCT_SCALING_SUPPORTED	    /* Output rescaling via IDCT? */
 #undef  UPSAMPLE_SCALING_SUPPORTED  /* Output rescaling at upsample stage? */
diff --git a/jpegint.h b/jpegint.h
index 7ba30c3..95b00d4 100644
--- a/jpegint.h
+++ b/jpegint.h
@@ -1,7 +1,7 @@
 /*
  * jpegint.h
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -118,15 +118,16 @@
 
 /* Marker writing */
 struct jpeg_marker_writer {
-  /* write_any_marker is exported for use by applications */
-  /* Probably only COM and APPn markers should be written */
-  JMETHOD(void, write_any_marker, (j_compress_ptr cinfo, int marker,
-				   const JOCTET *dataptr, unsigned int datalen));
   JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
   JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
   JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
   JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
   JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
+  /* These routines are exported to allow insertion of extra markers */
+  /* Probably only COM and APPn markers should be written this way */
+  JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
+				      unsigned int datalen));
+  JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
 };
 
 
@@ -194,9 +195,6 @@
   JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
   /* Read a restart marker --- exported for use by entropy decoder only */
   jpeg_marker_parser_method read_restart_marker;
-  /* Application-overridable marker processing methods */
-  jpeg_marker_parser_method process_COM;
-  jpeg_marker_parser_method process_APPn[16];
 
   /* State of marker reader --- nominally internal, but applications
    * supplying COM or APPn handlers might like to know the state.
@@ -212,6 +210,10 @@
   JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
   JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
 				JBLOCKROW *MCU_data));
+
+  /* This is here to share code between baseline and progressive decoders; */
+  /* other modules probably should not use it */
+  boolean insufficient_data;	/* set TRUE after emitting warning */
 };
 
 /* Inverse DCT (also performs dequantization) */
@@ -375,7 +377,9 @@
 				  JDIMENSION num_blocks));
 EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
 /* Constant tables in jutils.c */
+#if 0				/* This table is not actually needed in v6a */
 extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
+#endif
 extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
 
 /* Suppress undefined-structure complaints if necessary. */
diff --git a/jpeglib.h b/jpeglib.h
index b778e2d..d1be8dd 100644
--- a/jpeglib.h
+++ b/jpeglib.h
@@ -1,7 +1,7 @@
 /*
  * jpeglib.h
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -30,7 +30,7 @@
  * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
  */
 
-#define JPEG_LIB_VERSION  61	/* Version 6a */
+#define JPEG_LIB_VERSION  62	/* Version 6b */
 
 
 /* Various constants determining the sizes of things.
@@ -188,6 +188,18 @@
   int Ah, Al;			/* progressive JPEG successive approx. parms */
 } jpeg_scan_info;
 
+/* The decompressor can save APPn and COM markers in a list of these: */
+
+typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
+
+struct jpeg_marker_struct {
+  jpeg_saved_marker_ptr next;	/* next in list, or NULL */
+  UINT8 marker;			/* marker code: JPEG_COM, or JPEG_APP0+n */
+  unsigned int original_length;	/* # bytes of data in the file */
+  unsigned int data_length;	/* # bytes of data saved at data[] */
+  JOCTET FAR * data;		/* the data contained in the marker */
+  /* the marker length word is not counted in data_length or original_length */
+};
 
 /* Known color spaces. */
 
@@ -230,8 +242,9 @@
   struct jpeg_error_mgr * err;	/* Error handler module */\
   struct jpeg_memory_mgr * mem;	/* Memory manager module */\
   struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
-  boolean is_decompressor;	/* so common code can tell which is which */\
-  int global_state		/* for checking call sequence validity */
+  void * client_data;		/* Available for use by application */\
+  boolean is_decompressor;	/* So common code can tell which is which */\
+  int global_state		/* For checking call sequence validity */
 
 /* Routines that are to be used by both halves of the library are declared
  * to receive a pointer to this structure.  There are no actual instances of
@@ -322,6 +335,8 @@
   /* Parameters controlling emission of special markers. */
 
   boolean write_JFIF_header;	/* should a JFIF marker be written? */
+  UINT8 JFIF_major_version;	/* What to write for the JFIF version number */
+  UINT8 JFIF_minor_version;
   /* These three values are not used by the JPEG code, merely 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 */
@@ -386,6 +401,8 @@
   struct jpeg_downsampler * downsample;
   struct jpeg_forward_dct * fdct;
   struct jpeg_entropy_encoder * entropy;
+  jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
+  int script_space_size;
 };
 
 
@@ -531,7 +548,9 @@
    * the JPEG library.
    */
   boolean saw_JFIF_marker;	/* TRUE iff a JFIF APP0 marker was found */
-  /* Data copied from JFIF marker: */
+  /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
+  UINT8 JFIF_major_version;	/* JFIF version number */
+  UINT8 JFIF_minor_version;
   UINT8 density_unit;		/* JFIF code for pixel size units */
   UINT16 X_density;		/* Horizontal pixel density */
   UINT16 Y_density;		/* Vertical pixel density */
@@ -540,6 +559,12 @@
 
   boolean CCIR601_sampling;	/* TRUE=first samples are cosited */
 
+  /* Aside from the specific data retained from APPn markers known to the
+   * library, the uninterpreted contents of any or all APPn and COM markers
+   * can be saved in a list for examination by the application.
+   */
+  jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
+
   /* Remaining fields are known throughout decompressor, but generally
    * should not be touched by a surrounding application.
    */
@@ -772,6 +797,9 @@
    * after creating the JPEG object.
    */
   long max_memory_to_use;
+
+  /* Maximum allocation request accepted by alloc_large. */
+  long max_alloc_chunk;
 };
 
 
@@ -824,6 +852,8 @@
 #define jpeg_finish_compress	jFinCompress
 #define jpeg_write_raw_data	jWrtRawData
 #define jpeg_write_marker	jWrtMarker
+#define jpeg_write_m_header	jWrtMHeader
+#define jpeg_write_m_byte	jWrtMByte
 #define jpeg_write_tables	jWrtTables
 #define jpeg_read_header	jReadHeader
 #define jpeg_start_decompress	jStrtDecompress
@@ -837,6 +867,7 @@
 #define jpeg_new_colormap	jNewCMap
 #define jpeg_consume_input	jConsumeInput
 #define jpeg_calc_output_dimensions	jCalcDimensions
+#define jpeg_save_markers	jSaveMarkers
 #define jpeg_set_marker_processor	jSetMarker
 #define jpeg_read_coefficients	jReadCoefs
 #define jpeg_write_coefficients	jWrtCoefs
@@ -918,6 +949,11 @@
 EXTERN(void) jpeg_write_marker
 	JPP((j_compress_ptr cinfo, int marker,
 	     const JOCTET * dataptr, unsigned int datalen));
+/* Same, but piecemeal. */
+EXTERN(void) jpeg_write_m_header
+	JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
+EXTERN(void) jpeg_write_m_byte
+	JPP((j_compress_ptr cinfo, int val));
 
 /* Alternate compression function: just write an abbreviated table file */
 EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
@@ -965,6 +1001,11 @@
 /* Precalculate output dimensions for current decompression parameters. */
 EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
 
+/* Control saving of COM and APPn markers into marker_list. */
+EXTERN(void) jpeg_save_markers
+	JPP((j_decompress_ptr cinfo, int marker_code,
+	     unsigned int length_limit));
+
 /* Install a special processing method for COM or APPn markers. */
 EXTERN(void) jpeg_set_marker_processor
 	JPP((j_decompress_ptr cinfo, int marker_code,
diff --git a/jpegtran.1 b/jpegtran.1
index 7319884..6de18e2 100644
--- a/jpegtran.1
+++ b/jpegtran.1
@@ -1,6 +1,6 @@
-.TH JPEGTRAN 1 "15 June 1995"
+.TH JPEGTRAN 1 "3 August 1997"
 .SH NAME
-jpegtran \- lossless transcoding of JPEG files
+jpegtran \- lossless transformation of JPEG files
 .SH SYNOPSIS
 .B jpegtran
 [
@@ -13,23 +13,27 @@
 .SH DESCRIPTION
 .LP
 .B jpegtran
-translates JPEG files from one variant of JPEG to another, for example
-from baseline JPEG to progressive JPEG.  The transformation is lossless:
-no image degradation occurs, which would not be true if you used
+performs various useful transformations of JPEG files.
+It can translate the coded representation from one variant of JPEG to another,
+for example from baseline JPEG to progressive JPEG or vice versa.  It can also
+perform some rearrangements of the image data, for example turning an image
+from landscape to portrait format by rotation.
+.PP
+.B jpegtran
+works by rearranging the compressed data (DCT coefficients), without
+ever fully decoding the image.  Therefore, its transformations are lossless:
+there is no image degradation at all, which would not be true if you used
 .B djpeg
 followed by
-.BR cjpeg .
-However, you cannot alter the image quality, because that would not be
-a lossless operation.
+.B cjpeg
+to accomplish the same conversion.  But by the same token,
+.B jpegtran
+cannot perform lossy operations such as changing the image quality.
+.PP
 .B jpegtran
 reads the named JPEG/JFIF file, or the standard input if no file is
 named, and produces a JPEG/JFIF file on the standard output.
 .SH OPTIONS
-.B jpegtran
-accepts a subset of the switches recognized by
-.BR cjpeg .
-If you specify no switches, you get a plain baseline JPEG output file.
-.PP
 All switch names may be abbreviated; for example,
 .B \-optimize
 may be written
@@ -41,41 +45,131 @@
 .BR \-optimise ),
 though for brevity these are not mentioned below.
 .PP
-The basic switches are:
+To specify the coded JPEG representation used in the output file,
+.B jpegtran
+accepts a subset of the switches recognized by
+.BR cjpeg :
 .TP
 .B \-optimize
-Perform optimization of entropy encoding parameters.  Without this, default
-encoding parameters are used.
-.B \-optimize
-usually makes the JPEG file a little smaller, but at the price of slower
-compression.  Note that
-.B \-progressive
-implies
-.BR \-optimize .
+Perform optimization of entropy encoding parameters.
 .TP
 .B \-progressive
-Create progressive JPEG file (see below).
-.PP
-The
-.B \-progressive
-switch creates a "progressive JPEG" file.  In this type of JPEG file, the data
-is stored in multiple scans of increasing quality.  If the file is being
-transmitted over a slow communications link, the decoder can use the first
-scan to display a low-quality image very quickly, and can then improve the
-display with each subsequent scan.  The final image is exactly equivalent to a
-standard JPEG file of the same quality setting, and the total file size is
-about the same --- often a little smaller.
-.B Caution:
-progressive JPEG is not yet widely implemented, so many decoders will be
-unable to view a progressive JPEG file at all.
-.PP
-Switches for advanced users:
+Create progressive JPEG file.
 .TP
 .BI \-restart " N"
 Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
 attached to the number.
-.B \-restart 0
-(the default) means no restart markers.
+.TP
+.BI \-scans " file"
+Use the scan script given in the specified text file.
+.PP
+See
+.BR cjpeg (1)
+for more details about these switches.
+If you specify none of these switches, you get a plain baseline-JPEG output
+file.  The quality setting and so forth are determined by the input file.
+.PP
+The image can be losslessly transformed by giving one of these switches:
+.TP
+.B \-flip horizontal
+Mirror image horizontally (left-right).
+.TP
+.B \-flip vertical
+Mirror image vertically (top-bottom).
+.TP
+.B \-rotate 90
+Rotate image 90 degrees clockwise.
+.TP
+.B \-rotate 180
+Rotate image 180 degrees.
+.TP
+.B \-rotate 270
+Rotate image 270 degrees clockwise (or 90 ccw).
+.TP
+.B \-transpose
+Transpose image (across UL-to-LR axis).
+.TP
+.B \-transverse
+Transverse transpose (across UR-to-LL axis).
+.PP
+The transpose transformation has no restrictions regarding image dimensions.
+The other transformations operate rather oddly if the image dimensions are not
+a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
+transform complete blocks of DCT coefficient data in the desired way.
+.PP
+.BR jpegtran 's
+default behavior when transforming an odd-size image is designed
+to preserve exact reversibility and mathematical consistency of the
+transformation set.  As stated, transpose is able to flip the entire image
+area.  Horizontal mirroring leaves any partial iMCU column at the right edge
+untouched, but is able to flip all rows of the image.  Similarly, vertical
+mirroring leaves any partial iMCU row at the bottom edge untouched, but is
+able to flip all columns.  The other transforms can be built up as sequences
+of transpose and flip operations; for consistency, their actions on edge
+pixels are defined to be the same as the end result of the corresponding
+transpose-and-flip sequence.
+.PP
+For practical use, you may prefer to discard any untransformable edge pixels
+rather than having a strange-looking strip along the right and/or bottom edges
+of a transformed image.  To do this, add the
+.B \-trim
+switch:
+.TP
+.B \-trim
+Drop non-transformable edge blocks.
+.PP
+Obviously, a transformation with
+.B \-trim
+is not reversible, so strictly speaking
+.B jpegtran
+with this switch is not lossless.  Also, the expected mathematical
+equivalences between the transformations no longer hold.  For example,
+.B \-rot 270 -trim
+trims only the bottom edge, but
+.B \-rot 90 -trim
+followed by
+.B \-rot 180 -trim
+trims both edges.
+.PP
+Another not-strictly-lossless transformation switch is:
+.TP
+.B \-grayscale
+Force grayscale output.
+.PP
+This option discards the chrominance channels if the input image is YCbCr
+(ie, a standard color JPEG), resulting in a grayscale JPEG file.  The
+luminance channel is preserved exactly, so this is a better method of reducing
+to grayscale than decompression, conversion, and recompression.  This switch
+is particularly handy for fixing a monochrome picture that was mistakenly
+encoded as a color JPEG.  (In such a case, the space savings from getting rid
+of the near-empty chroma channels won't be large; but the decoding time for
+a grayscale JPEG is substantially less than that for a color JPEG.)
+.PP
+.B jpegtran
+also recognizes these switches that control what to do with "extra" markers,
+such as comment blocks:
+.TP
+.B \-copy none
+Copy no extra markers from source file.  This setting suppresses all
+comments and other excess baggage present in the source file.
+.TP
+.B \-copy comments
+Copy only comment markers.  This setting copies comments from the source file,
+but discards any other inessential data.
+.TP
+.B \-copy all
+Copy all extra markers.  This setting preserves miscellaneous markers
+found in the source file, such as JFIF thumbnails and Photoshop settings.
+In some files these extra markers can be sizable.
+.PP
+The default behavior is
+.BR "\-copy comments" .
+(Note: in IJG releases v6 and v6a,
+.B jpegtran
+always did the equivalent of
+.BR "\-copy none" .)
+.PP
+Additional switches recognized by jpegtran are:
 .TP
 .BI \-maxmemory " N"
 Set limit for amount of memory to use in processing large images.  Value is
@@ -95,26 +189,6 @@
 .B \-debug
 Same as
 .BR \-verbose .
-.PP
-The
-.B \-restart
-option inserts extra markers that allow a JPEG decoder to resynchronize after
-a transmission error.  Without restart markers, any damage to a compressed
-file will usually ruin the image from the point of the error to the end of the
-image; with restart markers, the damage is usually confined to the portion of
-the image up to the next restart marker.  Of course, the restart markers
-occupy extra space.  We recommend
-.B \-restart 1
-for images that will be transmitted across unreliable networks such as Usenet.
-.PP
-Switches for wizards:
-.TP
-.BI \-scans " file"
-Use the scan script given in the specified text file.
-.PP
-The "wizard" switches are intended for experimentation with JPEG.  If you
-don't know what you are doing, \fBdon't use them\fR.  These switches are
-documented further in the file wizard.doc.
 .SH EXAMPLES
 .LP
 This example converts a baseline JPEG file to progressive form:
@@ -123,6 +197,14 @@
 .I foo.jpg
 .B >
 .I fooprog.jpg
+.PP
+This example rotates an image 90 degrees clockwise, discarding any
+unrotatable edge pixels:
+.IP
+.B jpegtran \-rot 90 -trim
+.I foo.jpg
+.B >
+.I foo90.jpg
 .SH ENVIRONMENT
 .TP
 .B JPEGMEM
@@ -147,4 +229,10 @@
 .SH BUGS
 Arithmetic coding is not supported for legal reasons.
 .PP
-Still not as fast as we'd like.
+The transform options can't transform odd-size images perfectly.  Use
+.B \-trim
+if you don't like the results without it.
+.PP
+The entire image is read into memory and then written out again, even in
+cases where this isn't really necessary.  Expect swapping on large images,
+especially when using the more complex transform options.
diff --git a/jpegtran.c b/jpegtran.c
index 5190102..20ef111 100644
--- a/jpegtran.c
+++ b/jpegtran.c
@@ -1,16 +1,18 @@
 /*
  * jpegtran.c
  *
- * Copyright (C) 1995-1996, Thomas G. Lane.
+ * Copyright (C) 1995-1997, 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 command-line user interface for JPEG transcoding.
  * It is very similar to cjpeg.c, but provides lossless transcoding between
- * different JPEG file formats.
+ * different JPEG file formats.  It also provides some lossless and sort-of-
+ * lossless transformations of JPEG data.
  */
 
 #include "cdjpeg.h"		/* Common decls for cjpeg/djpeg applications */
+#include "transupp.h"		/* Support routines for jpegtran */
 #include "jversion.h"		/* for version message */
 
 #ifdef USE_CCOMMAND		/* command-line reader for Macintosh */
@@ -35,6 +37,8 @@
 
 static const char * progname;	/* program name for error messages */
 static char * outfilename;	/* for -outfile switch */
+static JCOPY_OPTION copyoption;	/* -copy switch */
+static jpeg_transform_info transformoption; /* image transformation options */
 
 
 LOCAL(void)
@@ -49,12 +53,24 @@
 #endif
 
   fprintf(stderr, "Switches (names may be abbreviated):\n");
+  fprintf(stderr, "  -copy none     Copy no extra markers from source file\n");
+  fprintf(stderr, "  -copy comments Copy only comment markers (default)\n");
+  fprintf(stderr, "  -copy all      Copy all extra markers\n");
 #ifdef ENTROPY_OPT_SUPPORTED
   fprintf(stderr, "  -optimize      Optimize Huffman table (smaller file, but slow compression)\n");
 #endif
 #ifdef C_PROGRESSIVE_SUPPORTED
   fprintf(stderr, "  -progressive   Create progressive JPEG file\n");
 #endif
+#if TRANSFORMS_SUPPORTED
+  fprintf(stderr, "Switches for modifying the image:\n");
+  fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
+  fprintf(stderr, "  -flip [horizontal|vertical]  Mirror image (left-right or top-bottom)\n");
+  fprintf(stderr, "  -rotate [90|180|270]         Rotate image (degrees clockwise)\n");
+  fprintf(stderr, "  -transpose     Transpose image\n");
+  fprintf(stderr, "  -transverse    Transverse transpose image\n");
+  fprintf(stderr, "  -trim          Drop non-transformable edge blocks\n");
+#endif /* TRANSFORMS_SUPPORTED */
   fprintf(stderr, "Switches for advanced users:\n");
   fprintf(stderr, "  -restart N     Set restart interval in rows, or in blocks with B\n");
   fprintf(stderr, "  -maxmemory N   Maximum memory to use (in kbytes)\n");
@@ -71,6 +87,29 @@
 }
 
 
+LOCAL(void)
+select_transform (JXFORM_CODE transform)
+/* Silly little routine to detect multiple transform options,
+ * which we can't handle.
+ */
+{
+#if TRANSFORMS_SUPPORTED
+  if (transformoption.transform == JXFORM_NONE ||
+      transformoption.transform == transform) {
+    transformoption.transform = transform;
+  } else {
+    fprintf(stderr, "%s: can only do one image transformation at a time\n",
+	    progname);
+    usage();
+  }
+#else
+  fprintf(stderr, "%s: sorry, image transformation was not compiled\n",
+	  progname);
+  exit(EXIT_FAILURE);
+#endif
+}
+
+
 LOCAL(int)
 parse_switches (j_compress_ptr cinfo, int argc, char **argv,
 		int last_file_arg_seen, boolean for_real)
@@ -91,6 +130,10 @@
   /* Set up default JPEG parameters. */
   simple_progressive = FALSE;
   outfilename = NULL;
+  copyoption = JCOPYOPT_DEFAULT;
+  transformoption.transform = JXFORM_NONE;
+  transformoption.trim = FALSE;
+  transformoption.force_grayscale = FALSE;
   cinfo->err->trace_level = 0;
 
   /* Scan command line options, adjust parameters */
@@ -117,6 +160,19 @@
       exit(EXIT_FAILURE);
 #endif
 
+    } else if (keymatch(arg, "copy", 1)) {
+      /* Select which extra markers to copy. */
+      if (++argn >= argc)	/* advance to next argument */
+	usage();
+      if (keymatch(argv[argn], "none", 1)) {
+	copyoption = JCOPYOPT_NONE;
+      } else if (keymatch(argv[argn], "comments", 1)) {
+	copyoption = JCOPYOPT_COMMENTS;
+      } else if (keymatch(argv[argn], "all", 1)) {
+	copyoption = JCOPYOPT_ALL;
+      } else
+	usage();
+
     } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
       /* Enable debug printouts. */
       /* On first -d, print version identification */
@@ -129,6 +185,25 @@
       }
       cinfo->err->trace_level++;
 
+    } else if (keymatch(arg, "flip", 1)) {
+      /* Mirror left-right or top-bottom. */
+      if (++argn >= argc)	/* advance to next argument */
+	usage();
+      if (keymatch(argv[argn], "horizontal", 1))
+	select_transform(JXFORM_FLIP_H);
+      else if (keymatch(argv[argn], "vertical", 1))
+	select_transform(JXFORM_FLIP_V);
+      else
+	usage();
+
+    } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) {
+      /* Force to grayscale. */
+#if TRANSFORMS_SUPPORTED
+      transformoption.force_grayscale = TRUE;
+#else
+      select_transform(JXFORM_NONE);	/* force an error */
+#endif
+
     } else if (keymatch(arg, "maxmemory", 3)) {
       /* Maximum memory in Kb (or Mb with 'm'). */
       long lval;
@@ -188,7 +263,20 @@
 	/* restart_interval will be computed during startup */
       }
 
-    } else if (keymatch(arg, "scans", 2)) {
+    } else if (keymatch(arg, "rotate", 2)) {
+      /* Rotate 90, 180, or 270 degrees (measured clockwise). */
+      if (++argn >= argc)	/* advance to next argument */
+	usage();
+      if (keymatch(argv[argn], "90", 2))
+	select_transform(JXFORM_ROT_90);
+      else if (keymatch(argv[argn], "180", 3))
+	select_transform(JXFORM_ROT_180);
+      else if (keymatch(argv[argn], "270", 3))
+	select_transform(JXFORM_ROT_270);
+      else
+	usage();
+
+    } else if (keymatch(arg, "scans", 1)) {
       /* Set scan script. */
 #ifdef C_MULTISCAN_FILES_SUPPORTED
       if (++argn >= argc)	/* advance to next argument */
@@ -201,6 +289,18 @@
       exit(EXIT_FAILURE);
 #endif
 
+    } else if (keymatch(arg, "transpose", 1)) {
+      /* Transpose (across UL-to-LR axis). */
+      select_transform(JXFORM_TRANSPOSE);
+
+    } else if (keymatch(arg, "transverse", 6)) {
+      /* Transverse transpose (across UR-to-LL axis). */
+      select_transform(JXFORM_TRANSVERSE);
+
+    } else if (keymatch(arg, "trim", 3)) {
+      /* Trim off any partial edge MCUs that the transform can't handle. */
+      transformoption.trim = TRUE;
+
     } else {
       usage();			/* bogus switch */
     }
@@ -239,7 +339,8 @@
 #ifdef PROGRESS_REPORT
   struct cdjpeg_progress_mgr progress;
 #endif
-  jvirt_barray_ptr * coef_arrays;
+  jvirt_barray_ptr * src_coef_arrays;
+  jvirt_barray_ptr * dst_coef_arrays;
   int file_index;
   FILE * input_file;
   FILE * output_file;
@@ -269,8 +370,10 @@
 
   /* Scan command line to find file names.
    * It is convenient to use just one switch-parsing routine, but the switch
-   * values read here are ignored; we will rescan the switches after opening
-   * the input file.
+   * values read here are mostly ignored; we will rescan the switches after
+   * opening the input file.  Also note that most of the switches affect the
+   * destination JPEG object, so we parse into that and then copy over what
+   * needs to affects the source too.
    */
 
   file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
@@ -330,25 +433,54 @@
   /* Specify data source for decompression */
   jpeg_stdio_src(&srcinfo, input_file);
 
+  /* Enable saving of extra markers that we want to copy */
+  jcopy_markers_setup(&srcinfo, copyoption);
+
   /* Read file header */
   (void) jpeg_read_header(&srcinfo, TRUE);
 
+  /* Any space needed by a transform option must be requested before
+   * jpeg_read_coefficients so that memory allocation will be done right.
+   */
+#if TRANSFORMS_SUPPORTED
+  jtransform_request_workspace(&srcinfo, &transformoption);
+#endif
+
   /* Read source file as DCT coefficients */
-  coef_arrays = jpeg_read_coefficients(&srcinfo);
+  src_coef_arrays = jpeg_read_coefficients(&srcinfo);
 
   /* Initialize destination compression parameters from source values */
   jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
 
+  /* Adjust destination parameters if required by transform options;
+   * also find out which set of coefficient arrays will hold the output.
+   */
+#if TRANSFORMS_SUPPORTED
+  dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
+						 src_coef_arrays,
+						 &transformoption);
+#else
+  dst_coef_arrays = src_coef_arrays;
+#endif
+
   /* Adjust default compression parameters by re-parsing the options */
   file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
 
   /* Specify data destination for compression */
   jpeg_stdio_dest(&dstinfo, output_file);
 
-  /* Start compressor */
-  jpeg_write_coefficients(&dstinfo, coef_arrays);
+  /* Start compressor (note no image data is actually written here) */
+  jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
 
-  /* ought to copy source comments here... */
+  /* Copy to the output file any extra markers that we want to preserve */
+  jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
+
+  /* Execute image transformation, if any */
+#if TRANSFORMS_SUPPORTED
+  jtransform_execute_transformation(&srcinfo, &dstinfo,
+				    src_coef_arrays,
+				    &transformoption);
+#endif
 
   /* Finish compression and release memory */
   jpeg_finish_compress(&dstinfo);
diff --git a/jversion.h b/jversion.h
index b903be7..6472c58 100644
--- a/jversion.h
+++ b/jversion.h
@@ -1,7 +1,7 @@
 /*
  * jversion.h
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1998, 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.
  *
@@ -9,6 +9,6 @@
  */
 
 
-#define JVERSION	"6a  7-Feb-96"
+#define JVERSION	"6b  27-Mar-1998"
 
-#define JCOPYRIGHT	"Copyright (C) 1996, Thomas G. Lane"
+#define JCOPYRIGHT	"Copyright (C) 1998, Thomas G. Lane"
diff --git a/libjpeg.doc b/libjpeg.doc
index b3333a8..689b206 100644
--- a/libjpeg.doc
+++ b/libjpeg.doc
@@ -1,6 +1,6 @@
 USING THE IJG JPEG LIBRARY
 
-Copyright (C) 1994-1996, Thomas G. Lane.
+Copyright (C) 1994-1998, 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.
 
@@ -47,6 +47,7 @@
 	Really raw data: DCT coefficients
 	Progress monitoring
 	Memory management
+	Memory usage
 	Library compile-time options
 	Portability considerations
 	Notes for MS-DOS implementors
@@ -437,7 +438,7 @@
 	jpeg_finish_compress(&cinfo);
 
 If using the stdio destination manager, don't forget to close the output
-stdio stream if necessary.
+stdio stream (if necessary) afterwards.
 
 If you have requested a multi-pass operating mode, such as Huffman code
 optimization, jpeg_finish_compress() will perform the additional passes using
@@ -463,12 +464,13 @@
 7. Release the JPEG compression object.
 
 When you are done with a JPEG compression object, destroy it by calling
-jpeg_destroy_compress().  This will free all subsidiary memory.  Or you can
-call jpeg_destroy() which works for either compression or decompression
-objects --- this may be more convenient if you are sharing code between
-compression and decompression cases.  (Actually, these routines are equivalent
-except for the declared type of the passed pointer.  To avoid gripes from
-ANSI C compilers, jpeg_destroy() should be passed a j_common_ptr.)
+jpeg_destroy_compress().  This will free all subsidiary memory (regardless of
+the previous state of the object).  Or you can call jpeg_destroy(), which
+works for either compression or decompression objects --- this may be more
+convenient if you are sharing code between compression and decompression
+cases.  (Actually, these routines are equivalent except for the declared type
+of the passed pointer.  To avoid gripes from ANSI C compilers, jpeg_destroy()
+should be passed a j_common_ptr.)
 
 If you allocated the jpeg_compress_struct structure from malloc(), freeing
 it is your responsibility --- jpeg_destroy() won't.  Ditto for the error
@@ -489,13 +491,19 @@
   legitimate at any point after calling jpeg_create_compress() --- in fact,
   it's safe even if jpeg_create_compress() fails.
 
-* If you want to re-use the JPEG object, call jpeg_abort_compress(), or
+* If you want to re-use the JPEG object, call jpeg_abort_compress(), or call
   jpeg_abort() which works on both compression and decompression objects.
   This will return the object to an idle state, releasing any working memory.
   jpeg_abort() is allowed at any time after successful object creation.
 
 Note that cleaning up the data destination, if required, is your
-responsibility.
+responsibility; neither of these routines will call term_destination().
+(See "Compressed data handling", below, for more about that.)
+
+jpeg_destroy() and jpeg_abort() are the only safe calls to make on a JPEG
+object that has reported an error by calling error_exit (see "Error handling"
+for more info).  The internal state of such an object is likely to be out of
+whack.  Either of these two routines will return the object to a known state.
 
 
 Decompression details
@@ -673,10 +681,10 @@
 bottom of the image has been reached.
 
 If you use a buffer larger than one scanline, it is NOT safe to assume that
-jpeg_read_scanlines() fills it.  (The current implementation won't return
-more than cinfo.rec_outbuf_height scanlines per call, no matter how large
-a buffer you pass.)  So you must always provide a loop that calls
-jpeg_read_scanlines() repeatedly until the whole image has been read.
+jpeg_read_scanlines() fills it.  (The current implementation returns only a
+few scanlines per call, no matter how large a buffer you pass.)  So you must
+always provide a loop that calls jpeg_read_scanlines() repeatedly until the
+whole image has been read.
 
 
 7. jpeg_finish_decompress(...);
@@ -693,7 +701,7 @@
 stream if necessary.
 
 It is an error to call jpeg_finish_decompress() before reading the correct
-total number of scanlines.  If you wish to abort compression, call
+total number of scanlines.  If you wish to abort decompression, call
 jpeg_abort() as discussed below.
 
 After completing a decompression cycle, you may dispose of the JPEG object as
@@ -744,6 +752,17 @@
 included from the library, unless your linker is hopelessly brain-damaged.
 The supplied makefiles build libjpeg.a automatically (see install.doc).
 
+While you can build the JPEG library as a shared library if the whim strikes
+you, we don't really recommend it.  The trouble with shared libraries is that
+at some point you'll probably try to substitute a new version of the library
+without recompiling the calling applications.  That generally doesn't work
+because the parameter struct declarations usually change with each new
+version.  In other words, the library's API is *not* guaranteed binary
+compatible across versions; we only try to ensure source-code compatibility.
+(In hindsight, it might have been smarter to hide the parameter structs from
+applications and introduce a ton of access functions instead.  Too late now,
+however.)
+
 On some systems your application may need to set up a signal handler to ensure
 that temporary files are deleted if the program is interrupted.  This is most
 critical if you are on MS-DOS and use the jmemdos.c memory manager back end;
@@ -893,6 +912,11 @@
 	Set restart_in_rows to specify the interval in MCU rows.  (If
 	restart_in_rows is not 0, then restart_interval is set after the
 	image width in MCUs is computed.)  Defaults are zero (no restarts).
+	One restart marker per MCU row is often a good choice.
+	NOTE: the overhead of restart markers is higher in grayscale JPEG
+	files than in color files, and MUCH higher in progressive JPEGs.
+	If you use restarts, you may want to use larger intervals in those
+	cases.
 
 const jpeg_scan_info * scan_info
 int num_scans
@@ -916,6 +940,13 @@
 	jpeg_set_colorspace() set this TRUE if a JFIF-legal JPEG color space
 	(ie, YCbCr or grayscale) is selected, otherwise FALSE.
 
+UINT8 JFIF_major_version
+UINT8 JFIF_minor_version
+	The version number to be written into the JFIF marker.
+	jpeg_set_defaults() initializes the version to 1.01 (major=minor=1).
+	You should set it to 1.02 (major=1, minor=2) if you plan to write
+	any JFIF 1.02 extension markers.
+
 UINT8 density_unit
 UINT16 X_density
 UINT16 Y_density
@@ -1013,6 +1044,8 @@
 int num_components			Number of color components
 J_COLOR_SPACE jpeg_color_space		Colorspace of image
 boolean saw_JFIF_marker			TRUE if a JFIF APP0 marker was seen
+  UINT8 JFIF_major_version		Version information from JFIF marker
+  UINT8 JFIF_minor_version
   UINT8 density_unit			Resolution data from JFIF marker
   UINT16 X_density
   UINT16 Y_density
@@ -1144,6 +1177,8 @@
 faster, lower-quality modes set it to larger values (typically 2 to 4).
 If you are going to ask for a high-speed processing mode, you may as well
 go to the trouble of honoring rec_outbuf_height so as to avoid data copying.
+(An output buffer larger than rec_outbuf_height lines is OK, but won't
+provide any material speed improvement over that height.)
 
 
 Special color spaces
@@ -1204,8 +1239,11 @@
 transformation.  jdcolor.c currently supports
 	YCbCr => GRAYSCALE
 	YCbCr => RGB
+	GRAYSCALE => RGB
 	YCCK => CMYK
-as well as the null transforms.
+as well as the null transforms.  (Since GRAYSCALE=>RGB is provided, an
+application can force grayscale JPEGs to look like color JPEGs if it only
+wants to handle one case.)
 
 The two-pass color quantizer, jquant2.c, is specialized to handle RGB data
 (it weights distances appropriately for RGB colors).  You'll need to modify
@@ -1264,7 +1302,10 @@
 handler.  The most convenient way to do this is to embed either the JPEG
 object or the jpeg_error_mgr struct in a larger structure that contains
 additional fields; then casting the passed pointer provides access to the
-additional fields.  Again, see example.c for one way to do it.
+additional fields.  Again, see example.c for one way to do it.  (Beginning
+with IJG version 6b, there is also a void pointer "client_data" in each
+JPEG object, which the application can also use to find related data.
+The library does not touch client_data at all.)
 
 The individual methods that you might wish to override are:
 
@@ -1603,19 +1644,27 @@
 pointer/count to point to a dummy EOI marker and then return TRUE just as
 though it had read more data in a non-suspending situation.
 
-The decompressor does not attempt to suspend within any JPEG marker; it will
-backtrack to the start of the marker.  Hence the input buffer must be large
-enough to hold the longest marker in the file.  We recommend at least a 2K
-buffer.  The buffer would need to be 64K to allow for arbitrary COM or APPn
-markers, but the decompressor does not actually try to read these; it just
-skips them by calling skip_input_data().  If you provide a special marker
-handling routine that does look at such markers, coping with buffer overflow
-is your problem.  Ordinary JPEG markers should normally not exceed a few
-hundred bytes each (DHT tables are typically the longest).  For robustness
-against damaged marker length counts, you may wish to insert a test in your
-application for the case that the input buffer is completely full and yet the
-decoder has suspended without consuming any data --- otherwise, if this
-situation did occur, it would lead to an endless loop.
+The decompressor does not attempt to suspend within standard JPEG markers;
+instead it will backtrack to the start of the marker and reprocess the whole
+marker next time.  Hence the input buffer must be large enough to hold the
+longest standard marker in the file.  Standard JPEG markers should normally
+not exceed a few hundred bytes each (DHT tables are typically the longest).
+We recommend at least a 2K buffer for performance reasons, which is much
+larger than any correct marker is likely to be.  For robustness against
+damaged marker length counts, you may wish to insert a test in your
+application for the case that the input buffer is completely full and yet
+the decoder has suspended without consuming any data --- otherwise, if this
+situation did occur, it would lead to an endless loop.  (The library can't
+provide this test since it has no idea whether "the buffer is full", or
+even whether there is a fixed-size input buffer.)
+
+The input buffer would need to be 64K to allow for arbitrary COM or APPn
+markers, but these are handled specially: they are either saved into allocated
+memory, or skipped over by calling skip_input_data().  In the former case,
+suspension is handled correctly, and in the latter case, the problem of
+buffer overrun is placed on skip_input_data's shoulders, as explained above.
+Note that if you provide your own marker handling routine for large markers,
+you should consider how to deal with buffer overflow.
 
 Multiple-buffer management:
 
@@ -2186,11 +2235,42 @@
 To read abbreviated image files, you simply need to load the proper tables
 into the decompression object before trying to read the abbreviated image.
 If the proper tables are stored in the application program, you can just
-allocate the table structs and fill in their contents directly.  More commonly
-you'd want to read the tables from a tables-only file.  The jpeg_read_header()
-call is sufficient to read a tables-only file.  You must pass a second
-parameter of FALSE to indicate that you do not require an image to be present.
-Thus, the typical scenario is
+allocate the table structs and fill in their contents directly.  For example,
+to load a fixed quantization table into table slot "n":
+
+    if (cinfo.quant_tbl_ptrs[n] == NULL)
+      cinfo.quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) &cinfo);
+    quant_ptr = cinfo.quant_tbl_ptrs[n];	/* quant_ptr is JQUANT_TBL* */
+    for (i = 0; i < 64; i++) {
+      /* Qtable[] is desired quantization table, in natural array order */
+      quant_ptr->quantval[i] = Qtable[i];
+    }
+
+Code to load a fixed Huffman table is typically (for AC table "n"):
+
+    if (cinfo.ac_huff_tbl_ptrs[n] == NULL)
+      cinfo.ac_huff_tbl_ptrs[n] = jpeg_alloc_huff_table((j_common_ptr) &cinfo);
+    huff_ptr = cinfo.ac_huff_tbl_ptrs[n];	/* huff_ptr is JHUFF_TBL* */
+    for (i = 1; i <= 16; i++) {
+      /* counts[i] is number of Huffman codes of length i bits, i=1..16 */
+      huff_ptr->bits[i] = counts[i];
+    }
+    for (i = 0; i < 256; i++) {
+      /* symbols[] is the list of Huffman symbols, in code-length order */
+      huff_ptr->huffval[i] = symbols[i];
+    }
+
+(Note that trying to set cinfo.quant_tbl_ptrs[n] to point directly at a
+constant JQUANT_TBL object is not safe.  If the incoming file happened to
+contain a quantization table definition, your master table would get
+overwritten!  Instead allocate a working table copy and copy the master table
+into it, as illustrated above.  Ditto for Huffman tables, of course.)
+
+You might want to read the tables from a tables-only file, rather than
+hard-wiring them into your application.  The jpeg_read_header() call is
+sufficient to read a tables-only file.  You must pass a second parameter of
+FALSE to indicate that you do not require an image to be present.  Thus, the
+typical scenario is
 
 	create JPEG decompression object
 	set source to tables-only file
@@ -2264,6 +2344,7 @@
 we don't recommend it.  The decompression library will recognize JFIF and
 Adobe markers and will set the JPEG colorspace properly when one is found.
 
+
 You can write special markers immediately following the datastream header by
 calling jpeg_write_marker() after jpeg_start_compress() and before the first
 call to jpeg_write_scanlines().  When you do this, the markers appear after
@@ -2273,18 +2354,96 @@
 any marker type, but we don't recommend writing any other kinds of marker.)
 For example, to write a user comment string pointed to by comment_text:
 	jpeg_write_marker(cinfo, JPEG_COM, comment_text, strlen(comment_text));
-Or if you prefer to synthesize the marker byte sequence yourself, you can
-just cram it straight into the data destination module.
 
-For decompression, you can supply your own routine to process COM or APPn
-markers by calling jpeg_set_marker_processor().  Usually you'd call this
-after creating a decompression object and before calling jpeg_read_header(),
-because the markers of interest will normally be scanned by jpeg_read_header.
-Once you've supplied a routine, it will be used for the life of that
-decompression object.  A separate routine may be registered for COM and for
-each APPn marker code.
+If it's not convenient to store all the marker data in memory at once,
+you can instead call jpeg_write_m_header() followed by multiple calls to
+jpeg_write_m_byte().  If you do it this way, it's your responsibility to
+call jpeg_write_m_byte() exactly the number of times given in the length
+parameter to jpeg_write_m_header().  (This method lets you empty the
+output buffer partway through a marker, which might be important when
+using a suspending data destination module.  In any case, if you are using
+a suspending destination, you should flush its buffer after inserting
+any special markers.  See "I/O suspension".)
 
-A marker processor routine must have the signature
+Or, if you prefer to synthesize the marker byte sequence yourself,
+you can just cram it straight into the data destination module.
+
+If you are writing JFIF 1.02 extension markers (thumbnail images), don't
+forget to set cinfo.JFIF_minor_version = 2 so that the encoder will write the
+correct JFIF version number in the JFIF header marker.  The library's default
+is to write version 1.01, but that's wrong if you insert any 1.02 extension
+markers.  (We could probably get away with just defaulting to 1.02, but there
+used to be broken decoders that would complain about unknown minor version
+numbers.  To reduce compatibility risks it's safest not to write 1.02 unless
+you are actually using 1.02 extensions.)
+
+
+When reading, two methods of handling special markers are available:
+1. You can ask the library to save the contents of COM and/or APPn markers
+into memory, and then examine them at your leisure afterwards.
+2. You can supply your own routine to process COM and/or APPn markers
+on-the-fly as they are read.
+The first method is simpler to use, especially if you are using a suspending
+data source; writing a marker processor that copes with input suspension is
+not easy (consider what happens if the marker is longer than your available
+input buffer).  However, the second method conserves memory since the marker
+data need not be kept around after it's been processed.
+
+For either method, you'd normally set up marker handling after creating a
+decompression object and before calling jpeg_read_header(), because the
+markers of interest will typically be near the head of the file and so will
+be scanned by jpeg_read_header.  Once you've established a marker handling
+method, it will be used for the life of that decompression object
+(potentially many datastreams), unless you change it.  Marker handling is
+determined separately for COM markers and for each APPn marker code.
+
+
+To save the contents of special markers in memory, call
+	jpeg_save_markers(cinfo, marker_code, length_limit)
+where marker_code is the marker type to save, JPEG_COM or JPEG_APP0+n.
+(To arrange to save all the special marker types, you need to call this
+routine 17 times, for COM and APP0-APP15.)  If the incoming marker is longer
+than length_limit data bytes, only length_limit bytes will be saved; this
+parameter allows you to avoid chewing up memory when you only need to see the
+first few bytes of a potentially large marker.  If you want to save all the
+data, set length_limit to 0xFFFF; that is enough since marker lengths are only
+16 bits.  As a special case, setting length_limit to 0 prevents that marker
+type from being saved at all.  (That is the default behavior, in fact.)
+
+After jpeg_read_header() completes, you can examine the special markers by
+following the cinfo->marker_list pointer chain.  All the special markers in
+the file appear in this list, in order of their occurrence in the file (but
+omitting any markers of types you didn't ask for).  Both the original data
+length and the saved data length are recorded for each list entry; the latter
+will not exceed length_limit for the particular marker type.  Note that these
+lengths exclude the marker length word, whereas the stored representation
+within the JPEG file includes it.  (Hence the maximum data length is really
+only 65533.)
+
+It is possible that additional special markers appear in the file beyond the
+SOS marker at which jpeg_read_header stops; if so, the marker list will be
+extended during reading of the rest of the file.  This is not expected to be
+common, however.  If you are short on memory you may want to reset the length
+limit to zero for all marker types after finishing jpeg_read_header, to
+ensure that the max_memory_to_use setting cannot be exceeded due to addition
+of later markers.
+
+The marker list remains stored until you call jpeg_finish_decompress or
+jpeg_abort, at which point the memory is freed and the list is set to empty.
+(jpeg_destroy also releases the storage, of course.)
+
+Note that the library is internally interested in APP0 and APP14 markers;
+if you try to set a small nonzero length limit on these types, the library
+will silently force the length up to the minimum it wants.  (But you can set
+a zero length limit to prevent them from being saved at all.)  Also, in a
+16-bit environment, the maximum length limit may be constrained to less than
+65533 by malloc() limitations.  It is therefore best not to assume that the
+effective length limit is exactly what you set it to be.
+
+
+If you want to supply your own marker-reading routine, you do it by calling
+jpeg_set_marker_processor().  A marker processor routine must have the
+signature
 	boolean jpeg_marker_parser_method (j_decompress_ptr cinfo)
 Although the marker code is not explicitly passed, the routine can find it
 in cinfo->unread_marker.  At the time of call, the marker proper has been
@@ -2298,9 +2457,16 @@
 If you override the default APP0 or APP14 processors, it is up to you to
 recognize JFIF and Adobe markers if you want colorspace recognition to occur
 properly.  We recommend copying and extending the default processors if you
-want to do that.
+want to do that.  (A better idea is to save these marker types for later
+examination by calling jpeg_save_markers(); that method doesn't interfere
+with the library's own processing of these markers.)
+
+jpeg_set_marker_processor() and jpeg_save_markers() are mutually exclusive
+--- if you call one it overrides any previous call to the other, for the
+particular marker type specified.
 
 A simple example of an external COM processor can be found in djpeg.c.
+Also, see jpegtran.c for an example of using jpeg_save_markers.
 
 
 Raw (downsampled) image data
@@ -2446,6 +2612,15 @@
 for simple transcoding to a different JPEG file format, the array list can
 just be handed directly to jpeg_write_coefficients().
 
+Each block in the block arrays contains quantized coefficient values in
+normal array order (not JPEG zigzag order).  The block arrays contain only
+DCT blocks containing real data; any entirely-dummy blocks added to fill out
+interleaved MCUs at the right or bottom edges of the image are discarded
+during reading and are not stored in the block arrays.  (The size of each
+block array can be determined from the width_in_blocks and height_in_blocks
+fields of the component's comp_info entry.)  This is also the data format
+expected by jpeg_write_coefficients().
+
 When you are done using the virtual arrays, call jpeg_finish_decompress()
 to release the array storage and return the decompression object to an idle
 state; or just call jpeg_destroy() if you don't need to reuse the object.
@@ -2455,14 +2630,14 @@
 completion.  You need not test for a NULL return value when using a
 non-suspending data source.
 
-Each block in the block arrays contains quantized coefficient values in
-normal array order (not JPEG zigzag order).  The block arrays contain only
-DCT blocks containing real data; any entirely-dummy blocks added to fill out
-interleaved MCUs at the right or bottom edges of the image are discarded
-during reading and are not stored in the block arrays.  (The size of each
-block array can be determined from the width_in_blocks and height_in_blocks
-fields of the component's comp_info entry.)  This is also the data format
-expected by jpeg_write_coefficients().
+It is also possible to call jpeg_read_coefficients() to obtain access to the
+decoder's coefficient arrays during a normal decode cycle in buffered-image
+mode.  This frammish might be useful for progressively displaying an incoming
+image and then re-encoding it without loss.  To do this, decode in buffered-
+image mode as discussed previously, then call jpeg_read_coefficients() after
+the last jpeg_finish_output() call.  The arrays will be available for your use
+until you call jpeg_finish_decompress().
+
 
 To write the contents of a JPEG file as DCT coefficients, you must provide
 the DCT coefficients stored in virtual block arrays.  You can either pass
@@ -2635,13 +2810,59 @@
 tmpfile().
 
 
+Memory usage
+------------
+
+Working memory requirements while performing compression or decompression
+depend on image dimensions, image characteristics (such as colorspace and
+JPEG process), and operating mode (application-selected options).
+
+As of v6b, the decompressor requires:
+ 1. About 24K in more-or-less-fixed-size data.  This varies a bit depending
+    on operating mode and image characteristics (particularly color vs.
+    grayscale), but it doesn't depend on image dimensions.
+ 2. Strip buffers (of size proportional to the image width) for IDCT and
+    upsampling results.  The worst case for commonly used sampling factors
+    is about 34 bytes * width in pixels for a color image.  A grayscale image
+    only needs about 8 bytes per pixel column.
+ 3. A full-image DCT coefficient buffer is needed to decode a multi-scan JPEG
+    file (including progressive JPEGs), or whenever you select buffered-image
+    mode.  This takes 2 bytes/coefficient.  At typical 2x2 sampling, that's
+    3 bytes per pixel for a color image.  Worst case (1x1 sampling) requires
+    6 bytes/pixel.  For grayscale, figure 2 bytes/pixel.
+ 4. To perform 2-pass color quantization, the decompressor also needs a
+    128K color lookup table and a full-image pixel buffer (3 bytes/pixel).
+This does not count any memory allocated by the application, such as a
+buffer to hold the final output image.
+
+The above figures are valid for 8-bit JPEG data precision and a machine with
+32-bit ints.  For 12-bit JPEG data, double the size of the strip buffers and
+quantization pixel buffer.  The "fixed-size" data will be somewhat smaller
+with 16-bit ints, larger with 64-bit ints.  Also, CMYK or other unusual
+color spaces will require different amounts of space.
+
+The full-image coefficient and pixel buffers, if needed at all, do not
+have to be fully RAM resident; you can have the library use temporary
+files instead when the total memory usage would exceed a limit you set.
+(But if your OS supports virtual memory, it's probably better to just use
+jmemnobs and let the OS do the swapping.)
+
+The compressor's memory requirements are similar, except that it has no need
+for color quantization.  Also, it needs a full-image DCT coefficient buffer
+if Huffman-table optimization is asked for, even if progressive mode is not
+requested.
+
+If you need more detailed information about memory usage in a particular
+situation, you can enable the MEM_STATS code in jmemmgr.c.
+
+
 Library compile-time options
 ----------------------------
 
 A number of compile-time options are available by modifying jmorecfg.h.
 
 The JPEG standard provides for both the baseline 8-bit DCT process and
-a 12-bit DCT process.  12-bit lossy JPEG is supported if you define
+a 12-bit DCT process.  The IJG code supports 12-bit lossy JPEG if you define
 BITS_IN_JSAMPLE as 12 rather than 8.  Note that this causes JSAMPLE to be
 larger than a char, so it affects the surrounding application's image data.
 The sample applications cjpeg and djpeg can support 12-bit mode only for PPM
@@ -2658,6 +2879,9 @@
 in order to generate valid Huffman tables.  This is necessary because our
 default Huffman tables only cover 8-bit data.  If you need to output 12-bit
 files in one pass, you'll have to supply suitable default Huffman tables.
+You may also want to supply your own DCT quantization tables; the existing
+quality-scaling code has been developed for 8-bit use, and probably doesn't
+generate especially good tables for 12-bit.
 
 The maximum number of components (color channels) in the image is determined
 by MAX_COMPONENTS.  The JPEG standard allows up to 255 components, but we
@@ -2674,6 +2898,16 @@
 You can reduce the size of the library by compiling out various optional
 functions.  To do this, undefine xxx_SUPPORTED symbols as necessary.
 
+You can also save a few K by not having text error messages in the library;
+the standard error message table occupies about 5Kb.  This is particularly
+reasonable for embedded applications where there's no good way to display 
+a message anyway.  To do this, remove the creation of the message table
+(jpeg_std_message_table[]) from jerror.c, and alter format_message to do
+something reasonable without it.  You could output the numeric value of the
+message code number, for example.  If you do this, you can also save a couple
+more K by modifying the TRACEMSn() macros in jerror.h to expand to nothing;
+you don't need trace capability anyway, right?
+
 
 Portability considerations
 --------------------------
@@ -2684,9 +2918,9 @@
 library to be less portable than is claimed here, we'd appreciate hearing
 about them.)
 
-The code works fine on both ANSI and pre-ANSI C compilers, using any of the
-popular system include file setups, and some not-so-popular ones too.  See
-install.doc for configuration procedures.
+The code works fine on ANSI C, C++, and pre-ANSI C compilers, using any of
+the popular system include file setups, and some not-so-popular ones too.
+See install.doc for configuration procedures.
 
 The code is not dependent on the exact sizes of the C data types.  As
 distributed, we make the assumptions that
@@ -2763,7 +2997,7 @@
 images.  The most memory-intensive case is decompression with two-pass color
 quantization, or single-pass quantization to an externally supplied color
 map.  This requires a 128Kb color lookup table plus strip buffers amounting
-to about 50 bytes per column for typical sampling ratios (eg, about 32000
+to about 40 bytes per column for typical sampling ratios (eg, about 25600
 bytes for a 640-pixel-wide image).  You may not be able to process wide
 images if you have large data structures of your own.
 
diff --git a/ltconfig b/ltconfig
new file mode 100755
index 0000000..2347e69
--- /dev/null
+++ b/ltconfig
@@ -0,0 +1,1512 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+echo=echo
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then :
+else
+  # The Solaris and AIX default echo program unquotes backslashes.
+  # This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  # So, we emulate echo with printf '%s\n'
+  echo="printf %s\\n"
+  if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then :
+  else
+    # Oops.  We have no working printf.  Try to find a not-so-buggy echo.
+    echo=echo
+    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}:"
+    for dir in $PATH /usr/ucb; do
+      if test -f $dir/echo && test "X`$dir/echo '\t'`" = 'X\t'; then
+        echo="$dir/echo"
+        break
+      fi
+    done
+    IFS="$save_ifs"
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.2
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking.
+enable_static=yes
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... LTMAIN [HOST]
+
+Generate a system-specific libtool script.
+
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+
+LTMAIN is the \`ltmain.sh' shell script fragment that provides basic libtool
+functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test -f "$ltmain"; then :
+else
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to ltmain.sh.
+  srcdir=`$echo "$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "${COLLECT_NAMES+set}" != set; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}:"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds;\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib;$old_postinstall_cmds"
+fi
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}:"
+    for dir in $PATH; do
+      IFS="$save_ifs"
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc; then
+	CC="gcc"
+	break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS="${IFS}:"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc; then
+	if test "$dir/cc" = "/usr/ucb/cc"; then
+	  cc_rejected=yes
+	  continue
+	fi
+	CC="cc"
+	break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+	# We chose a different compiler from the bogus one.
+	# However, it has the same name, so the bogon will be chosen
+	# first if we set CC to just the name; use the full file name.
+	shift
+	set dummy "$dir/cc" "$@"
+	shift
+	CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:424: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:432: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+  no_builtin_flag=' -fno-builtin'
+
+  case "$host_os" in
+  aix3* | aix4* | irix5* | irix6* | osf3* | osf4*)
+    # PIC is the default for these OSes.
+    ;;
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris2*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4.2uw2*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:547: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:548: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+    # create non-PIC objects.  So, if there were any warnings, we assume that
+    # PIC is not supported.
+    if test -s conftest.err; then
+      echo "$ac_t"no 1>&6
+      can_build_shared=no
+      pic_flag=
+    else
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+    fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[ 	]$special_shlib_compile_flags[ 	]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:591: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftestdata
+  if ln -s X conftestdata 2>/dev/null; then
+    $rm conftestdata
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:624: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    /* | [A-Za-z]:\\*)
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:642: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:645: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog"; then
+	LD="$ac_dir/$ac_prog"
+	# Check to see if the program is GNU ld.  I'd rather use --version,
+	# but apparently some GNU ld's only accept -v.
+	# Break only if it was the GNU/non-GNU ld that we prefer.
+	if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+	  test "$with_gnu_ld" != no && break
+	else
+	  test "$with_gnu_ld" != yes && break
+	fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+archive_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+
+case "$host_os" in
+amigaos* | sunos4*)
+  # On these operating systems, we should treat GNU ld like the system ld.
+  gnu_ld_acts_native=yes
+  ;;
+*)
+  gnu_ld_acts_native=no
+  ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes && test "$gnu_ld_acts_native" != yes; then
+
+  # See if GNU ld supports shared libraries.
+  if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+    archive_cmds='$CC -shared ${wl}-soname $wl$soname -o $lib$libobjs'
+    runpath_var=LD_RUN_PATH
+    ld_shlibs=yes
+  else
+    ld_shlibs=no
+  fi
+
+  if test "$ld_shlibs" = yes; then
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$LD -o $objdir/$soname$libobjs -bE:$lib.exp -T512 -H512 -bM:SRE;$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$CC -o $objdir/$soname$libobjs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry;$AR cru $lib $objdir/$soname'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data;$echo "#define NAME $libname" > $objdir/a2ixlibrary.data;$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data;$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data;$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data;$AR cru $lib$libobjs;$RANLIB $lib;(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3, at last, uses gcc -shared to do shared libraries.
+  freebsd3*)
+    archive_cmds='$CC -shared -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9*)
+    archive_cmds='$rm $objdir/$soname;$LD -b +s +b $install_libdir -o $objdir/$soname$libobjs;mv $objdir/$soname $lib'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  hpux10*)
+    archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib$libobjs'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    archive_cmds='$LD -shared -o $lib -soname $soname -set_version $verstring$libobjs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    ;;
+
+  netbsd*)
+    # Tested with NetBSD 1.2 ld
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def;$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def;$echo DATA >> $objdir/$libname.def;$echo " SINGLE NONSHARED" >> $objdir/$libname.def;$echo EXPORTS >> $objdir/$libname.def;emxexp$libobjs >> $objdir/$libname.def;$CC -Zdll -Zcrtdll -o $lib$libobjs $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3* | osf4*)
+    allow_undefined_flag=' -expect_unresolved \*'
+    archive_cmds='$LD -shared${allow_undefined_flag} -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -o $lib$libobjs'
+    hardcode_direct=yes
+    ;;
+
+  solaris2*)
+    no_undefined_flag=' -z text'
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+
+    # Solaris 2 before 2.5 hardcodes -L paths.
+    case "$host_os" in
+    solaris2.[0-4]*)
+      hardcode_minus_L=yes
+      ;;
+    esac
+    ;;
+
+  sunos4*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared -o $lib$libobjs'
+    else
+      archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs'
+    fi
+
+    if test "$with_gnu_ld" = yes; then
+      export_dynamic_flag_spec='${wl}-export-dynamic'
+    fi
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=no
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    can_build_shared=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  /* | [A-Za-z]:\\*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm; then
+        # Check to see if the nm accepts a BSD-compat flag.
+        # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+        #   nm: unknown option "B" ignored
+        if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -B"
+        elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -p"
+	else
+          NM="$ac_dir/nm"
+	fi
+        break
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRSTU]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \1'
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDTU]'
+  ;;
+irix*)
+  # Cannot use undefined symbols on IRIX because inlined functions mess us up.
+  symcode='[BCDEGRST]'
+  ;;
+solaris2*)
+  symcode='[BDTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTUW]'
+fi
+
+# Write the raw and C identifiers.
+global_symbol_pipe="sed -n -e 's/^.* $symcode $sympat$/$symxfrm/p'"
+
+# Check to see that the pipe works correctly.
+pipe_works=no
+$rm conftest*
+cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+echo "$progname:971: checking if global_symbol_pipe works" >&5
+if { (eval echo $progname:972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then
+  # Now try to grab the symbols.
+  nlist=conftest.nm
+  if { echo "$progname:975: eval \"$NM conftest.o | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.o | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+    # Try sorting and uniquifying the output.
+    if sort "$nlist" | uniq > "$nlist"T; then
+      mv -f "$nlist"T "$nlist"
+      wcout=`wc "$nlist" 2>/dev/null`
+      count=`$echo "X$wcout" | $Xsed -e 's/^[ 	]*\([0-9][0-9]*\).*$/\1/'`
+      (test "$count" -ge 0) 2>/dev/null || count=-1
+    else
+      rm -f "$nlist"T
+      count=-1
+    fi
+
+    # Make sure that we snagged all the symbols we need.
+    if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+      if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+	cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+        # Now generate the symbol file.
+        sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c
+
+	cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+        sed 's/^\(.*\) \(.*\)$/  {"\1", (__ptr_t) \&\2},/' < "$nlist" >> conftest.c
+        cat <<\EOF >> conftest.c
+  {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+        # Now try linking the two files.
+        mv conftest.o conftestm.o
+	save_LIBS="$LIBS"
+	save_CFLAGS="$CFLAGS"
+        LIBS='conftestm.o'
+	CFLAGS="$CFLAGS$no_builtin_flag"
+        if { (eval echo $progname:1033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+          pipe_works=yes
+        else
+          echo "$progname: failed program was:" >&5
+          cat conftest.c >&5
+        fi
+        LIBS="$save_LIBS"
+      else
+        echo "cannot find nm_test_func in $nlist" >&5
+      fi
+    else
+      echo "cannot find nm_test_var in $nlist" >&5
+    fi
+  else
+    echo "cannot run $global_symbol_pipe" >&5
+  fi
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+
+# Do not use the global_symbol_pipe unless it works.
+echo "$ac_t$pipe_works" 1>&6
+test "$pipe_works" = yes || global_symbol_pipe=
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no && \
+     test "$hardcode_minus_L" != no && \
+     test "$hardcode_shlibpath_var" != no; then
+
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+elif test "$hardcode_direct" != yes && \
+     test "$hardcode_minus_L" != yes && \
+     test "$hardcode_shlibpath_var" != yes; then
+  # We cannot hardcode anything.
+  hardcode_action=unsupported
+else
+  # We can only hardcode existing directories.
+  hardcode_action=relink
+fi
+echo "$ac_t$hardcode_action" 1>&6
+test "$hardcode_action" = unsupported && can_build_shared=no
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linker may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag"
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+version_type=none
+dynamic_linker="$host_os ld.so"
+
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3* | aix4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so.$major'
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+freebsd2* | freebsd3*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+  finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+gnu*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  shlibpath_var=SHLIB_PATH
+  library_names_spec='${libname}${release}.sl.$versuffix ${libname}${release}.sl.$major $libname.sl'
+  soname_spec='${libname}${release}.sl.$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=osf
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd* | openbsd*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix'
+  finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4*)
+  version_type=osf
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris2*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix'
+  finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4.2uw2*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker"
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds;\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+
+# Now quote all the things that may contain metacharacters.
+for var in ltecho old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+  old_LN_S AR CC LD LN_S NM reload_flag reload_cmds wl pic_flag \
+  link_static_flag no_builtin_flag export_dynamic_flag_spec \
+  libname_spec library_names_spec soname_spec RANLIB \
+  old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+  old_postuninstall_cmds archive_cmds postinstall_cmds postuninstall_cmds \
+  allow_undefined_flag no_undefined_flag \
+  finish_cmds finish_eval global_symbol_pipe \
+  hardcode_libdir_flag_spec hardcode_libdir_separator; do
+
+  case "$var" in
+  reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+  old_postinstall_cmds | old_postuninstall_cmds | archive_cmds | \
+  postinstall_cmds | postuninstall_cmds | finish_cmds)
+    # Double-quote double-evaled strings.
+    eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\"\`"
+    ;;
+  *)
+    eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`"
+    ;;
+  esac
+done
+
+ofile=libtool
+trap "$rm $ofile; exit 1" 1 2 15
+echo creating $ofile
+$rm $ofile
+cat <<EOF > $ofile
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM - GNU $PACKAGE $VERSION
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This program was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC="$old_CC" CFLAGS="$old_CFLAGS" CPPFLAGS="$old_CPPFLAGS" \\
+# LD="$old_LD" NM="$old_NM" RANLIB="$old_RANLIB" LN_S="$old_LN_S" \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+# An echo program that does not interpret backslashes.
+echo="$ltecho"
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION="$VERSION"
+
+# Shell to use when invoking shell scripts.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Whether or not to build libtool libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build old-style libraries.
+build_old_libs=$enable_static
+
+# The host system.
+host_alias="$host_alias"
+host="$host"
+
+# The archiver.
+AR="$AR"
+
+# The default C compiler.
+CC="$CC"
+
+# The linker used to build libraries.
+LD="$LD"
+
+# Whether we need hard or soft links.
+LN_S="$LN_S"
+
+# A BSD-compatible nm program.
+NM="$NM"
+
+# The name of the directory that contains temporary libtool files.
+objdir="$objdir"
+
+# How to create reloadable object files.
+reload_flag="$reload_flag"
+reload_cmds="$reload_cmds"
+
+# How to pass a linker flag through the compiler.
+wl="$wl"
+
+# Additional compiler flags for building library objects.
+pic_flag="$pic_flag"
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="$link_static_flag"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag="$no_builtin_flag"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="$export_dynamic_flag_spec"
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec="$libname_spec"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="$library_names_spec"
+
+# The coded name of the library, if different from the real name.
+soname_spec="$soname_spec"
+
+# Commands used to build and install an old-style archive.
+RANLIB="$RANLIB"
+old_archive_cmds="$old_archive_cmds"
+old_postinstall_cmds="$old_postinstall_cmds"
+old_postuninstall_cmds="$old_postuninstall_cmds"
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds="$old_archive_from_new_cmds"
+
+# Commands used to build and install a shared archive.
+archive_cmds="$archive_cmds"
+postinstall_cmds="$postinstall_cmds"
+postuninstall_cmds="$postuninstall_cmds"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="$allow_undefined_flag"
+
+# Flag that forces no undefined symbols.
+no_undefined_flag="$no_undefined_flag"
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds="$finish_cmds"
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval="$finish_eval"
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="$global_symbol_pipe"
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+EOF
+
+case "$host_os" in
+aix3*)
+  cat <<\EOF >> $ofile
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+
+EOF
+  ;;
+esac
+
+# Append the ltmain.sh script.
+cat "$ltmain" >> $ofile || (rm -f $ofile; exit 1)
+
+chmod +x $ofile
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644
index 0000000..e9350b3
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,2453 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.2
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION"
+    exit 0
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+        case "$arg" in
+        -c)
+           mode=compile
+           break
+           ;;
+        esac
+      done
+      ;;
+    *db | *dbx)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+        if test -n "$nonopt"; then
+          $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+        else
+          $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+        fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    for arg
+    do
+      # Accept any command-line options.
+      case "$arg" in
+      -o)
+	$echo "$modename: you cannot specify the output filename with \`-o'" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+	base_compile="$lastarg"
+      else
+	base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    # Get the name of the library object.
+    libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+
+    # Recognize several different file suffixes.
+    xform='[cCFSfms]'
+    case "$libobj" in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e 's/\.lo$/.o/'` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$srcfile'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      $run $rm $obj $libobj
+      trap "$run $rm $obj $libobj; exit 1" 1 2 15
+    else
+      $run $rm $libobj
+      trap "$run $rm $libobj; exit 1" 1 2 15
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      $show "$base_compile$pic_flag -DPIC $srcfile"
+      if $run eval "$base_compile\$pic_flag -DPIC \$srcfile"; then :
+      else
+        test -n "$obj" && $run $rm $obj
+        exit 1
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag"; then
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj
+        exit $?
+      fi
+
+      # Just move the object, then go on to compile the next one
+      $show "$mv $obj $libobj"
+      $run $mv $obj $libobj || exit 1
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      # Suppress compiler output if we already did a PIC compilation.
+      $show "$base_compile $srcfile$suppress_output"
+      if $run eval "$base_compile \$srcfile$suppress_output"; then :
+      else
+        $run $rm $obj $libobj
+        exit 1
+      fi
+    fi
+
+    # Create an invalid libtool object if no PIC, so that we do not
+    # accidentally link it into a program.
+    if test "$build_libtool_libs" != yes; then
+      $show "echo timestamp > $libobj"
+      $run eval "echo timestamp > \$libobj" || exit $?
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    modename="$modename: link"
+    CC="$nonopt"
+    allow_undefined=yes
+    compile_command="$CC"
+    finalize_command="$CC"
+
+    compile_shlibpath=
+    finalize_shlibpath=
+    deplibs=
+    dlfiles=
+    dlprefiles=
+    export_dynamic=no
+    hardcode_libdirs=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    objs=
+    prev=
+    prevarg=
+    release=
+    rpath=
+    perm_rpath=
+    temp_rpath=
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+        if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+        fi
+        build_libtool_libs=no
+	build_old_libs=yes
+        break
+        ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    for arg
+    do
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+        case "$prev" in
+        output)
+          compile_command="$compile_command @OUTPUT@"
+          finalize_command="$finalize_command @OUTPUT@"
+          ;;
+        esac
+
+        case "$prev" in
+        dlfiles|dlprefiles)
+          case "$arg" in
+          *.la | *.lo) ;;  # We handle these cases below.
+          *)
+            dlprefiles="$dlprefiles $arg"
+            test "$prev" = dlfiles && dlfiles="$dlfiles $arg"
+            prev=
+            ;;
+          esac
+          ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+        rpath)
+          rpath="$rpath $arg"
+	  prev=
+	  continue
+	  ;;
+        *)
+          eval "$prev=\"\$arg\""
+          prev=
+          continue
+          ;;
+        esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+	if test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+        fi
+        continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -dlopen)
+        prev=dlfiles
+        continue
+        ;;
+
+      -dlpreopen)
+        prev=dlprefiles
+        continue
+        ;;
+
+      -export-dynamic)
+        if test "$export_dynamic" != yes; then
+          export_dynamic=yes
+	  if test -n "$export_dynamic_flag_spec"; then
+	    eval arg=\"$export_dynamic_flag_spec\"
+	  else
+	    arg=
+	  fi
+
+          # Add the symbol object into the linking commands.
+	  compile_command="$compile_command @SYMFILE@"
+	  finalize_command="$finalize_command @SYMFILE@"
+        fi
+        ;;
+
+      -L*)
+        dir=`$echo "X$arg" | $Xsed -e 's%^-L\(.*\)$%\1%'`
+        case "$dir" in
+        /* | [A-Za-z]:\\*)
+	  # Add the corresponding hardcode_libdir_flag, if it is not identical.
+          ;;
+        *)
+          $echo "$modename: \`-L$dir' cannot specify a relative directory" 1>&2
+          exit 1
+          ;;
+        esac
+        deplibs="$deplibs $arg"
+        ;;
+
+      -l*) deplibs="$deplibs $arg" ;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+        prev=rpath
+        continue
+        ;;
+
+      -static)
+	# If we have no pic_flag, then this is the same as -all-static.
+	if test -z "$pic_flag" && test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+        fi
+	continue
+	;;
+
+      -version-info)
+        prev=vinfo
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case "$arg" in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	  arg="\"$arg\""
+	  ;;
+	esac
+        ;;
+
+      *.o | *.a)
+        # A standard object.
+        objs="$objs $arg"
+        ;;
+
+      *.lo)
+        # A library object.
+	if test "$prev" = dlfiles; then
+	  dlfiles="$dlfiles $arg"
+	  if test "$build_libtool_libs" = yes; then
+	    prev=
+	    continue
+	  else
+	    # If libtool objects are unsupported, then we need to preload.
+	    prev=dlprefiles
+	  fi
+	fi
+
+	if test "$prev" = dlprefiles; then
+	  # Preload the old-style object.
+	  dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e 's/\.lo$/\.o/'`
+	  prev=
+	fi
+	libobjs="$libobjs $arg"
+        ;;
+
+      *.la)
+        # A libtool-controlled library.
+
+        dlname=
+        libdir=
+        library_names=
+        old_library=
+
+        # Check to see that this really is a libtool archive.
+        if (sed -e '2q' $arg | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+        else
+          $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+          exit 1
+        fi
+
+        # If there is no directory component, then add one.
+        case "$arg" in
+        */* | *\\*) . $arg ;;
+        *) . ./$arg ;;
+        esac
+
+        if test -z "$libdir"; then
+          $echo "$modename: \`$arg' contains no -rpath information" 1>&2
+          exit 1
+        fi
+
+        # Get the name of the library we link against.
+        linklib=
+        for l in $old_library $library_names; do
+          linklib="$l"
+        done
+
+        if test -z "$linklib"; then
+          $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+          exit 1
+        fi
+
+        # Find the relevant object directory and library name.
+        name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+        dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+        if test "X$dir" = "X$arg"; then
+          dir="$objdir"
+        else
+          dir="$dir/$objdir"
+        fi
+
+        # This library was specified with -dlopen.
+        if test "$prev" = dlfiles; then
+          dlfiles="$dlfiles $arg"
+          if test -z "$dlname"; then
+            # If there is no dlname, we need to preload.
+            prev=dlprefiles
+          else
+            # We should not create a dependency on this library, but we
+	    # may need any libraries it requires.
+	    compile_command="$compile_command$dependency_libs"
+	    finalize_command="$finalize_command$dependency_libs"
+            prev=
+            continue
+          fi
+        fi
+
+        # The library was specified with -dlpreopen.
+        if test "$prev" = dlprefiles; then
+          # Prefer using a static library (so that no silly _DYNAMIC symbols
+          # are required to link).
+          if test -n "$old_library"; then
+            dlprefiles="$dlprefiles $dir/$old_library"
+          else
+            dlprefiles="$dlprefiles $dir/$linklib"
+          fi
+          prev=
+        fi
+
+        if test "$build_libtool_libs" = yes && test -n "$library_names"; then
+          link_against_libtool_libs="$link_against_libtool_libs $arg"
+          if test -n "$shlibpath_var"; then
+            # Make sure the rpath contains only unique directories.
+            case "$temp_rpath " in
+            *" $dir "*) ;;
+            *) temp_rpath="$temp_rpath $dir" ;;
+            esac
+          fi
+
+	  # This is the magic to use -rpath.
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+		case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+		*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		  ;;
+		*)
+		  hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		  ;;
+		esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              eval flag=\"$hardcode_libdir_flag_spec\"
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test -n "$runpath_var"; then
+            # Do the same for the permanent run path.
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+
+
+          case "$hardcode_action" in
+          immediate)
+            if test "$hardcode_direct" = no; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = no; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = no; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          relink)
+            # We need an absolute path.
+            case "$dir" in
+            /* | [A-Za-z]:\\*) ;;
+            *)
+              absdir=`cd "$dir" && pwd`
+              if test -z "$absdir"; then
+                $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+                exit 1
+              fi
+              dir="$absdir"
+              ;;
+            esac
+
+            if test "$hardcode_direct" = yes; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = yes; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = yes; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          *)
+            $echo "$modename: \`$hardcode_action' is an unknown hardcode action" 1>&2
+            exit 1
+            ;;
+          esac
+
+          # Finalize command for both is simple: just hardcode it.
+          if test "$hardcode_direct" = yes; then
+            finalize_command="$finalize_command $libdir/$linklib"
+          elif test "$hardcode_minus_L" = yes; then
+            finalize_command="$finalize_command -L$libdir -l$name"
+          elif test "$hardcode_shlibpath_var" = yes; then
+            finalize_shlibpath="$finalize_shlibpath$libdir:"
+            finalize_command="$finalize_command -l$name"
+          else
+            # We cannot seem to hardcode it, guess we'll fake it.
+            finalize_command="$finalize_command -L$libdir -l$name"
+          fi
+        else
+          # Transform directly to old archives if we don't build new libraries.
+          if test -n "$pic_flag" && test -z "$old_library"; then
+            $echo "$modename: cannot find static library for \`$arg'" 1>&2
+            exit 1
+          fi
+
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_command="$compile_command $dir/$linklib"
+	    finalize_command="$finalize_command $dir/$linklib"
+	  else
+	    compile_command="$compile_command -L$dir -l$name"
+	    finalize_command="$finalize_command -L$dir -l$name"
+	  fi
+        fi
+
+	# Add in any libraries that this one depends upon.
+	compile_command="$compile_command$dependency_libs"
+	finalize_command="$finalize_command$dependency_libs"
+	continue
+        ;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case "$arg" in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	  arg="\"$arg\""
+	  ;;
+	esac
+        ;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$vinfo" && test -n "$release"; then
+      $echo "$modename: you cannot specify both \`-version-info' and \`-release'" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    oldlib=
+    oldobjs=
+    case "$output" in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    */* | *\\*)
+      $echo "$modename: output file \`$output' must have no directory components" 1>&2
+      exit 1
+      ;;
+
+    *.a)
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      build_old_libs=yes
+      oldlib="$output"
+      $show "$rm $oldlib"
+      $run $rm $oldlib
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$output" in
+      lib*) ;;
+      *)
+	$echo "$modename: libtool library \`$arg' must begin with \`lib'" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+	;;
+      esac
+
+      name=`$echo "X$output" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+      eval libname=\"$libname_spec\"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      current=0
+      revision=0
+      age=0
+
+      if test -n "$objs"; then
+        $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+        exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$modename: libtool library \`$output' may not depend on uninstalled libraries:$link_against_libtool_libs" 1>&2
+        exit 1
+      fi
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$modename: warning: \`-dlopen' is ignored while creating libtool libraries" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$rpath"; then
+        $echo "$modename: you must specify an installation directory with \`-rpath'" 1>&2
+	$echo "$help" 1>&2
+        exit 1
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      # Parse the version information argument.
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=':'
+      set dummy $vinfo
+      IFS="$save_ifs"
+
+      if test -n "$5"; then
+        $echo "$modename: too many parameters to \`-version-info'" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+
+      test -n "$2" && current="$2"
+      test -n "$3" && revision="$3"
+      test -n "$4" && age="$4"
+
+      # Check that each of the things are valid numbers.
+      case "$current" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$revision" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$age" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      if test $age -gt $current; then
+        $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+      fi
+
+      # Calculate the version variables.
+      version_vars="version_type current age revision"
+      case "$version_type" in
+      none) ;;
+
+      linux)
+        version_vars="$version_vars major versuffix"
+        major=`expr $current - $age`
+        versuffix="$major.$age.$revision"
+        ;;
+
+      osf)
+        version_vars="$version_vars versuffix verstring"
+        major=`expr $current - $age`
+        versuffix="$current.$age.$revision"
+        verstring="$versuffix"
+
+        # Add in all the interfaces that we are compatible with.
+        loop=$age
+        while test $loop != 0; do
+          iface=`expr $current - $loop`
+          loop=`expr $loop - 1`
+          verstring="$verstring:${iface}.0"
+        done
+
+        # Make executables depend on our current version.
+        verstring="$verstring:${current}.0"
+        ;;
+
+      sunos)
+        version_vars="$version_vars major versuffix"
+        major="$current"
+        versuffix="$current.$revision"
+        ;;
+
+      *)
+        $echo "$modename: unknown library version type \`$version_type'" 1>&2
+        echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+        exit 1
+        ;;
+      esac
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $objdir; then
+        $show "$rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*"
+        $run $rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir
+	status=$?
+	if test $status -eq 0 || test -d $objdir; then :
+	else
+	  exit $status
+	fi
+      fi
+
+      # Check to see if the archive will have undefined symbols.
+      if test "$allow_undefined" = yes; then
+        if test "$allow_undefined_flag" = unsupported; then
+          $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+          build_libtool_libs=no
+	  build_old_libs=yes
+        fi
+      else
+        # Don't allow undefined symbols.
+        allow_undefined_flag="$no_undefined_flag"
+      fi
+
+      # Add libc to deplibs on all systems.
+      dependency_libs="$deplibs"
+      deplibs="$deplibs -lc"
+
+      if test "$build_libtool_libs" = yes; then
+        # Get the real and link names of the library.
+        eval library_names=\"$library_names_spec\"
+        set dummy $library_names
+        realname="$2"
+        shift; shift
+
+        if test -n "$soname_spec"; then
+          eval soname=\"$soname_spec\"
+        else
+          soname="$realname"
+        fi
+
+        lib="$objdir/$realname"
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+        # Use standard objects if they are PIC.
+        test -z "$pic_flag" && libobjs=`$echo "X$libobjs " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+        # Do each of the archive commands.
+        eval cmds=\"$archive_cmds\"
+        IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+
+        # Create links to the real library.
+        for linkname in $linknames; do
+          $show "(cd $objdir && $LN_S $realname $linkname)"
+          $run eval '(cd $objdir && $LN_S $realname $linkname)' || exit $?
+        done
+
+        # If -export-dynamic was specified, set the dlname.
+        if test "$export_dynamic" = yes; then
+          # On all known operating systems, these are identical.
+          dlname="$soname"
+        fi
+      fi
+
+      # Now set the variables for building old libraries.
+      oldlib="$objdir/$libname.a"
+      ;;
+
+    *.lo | *.o)
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$modename: error: cannot link libtool libraries into reloadable objects" 1>&2
+        exit 1
+      fi
+
+      if test -n "$deplibs"; then
+        $echo "$modename: warning: \`-l' and \`-L' are ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$modename: warning: \`-dlopen' is ignored while creating objects" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -n "$rpath"; then
+        $echo "$modename: warning: \`-rpath' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+        $echo "$modename: warning: \`-version-info' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+        $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+        if test -n "$objs"; then
+          $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+          exit 1
+        fi
+        libobj="$output"
+        obj=`$echo "X$output" | $Xsed -e 's/\.lo$/.o/'`
+        ;;
+      *)
+        libobj=
+        obj="$output"
+        ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Create the old-style object.
+      reload_objs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^       ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      test -z "$libobj" && exit 0
+
+      if test "$build_libtool_libs" != yes; then
+        # Create an invalid libtool object if no PIC, so that we don't
+        # accidentally link it into a program.
+        $show "echo timestamp > $libobj"
+        $run eval "echo timestamp > $libobj" || exit $?
+        exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+        # Only do commands if we really have different PIC objects.
+        reload_objs="$libobjs"
+        output="$libobj"
+        eval cmds=\"$reload_cmds\"
+        IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+      else
+        # Just create a symlink.
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj || exit 1
+      fi
+
+      exit 0
+      ;;
+
+    *)
+      if test -n "$vinfo"; then
+        $echo "$modename: warning: \`-version-info' is ignored while linking programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+        $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath; do
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+		case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+		*"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		  ;;
+		*)
+		  hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		  ;;
+		esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              eval flag=\"$hardcode_libdir_flag_spec\"
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test -n "$runpath_var"; then
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+	done
+      fi
+
+      # Substitute the hardcoded libdirs into the compile commands.
+      if test -n "$hardcode_libdir_separator"; then
+	compile_command=`$echo "X$compile_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+        # Transform all the library objects into standard objects.
+        compile_command=`$echo "X$compile_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+        finalize_command=`$echo "X$finalize_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+      fi
+
+      if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then
+        dlsyms="${output}S.c"
+      else
+        dlsyms=
+      fi
+
+      if test -n "$dlsyms"; then
+        # Add our own program objects to the preloaded list.
+        dlprefiles=`$echo "X$objs$dlprefiles " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+
+	# Discover the nlist of each of the dlfiles.
+        nlist="$objdir/${output}.nm"
+
+	if test -d $objdir; then
+	  $show "$rm $nlist ${nlist}T"
+	  $run $rm "$nlist" "${nlist}T"
+	else
+	  $show "$mkdir $objdir"
+	  $run $mkdir $objdir
+	  status=$?
+	  if test $status -eq 0 || test -d $objdir; then :
+	  else
+	    exit $status
+	  fi
+	fi
+
+        for arg in $dlprefiles; do
+	  $show "extracting global C symbols from \`$arg'"
+	  $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+        done
+
+        # Parse the name list into a source file.
+        $show "creating $objdir/$dlsyms"
+        if test -z "$run"; then
+	  # Make sure we at least have an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  # Try sorting and uniquifying the output.
+	  if sort "$nlist" | uniq > "$nlist"T; then
+	    mv -f "$nlist"T "$nlist"
+	    wcout=`wc "$nlist" 2>/dev/null`
+	    count=`echo "X$wcout" | $Xsed -e 's/^[ 	]*\([0-9][0-9]*\).*$/\1/'`
+	    (test "$count" -ge 0) 2>/dev/null || count=-1
+	  else
+	    $rm "$nlist"T
+	    count=-1
+	  fi
+
+	  case "$dlsyms" in
+	  "") ;;
+	  *.c)
+	    $echo > "$objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$output' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define dld_preloaded_symbol_count some_other_symbol
+#define dld_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+	    if test -f "$nlist"; then
+	      sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$objdir/$dlsyms"
+	    else
+	      echo '/* NONE */' >> "$objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$objdir/$dlsyms" "\
+
+#undef dld_preloaded_symbol_count
+#undef dld_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{\
+"
+
+	    if test -f "$nlist"; then
+	      sed 's/^\(.*\) \(.*\)$/  {"\1", (__ptr_t) \&\2},/' < "$nlist" >> "$objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$objdir/$dlsyms" "\
+  {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	    ;;
+
+	  *)
+	    $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+	    exit 1
+	    ;;
+	  esac
+        fi
+
+        # Now compile the dynamic symbol file.
+        $show "(cd $objdir && $CC -c$no_builtin_flag \"$dlsyms\")"
+        $run eval '(cd $objdir && $CC -c$no_builtin_flag "$dlsyms")' || exit $?
+
+        # Transform the symbol file into the correct name.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"`
+      elif test "$export_dynamic" != yes; then
+        test -n "$dlfiles$dlprefiles" && $echo "$modename: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2
+      else
+        # We keep going just in case the user didn't refer to
+        # dld_preloaded_symbols.  The linker will fail if global_symbol_pipe
+        # really was required.
+        $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+
+        # Nullify the symbol file.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+        # Replace the output file specification.
+        compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+
+        # We have no uninstalled library dependencies, so finalize right now.
+        $show "$compile_command"
+        $run eval "$compile_command"
+        exit $?
+      fi
+
+      # Replace the output file specification.
+      compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'%g'`
+      finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'T%g'`
+
+      # Create the binary in the object directory, then wrap it.
+      if test -d $objdir; then :
+      else
+        $show "$mkdir $objdir"
+	$run $mkdir $objdir
+	status=$?
+	if test $status -eq 0 || test -d $objdir; then :
+	else
+	  exit $status
+	fi
+      fi
+
+      if test -n "$shlibpath_var"; then
+        # We should set the shlibpath_var
+        rpath=
+        for dir in $temp_rpath; do
+          case "$dir" in
+          /* | [A-Za-z]:\\*)
+            # Absolute path.
+            rpath="$rpath$dir:"
+            ;;
+          *)
+            # Relative path: add a thisdir entry.
+            rpath="$rpath\$thisdir/$dir:"
+            ;;
+          esac
+        done
+        temp_rpath="$rpath"
+      fi
+
+      # Delete the old output file.
+      $run $rm $output
+
+      if test -n "$compile_shlibpath"; then
+        compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+        finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      if test -n "$runpath_var" && test -n "$perm_rpath"; then
+        # We should set the runpath_var.
+        rpath=
+        for dir in $perm_rpath; do
+          rpath="$rpath$dir:"
+        done
+        compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command"
+        finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command"
+      fi
+
+      case "$hardcode_action" in
+      relink)
+        # AGH! Flame the AIX and HP-UX people for me, will ya?
+        $echo "$modename: warning: using a buggy system linker" 1>&2
+        $echo "$modename: relinking will be required before \`$output' can be installed" 1>&2
+        ;;
+      esac
+
+      $show "$compile_command"
+      $run eval "$compile_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the finalize command for shipping.
+      finalize_command=`$echo "X$finalize_command" | $Xsed -e "$sed_quote_subst"`
+
+      # Quote $echo for shipping.
+      qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+        $rm $output
+        trap "$rm $output; exit 1" 1 2 15
+
+        $echo > $output "\
+#! /bin/sh
+
+# $output - temporary wrapper script for $objdir/$output
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of \``pwd`'.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  link_against_libtool_libs='$link_against_libtool_libs'
+  finalize_command=\"$finalize_command\"
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" = \"$magic\"; then :
+  else
+    echo=\"$qecho\"
+    file=\"\$0\"
+  fi\
+"
+        $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      /* | [A-Za-z]:\\*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+
+  progdir=\"\$thisdir/$objdir\"
+  program='$output'
+
+  if test -f \"\$progdir/\$program\"; then"
+
+        # Export our shlibpath_var if we have one.
+        if test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+          $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/:*\$//'\`
+
+    export $shlibpath_var
+"
+        fi
+
+        $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+        chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    if test "$build_old_libs" = "yes"; then
+      # Transform .lo files to .o files.
+      oldobjs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^   ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	eval cmds=\"$old_archive_from_new_cmds\"
+      else
+	eval cmds=\"$old_archive_cmds\"
+      fi
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.a"
+
+      $show "creating $output"
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+        $echo > $output "\
+# $output - a libtool library file
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $objdir && $LN_S ../$output $output)"
+      $run eval "(cd $objdir && $LN_S ../$output $output)" || exit 1
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional /bin/sh argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL"; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+        files="$files $dest"
+        dest="$arg"
+        continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+        stripme=" -s"
+        continue
+        ;;
+      -*) ;;
+
+      *)
+        # If the previous option needed an argument, then skip it.
+        if test -n "$prev"; then
+          prev=
+        else
+          dest="$arg"
+          continue
+        fi
+        ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+        $echo "$modename: no file or destination specified" 1>&2
+      else
+        $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test -n "$isdir"; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+        $echo "$modename: \`$dest' is not a directory" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+    fi
+    case "$destdir" in
+    /* | [A-Za-z]:\\*) ;;
+    *)
+      for file in $files; do
+        case "$file" in
+        *.lo) ;;
+        *)
+          $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a)
+        # Do the static libraries later.
+        staticlibs="$staticlibs $file"
+        ;;
+
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+        else
+          $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+        library_names=
+        old_library=
+        # If there is no directory component, then add one.
+        case "$file" in
+        */* | *\\*) . $file ;;
+        *) . ./$file ;;
+        esac
+
+        # Add the libdir to current_libdirs if it is the destination.
+        if test "X$destdir" = "X$libdir"; then
+          case "$current_libdirs " in
+          *" $libdir "*) ;;
+          *) current_libdirs="$current_libdirs $libdir" ;;
+          esac
+        else
+          # Note the libdir as a future libdir.
+          case "$future_libdirs " in
+          *" $libdir "*) ;;
+          *) future_libdirs="$future_libdirs $libdir" ;;
+          esac
+        fi
+
+        dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+        test "X$dir" = "X$file/" && dir=
+        dir="$dir$objdir"
+
+        # See the names of the shared library.
+        set dummy $library_names
+        if test -n "$2"; then
+          realname="$2"
+          shift
+          shift
+
+          # Install the shared library and build the symlinks.
+          $show "$install_prog $dir/$realname $destdir/$realname"
+          $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+          test "X$dlname" = "X$realname" && dlname=
+
+          if test $# -gt 0; then
+            # Delete the old symlinks.
+            rmcmd="$rm"
+            for linkname
+            do
+              rmcmd="$rmcmd $destdir/$linkname"
+            done
+            $show "$rmcmd"
+            $run $rmcmd
+
+            # ... and create new ones.
+            for linkname
+            do
+              test "X$dlname" = "X$linkname" && dlname=
+              $show "(cd $destdir && $LN_S $realname $linkname)"
+              $run eval "(cd $destdir && $LN_S $realname $linkname)"
+            done
+          fi
+
+          if test -n "$dlname"; then
+            # Install the dynamically-loadable library.
+            $show "$install_prog $dir/$dlname $destdir/$dlname"
+            $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+          fi
+
+          # Do each command in the postinstall commands.
+          lib="$destdir/$realname"
+          eval cmds=\"$postinstall_cmds\"
+          IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+          for cmd in $cmds; do
+            IFS="$save_ifs"
+            $show "$cmd"
+            $run eval "$cmd" || exit $?
+          done
+          IFS="$save_ifs"
+        fi
+
+        # Install the pseudo-library for information purposes.
+        name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+        $show "$install_prog $file $destdir/$name"
+        $run eval "$install_prog $file $destdir/$name" || exit $?
+
+        # Maybe install the static library, too.
+        test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+        ;;
+
+      *.lo)
+        # Install (i.e. copy) a libtool object.
+
+        # Figure out destination file name, if it wasn't already specified.
+        if test -n "$destname"; then
+          destfile="$destdir/$destname"
+        else
+          destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+          destfile="$destdir/$destfile"
+        fi
+
+        # Deduce the name of the destination old-style object file.
+        case "$destfile" in
+        *.lo)
+          staticdest=`$echo "X$destfile" | $Xsed -e 's/\.lo$/\.o/'`
+          ;;
+        *.o)
+          staticdest="$destfile"
+          destfile=
+          ;;
+        *)
+          $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+
+        # Install the libtool object if requested.
+        if test -n "$destfile"; then
+          $show "$install_prog $file $destfile"
+          $run eval "$install_prog $file $destfile" || exit $?
+        fi
+
+        # Install the old object if enabled.
+        if test "$build_old_libs" = yes; then
+          # Deduce the name of the old-style object file.
+          staticobj=`$echo "X$file" | $Xsed -e 's/\.lo$/\.o/'`
+
+          $show "$install_prog $staticobj $staticdest"
+          $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+        fi
+        exit 0
+        ;;
+
+      *)
+        # Do a test to see if this is really a libtool program.
+        if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+          link_against_libtool_libs=
+          finalize_command=
+
+          # If there is no directory component, then add one.
+          case "$file" in
+          */* | *\\*) . $file ;;
+          *) . ./$file ;;
+          esac
+
+          # Check the variables that should have been set.
+          if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then
+            $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+            exit 1
+          fi
+
+          finalize=yes
+          for lib in $link_against_libtool_libs; do
+            # Check to see that each library is installed.
+            libdir=
+            if test -f "$lib"; then
+              # If there is no directory component, then add one.
+              case "$lib" in
+              */* | *\\*) . $lib ;;
+              *) . ./$lib ;;
+              esac
+            fi
+            libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+            if test -z "$libdir"; then
+              $echo "$modename: warning: \`$lib' contains no -rpath information" 1>&2
+            elif test -f "$libfile"; then :
+            else
+              $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+              finalize=no
+            fi
+          done
+
+          if test "$hardcode_action" = relink; then
+            if test "$finalize" = yes; then
+              $echo "$modename: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2
+              $show "$finalize_command"
+              if $run eval "$finalize_command"; then :
+              else
+                $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+                continue
+              fi
+              file="$objdir/$file"T
+            else
+              $echo "$modename: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2
+            fi
+          else
+            # Install the binary that we compiled earlier.
+	    file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+          fi
+        fi
+
+        $show "$install_prog$stripme $file $dest"
+        $run eval "$install_prog\$stripme \$file \$dest" || exit $?
+        ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+        libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  eval cmds=\"$finish_cmds\"
+          IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+          for cmd in $cmds; do
+            IFS="$save_ifs"
+            $show "$cmd"
+            $run eval "$cmd"
+          done
+          IFS="$save_ifs"
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $run eval "$cmds"
+	fi
+      done
+    fi
+
+    echo "------------------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "To link against installed libraries in a given directory, LIBDIR,"
+    echo "you must use the \`-LLIBDIR' flag during linking."
+    echo
+    echo " You will also need to do one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "------------------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test -f "$file"; then :
+      else
+	$echo "$modename: \`$file' is not a file" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+        else
+          $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+
+        # If there is no directory component, then add one.
+	case "$file" in
+	*/* | *\\*) . $file ;;
+        *) . ./$file ;;
+	esac
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+	  exit 1
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+	;;
+
+      *)
+	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+        continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+        # Do a test to see if this is really a libtool program.
+        if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+	  # If there is no directory component, then add one.
+	  case "$file" in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+        ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      # Export the shlibpath_var.
+      eval "export $shlibpath_var"
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$modename: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+      $echo "export $shlibpath_var"
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    modename="$modename: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+        # Possibly a libtool archive, so verify it.
+        if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+          . $dir/$name
+
+          # Delete the libtool libraries and symlinks.
+          for n in $library_names; do
+            rmfiles="$rmfiles $dir/$n"
+            test "X$n" = "X$dlname" && dlname=
+          done
+          test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+          test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+	  $show "$rm $rmfiles"
+	  $run $rm $rmfiles
+
+	  if test -n "$library_names"; then
+	    # Do each command in the postuninstall commands.
+	    eval cmds=\"$postuninstall_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd"
+	    done
+	    IFS="$save_ifs"
+	  fi
+
+          if test -n "$old_library"; then
+	    # Do each command in the old_postuninstall commands.
+	    eval cmds=\"$old_postuninstall_cmds\"
+	    IFS="${IFS= 	}"; save_ifs="$IFS"; IFS=';'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      $show "$cmd"
+	      $run eval "$cmd"
+	    done
+	    IFS="$save_ifs"
+	  fi
+
+          # FIXME: should reinstall the best remaining shared library.
+        fi
+        ;;
+
+      *.lo)
+        if test "$build_old_libs" = yes; then
+          oldobj=`$echo "X$name" | $Xsed -e 's/\.lo$/\.o/'`
+          rmfiles="$rmfiles $dir/$oldobj"
+        fi
+	$show "$rm $rmfiles"
+	$run $rm $rmfiles
+        ;;
+
+      *)
+      	$show "$rm $rmfiles"
+	$run $rm $rmfiles
+	;;
+      esac
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+-n, --dry-run         display commands without modifying any files
+    --features        display configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to dld_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only
+library objects (\`.lo' files) may be specified, and \`-rpath' is required.
+
+If OUTPUT-FILE ends in \`.a', then a standard library is created using \`ar'
+and \`ranlib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.o', then a reloadable object file is
+created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/makcjpeg.st b/makcjpeg.st
index 3b523db..fc72c89 100644
--- a/makcjpeg.st
+++ b/makcjpeg.st
@@ -1,11 +1,12 @@
 ; Project file for Independent JPEG Group's software
 ;
 ; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C.
-; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de)
-; and to Dr. B. Setzepfandt (bernd@gina.uni-muenster.de).
+; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de),
+; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de),
+; and Guido Vollbeding (guivol@esc.de).
 ;
-; To use this file, rename it to CJPEG.PRJ.
-; If you are using Turbo C, change filenames beginning with "PC..." to "TC..."
+; To use this file, rename it to cjpeg.prj.
+; If you are using Turbo C, change filenames beginning with "pc..." to "tc..."
 ; Read installation instructions before trying to make the program!
 ;
 ;
@@ -21,7 +22,7 @@
 .C[-wsig]     ; warn if significant digits may be lost
 =
 ; * * * * List of modules * * * * 
-PCSTART.O
+pcstart.o
 cjpeg.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h,jversion.h)
 cdjpeg.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
 rdswitch.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
@@ -30,8 +31,8 @@
 rdtarga.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
 rdbmp.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
 rdrle.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
-LIBJPEG.LIB        ; built by LIBJPEG.PRJ
-PCFLTLIB.LIB       ; floating point library
+libjpeg.lib        ; built by libjpeg.prj
+pcfltlib.lib       ; floating point library
 ; the float library can be omitted if you've turned off DCT_FLOAT_SUPPORTED
-PCSTDLIB.LIB       ; standard library
-PCEXTLIB.LIB       ; extended library
+pcstdlib.lib       ; standard library
+pcextlib.lib       ; extended library
diff --git a/makdjpeg.st b/makdjpeg.st
index 49d23ea..3226726 100644
--- a/makdjpeg.st
+++ b/makdjpeg.st
@@ -1,11 +1,12 @@
 ; Project file for Independent JPEG Group's software
 ;
 ; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C.
-; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de)
-; and to Dr. B. Setzepfandt (bernd@gina.uni-muenster.de).
+; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de),
+; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de),
+; and Guido Vollbeding (guivol@esc.de).
 ;
-; To use this file, rename it to DJPEG.PRJ.
-; If you are using Turbo C, change filenames beginning with "PC..." to "TC..."
+; To use this file, rename it to djpeg.prj.
+; If you are using Turbo C, change filenames beginning with "pc..." to "tc..."
 ; Read installation instructions before trying to make the program!
 ;
 ;
@@ -21,7 +22,7 @@
 .C[-wsig]     ; warn if significant digits may be lost
 =
 ; * * * * List of modules * * * * 
-PCSTART.O
+pcstart.o
 djpeg.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h,jversion.h)
 cdjpeg.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
 rdcolmap.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
@@ -30,8 +31,8 @@
 wrtarga.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
 wrbmp.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
 wrrle.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
-LIBJPEG.LIB        ; built by LIBJPEG.PRJ
-PCFLTLIB.LIB       ; floating point library
+libjpeg.lib        ; built by libjpeg.prj
+pcfltlib.lib       ; floating point library
 ; the float library can be omitted if you've turned off DCT_FLOAT_SUPPORTED
-PCSTDLIB.LIB       ; standard library
-PCEXTLIB.LIB       ; extended library
+pcstdlib.lib       ; standard library
+pcextlib.lib       ; extended library
diff --git a/makeapps.ds b/makeapps.ds
new file mode 100644
index 0000000..bedd038
--- /dev/null
+++ b/makeapps.ds
@@ -0,0 +1,828 @@
+# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+!IF "$(CFG)" == ""
+CFG=cjpeg - Win32
+!MESSAGE No configuration specified.  Defaulting to cjpeg - Win32.
+!ENDIF 
+
+!IF "$(CFG)" != "cjpeg - Win32" && "$(CFG)" != "djpeg - Win32" &&\
+ "$(CFG)" != "jpegtran - Win32" && "$(CFG)" != "rdjpgcom - Win32" &&\
+ "$(CFG)" != "wrjpgcom - Win32"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line.  For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "apps.mak" CFG="cjpeg - Win32"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "cjpeg - Win32" (based on "Win32 (x86) Console Application")
+!MESSAGE "djpeg - Win32" (based on "Win32 (x86) Console Application")
+!MESSAGE "jpegtran - Win32" (based on "Win32 (x86) Console Application")
+!MESSAGE "rdjpgcom - Win32" (based on "Win32 (x86) Console Application")
+!MESSAGE "wrjpgcom - Win32" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+!ERROR An invalid configuration is specified.
+!ENDIF 
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE 
+NULL=nul
+!ENDIF 
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "cjpeg - Win32"
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "cjpeg - Win32"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "cjpeg\Release"
+# PROP BASE Intermediate_Dir "cjpeg\Release"
+# PROP BASE Target_Dir "cjpeg"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "cjpeg\Release"
+# PROP Intermediate_Dir "cjpeg\Release"
+# PROP Target_Dir "cjpeg"
+OUTDIR=.\cjpeg\Release
+INTDIR=.\cjpeg\Release
+
+ALL : "$(OUTDIR)\cjpeg.exe"
+
+CLEAN : 
+	-@erase "$(INTDIR)\cjpeg.obj"
+	-@erase "$(INTDIR)\rdppm.obj"
+	-@erase "$(INTDIR)\rdgif.obj"
+	-@erase "$(INTDIR)\rdtarga.obj"
+	-@erase "$(INTDIR)\rdrle.obj"
+	-@erase "$(INTDIR)\rdbmp.obj"
+	-@erase "$(INTDIR)\rdswitch.obj"
+	-@erase "$(INTDIR)\cdjpeg.obj"
+	-@erase "$(OUTDIR)\cjpeg.exe"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
+ /Fp"$(INTDIR)/cjpeg.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\cjpeg\Release/
+CPP_SBRS=.\.
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/cjpeg.bsc" 
+BSC32_SBRS= \
+	
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\
+ odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\
+ /pdb:"$(OUTDIR)/cjpeg.pdb" /machine:I386 /out:"$(OUTDIR)/cjpeg.exe" 
+LINK32_OBJS= \
+	"$(INTDIR)\cjpeg.obj" \
+	"$(INTDIR)\rdppm.obj" \
+	"$(INTDIR)\rdgif.obj" \
+	"$(INTDIR)\rdtarga.obj" \
+	"$(INTDIR)\rdrle.obj" \
+	"$(INTDIR)\rdbmp.obj" \
+	"$(INTDIR)\rdswitch.obj" \
+	"$(INTDIR)\cdjpeg.obj" \
+
+
+"$(OUTDIR)\cjpeg.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "djpeg - Win32"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "djpeg\Release"
+# PROP BASE Intermediate_Dir "djpeg\Release"
+# PROP BASE Target_Dir "djpeg"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "djpeg\Release"
+# PROP Intermediate_Dir "djpeg\Release"
+# PROP Target_Dir "djpeg"
+OUTDIR=.\djpeg\Release
+INTDIR=.\djpeg\Release
+
+ALL : "$(OUTDIR)\djpeg.exe"
+
+CLEAN : 
+	-@erase "$(INTDIR)\djpeg.obj"
+	-@erase "$(INTDIR)\wrppm.obj"
+	-@erase "$(INTDIR)\wrgif.obj"
+	-@erase "$(INTDIR)\wrtarga.obj"
+	-@erase "$(INTDIR)\wrrle.obj"
+	-@erase "$(INTDIR)\wrbmp.obj"
+	-@erase "$(INTDIR)\rdcolmap.obj"
+	-@erase "$(INTDIR)\cdjpeg.obj"
+	-@erase "$(OUTDIR)\djpeg.exe"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
+ /Fp"$(INTDIR)/djpeg.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\djpeg\Release/
+CPP_SBRS=.\.
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/djpeg.bsc" 
+BSC32_SBRS= \
+	
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\
+ odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\
+ /pdb:"$(OUTDIR)/djpeg.pdb" /machine:I386 /out:"$(OUTDIR)/djpeg.exe" 
+LINK32_OBJS= \
+	"$(INTDIR)\djpeg.obj" \
+	"$(INTDIR)\wrppm.obj" \
+	"$(INTDIR)\wrgif.obj" \
+	"$(INTDIR)\wrtarga.obj" \
+	"$(INTDIR)\wrrle.obj" \
+	"$(INTDIR)\wrbmp.obj" \
+	"$(INTDIR)\rdcolmap.obj" \
+	"$(INTDIR)\cdjpeg.obj" \
+
+
+"$(OUTDIR)\djpeg.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "jpegtran - Win32"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "jpegtran\Release"
+# PROP BASE Intermediate_Dir "jpegtran\Release"
+# PROP BASE Target_Dir "jpegtran"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "jpegtran\Release"
+# PROP Intermediate_Dir "jpegtran\Release"
+# PROP Target_Dir "jpegtran"
+OUTDIR=.\jpegtran\Release
+INTDIR=.\jpegtran\Release
+
+ALL : "$(OUTDIR)\jpegtran.exe"
+
+CLEAN : 
+	-@erase "$(INTDIR)\jpegtran.obj"
+	-@erase "$(INTDIR)\rdswitch.obj"
+	-@erase "$(INTDIR)\cdjpeg.obj"
+	-@erase "$(INTDIR)\transupp.obj"
+	-@erase "$(OUTDIR)\jpegtran.exe"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
+ /Fp"$(INTDIR)/jpegtran.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\jpegtran\Release/
+CPP_SBRS=.\.
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/jpegtran.bsc" 
+BSC32_SBRS= \
+	
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\
+ odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\
+ /pdb:"$(OUTDIR)/jpegtran.pdb" /machine:I386 /out:"$(OUTDIR)/jpegtran.exe" 
+LINK32_OBJS= \
+	"$(INTDIR)\jpegtran.obj" \
+	"$(INTDIR)\rdswitch.obj" \
+	"$(INTDIR)\cdjpeg.obj" \
+	"$(INTDIR)\transupp.obj" \
+
+
+"$(OUTDIR)\jpegtran.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "rdjpgcom - Win32"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "rdjpgcom\Release"
+# PROP BASE Intermediate_Dir "rdjpgcom\Release"
+# PROP BASE Target_Dir "rdjpgcom"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "rdjpgcom\Release"
+# PROP Intermediate_Dir "rdjpgcom\Release"
+# PROP Target_Dir "rdjpgcom"
+OUTDIR=.\rdjpgcom\Release
+INTDIR=.\rdjpgcom\Release
+
+ALL : "$(OUTDIR)\rdjpgcom.exe"
+
+CLEAN : 
+	-@erase "$(INTDIR)\rdjpgcom.obj"
+	-@erase "$(OUTDIR)\rdjpgcom.exe"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
+ /Fp"$(INTDIR)/rdjpgcom.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\rdjpgcom\Release/
+CPP_SBRS=.\.
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/rdjpgcom.bsc" 
+BSC32_SBRS= \
+	
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\
+ odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\
+ /pdb:"$(OUTDIR)/rdjpgcom.pdb" /machine:I386 /out:"$(OUTDIR)/rdjpgcom.exe" 
+LINK32_OBJS= \
+	"$(INTDIR)\rdjpgcom.obj"
+
+"$(OUTDIR)\rdjpgcom.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF  "$(CFG)" == "wrjpgcom - Win32"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "wrjpgcom\Release"
+# PROP BASE Intermediate_Dir "wrjpgcom\Release"
+# PROP BASE Target_Dir "wrjpgcom"
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "wrjpgcom\Release"
+# PROP Intermediate_Dir "wrjpgcom\Release"
+# PROP Target_Dir "wrjpgcom"
+OUTDIR=.\wrjpgcom\Release
+INTDIR=.\wrjpgcom\Release
+
+ALL : "$(OUTDIR)\wrjpgcom.exe"
+
+CLEAN : 
+	-@erase "$(INTDIR)\wrjpgcom.obj"
+	-@erase "$(OUTDIR)\wrjpgcom.exe"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
+ /Fp"$(INTDIR)/wrjpgcom.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\wrjpgcom\Release/
+CPP_SBRS=.\.
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/wrjpgcom.bsc" 
+BSC32_SBRS= \
+	
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+LINK32_FLAGS=Release\jpeg.lib kernel32.lib user32.lib gdi32.lib winspool.lib\
+ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\
+ odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no\
+ /pdb:"$(OUTDIR)/wrjpgcom.pdb" /machine:I386 /out:"$(OUTDIR)/wrjpgcom.exe" 
+LINK32_OBJS= \
+	"$(INTDIR)\wrjpgcom.obj"
+
+"$(OUTDIR)\wrjpgcom.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+    $(LINK32) @<<
+  $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF 
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+################################################################################
+# Begin Target
+
+# Name "cjpeg - Win32"
+
+!IF  "$(CFG)" == "cjpeg - Win32"
+
+!ENDIF 
+
+################################################################################
+# Begin Source File
+
+SOURCE="cjpeg.c"
+DEP_CPP_CJPEG=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	"jversion.h"\
+	
+
+"$(INTDIR)\cjpeg.obj" : $(SOURCE) $(DEP_CPP_CJPEG) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="cdjpeg.c"
+DEP_CPP_CDJPE=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\cdjpeg.obj" : $(SOURCE) $(DEP_CPP_CDJPE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdswitch.c"
+DEP_CPP_RDSWI=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdswitch.obj" : $(SOURCE) $(DEP_CPP_RDSWI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdppm.c"
+DEP_CPP_RDPPM=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdppm.obj" : $(SOURCE) $(DEP_CPP_RDPPM) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdgif.c"
+DEP_CPP_RDGIF=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdgif.obj" : $(SOURCE) $(DEP_CPP_RDGIF) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdtarga.c"
+DEP_CPP_RDTAR=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdtarga.obj" : $(SOURCE) $(DEP_CPP_RDTAR) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdbmp.c"
+DEP_CPP_RDBMP=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdbmp.obj" : $(SOURCE) $(DEP_CPP_RDBMP) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdrle.c"
+DEP_CPP_RDRLE=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdrle.obj" : $(SOURCE) $(DEP_CPP_RDRLE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+# End Target
+################################################################################
+# Begin Target
+
+# Name "djpeg - Win32"
+
+!IF  "$(CFG)" == "djpeg - Win32"
+
+!ENDIF 
+
+################################################################################
+# Begin Source File
+
+SOURCE="djpeg.c"
+DEP_CPP_DJPEG=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	"jversion.h"\
+	
+
+"$(INTDIR)\djpeg.obj" : $(SOURCE) $(DEP_CPP_DJPEG) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="cdjpeg.c"
+DEP_CPP_CDJPE=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\cdjpeg.obj" : $(SOURCE) $(DEP_CPP_CDJPE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdcolmap.c"
+DEP_CPP_RDCOL=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdcolmap.obj" : $(SOURCE) $(DEP_CPP_RDCOL) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="wrppm.c"
+DEP_CPP_WRPPM=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\wrppm.obj" : $(SOURCE) $(DEP_CPP_WRPPM) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="wrgif.c"
+DEP_CPP_WRGIF=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\wrgif.obj" : $(SOURCE) $(DEP_CPP_WRGIF) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="wrtarga.c"
+DEP_CPP_WRTAR=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\wrtarga.obj" : $(SOURCE) $(DEP_CPP_WRTAR) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="wrbmp.c"
+DEP_CPP_WRBMP=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\wrbmp.obj" : $(SOURCE) $(DEP_CPP_WRBMP) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="wrrle.c"
+DEP_CPP_WRRLE=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\wrrle.obj" : $(SOURCE) $(DEP_CPP_WRRLE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+# End Target
+################################################################################
+# Begin Target
+
+# Name "jpegtran - Win32"
+
+!IF  "$(CFG)" == "jpegtran - Win32"
+
+!ENDIF 
+
+################################################################################
+# Begin Source File
+
+SOURCE="jpegtran.c"
+DEP_CPP_JPEGT=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	"transupp.h"\
+	"jversion.h"\
+	
+
+"$(INTDIR)\jpegtran.obj" : $(SOURCE) $(DEP_CPP_JPEGT) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="cdjpeg.c"
+DEP_CPP_CDJPE=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\cdjpeg.obj" : $(SOURCE) $(DEP_CPP_CDJPE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="rdswitch.c"
+DEP_CPP_RDSWI=\
+	"cdjpeg.h"\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	"cderror.h"\
+	
+
+"$(INTDIR)\rdswitch.obj" : $(SOURCE) $(DEP_CPP_RDSWI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="transupp.c"
+DEP_CPP_TRANS=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"transupp.h"\
+	
+
+"$(INTDIR)\transupp.obj" : $(SOURCE) $(DEP_CPP_TRANS) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+# End Target
+################################################################################
+# Begin Target
+
+# Name "rdjpgcom - Win32"
+
+!IF  "$(CFG)" == "rdjpgcom - Win32"
+
+!ENDIF 
+
+################################################################################
+# Begin Source File
+
+SOURCE="rdjpgcom.c"
+DEP_CPP_RDJPG=\
+	"jinclude.h"\
+	"jconfig.h"\
+	
+
+"$(INTDIR)\rdjpgcom.obj" : $(SOURCE) $(DEP_CPP_RDJPG) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+# End Target
+################################################################################
+# Begin Target
+
+# Name "wrjpgcom - Win32"
+
+!IF  "$(CFG)" == "wrjpgcom - Win32"
+
+!ENDIF 
+
+################################################################################
+# Begin Source File
+
+SOURCE="wrjpgcom.c"
+DEP_CPP_WRJPG=\
+	"jinclude.h"\
+	"jconfig.h"\
+	
+
+"$(INTDIR)\wrjpgcom.obj" : $(SOURCE) $(DEP_CPP_WRJPG) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+# End Target
+# End Project
+################################################################################
+
diff --git a/makefile.ansi b/makefile.ansi
index 8175ca0..8291913 100644
--- a/makefile.ansi
+++ b/makefile.ansi
@@ -49,28 +49,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
 # compression library object files
@@ -90,7 +93,7 @@
         cdjpeg.o
 DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
         cdjpeg.o
-TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
 
 
 all: libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom
@@ -127,13 +130,13 @@
 test: cjpeg djpeg jpegtran
 	$(RM) testout*
 	./djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	./djpeg -dct int -gif -outfile testout.gif  testorig.jpg
+	./djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
 	./cjpeg -dct int -outfile testout.jpg  testimg.ppm
 	./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	./jpegtran -outfile testoutt.jpg testprog.jpg
 	cmp testimg.ppm testout.ppm
-	cmp testimg.gif testout.gif
+	cmp testimg.bmp testout.bmp
 	cmp testimg.jpg testout.jpg
 	cmp testimg.ppm testoutp.ppm
 	cmp testimgp.jpg testoutp.jpg
@@ -192,12 +195,13 @@
 jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.bcc b/makefile.bcc
index 4f20bea..a1cfcde 100644
--- a/makefile.bcc
+++ b/makefile.bcc
@@ -2,7 +2,8 @@
 
 # This makefile is suitable for Borland C on MS-DOS or OS/2.
 # It works with Borland C++ for DOS, revision 3.0 or later,
-# and has been tested with Borland C++ for OS/2, revision 2.0.
+# and has been tested with Borland C++ for OS/2.
+# Watch out for optimization bugs in the OS/2 compilers --- see notes below!
 # Thanks to Tom Wright and Ge' Weijers (original DOS) and
 # Ken Porter (OS/2) for this file.
 
@@ -27,7 +28,8 @@
 CFLAGS= -O1 -w-par -w-stu -w-ccc -w-rch
 !endif
 # -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z).
-# -O2 is buggy in Borland OS/2 C++ revision 2.0, so use -O1 for now.
+# -O2 is buggy in Borland OS/2 C++ revision 2.0, so use -O1 there for now.
+# If you have Borland OS/2 C++ revision 1.0, use -O or no optimization at all.
 # -mm selects medium memory model (near data, far code pointers; DOS only!)
 # -w-par suppresses warnings about unused function parameters
 # -w-stu suppresses warnings about incomplete structures
@@ -74,28 +76,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
 # compression library object files
@@ -116,7 +121,7 @@
         rdswitch.obj cdjpeg.obj
 DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
         rdcolmap.obj cdjpeg.obj
-TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
 
 
 all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
@@ -183,14 +188,14 @@
 test: cjpeg.exe djpeg.exe jpegtran.exe
 	- del testout*.*
 	djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	djpeg -dct int -gif -outfile testout.gif  testorig.jpg
+	djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
 	cjpeg -dct int -outfile testout.jpg  testimg.ppm
 	djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	jpegtran -outfile testoutt.jpg testprog.jpg
 !if $d(DOS)
 	fc /b testimg.ppm testout.ppm
-	fc /b testimg.gif testout.gif
+	fc /b testimg.bmp testout.bmp
 	fc /b testimg.jpg testout.jpg
 	fc /b testimg.ppm testoutp.ppm
 	fc /b testimgp.jpg testoutp.jpg
@@ -198,7 +203,7 @@
 !else
 	echo n > n.tmp
 	comp testimg.ppm testout.ppm < n.tmp
-	comp testimg.gif testout.gif < n.tmp
+	comp testimg.bmp testout.bmp < n.tmp
 	comp testimg.jpg testout.jpg < n.tmp
 	comp testimg.ppm testoutp.ppm < n.tmp
 	comp testimgp.jpg testoutp.jpg < n.tmp
@@ -259,12 +264,13 @@
 jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.cfg b/makefile.cfg
index d3241c6..f25e42e 100644
--- a/makefile.cfg
+++ b/makefile.cfg
@@ -35,6 +35,17 @@
 # To link any special libraries, add the necessary -l commands here.
 LDLIBS= @LIBS@
 
+# If using GNU libtool, LIBTOOL references it; if not, LIBTOOL is empty.
+LIBTOOL = @LIBTOOL@
+# $(O) expands to "lo" if using libtool, plain "o" if not.
+# Similarly, $(A) expands to "la" or "a".
+O = @O@
+A = @A@
+
+# Library version ID; libtool uses this for the shared library version number.
+# Note: we suggest this match the macro of the same name in jpeglib.h.
+JPEG_LIB_VERSION = @JPEG_LIB_VERSION@
+
 # Put here the object file name for the correct system-dependent memory
 # manager file.  For Unix this is usually jmemnobs.o, but you may want
 # to use jmemansi.o or jmemname.o if you have limited swap space.
@@ -43,11 +54,11 @@
 # miscellaneous OS-dependent stuff
 SHELL= /bin/sh
 # linker
-LN= $(CC)
+LN= @LN@
 # file deletion command
 RM= rm -f
-# file rename command
-MV= mv
+# directory creation command
+MKDIR= mkdir
 # library (.a) file creation command
 AR= ar rc
 # second step in .a creation (use "touch" if not needed)
@@ -55,6 +66,7 @@
 # installation program
 INSTALL= @INSTALL@
 INSTALL_PROGRAM= @INSTALL_PROGRAM@
+INSTALL_LIB= @INSTALL_LIB@
 INSTALL_DATA= @INSTALL_DATA@
 
 # End of configurable options.
@@ -72,88 +84,113 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
-COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
+COMOBJECTS= jcomapi.$(O) jutils.$(O) jerror.$(O) jmemmgr.$(O) $(SYSDEPMEM)
 # compression library object files
-CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
-        jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
-        jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
-        jfdctint.o
+CLIBOBJECTS= jcapimin.$(O) jcapistd.$(O) jctrans.$(O) jcparam.$(O) \
+        jdatadst.$(O) jcinit.$(O) jcmaster.$(O) jcmarker.$(O) jcmainct.$(O) \
+        jcprepct.$(O) jccoefct.$(O) jccolor.$(O) jcsample.$(O) jchuff.$(O) \
+        jcphuff.$(O) jcdctmgr.$(O) jfdctfst.$(O) jfdctflt.$(O) \
+        jfdctint.$(O)
 # decompression library object files
-DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \
-        jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
-        jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
-        jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
+DLIBOBJECTS= jdapimin.$(O) jdapistd.$(O) jdtrans.$(O) jdatasrc.$(O) \
+        jdmaster.$(O) jdinput.$(O) jdmarker.$(O) jdhuff.$(O) jdphuff.$(O) \
+        jdmainct.$(O) jdcoefct.$(O) jdpostct.$(O) jddctmgr.$(O) \
+        jidctfst.$(O) jidctflt.$(O) jidctint.$(O) jidctred.$(O) \
+        jdsample.$(O) jdcolor.$(O) jquant1.$(O) jquant2.$(O) jdmerge.$(O)
 # These objectfiles are included in libjpeg.a
 LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
 # object files for sample applications (excluding library files)
-COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \
-        cdjpeg.o
-DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
-        cdjpeg.o
-TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o
+COBJECTS= cjpeg.$(O) rdppm.$(O) rdgif.$(O) rdtarga.$(O) rdrle.$(O) \
+        rdbmp.$(O) rdswitch.$(O) cdjpeg.$(O)
+DOBJECTS= djpeg.$(O) wrppm.$(O) wrgif.$(O) wrtarga.$(O) wrrle.$(O) \
+        wrbmp.$(O) rdcolmap.$(O) cdjpeg.$(O)
+TROBJECTS= jpegtran.$(O) rdswitch.$(O) cdjpeg.$(O) transupp.$(O)
 
 
-all: @ANSI2KNR@ libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+all: @A2K_DEPS@ libjpeg.$(A) cjpeg djpeg jpegtran rdjpgcom wrjpgcom
 
-# This rule causes ansi2knr to be invoked.
-@ISANSICOM@.c.o:
-@ISANSICOM@	./ansi2knr $(srcdir)/$*.c T$*.c
-@ISANSICOM@	$(CC) $(CFLAGS) -c T$*.c
-@ISANSICOM@	$(RM) T$*.c $*.o
-@ISANSICOM@	$(MV) T$*.o $*.o
+# Special compilation rules to support ansi2knr and libtool.
+.SUFFIXES: .lo .la
+
+# How to compile with libtool.
+@COM_LT@.c.lo:
+@COM_LT@	$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/$*.c
+
+# How to use ansi2knr, when not using libtool.
+@COM_A2K@.c.o:
+@COM_A2K@	./ansi2knr $(srcdir)/$*.c knr/$*.c
+@COM_A2K@	$(CC) $(CFLAGS) -c knr/$*.c
+@COM_A2K@	$(RM) knr/$*.c
+
+# How to use ansi2knr AND libtool.
+@COM_A2K@.c.lo:
+@COM_A2K@	./ansi2knr $(srcdir)/$*.c knr/$*.c
+@COM_A2K@	$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c knr/$*.c
+@COM_A2K@	$(RM) knr/$*.c
 
 ansi2knr: ansi2knr.c
-	$(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c
+	$(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr $(srcdir)/ansi2knr.c
+	$(MKDIR) knr
 
-libjpeg.a: @ANSI2KNR@ $(LIBOBJECTS)
+# the library:
+
+# without libtool:
+libjpeg.a: @A2K_DEPS@ $(LIBOBJECTS)
 	$(RM) libjpeg.a
 	$(AR) libjpeg.a  $(LIBOBJECTS)
 	$(AR2) libjpeg.a
 
-cjpeg: $(COBJECTS) libjpeg.a
-	$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.a $(LDLIBS)
+# with libtool:
+libjpeg.la: @A2K_DEPS@ $(LIBOBJECTS)
+	$(LIBTOOL) --mode=link $(CC) -o libjpeg.la $(LIBOBJECTS) \
+		-rpath $(libdir) -version-info $(JPEG_LIB_VERSION)
 
-djpeg: $(DOBJECTS) libjpeg.a
-	$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.a $(LDLIBS)
+# sample programs:
 
-jpegtran: $(TROBJECTS) libjpeg.a
-	$(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.a $(LDLIBS)
+cjpeg: $(COBJECTS) libjpeg.$(A)
+	$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.$(A) $(LDLIBS)
 
-rdjpgcom: rdjpgcom.o
-	$(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS)
+djpeg: $(DOBJECTS) libjpeg.$(A)
+	$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.$(A) $(LDLIBS)
 
-wrjpgcom: wrjpgcom.o
-	$(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS)
+jpegtran: $(TROBJECTS) libjpeg.$(A)
+	$(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.$(A) $(LDLIBS)
 
-jconfig.h: jconfig.doc
-	echo You must prepare a system-dependent jconfig.h file.
-	echo Please read the installation directions in install.doc.
-	exit 1
+rdjpgcom: rdjpgcom.$(O)
+	$(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.$(O) $(LDLIBS)
 
-install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+wrjpgcom: wrjpgcom.$(O)
+	$(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.$(O) $(LDLIBS)
+
+# Installation rules:
+
+install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom @FORCE_INSTALL_LIB@
 	$(INSTALL_PROGRAM) cjpeg $(bindir)/$(binprefix)cjpeg
 	$(INSTALL_PROGRAM) djpeg $(bindir)/$(binprefix)djpeg
 	$(INSTALL_PROGRAM) jpegtran $(bindir)/$(binprefix)jpegtran
@@ -165,8 +202,8 @@
 	$(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext)
 	$(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext)
 
-install-lib: libjpeg.a install-headers
-	$(INSTALL_DATA) libjpeg.a $(libdir)/$(binprefix)libjpeg.a
+install-lib: libjpeg.$(A) install-headers
+	$(INSTALL_LIB) libjpeg.$(A) $(libdir)/$(binprefix)libjpeg.$(A)
 
 install-headers: jconfig.h
 	$(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h
@@ -175,24 +212,24 @@
 	$(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h
 
 clean:
-	$(RM) *.o cjpeg djpeg jpegtran libjpeg.a rdjpgcom wrjpgcom
+	$(RM) *.o *.lo libjpeg.a libjpeg.la
+	$(RM) cjpeg djpeg jpegtran rdjpgcom wrjpgcom
 	$(RM) ansi2knr core testout* config.log config.status
+	$(RM) -r knr .libs _libs
 
-distribute:
-	$(RM) jpegsrc.tar*
-	tar cvf jpegsrc.tar $(DISTFILES)
-	compress -v jpegsrc.tar
+distclean: clean
+	$(RM) Makefile jconfig.h libtool config.cache
 
 test: cjpeg djpeg jpegtran
 	$(RM) testout*
 	./djpeg -dct int -ppm -outfile testout.ppm  $(srcdir)/testorig.jpg
-	./djpeg -dct int -gif -outfile testout.gif  $(srcdir)/testorig.jpg
+	./djpeg -dct int -bmp -colors 256 -outfile testout.bmp  $(srcdir)/testorig.jpg
 	./cjpeg -dct int -outfile testout.jpg  $(srcdir)/testimg.ppm
 	./djpeg -dct int -ppm -outfile testoutp.ppm $(srcdir)/testprog.jpg
 	./cjpeg -dct int -progressive -opt -outfile testoutp.jpg $(srcdir)/testimg.ppm
 	./jpegtran -outfile testoutt.jpg $(srcdir)/testprog.jpg
 	cmp $(srcdir)/testimg.ppm testout.ppm
-	cmp $(srcdir)/testimg.gif testout.gif
+	cmp $(srcdir)/testimg.bmp testout.bmp
 	cmp $(srcdir)/testimg.jpg testout.jpg
 	cmp $(srcdir)/testimg.ppm testoutp.ppm
 	cmp $(srcdir)/testimgp.jpg testoutp.jpg
@@ -200,75 +237,83 @@
 
 check: test
 
+# Mistake catcher:
+
+jconfig.h: jconfig.doc
+	echo You must prepare a system-dependent jconfig.h file.
+	echo Please read the installation directions in install.doc.
+	exit 1
+
 # GNU Make likes to know which target names are not really files to be made:
-.PHONY: all install install-lib install-headers clean distribute test check
+.PHONY: all install install-lib install-headers clean distclean test check
 
 
-jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
-jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
-jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
-jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
-jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
-jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
-jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
-jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
-jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
-jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
-jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
-jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
-jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
-jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
-jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
-cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
-rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+jcapimin.$(O): jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.$(O): jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.$(O): jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.$(O): jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.$(O): jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.$(O): jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.$(O): jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.$(O): jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.$(O): jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.$(O): jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.$(O): jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.$(O): jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.$(O): jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.$(O): jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.$(O): jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.$(O): jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.$(O): jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.$(O): jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.$(O): jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.$(O): jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.$(O): jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.$(O): jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.$(O): jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.$(O): jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.$(O): jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.$(O): jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.$(O): jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.$(O): jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.$(O): jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.$(O): jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.$(O): jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.$(O): jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.$(O): jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.$(O): jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.$(O): jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.$(O): jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.$(O): jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.$(O): jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.$(O): jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.$(O): jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.$(O): jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.$(O): jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.$(O): jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.$(O): jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.$(O): jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.$(O): jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.$(O): jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.$(O): jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.$(O): jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.$(O): jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.$(O): cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.$(O): djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.$(O): jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.$(O): rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.$(O): wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.$(O): cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.$(O): rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.$(O): rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.$(O): transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.$(O): rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.$(O): wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.$(O): rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.$(O): wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.$(O): rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.$(O): wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.$(O): rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.$(O): wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.$(O): rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.$(O): wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.dj b/makefile.dj
index 811fd7d..f766d25 100644
--- a/makefile.dj
+++ b/makefile.dj
@@ -1,24 +1,20 @@
 # Makefile for Independent JPEG Group's software
 
-# This makefile is for DJGPP (Delorie's GNU C port) on MS-DOS.
-# Say "make exe" to get stub-style .exe's, or
-# "make standalone" to get standalone .exe's.
+# This makefile is for DJGPP (Delorie's GNU C port on MS-DOS), v2.0 or later.
+# Thanks to Frank J. Donahoe for this version.
 
 # Read installation instructions before saying "make" !!
 
-# To do "make standalone", you'll need to be sure this points to go32.exe:
-GO32= c:/djgpp/bin/go32.exe
-
 # The name of your C compiler:
 CC= gcc
 
 # You may need to adjust these cc options:
-CFLAGS= -O2 -Wall
+CFLAGS= -O2 -Wall -I.
 # Generally, we recommend defining any configuration symbols in jconfig.h,
 # NOT via -D switches here.
 
 # Link-time cc options:
-LDFLAGS= 
+LDFLAGS= -s
 
 # To link any special libraries, add the necessary -l commands here.
 LDLIBS= 
@@ -53,28 +49,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
 # compression library object files
@@ -94,44 +93,30 @@
         cdjpeg.o
 DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
         cdjpeg.o
-TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
 
 
-all: libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+all: libjpeg.a cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
 
 libjpeg.a: $(LIBOBJECTS)
 	$(RM) libjpeg.a
 	$(AR) libjpeg.a  $(LIBOBJECTS)
 	$(AR2) libjpeg.a
 
-cjpeg: $(COBJECTS) libjpeg.a
-	$(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.a $(LDLIBS)
+cjpeg.exe: $(COBJECTS) libjpeg.a
+	$(LN) $(LDFLAGS) -o cjpeg.exe $(COBJECTS) libjpeg.a $(LDLIBS)
 
-djpeg: $(DOBJECTS) libjpeg.a
-	$(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.a $(LDLIBS)
+djpeg.exe: $(DOBJECTS) libjpeg.a
+	$(LN) $(LDFLAGS) -o djpeg.exe $(DOBJECTS) libjpeg.a $(LDLIBS)
 
-jpegtran: $(TROBJECTS) libjpeg.a
-	$(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.a $(LDLIBS)
+jpegtran.exe: $(TROBJECTS) libjpeg.a
+	$(LN) $(LDFLAGS) -o jpegtran.exe $(TROBJECTS) libjpeg.a $(LDLIBS)
 
-rdjpgcom: rdjpgcom.o
-	$(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS)
+rdjpgcom.exe: rdjpgcom.o
+	$(LN) $(LDFLAGS) -o rdjpgcom.exe rdjpgcom.o $(LDLIBS)
 
-wrjpgcom: wrjpgcom.o
-	$(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS)
-
-exe: cjpeg djpeg jpegtran rdjpgcom wrjpgcom
-	coff2exe cjpeg
-	coff2exe djpeg
-	coff2exe jpegtran
-	coff2exe rdjpgcom
-	coff2exe wrjpgcom
-
-standalone: cjpeg djpeg jpegtran rdjpgcom wrjpgcom
-	coff2exe -s $(GO32) cjpeg
-	coff2exe -s $(GO32) djpeg
-	coff2exe -s $(GO32) jpegtran
-	coff2exe -s $(GO32) rdjpgcom
-	coff2exe -s $(GO32) wrjpgcom
+wrjpgcom.exe: wrjpgcom.o
+	$(LN) $(LDFLAGS) -o wrjpgcom.exe wrjpgcom.o $(LDLIBS)
 
 jconfig.h: jconfig.doc
 	echo You must prepare a system-dependent jconfig.h file.
@@ -140,24 +125,24 @@
 
 clean:
 	$(RM) *.o
-	$(RM) cjpeg
-	$(RM) djpeg
-	$(RM) jpegtran
-	$(RM) rdjpgcom
-	$(RM) wrjpgcom
+	$(RM) cjpeg.exe
+	$(RM) djpeg.exe
+	$(RM) jpegtran.exe
+	$(RM) rdjpgcom.exe
+	$(RM) wrjpgcom.exe
 	$(RM) libjpeg.a
 	$(RM) testout*.*
 
-test: cjpeg djpeg jpegtran
+test: cjpeg.exe djpeg.exe jpegtran.exe
 	$(RM) testout*.*
-	go32 djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	go32 djpeg -dct int -gif -outfile testout.gif  testorig.jpg
-	go32 cjpeg -dct int -outfile testout.jpg  testimg.ppm
-	go32 djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
-	go32 cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
-	go32 jpegtran -outfile testoutt.jpg testprog.jpg
+	./djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
+	./djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
+	./cjpeg -dct int -outfile testout.jpg  testimg.ppm
+	./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+	./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+	./jpegtran -outfile testoutt.jpg testprog.jpg
 	fc /b testimg.ppm testout.ppm
-	fc /b testimg.gif testout.gif
+	fc /b testimg.bmp testout.bmp
 	fc /b testimg.jpg testout.jpg
 	fc /b testimg.ppm testoutp.ppm
 	fc /b testimgp.jpg testoutp.jpg
@@ -216,12 +201,13 @@
 jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.manx b/makefile.manx
index fa035fc..4cb42d1 100644
--- a/makefile.manx
+++ b/makefile.manx
@@ -50,28 +50,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
 # compression library object files
@@ -91,7 +94,7 @@
         cdjpeg.o
 DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
         cdjpeg.o
-TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
 
 
 all: libjpeg.lib cjpeg djpeg jpegtran rdjpgcom wrjpgcom
@@ -127,13 +130,13 @@
 test: cjpeg djpeg jpegtran
 	-$(RM) testout*.*
 	djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	djpeg -dct int -gif -outfile testout.gif  testorig.jpg
+	djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
 	cjpeg -dct int -outfile testout.jpg  testimg.ppm
 	djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	jpegtran -outfile testoutt.jpg testprog.jpg
 	cmp testimg.ppm testout.ppm
-	cmp testimg.gif testout.gif
+	cmp testimg.bmp testout.bmp
 	cmp testimg.jpg testout.jpg
 	cmp testimg.ppm testoutp.ppm
 	cmp testimgp.jpg testoutp.jpg
@@ -192,12 +195,13 @@
 jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.mc6 b/makefile.mc6
index a8ab313..6aff054 100644
--- a/makefile.mc6
+++ b/makefile.mc6
@@ -15,11 +15,22 @@
 # Generally, we recommend defining any configuration symbols in jconfig.h,
 # NOT via -D switches here.
 
+# Jan-Herman Buining suggests the following switches for MS C 8.0 and a 486:
+# CFLAGS = /AM /f- /FPi87 /G3 /Gs /Gy /Ob1 /Oc /Oe /Og /Oi /Ol /On /Oo /Ot \
+#          /OV4 /W3
+# except for jquant1.c, which must be compiled with /Oo- to avoid a compiler
+# crash.
+
+# Ingar Steinsland suggests the following switches when building
+# a 16-bit Windows DLL:
+# CFLAGS = -ALw -Gsw -Zpe -W3 -O2 -Zi -Zd
+
 # Put here the object file name for the correct system-dependent memory
 # manager file.  For DOS, we recommend jmemdos.c and jmemdosa.asm.
-# If you change this, you'll need to modify the linker response file
-# name list, below, by hand!
+# (But not for Windows; see install.doc if you use this makefile for Windows.)
 SYSDEPMEM= jmemdos.obj jmemdosa.obj
+# SYSDEPMEMLIB must list the same files with "+" signs for the librarian.
+SYSDEPMEMLIB= +jmemdos.obj +jmemdosa.obj
 
 # End of configurable options.
 
@@ -36,28 +47,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
 # compression library object files
@@ -78,7 +92,7 @@
         rdswitch.obj cdjpeg.obj
 DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
         rdcolmap.obj cdjpeg.obj
-TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
 
 # need linker response file because file list > 128 chars
 RFILE = libjpeg.ans
@@ -108,7 +122,8 @@
 	echo +jidctfst.obj +jidctflt.obj +jidctint.obj & >>$(RFILE)
 	echo +jidctred.obj +jdsample.obj +jdcolor.obj +jquant1.obj & >>$(RFILE)
 	echo +jquant2.obj +jdmerge.obj +jcomapi.obj +jutils.obj & >>$(RFILE)
-	echo +jerror.obj +jmemmgr.obj +jmemdos.obj +jmemdosa.obj ; >>$(RFILE)
+	echo +jerror.obj +jmemmgr.obj & >>$(RFILE)
+	echo $(SYSDEPMEMLIB) ; >>$(RFILE)
 
 cjpeg.exe: $(COBJECTS) libjpeg.lib
 	echo $(COBJECTS) >cjpeg.lst
@@ -148,13 +163,13 @@
 test: cjpeg.exe djpeg.exe jpegtran.exe
 	del testout*.*
 	djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	djpeg -dct int -gif -outfile testout.gif  testorig.jpg
+	djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
 	cjpeg -dct int -outfile testout.jpg  testimg.ppm
 	djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	jpegtran -outfile testoutt.jpg testprog.jpg
 	fc /b testimg.ppm testout.ppm
-	fc /b testimg.gif testout.gif
+	fc /b testimg.bmp testout.bmp
 	fc /b testimg.jpg testout.jpg
 	fc /b testimg.ppm testoutp.ppm
 	fc /b testimgp.jpg testoutp.jpg
@@ -213,12 +228,13 @@
 jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.mms b/makefile.mms
index 401fe20..cf130e5 100644
--- a/makefile.mms
+++ b/makefile.mms
@@ -36,28 +36,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
 # compression library object files
@@ -78,13 +81,13 @@
         rdswitch.obj cdjpeg.obj
 DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
         rdcolmap.obj cdjpeg.obj
-TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
 # objectfile lists with commas --- what a crock
 COBJLIST= cjpeg.obj,rdppm.obj,rdgif.obj,rdtarga.obj,rdrle.obj,rdbmp.obj,\
           rdswitch.obj,cdjpeg.obj
 DOBJLIST= djpeg.obj,wrppm.obj,wrgif.obj,wrtarga.obj,wrrle.obj,wrbmp.obj,\
           rdcolmap.obj,cdjpeg.obj
-TROBJLIST= jpegtran.obj,rdswitch.obj,cdjpeg.obj
+TROBJLIST= jpegtran.obj,rdswitch.obj,cdjpeg.obj,transupp.obj
 LIBOBJLIST= jcapimin.obj,jcapistd.obj,jctrans.obj,jcparam.obj,jdatadst.obj,\
           jcinit.obj,jcmaster.obj,jcmarker.obj,jcmainct.obj,jcprepct.obj,\
           jccoefct.obj,jccolor.obj,jcsample.obj,jchuff.obj,jcphuff.obj,\
@@ -131,13 +134,13 @@
 
 test : cjpeg.exe djpeg.exe jpegtran.exe
 	mcr sys$disk:[]djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
-	mcr sys$disk:[]djpeg -dct int -gif -outfile testout.gif testorig.jpg
+	mcr sys$disk:[]djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
 	mcr sys$disk:[]cjpeg -dct int      -outfile testout.jpg testimg.ppm
 	mcr sys$disk:[]djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	mcr sys$disk:[]cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	mcr sys$disk:[]jpegtran -outfile testoutt.jpg testprog.jpg
 	- Backup /Compare/Log	  testimg.ppm testout.ppm
-	- Backup /Compare/Log	  testimg.gif testout.gif
+	- Backup /Compare/Log	  testimg.bmp testout.bmp
 	- Backup /Compare/Log	  testimg.jpg testout.jpg
 	- Backup /Compare/Log	  testimg.ppm testoutp.ppm
 	- Backup /Compare/Log	  testimgp.jpg testoutp.jpg
@@ -196,12 +199,13 @@
 jmemmac.obj : jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.obj : cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.obj : djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.obj : jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj : jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj : rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj : wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.obj : cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.obj : rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.obj : rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.obj : rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.obj : wrjpgcom.c jinclude.h jconfig.h
+transupp.obj : transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.obj : rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.obj : wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.obj : rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.sas b/makefile.sas
index 14be5a4..f296faf 100644
--- a/makefile.sas
+++ b/makefile.sas
@@ -58,28 +58,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
 # compression library object files
@@ -99,14 +102,18 @@
         cdjpeg.o
 DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
         cdjpeg.o
-TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
 
 
 all: libjpeg.lib cjpeg$(SUFFIX) djpeg$(SUFFIX) jpegtran$(SUFFIX) rdjpgcom$(SUFFIX) wrjpgcom$(SUFFIX)
 
+# note: do several AR steps to avoid command line length limitations
+
 libjpeg.lib: $(LIBOBJECTS)
 	-$(RM) libjpeg.lib
-	$(AR) libjpeg.lib r $(LIBOBJECTS)
+	$(AR) libjpeg.lib r $(CLIBOBJECTS)
+	$(AR) libjpeg.lib r $(DLIBOBJECTS)
+	$(AR) libjpeg.lib r $(COMOBJECTS)
 
 cjpeg$(SUFFIX): $(COBJECTS) libjpeg.lib
 	$(LN) <WITH <
@@ -161,13 +168,13 @@
 test: cjpeg djpeg jpegtran
 	-$(RM) testout*.*
 	djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	djpeg -dct int -gif -outfile testout.gif  testorig.jpg
+	djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
 	cjpeg -dct int -outfile testout.jpg  testimg.ppm
 	djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	jpegtran -outfile testoutt.jpg testprog.jpg
 	cmp testimg.ppm testout.ppm
-	cmp testimg.gif testout.gif
+	cmp testimg.bmp testout.bmp
 	cmp testimg.jpg testout.jpg
 	cmp testimg.ppm testoutp.ppm
 	cmp testimgp.jpg testoutp.jpg
@@ -226,12 +233,13 @@
 jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.unix b/makefile.unix
index 2ce9820..00455ab 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -53,28 +53,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c \
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c \
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st \
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms \
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc \
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg \
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
 # compression library object files
@@ -94,7 +97,7 @@
         cdjpeg.o
 DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
         cdjpeg.o
-TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
 
 
 all: ansi2knr libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom
@@ -141,13 +144,13 @@
 test: cjpeg djpeg jpegtran
 	$(RM) testout*
 	./djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	./djpeg -dct int -gif -outfile testout.gif  testorig.jpg
+	./djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
 	./cjpeg -dct int -outfile testout.jpg  testimg.ppm
 	./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	./jpegtran -outfile testoutt.jpg testprog.jpg
 	cmp testimg.ppm testout.ppm
-	cmp testimg.gif testout.gif
+	cmp testimg.bmp testout.bmp
 	cmp testimg.jpg testout.jpg
 	cmp testimg.ppm testoutp.ppm
 	cmp testimgp.jpg testoutp.jpg
@@ -206,12 +209,13 @@
 jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.vc b/makefile.vc
new file mode 100644
index 0000000..2acf069
--- /dev/null
+++ b/makefile.vc
@@ -0,0 +1,211 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Microsoft Visual C++ on Windows NT (and 95?).
+# It builds the IJG library as a statically linkable library (.LIB),
+# and builds the sample applications as console-mode apps.
+# Thanks to Xingong Chang, Raymond Everly and others.
+
+# Read installation instructions before saying "nmake" !!
+# To build an optimized library without debug info, say "nmake nodebug=1".
+
+# Pull in standard variable definitions
+!include <win32.mak>
+
+# You may want to adjust these compiler options:
+CFLAGS= $(cflags) $(cdebug) $(cvars) -I.
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+
+# Link-time options:
+LDFLAGS= $(ldebug) $(conlflags)
+
+# To link any special libraries, add the necessary commands here.
+LDLIBS= $(conlibs)
+
+# Put here the object file name for the correct system-dependent memory
+# manager file.  For NT we suggest jmemnobs.obj, which expects the OS to
+# provide adequate virtual memory.
+SYSDEPMEM= jmemnobs.obj
+
+# miscellaneous OS-dependent stuff
+# file deletion command
+RM= del
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+        jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+        jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+        jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+        jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+        jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+        jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+        jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+        wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+        coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+        testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \
+        jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \
+        jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \
+        jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj
+# decompression library object files
+DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \
+        jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \
+        jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \
+        jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \
+        jquant1.obj jquant2.obj jdmerge.obj
+# These objectfiles are included in libjpeg.lib
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \
+        rdswitch.obj cdjpeg.obj
+DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
+        rdcolmap.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
+
+# Template command for compiling .c to .obj
+.c.obj:
+	$(cc) $(CFLAGS) $*.c
+
+
+all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
+
+libjpeg.lib: $(LIBOBJECTS)
+	$(RM) libjpeg.lib
+	lib -out:libjpeg.lib  $(LIBOBJECTS)
+
+cjpeg.exe: $(COBJECTS) libjpeg.lib
+	$(link) $(LDFLAGS) -out:cjpeg.exe $(COBJECTS) libjpeg.lib $(LDLIBS)
+
+djpeg.exe: $(DOBJECTS) libjpeg.lib
+	$(link) $(LDFLAGS) -out:djpeg.exe $(DOBJECTS) libjpeg.lib $(LDLIBS)
+
+jpegtran.exe: $(TROBJECTS) libjpeg.lib
+	$(link) $(LDFLAGS) -out:jpegtran.exe $(TROBJECTS) libjpeg.lib $(LDLIBS)
+
+rdjpgcom.exe: rdjpgcom.obj
+	$(link) $(LDFLAGS) -out:rdjpgcom.exe rdjpgcom.obj $(LDLIBS)
+
+wrjpgcom.exe: wrjpgcom.obj
+	$(link) $(LDFLAGS) -out:wrjpgcom.exe wrjpgcom.obj $(LDLIBS)
+
+
+clean:
+	$(RM) *.obj *.exe libjpeg.lib
+	$(RM) testout*
+
+test: cjpeg.exe djpeg.exe jpegtran.exe
+	$(RM) testout*
+	.\djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
+	.\djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
+	.\cjpeg -dct int -outfile testout.jpg  testimg.ppm
+	.\djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+	.\cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+	.\jpegtran -outfile testoutt.jpg testprog.jpg
+	fc /b testimg.ppm testout.ppm
+	fc /b testimg.bmp testout.bmp
+	fc /b testimg.jpg testout.jpg
+	fc /b testimg.ppm testoutp.ppm
+	fc /b testimgp.jpg testoutp.jpg
+	fc /b testorig.jpg testoutt.jpg
+
+
+jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makefile.vms b/makefile.vms
index 4501847..a42358d 100644
--- a/makefile.vms
+++ b/makefile.vms
@@ -111,9 +111,10 @@
 $ DoCompile jpegtran.c
 $ DoCompile rdswitch.c
 $ DoCompile cdjpeg.c
+$ DoCompile transupp.c
 $!
 $ Link /NoMap /Executable = jpegtran.exe  jpegtran.obj,rdswitch.obj, -
-          cdjpeg.obj,libjpeg.olb/Library'OPT'
+          cdjpeg.obj,transupp.obj,libjpeg.olb/Library'OPT'
 $!
 $ DoCompile rdjpgcom.c
 $ Link /NoMap /Executable = rdjpgcom.exe  rdjpgcom.obj'OPT'
@@ -124,13 +125,13 @@
 $! Run the self-test
 $!
 $ mcr sys$disk:[]djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
-$ mcr sys$disk:[]djpeg -dct int -gif -outfile testout.gif testorig.jpg
+$ mcr sys$disk:[]djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
 $ mcr sys$disk:[]cjpeg -dct int      -outfile testout.jpg testimg.ppm
 $ mcr sys$disk:[]djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 $ mcr sys$disk:[]cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 $ mcr sys$disk:[]jpegtran -outfile testoutt.jpg testprog.jpg
 $ Backup /Compare/Log testimg.ppm testout.ppm
-$ Backup /Compare/Log testimg.gif testout.gif
+$ Backup /Compare/Log testimg.bmp testout.bmp
 $ Backup /Compare/Log testimg.jpg testout.jpg
 $ Backup /Compare/Log testimg.ppm testoutp.ppm
 $ Backup /Compare/Log testimgp.jpg testoutp.jpg
diff --git a/makefile.wat b/makefile.wat
index ff022a0..d953e46 100644
--- a/makefile.wat
+++ b/makefile.wat
@@ -48,28 +48,31 @@
 # memmgr back ends: compile only one of these into a working library
 SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
 # source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
-APPSOURCES= cjpeg.c djpeg.c jpegtran.c cdjpeg.c rdcolmap.c rdswitch.c &
-        rdjpgcom.c wrjpgcom.c rdppm.c wrppm.c rdgif.c wrgif.c rdtarga.c &
-        wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c &
+        rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c &
+        rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
 SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
 # files included by source files
 INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h &
-        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h
+        jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
 # documentation, test, and support files
 DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 &
         wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc &
         coderules.doc filelist.doc change.log
 MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc &
-        makefile.mc6 makefile.dj makefile.wat makcjpeg.st makdjpeg.st &
-        makljpeg.st maktjpeg.st makefile.manx makefile.sas makefile.mms &
-        makefile.vms makvms.opt
-CONFIGFILES= jconfig.cfg jconfig.manx jconfig.sas jconfig.st jconfig.bcc &
-        jconfig.mc6 jconfig.dj jconfig.wat jconfig.vms
+        makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds &
+        makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st &
+        maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms &
+        makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat &
+        jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas &
+        jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
 OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
-TESTFILES= testorig.jpg testimg.ppm testimg.gif testimg.jpg testprog.jpg &
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg &
         testimgp.jpg
 DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) &
-        $(OTHERFILES) $(TESTFILES)
+        $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
 # library object files common to compression and decompression
 COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
 # compression library object files
@@ -90,7 +93,7 @@
         rdswitch.obj cdjpeg.obj
 DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj &
         rdcolmap.obj cdjpeg.obj
-TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
 
 
 all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
@@ -135,14 +138,14 @@
 test: cjpeg.exe djpeg.exe jpegtran.exe  .SYMBOLIC
 	- del testout*.*
 	djpeg -dct int -ppm -outfile testout.ppm  testorig.jpg
-	djpeg -dct int -gif -outfile testout.gif  testorig.jpg
+	djpeg -dct int -bmp -colors 256 -outfile testout.bmp  testorig.jpg
 	cjpeg -dct int -outfile testout.jpg  testimg.ppm
 	djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
 	cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
 	jpegtran -outfile testoutt.jpg testprog.jpg
 !ifeq SYSTEM DOS
 	fc /b testimg.ppm testout.ppm
-	fc /b testimg.gif testout.gif
+	fc /b testimg.bmp testout.bmp
 	fc /b testimg.jpg testout.jpg
 	fc /b testimg.ppm testoutp.ppm
 	fc /b testimgp.jpg testoutp.jpg
@@ -150,7 +153,7 @@
 !else
 	echo n > n.tmp
 	comp testimg.ppm testout.ppm < n.tmp
-	comp testimg.gif testout.gif < n.tmp
+	comp testimg.bmp testout.bmp < n.tmp
 	comp testimg.jpg testout.jpg < n.tmp
 	comp testimg.ppm testoutp.ppm < n.tmp
 	comp testimgp.jpg testoutp.jpg < n.tmp
@@ -211,12 +214,13 @@
 jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
 cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
 djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
-jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
 cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
-rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
-wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
 rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
 rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/makelib.ds b/makelib.ds
new file mode 100644
index 0000000..c7ad36d
--- /dev/null
+++ b/makelib.ds
@@ -0,0 +1,1046 @@
+# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+!IF "$(CFG)" == ""
+CFG=jpeg - Win32
+!MESSAGE No configuration specified.  Defaulting to jpeg - Win32.
+!ENDIF 
+
+!IF "$(CFG)" != "jpeg - Win32"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE on this makefile
+!MESSAGE by defining the macro CFG on the command line.  For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "jpeg.mak" CFG="jpeg - Win32"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "jpeg - Win32" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+!ERROR An invalid configuration is specified.
+!ENDIF 
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE 
+NULL=nul
+!ENDIF 
+################################################################################
+# Begin Project
+# PROP Target_Last_Scanned "jpeg - Win32"
+CPP=cl.exe
+
+!IF  "$(CFG)" == "jpeg - Win32"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : "$(OUTDIR)\jpeg.lib"
+
+CLEAN : 
+	-@erase "$(INTDIR)\jcapimin.obj"
+	-@erase "$(INTDIR)\jcapistd.obj"
+	-@erase "$(INTDIR)\jctrans.obj"
+	-@erase "$(INTDIR)\jcparam.obj"
+	-@erase "$(INTDIR)\jdatadst.obj"
+	-@erase "$(INTDIR)\jcinit.obj"
+	-@erase "$(INTDIR)\jcmaster.obj"
+	-@erase "$(INTDIR)\jcmarker.obj"
+	-@erase "$(INTDIR)\jcmainct.obj"
+	-@erase "$(INTDIR)\jcprepct.obj"
+	-@erase "$(INTDIR)\jccoefct.obj"
+	-@erase "$(INTDIR)\jccolor.obj"
+	-@erase "$(INTDIR)\jcsample.obj"
+	-@erase "$(INTDIR)\jchuff.obj"
+	-@erase "$(INTDIR)\jcphuff.obj"
+	-@erase "$(INTDIR)\jcdctmgr.obj"
+	-@erase "$(INTDIR)\jfdctfst.obj"
+	-@erase "$(INTDIR)\jfdctflt.obj"
+	-@erase "$(INTDIR)\jfdctint.obj"
+	-@erase "$(INTDIR)\jdapimin.obj"
+	-@erase "$(INTDIR)\jdapistd.obj"
+	-@erase "$(INTDIR)\jdtrans.obj"
+	-@erase "$(INTDIR)\jdatasrc.obj"
+	-@erase "$(INTDIR)\jdmaster.obj"
+	-@erase "$(INTDIR)\jdinput.obj"
+	-@erase "$(INTDIR)\jdmarker.obj"
+	-@erase "$(INTDIR)\jdhuff.obj"
+	-@erase "$(INTDIR)\jdphuff.obj"
+	-@erase "$(INTDIR)\jdmainct.obj"
+	-@erase "$(INTDIR)\jdcoefct.obj"
+	-@erase "$(INTDIR)\jdpostct.obj"
+	-@erase "$(INTDIR)\jddctmgr.obj"
+	-@erase "$(INTDIR)\jidctfst.obj"
+	-@erase "$(INTDIR)\jidctflt.obj"
+	-@erase "$(INTDIR)\jidctint.obj"
+	-@erase "$(INTDIR)\jidctred.obj"
+	-@erase "$(INTDIR)\jdsample.obj"
+	-@erase "$(INTDIR)\jdcolor.obj"
+	-@erase "$(INTDIR)\jquant1.obj"
+	-@erase "$(INTDIR)\jquant2.obj"
+	-@erase "$(INTDIR)\jdmerge.obj"
+	-@erase "$(INTDIR)\jcomapi.obj"
+	-@erase "$(INTDIR)\jutils.obj"
+	-@erase "$(INTDIR)\jerror.obj"
+	-@erase "$(INTDIR)\jmemmgr.obj"
+	-@erase "$(INTDIR)\jmemnobs.obj"
+	-@erase "$(OUTDIR)\jpeg.lib"
+
+"$(OUTDIR)" :
+    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
+CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\
+ /Fp"$(INTDIR)/jpeg.pch" /YX /Fo"$(INTDIR)/" /c 
+CPP_OBJS=.\Release/
+CPP_SBRS=.\.
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+BSC32_FLAGS=/nologo /o"$(OUTDIR)/jpeg.bsc" 
+BSC32_SBRS= \
+	
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+LIB32_FLAGS=/nologo /out:"$(OUTDIR)/jpeg.lib" 
+LIB32_OBJS= \
+	"$(INTDIR)\jcapimin.obj" \
+	"$(INTDIR)\jcapistd.obj" \
+	"$(INTDIR)\jctrans.obj" \
+	"$(INTDIR)\jcparam.obj" \
+	"$(INTDIR)\jdatadst.obj" \
+	"$(INTDIR)\jcinit.obj" \
+	"$(INTDIR)\jcmaster.obj" \
+	"$(INTDIR)\jcmarker.obj" \
+	"$(INTDIR)\jcmainct.obj" \
+	"$(INTDIR)\jcprepct.obj" \
+	"$(INTDIR)\jccoefct.obj" \
+	"$(INTDIR)\jccolor.obj" \
+	"$(INTDIR)\jcsample.obj" \
+	"$(INTDIR)\jchuff.obj" \
+	"$(INTDIR)\jcphuff.obj" \
+	"$(INTDIR)\jcdctmgr.obj" \
+	"$(INTDIR)\jfdctfst.obj" \
+	"$(INTDIR)\jfdctflt.obj" \
+	"$(INTDIR)\jfdctint.obj" \
+	"$(INTDIR)\jdapimin.obj" \
+	"$(INTDIR)\jdapistd.obj" \
+	"$(INTDIR)\jdtrans.obj" \
+	"$(INTDIR)\jdatasrc.obj" \
+	"$(INTDIR)\jdmaster.obj" \
+	"$(INTDIR)\jdinput.obj" \
+	"$(INTDIR)\jdmarker.obj" \
+	"$(INTDIR)\jdhuff.obj" \
+	"$(INTDIR)\jdphuff.obj" \
+	"$(INTDIR)\jdmainct.obj" \
+	"$(INTDIR)\jdcoefct.obj" \
+	"$(INTDIR)\jdpostct.obj" \
+	"$(INTDIR)\jddctmgr.obj" \
+	"$(INTDIR)\jidctfst.obj" \
+	"$(INTDIR)\jidctflt.obj" \
+	"$(INTDIR)\jidctint.obj" \
+	"$(INTDIR)\jidctred.obj" \
+	"$(INTDIR)\jdsample.obj" \
+	"$(INTDIR)\jdcolor.obj" \
+	"$(INTDIR)\jquant1.obj" \
+	"$(INTDIR)\jquant2.obj" \
+	"$(INTDIR)\jdmerge.obj" \
+	"$(INTDIR)\jcomapi.obj" \
+	"$(INTDIR)\jutils.obj" \
+	"$(INTDIR)\jerror.obj" \
+	"$(INTDIR)\jmemmgr.obj" \
+	"$(INTDIR)\jmemnobs.obj"
+
+"$(OUTDIR)\jpeg.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
+    $(LIB32) @<<
+  $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
+<<
+
+!ENDIF 
+
+.c{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_OBJS)}.obj:
+   $(CPP) $(CPP_PROJ) $<  
+
+.c{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cpp{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+.cxx{$(CPP_SBRS)}.sbr:
+   $(CPP) $(CPP_PROJ) $<  
+
+################################################################################
+# Begin Target
+
+# Name "jpeg - Win32"
+
+!IF  "$(CFG)" == "jpeg - Win32"
+
+!ENDIF 
+
+################################################################################
+# Begin Source File
+
+SOURCE="jcapimin.c"
+DEP_CPP_JCAPI=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcapimin.obj" : $(SOURCE) $(DEP_CPP_JCAPI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcapistd.c"
+DEP_CPP_JCAPIS=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcapistd.obj" : $(SOURCE) $(DEP_CPP_JCAPIS) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jccoefct.c"
+DEP_CPP_JCCOE=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jccoefct.obj" : $(SOURCE) $(DEP_CPP_JCCOE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jccolor.c"
+DEP_CPP_JCCOL=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jccolor.obj" : $(SOURCE) $(DEP_CPP_JCCOL) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcdctmgr.c"
+DEP_CPP_JCDCT=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jcdctmgr.obj" : $(SOURCE) $(DEP_CPP_JCDCT) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jchuff.c"
+DEP_CPP_JCHUF=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jchuff.h"\
+	
+
+"$(INTDIR)\jchuff.obj" : $(SOURCE) $(DEP_CPP_JCHUF) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcinit.c"
+DEP_CPP_JCINI=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcinit.obj" : $(SOURCE) $(DEP_CPP_JCINI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcmainct.c"
+DEP_CPP_JCMAI=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcmainct.obj" : $(SOURCE) $(DEP_CPP_JCMAI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcmarker.c"
+DEP_CPP_JCMAR=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcmarker.obj" : $(SOURCE) $(DEP_CPP_JCMAR) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcmaster.c"
+DEP_CPP_JCMAS=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcmaster.obj" : $(SOURCE) $(DEP_CPP_JCMAS) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcomapi.c"
+DEP_CPP_JCOMA=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcomapi.obj" : $(SOURCE) $(DEP_CPP_JCOMA) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcparam.c"
+DEP_CPP_JCPAR=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcparam.obj" : $(SOURCE) $(DEP_CPP_JCPAR) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcphuff.c"
+DEP_CPP_JCPHU=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jchuff.h"\
+	
+
+"$(INTDIR)\jcphuff.obj" : $(SOURCE) $(DEP_CPP_JCPHU) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcprepct.c"
+DEP_CPP_JCPRE=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcprepct.obj" : $(SOURCE) $(DEP_CPP_JCPRE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jcsample.c"
+DEP_CPP_JCSAM=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jcsample.obj" : $(SOURCE) $(DEP_CPP_JCSAM) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jctrans.c"
+DEP_CPP_JCTRA=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jctrans.obj" : $(SOURCE) $(DEP_CPP_JCTRA) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdapimin.c"
+DEP_CPP_JDAPI=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdapimin.obj" : $(SOURCE) $(DEP_CPP_JDAPI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdapistd.c"
+DEP_CPP_JDAPIS=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdapistd.obj" : $(SOURCE) $(DEP_CPP_JDAPIS) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdatadst.c"
+DEP_CPP_JDATA=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdatadst.obj" : $(SOURCE) $(DEP_CPP_JDATA) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdatasrc.c"
+DEP_CPP_JDATAS=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdatasrc.obj" : $(SOURCE) $(DEP_CPP_JDATAS) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdcoefct.c"
+DEP_CPP_JDCOE=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdcoefct.obj" : $(SOURCE) $(DEP_CPP_JDCOE) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdcolor.c"
+DEP_CPP_JDCOL=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdcolor.obj" : $(SOURCE) $(DEP_CPP_JDCOL) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jddctmgr.c"
+DEP_CPP_JDDCT=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jddctmgr.obj" : $(SOURCE) $(DEP_CPP_JDDCT) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdhuff.c"
+DEP_CPP_JDHUF=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdhuff.h"\
+	
+
+"$(INTDIR)\jdhuff.obj" : $(SOURCE) $(DEP_CPP_JDHUF) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdinput.c"
+DEP_CPP_JDINP=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdinput.obj" : $(SOURCE) $(DEP_CPP_JDINP) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdmainct.c"
+DEP_CPP_JDMAI=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdmainct.obj" : $(SOURCE) $(DEP_CPP_JDMAI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdmarker.c"
+DEP_CPP_JDMAR=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdmarker.obj" : $(SOURCE) $(DEP_CPP_JDMAR) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdmaster.c"
+DEP_CPP_JDMAS=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdmaster.obj" : $(SOURCE) $(DEP_CPP_JDMAS) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdmerge.c"
+DEP_CPP_JDMER=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdmerge.obj" : $(SOURCE) $(DEP_CPP_JDMER) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdphuff.c"
+DEP_CPP_JDPHU=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdhuff.h"\
+	
+
+"$(INTDIR)\jdphuff.obj" : $(SOURCE) $(DEP_CPP_JDPHU) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdpostct.c"
+DEP_CPP_JDPOS=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdpostct.obj" : $(SOURCE) $(DEP_CPP_JDPOS) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdsample.c"
+DEP_CPP_JDSAM=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdsample.obj" : $(SOURCE) $(DEP_CPP_JDSAM) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jdtrans.c"
+DEP_CPP_JDTRA=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jdtrans.obj" : $(SOURCE) $(DEP_CPP_JDTRA) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jerror.c"
+DEP_CPP_JERRO=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jversion.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jerror.obj" : $(SOURCE) $(DEP_CPP_JERRO) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jfdctflt.c"
+DEP_CPP_JFDCT=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jfdctflt.obj" : $(SOURCE) $(DEP_CPP_JFDCT) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jfdctfst.c"
+DEP_CPP_JFDCTF=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jfdctfst.obj" : $(SOURCE) $(DEP_CPP_JFDCTF) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jfdctint.c"
+DEP_CPP_JFDCTI=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jfdctint.obj" : $(SOURCE) $(DEP_CPP_JFDCTI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jidctflt.c"
+DEP_CPP_JIDCT=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jidctflt.obj" : $(SOURCE) $(DEP_CPP_JIDCT) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jidctfst.c"
+DEP_CPP_JIDCTF=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jidctfst.obj" : $(SOURCE) $(DEP_CPP_JIDCTF) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jidctint.c"
+DEP_CPP_JIDCTI=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jidctint.obj" : $(SOURCE) $(DEP_CPP_JIDCTI) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jidctred.c"
+DEP_CPP_JIDCTR=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jdct.h"\
+	
+
+"$(INTDIR)\jidctred.obj" : $(SOURCE) $(DEP_CPP_JIDCTR) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jquant1.c"
+DEP_CPP_JQUAN=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jquant1.obj" : $(SOURCE) $(DEP_CPP_JQUAN) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jquant2.c"
+DEP_CPP_JQUANT=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jquant2.obj" : $(SOURCE) $(DEP_CPP_JQUANT) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jutils.c"
+DEP_CPP_JUTIL=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	
+
+"$(INTDIR)\jutils.obj" : $(SOURCE) $(DEP_CPP_JUTIL) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jmemmgr.c"
+DEP_CPP_JMEMM=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jmemsys.h"\
+	
+
+"$(INTDIR)\jmemmgr.obj" : $(SOURCE) $(DEP_CPP_JMEMM) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+################################################################################
+# Begin Source File
+
+SOURCE="jmemnobs.c"
+DEP_CPP_JMEMN=\
+	"jinclude.h"\
+	"jconfig.h"\
+	"jpeglib.h"\
+	"jmorecfg.h"\
+	"jpegint.h"\
+	"jerror.h"\
+	"jmemsys.h"\
+	
+
+"$(INTDIR)\jmemnobs.obj" : $(SOURCE) $(DEP_CPP_JMEMN) "$(INTDIR)"
+   $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+# End Source File
+# End Target
+# End Project
+################################################################################
+
diff --git a/makeproj.mac b/makeproj.mac
new file mode 100644
index 0000000..ed277c8
--- /dev/null
+++ b/makeproj.mac
@@ -0,0 +1,213 @@
+--
+-- makeproj.mac
+--
+-- This AppleScript builds Code Warrior PRO Release 2 project files for the
+-- libjpeg library as well as the test programs 'cjpeg', 'djpeg', 'jpegtran'.
+-- (We'd distribute real project files, except they're not text
+-- and would create maintenance headaches.)
+--
+-- The script then compiles and links the library and the test programs.
+-- NOTE: if you haven't already created a 'jconfig.h' file, the script
+-- automatically copies 'jconfig.mac' to 'jconfig.h'.
+--
+-- To use this script, you must have AppleScript 1.1 or later installed
+-- and a suitable AppleScript editor like Script Editor or Script Debugger
+-- (http://www.latenightsw.com). Open this file with your AppleScript
+-- editor and execute the "run" command to build the projects.
+--
+-- Thanks to Dan Sears and Don Agro for this script.
+-- Questions about this script can be addressed to dogpark@interlog.com
+--
+
+on run
+
+	choose folder with prompt ">>> Select IJG source folder <<<"
+	set ijg_folder to result
+
+	choose folder with prompt ">>> Select MetroWerks folder <<<"
+	set cw_folder to result
+
+	-- if jconfig.h doesn't already exist, copy jconfig.mac
+
+	tell application "Finder"
+		if not (exists file "jconfig.h" of ijg_folder) then
+			duplicate {file "jconfig.mac" of folder ijg_folder}
+			select file "jconfig.mac copy" of folder ijg_folder
+			set name of selection to "jconfig.h"
+		end if
+	end tell
+
+	tell application "CodeWarrior IDE 2.1"
+	  with timeout of 10000 seconds
+
+		-- create libjpeg project
+
+		activate
+		Create Project (ijg_folder as string) & "libjpeg.proj"
+		Set Preferences of panel "Target Settings" to {Target Name:"libjpeg"}
+		Set Preferences of panel "PPC Project" to {File Name:"libjpeg"}
+		Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"}
+		Set Preferences of panel "PPC Project" to {Project Type:library}
+		Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true}
+		Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true}
+		Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC}
+		Set Preferences of panel "PPC Linker" to {Generate SYM File:false}
+
+		Add Files (ijg_folder as string) & "jcapimin.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcapistd.c" To Segment 1
+		Add Files (ijg_folder as string) & "jctrans.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcparam.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdatadst.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcinit.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcmaster.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcmarker.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcmainct.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcprepct.c" To Segment 1
+		Add Files (ijg_folder as string) & "jccoefct.c" To Segment 1
+		Add Files (ijg_folder as string) & "jccolor.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcsample.c" To Segment 1
+		Add Files (ijg_folder as string) & "jchuff.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcphuff.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcdctmgr.c" To Segment 1
+		Add Files (ijg_folder as string) & "jfdctfst.c" To Segment 1
+		Add Files (ijg_folder as string) & "jfdctflt.c" To Segment 1
+		Add Files (ijg_folder as string) & "jfdctint.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdapimin.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdapistd.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdtrans.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdatasrc.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdmaster.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdinput.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdmarker.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdhuff.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdphuff.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdmainct.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdcoefct.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdpostct.c" To Segment 1
+		Add Files (ijg_folder as string) & "jddctmgr.c" To Segment 1
+		Add Files (ijg_folder as string) & "jidctfst.c" To Segment 1
+		Add Files (ijg_folder as string) & "jidctflt.c" To Segment 1
+		Add Files (ijg_folder as string) & "jidctint.c" To Segment 1
+		Add Files (ijg_folder as string) & "jidctred.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdsample.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdcolor.c" To Segment 1
+		Add Files (ijg_folder as string) & "jquant1.c" To Segment 1
+		Add Files (ijg_folder as string) & "jquant2.c" To Segment 1
+		Add Files (ijg_folder as string) & "jdmerge.c" To Segment 1
+		Add Files (ijg_folder as string) & "jcomapi.c" To Segment 1
+		Add Files (ijg_folder as string) & "jutils.c" To Segment 1
+		Add Files (ijg_folder as string) & "jerror.c" To Segment 1
+		Add Files (ijg_folder as string) & "jmemmgr.c" To Segment 1
+		Add Files (ijg_folder as string) & "jmemmac.c" To Segment 1
+
+		-- compile and link the library
+
+		Make Project
+		Close Project
+
+		-- create cjpeg project
+
+		activate
+		Create Project (ijg_folder as string) & "cjpeg.proj"
+		Set Preferences of panel "Target Settings" to {Target Name:"cjpeg"}
+		Set Preferences of panel "PPC Project" to {File Name:"cjpeg"}
+		Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"}
+		Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true}
+		Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true}
+		Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC}
+		Set Preferences of panel "PPC Linker" to {Generate SYM File:false}
+
+		Add Files (ijg_folder as string) & "cjpeg.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdppm.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdgif.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdtarga.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdrle.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdbmp.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdswitch.c" To Segment 1
+		Add Files (ijg_folder as string) & "cdjpeg.c" To Segment 1
+
+		Add Files (ijg_folder as string) & "libjpeg" To Segment 2
+
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL C.PPC.Lib" To Segment 3
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL SIOUX.PPC.Lib" To Segment 3
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.Lib" To Segment 3
+
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:InterfaceLib" To Segment 4
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:MathLib" To Segment 4
+
+		-- compile and link cjpeg
+
+		Make Project
+		Close Project
+
+		-- create djpeg project
+
+		activate
+		Create Project (ijg_folder as string) & "djpeg.proj"
+		Set Preferences of panel "Target Settings" to {Target Name:"djpeg"}
+		Set Preferences of panel "PPC Project" to {File Name:"djpeg"}
+		Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"}
+		Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true}
+		Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true}
+		Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC}
+		Set Preferences of panel "PPC Linker" to {Generate SYM File:false}
+
+		Add Files (ijg_folder as string) & "djpeg.c" To Segment 1
+		Add Files (ijg_folder as string) & "wrppm.c" To Segment 1
+		Add Files (ijg_folder as string) & "wrgif.c" To Segment 1
+		Add Files (ijg_folder as string) & "wrtarga.c" To Segment 1
+		Add Files (ijg_folder as string) & "wrrle.c" To Segment 1
+		Add Files (ijg_folder as string) & "wrbmp.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdcolmap.c" To Segment 1
+		Add Files (ijg_folder as string) & "cdjpeg.c" To Segment 1
+
+		Add Files (ijg_folder as string) & "libjpeg" To Segment 2
+
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL C.PPC.Lib" To Segment 3
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL SIOUX.PPC.Lib" To Segment 3
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.Lib" To Segment 3
+
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:InterfaceLib" To Segment 4
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:MathLib" To Segment 4
+
+		-- compile and link djpeg
+
+		Make Project
+		Close Project
+
+		-- create jpegtran project
+
+		activate
+		Create Project (ijg_folder as string) & "jpegtran.proj"
+		Set Preferences of panel "Target Settings" to {Target Name:"jpegtran"}
+		Set Preferences of panel "PPC Project" to {File Name:"jpegtran"}
+		Set Preferences of panel "Target Settings" to {Linker:"MacOS PPC Linker"}
+		Set Preferences of panel "C/C++ Compiler" to {ANSI Strict:true}
+		Set Preferences of panel "C/C++ Compiler" to {Enums Always Ints:true}
+		Set Preferences of panel "PPC Codegen" to {Struct Alignment:PowerPC}
+		Set Preferences of panel "PPC Linker" to {Generate SYM File:false}
+
+		Add Files (ijg_folder as string) & "jpegtran.c" To Segment 1
+		Add Files (ijg_folder as string) & "rdswitch.c" To Segment 1
+		Add Files (ijg_folder as string) & "cdjpeg.c" To Segment 1
+		Add Files (ijg_folder as string) & "transupp.c" To Segment 1
+
+		Add Files (ijg_folder as string) & "libjpeg" To Segment 2
+
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL C.PPC.Lib" To Segment 3
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:Metrowerks Standard Library:MSL C:Bin:MSL SIOUX.PPC.Lib" To Segment 3
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.Lib" To Segment 3
+
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:InterfaceLib" To Segment 4
+		Add Files (cw_folder as string) & "Metrowerks CodeWarrior:MacOS Support:Libraries:MacOS Common:MathLib" To Segment 4
+
+		-- compile and link jpegtran
+
+		Make Project
+		Close Project
+
+		quit
+
+	  end timeout
+	end tell
+end run
diff --git a/makljpeg.st b/makljpeg.st
index 435e234..813493e 100644
--- a/makljpeg.st
+++ b/makljpeg.st
@@ -1,10 +1,11 @@
 ; Project file for Independent JPEG Group's software
 ;
 ; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C.
-; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de)
-; and to Dr. B. Setzepfandt (bernd@gina.uni-muenster.de).
+; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de),
+; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de),
+; and Guido Vollbeding (guivol@esc.de).
 ;
-; To use this file, rename it to LIBJPEG.PRJ.
+; To use this file, rename it to libjpeg.prj.
 ; Read installation instructions before trying to make the program!
 ;
 ;
diff --git a/maktjpeg.st b/maktjpeg.st
index 48e57e2..31f4d16 100644
--- a/maktjpeg.st
+++ b/maktjpeg.st
@@ -1,11 +1,12 @@
 ; Project file for Independent JPEG Group's software
 ;
 ; This project file is for Atari ST/STE/TT systems using Pure C or Turbo C.
-; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de)
-; and to Dr. B. Setzepfandt (bernd@gina.uni-muenster.de).
+; Thanks to Frank Moehle (Frank.Moehle@arbi.informatik.uni-oldenburg.de),
+; Dr. B. Setzepfandt (bernd@gina.uni-muenster.de),
+; and Guido Vollbeding (guivol@esc.de).
 ;
-; To use this file, rename it to JPEGTRAN.PRJ.
-; If you are using Turbo C, change filenames beginning with "PC..." to "TC..."
+; To use this file, rename it to jpegtran.prj.
+; If you are using Turbo C, change filenames beginning with "pc..." to "tc..."
 ; Read installation instructions before trying to make the program!
 ;
 ;
@@ -21,10 +22,11 @@
 .C[-wsig]     ; warn if significant digits may be lost
 =
 ; * * * * List of modules * * * * 
-PCSTART.O
-jpegtran.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h,jversion.h)
+pcstart.o
+jpegtran.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h,transupp.h,jversion.h)
 cdjpeg.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
 rdswitch.c	(cdjpeg.h,jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jerror.h,cderror.h)
-LIBJPEG.LIB        ; built by LIBJPEG.PRJ
-PCSTDLIB.LIB       ; standard library
-PCEXTLIB.LIB       ; extended library
+transupp.c	(jinclude.h,jconfig.h,jpeglib.h,jmorecfg.h,jpegint.h,jerror.h,transupp.h)
+libjpeg.lib        ; built by libjpeg.prj
+pcstdlib.lib       ; standard library
+pcextlib.lib       ; extended library
diff --git a/rdcolmap.c b/rdcolmap.c
index f79458e..42b3437 100644
--- a/rdcolmap.c
+++ b/rdcolmap.c
@@ -204,9 +204,9 @@
   case '6':			/* it's a raw-format PPM file */
     for (row = 0; row < h; row++) {
       for (col = 0; col < w; col++) {
-	R = pbm_getc(infile);
-	G = pbm_getc(infile);
-	B = pbm_getc(infile);
+	R = getc(infile);
+	G = getc(infile);
+	B = getc(infile);
 	if (R == EOF || G == EOF || B == EOF)
 	  ERREXIT(cinfo, JERR_BAD_CMAP_FILE);
 	add_map_entry(cinfo, R, G, B);
diff --git a/rdgif.c b/rdgif.c
index 0da2515..b27c167 100644
--- a/rdgif.c
+++ b/rdgif.c
@@ -1,39 +1,19 @@
 /*
  * rdgif.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
- **************************************************************************
- * WARNING: You will need an LZW patent license from Unisys in order to   *
- * use this file legally in any commercial or shareware application.      *
- **************************************************************************
- *
  * This file contains routines to read input images in GIF format.
  *
- * 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).
- */
-
-/*
- * 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.           |
- * +-------------------------------------------------------------------+
+ *****************************************************************************
+ * NOTE: to avoid entanglements with Unisys' patent on LZW compression,      *
+ * the ability to read GIF files has been removed from the IJG distribution. *
+ * Sorry about that.                                                         *
+ *****************************************************************************
  *
- * We are also required to state that
+ * We are required to state that
  *    "The Graphics Interchange Format(c) is the Copyright property of
  *    CompuServe Incorporated. GIF(sm) is a Service Mark property of
  *    CompuServe Incorporated."
@@ -43,622 +23,6 @@
 
 #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
-
-#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)	(JFREAD(file,buffer,len) == ((size_t) (len)))
-
-/* LZW decompression tables look like this:
- *   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.
- */
-
-
-/* Private version of data source object */
-
-typedef struct {
-  struct cjpeg_source_struct pub; /* public fields */
-
-  j_compress_ptr cinfo;		/* back link saves passing separate parm */
-
-  JSAMPARRAY colormap;		/* GIF colormap (converted to my format) */
-
-  /* State for GetCode and LZWReadByte */
-  char code_buf[256+4];		/* current input data block */
-  int last_byte;		/* # of bytes in code_buf */
-  int last_bit;			/* # of bits in code_buf */
-  int cur_bit;			/* next bit index to read */
-  boolean out_of_blocks;	/* TRUE if hit terminator data block */
-
-  int input_code_size;		/* codesize given in GIF file */
-  int clear_code,end_code;	/* values for Clear and End codes */
-
-  int code_size;		/* current actual code size */
-  int limit_code;		/* 2^code_size */
-  int max_code;			/* first unused code value */
-  boolean first_time;		/* flags first call to LZWReadByte */
-
-  /* Private state for LZWReadByte */
-  int oldcode;			/* previous LZW symbol */
-  int firstcode;		/* first byte of oldcode's expansion */
-
-  /* LZW symbol table and expansion stack */
-  UINT16 FAR *symbol_head;	/* => table of prefix symbols */
-  UINT8  FAR *symbol_tail;	/* => table of suffix bytes */
-  UINT8  FAR *symbol_stack;	/* => stack for symbol expansions */
-  UINT8  FAR *sp;		/* stack pointer */
-
-  /* State for interlaced image processing */
-  boolean is_interlaced;	/* TRUE if have interlaced image */
-  jvirt_sarray_ptr interlaced_image; /* full image in interlaced order */
-  JDIMENSION cur_row_number;	/* need to know actual row number */
-  JDIMENSION pass2_offset;	/* # of pixel rows in pass 1 */
-  JDIMENSION pass3_offset;	/* # of pixel rows in passes 1&2 */
-  JDIMENSION pass4_offset;	/* # of pixel rows in passes 1,2,3 */
-} gif_source_struct;
-
-typedef gif_source_struct * gif_source_ptr;
-
-
-/* Forward declarations */
-METHODDEF(JDIMENSION) get_pixel_rows
-	JPP((j_compress_ptr cinfo, cjpeg_source_ptr sinfo));
-METHODDEF(JDIMENSION) load_interlaced_image
-	JPP((j_compress_ptr cinfo, cjpeg_source_ptr sinfo));
-METHODDEF(JDIMENSION) get_interlaced_row
-	JPP((j_compress_ptr cinfo, cjpeg_source_ptr sinfo));
-
-
-LOCAL(int)
-ReadByte (gif_source_ptr sinfo)
-/* Read next byte from GIF file */
-{
-  register FILE * infile = sinfo->pub.input_file;
-  int c;
-
-  if ((c = getc(infile)) == EOF)
-    ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
-  return c;
-}
-
-
-LOCAL(int)
-GetDataBlock (gif_source_ptr sinfo, 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(sinfo);
-  if (count > 0) {
-    if (! ReadOK(sinfo->pub.input_file, buf, count))
-      ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
-  }
-  return count;
-}
-
-
-LOCAL(void)
-SkipDataBlocks (gif_source_ptr sinfo)
-/* Skip a series of data blocks, until a block terminator is found */
-{
-  char buf[256];
-
-  while (GetDataBlock(sinfo, buf) > 0)
-    /* skip */;
-}
-
-
-LOCAL(void)
-ReInitLZW (gif_source_ptr sinfo)
-/* (Re)initialize LZW state; shared code for startup and Clear processing */
-{
-  sinfo->code_size = sinfo->input_code_size + 1;
-  sinfo->limit_code = sinfo->clear_code << 1;	/* 2^code_size */
-  sinfo->max_code = sinfo->clear_code + 2;	/* first unused code value */
-  sinfo->sp = sinfo->symbol_stack;		/* init stack to empty */
-}
-
-
-LOCAL(void)
-InitLZWCode (gif_source_ptr sinfo)
-/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
-{
-  /* GetCode initialization */
-  sinfo->last_byte = 2;		/* make safe to "recopy last two bytes" */
-  sinfo->last_bit = 0;		/* nothing in the buffer */
-  sinfo->cur_bit = 0;		/* force buffer load on first call */
-  sinfo->out_of_blocks = FALSE;
-
-  /* LZWReadByte initialization: */
-  /* compute special code values (note that these do not change later) */
-  sinfo->clear_code = 1 << sinfo->input_code_size;
-  sinfo->end_code = sinfo->clear_code + 1;
-  sinfo->first_time = TRUE;
-  ReInitLZW(sinfo);
-}
-
-
-LOCAL(int)
-GetCode (gif_source_ptr sinfo)
-/* 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;
-
-  while ( (sinfo->cur_bit + sinfo->code_size) > sinfo->last_bit) {
-    /* Time to reload the buffer */
-    if (sinfo->out_of_blocks) {
-      WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
-      return sinfo->end_code;	/* fake something useful */
-    }
-    /* preserve last two bytes of what we have -- assume code_size <= 16 */
-    sinfo->code_buf[0] = sinfo->code_buf[sinfo->last_byte-2];
-    sinfo->code_buf[1] = sinfo->code_buf[sinfo->last_byte-1];
-    /* Load more bytes; set flag if we reach the terminator block */
-    if ((count = GetDataBlock(sinfo, &sinfo->code_buf[2])) == 0) {
-      sinfo->out_of_blocks = TRUE;
-      WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
-      return sinfo->end_code;	/* fake something useful */
-    }
-    /* Reset counters */
-    sinfo->cur_bit = (sinfo->cur_bit - sinfo->last_bit) + 16;
-    sinfo->last_byte = 2 + count;
-    sinfo->last_bit = sinfo->last_byte * 8;
-  }
-
-  /* Form up next 24 bits in accum */
-  offs = sinfo->cur_bit >> 3;	/* byte containing cur_bit */
-#ifdef CHAR_IS_UNSIGNED
-  accum = sinfo->code_buf[offs+2];
-  accum <<= 8;
-  accum |= sinfo->code_buf[offs+1];
-  accum <<= 8;
-  accum |= sinfo->code_buf[offs];
-#else
-  accum = sinfo->code_buf[offs+2] & 0xFF;
-  accum <<= 8;
-  accum |= sinfo->code_buf[offs+1] & 0xFF;
-  accum <<= 8;
-  accum |= sinfo->code_buf[offs] & 0xFF;
-#endif
-
-  /* Right-align cur_bit in accum, then mask off desired number of bits */
-  accum >>= (sinfo->cur_bit & 7);
-  ret = ((int) accum) & ((1 << sinfo->code_size) - 1);
-  
-  sinfo->cur_bit += sinfo->code_size;
-  return ret;
-}
-
-
-LOCAL(int)
-LZWReadByte (gif_source_ptr sinfo)
-/* Read an LZW-compressed byte */
-{
-  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 expected to be a raw byte. */
-  if (sinfo->first_time) {
-    sinfo->first_time = FALSE;
-    code = sinfo->clear_code;	/* enables sharing code with Clear case */
-  } else {
-
-    /* If any codes are stacked from a previously read symbol, return them */
-    if (sinfo->sp > sinfo->symbol_stack)
-      return (int) *(-- sinfo->sp);
-
-    /* Time to read a new symbol */
-    code = GetCode(sinfo);
-
-  }
-
-  if (code == sinfo->clear_code) {
-    /* Reinit state, swallow any extra Clear codes, and */
-    /* return next code, which is expected to be a raw byte. */
-    ReInitLZW(sinfo);
-    do {
-      code = GetCode(sinfo);
-    } while (code == sinfo->clear_code);
-    if (code > sinfo->clear_code) { /* make sure it is a raw byte */
-      WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
-      code = 0;			/* use something valid */
-    }
-    /* make firstcode, oldcode valid! */
-    sinfo->firstcode = sinfo->oldcode = code;
-    return code;
-  }
-
-  if (code == sinfo->end_code) {
-    /* Skip the rest of the image, unless GetCode already read terminator */
-    if (! sinfo->out_of_blocks) {
-      SkipDataBlocks(sinfo);
-      sinfo->out_of_blocks = TRUE;
-    }
-    /* Complain that there's not enough data */
-    WARNMS(sinfo->cinfo, JWRN_GIF_ENDCODE);
-    /* Pad data with 0's */
-    return 0;			/* fake something usable */
-  }
-
-  /* Got normal raw byte or LZW symbol */
-  incode = code;		/* save for a moment */
-  
-  if (code >= sinfo->max_code) { /* special case for not-yet-defined symbol */
-    /* code == max_code is OK; anything bigger is bad data */
-    if (code > sinfo->max_code) {
-      WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
-      incode = 0;		/* prevent creation of loops in symbol table */
-    }
-    /* this symbol will be defined as oldcode/firstcode */
-    *(sinfo->sp++) = (UINT8) sinfo->firstcode;
-    code = sinfo->oldcode;
-  }
-
-  /* If it's a symbol, expand it into the stack */
-  while (code >= sinfo->clear_code) {
-    *(sinfo->sp++) = sinfo->symbol_tail[code]; /* tail is a byte value */
-    code = sinfo->symbol_head[code]; /* head is another LZW symbol */
-  }
-  /* At this point code just represents a raw byte */
-  sinfo->firstcode = code;	/* save for possible future use */
-
-  /* If there's room in table, */
-  if ((code = sinfo->max_code) < LZW_TABLE_SIZE) {
-    /* Define a new symbol = prev sym + head of this sym's expansion */
-    sinfo->symbol_head[code] = sinfo->oldcode;
-    sinfo->symbol_tail[code] = (UINT8) sinfo->firstcode;
-    sinfo->max_code++;
-    /* Is it time to increase code_size? */
-    if ((sinfo->max_code >= sinfo->limit_code) &&
-	(sinfo->code_size < MAX_LZW_BITS)) {
-      sinfo->code_size++;
-      sinfo->limit_code <<= 1;	/* keep equal to 2^code_size */
-    }
-  }
-  
-  sinfo->oldcode = incode;	/* save last input symbol for future use */
-  return sinfo->firstcode;	/* return first byte of symbol's expansion */
-}
-
-
-LOCAL(void)
-ReadColorMap (gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap)
-/* Read a GIF colormap */
-{
-  int i;
-
-  for (i = 0; i < cmaplen; i++) {
-#if BITS_IN_JSAMPLE == 8
-#define UPSCALE(x)  (x)
-#else
-#define UPSCALE(x)  ((x) << (BITS_IN_JSAMPLE-8))
-#endif
-    cmap[CM_RED][i]   = (JSAMPLE) UPSCALE(ReadByte(sinfo));
-    cmap[CM_GREEN][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
-    cmap[CM_BLUE][i]  = (JSAMPLE) UPSCALE(ReadByte(sinfo));
-  }
-}
-
-
-LOCAL(void)
-DoExtension (gif_source_ptr sinfo)
-/* Process an extension block */
-/* Currently we ignore 'em all */
-{
-  int extlabel;
-
-  /* Read extension label byte */
-  extlabel = ReadByte(sinfo);
-  TRACEMS1(sinfo->cinfo, 1, JTRC_GIF_EXTENSION, extlabel);
-  /* Skip the data block(s) associated with the extension */
-  SkipDataBlocks(sinfo);
-}
-
-
-/*
- * Read the file header; return image size and component count.
- */
-
-METHODDEF(void)
-start_input_gif (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  gif_source_ptr source = (gif_source_ptr) sinfo;
-  char hdrbuf[10];		/* workspace for reading control blocks */
-  unsigned int width, height;	/* image dimensions */
-  int colormaplen, aspectRatio;
-  int c;
-
-  /* Allocate space to store the colormap */
-  source->colormap = (*cinfo->mem->alloc_sarray)
-    ((j_common_ptr) cinfo, JPOOL_IMAGE,
-     (JDIMENSION) MAXCOLORMAPSIZE, (JDIMENSION) NUMCOLORS);
-
-  /* Read and verify GIF Header */
-  if (! ReadOK(source->pub.input_file, hdrbuf, 6))
-    ERREXIT(cinfo, JERR_GIF_NOT);
-  if (hdrbuf[0] != 'G' || hdrbuf[1] != 'I' || hdrbuf[2] != 'F')
-    ERREXIT(cinfo, JERR_GIF_NOT);
-  /* Check for expected version numbers.
-   * If unknown version, give warning and try to process anyway;
-   * this is per recommendation in GIF89a standard.
-   */
-  if ((hdrbuf[3] != '8' || hdrbuf[4] != '7' || hdrbuf[5] != 'a') &&
-      (hdrbuf[3] != '8' || hdrbuf[4] != '9' || hdrbuf[5] != 'a'))
-    TRACEMS3(cinfo, 1, JTRC_GIF_BADVERSION, hdrbuf[3], hdrbuf[4], hdrbuf[5]);
-
-  /* Read and decipher Logical Screen Descriptor */
-  if (! ReadOK(source->pub.input_file, hdrbuf, 7))
-    ERREXIT(cinfo, JERR_INPUT_EOF);
-  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, 1, JTRC_GIF_NONSQUARE);
-
-  /* Read global colormap if header indicates it is present */
-  if (BitSet(hdrbuf[4], COLORMAPFLAG))
-    ReadColorMap(source, colormaplen, source->colormap);
-
-  /* Scan until we reach start of desired image.
-   * We don't currently support skipping images, but could add it easily.
-   */
-  for (;;) {
-    c = ReadByte(source);
-
-    if (c == ';')		/* GIF terminator?? */
-      ERREXIT(cinfo, JERR_GIF_IMAGENOTFOUND);
-
-    if (c == '!') {		/* Extension */
-      DoExtension(source);
-      continue;
-    }
-    
-    if (c != ',') {		/* Not an image separator? */
-      WARNMS1(cinfo, JWRN_GIF_CHAR, c);
-      continue;
-    }
-
-    /* Read and decipher Local Image Descriptor */
-    if (! ReadOK(source->pub.input_file, hdrbuf, 9))
-      ERREXIT(cinfo, JERR_INPUT_EOF);
-    /* 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]);
-    source->is_interlaced = BitSet(hdrbuf[8], INTERLACE);
-
-    /* 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)) {
-      colormaplen = 2 << (hdrbuf[8] & 0x07);
-      ReadColorMap(source, colormaplen, source->colormap);
-    }
-
-    source->input_code_size = ReadByte(source); /* get min-code-size byte */
-    if (source->input_code_size < 2 || source->input_code_size >= MAX_LZW_BITS)
-      ERREXIT1(cinfo, JERR_GIF_CODESIZE, source->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 */
-  source->symbol_head = (UINT16 FAR *)
-    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				LZW_TABLE_SIZE * SIZEOF(UINT16));
-  source->symbol_tail = (UINT8 FAR *)
-    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				LZW_TABLE_SIZE * SIZEOF(UINT8));
-  source->symbol_stack = (UINT8 FAR *)
-    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				LZW_TABLE_SIZE * SIZEOF(UINT8));
-  InitLZWCode(source);
-
-  /*
-   * If image is interlaced, we read it into a full-size sample array,
-   * decompressing as we go; then get_interlaced_row selects rows from the
-   * sample array in the proper order.
-   */
-  if (source->is_interlaced) {
-    /* We request the virtual array now, but can't access it until virtual
-     * arrays have been allocated.  Hence, the actual work of reading the
-     * image is postponed until the first call to get_pixel_rows.
-     */
-    source->interlaced_image = (*cinfo->mem->request_virt_sarray)
-      ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
-       (JDIMENSION) width, (JDIMENSION) height, (JDIMENSION) 1);
-    if (cinfo->progress != NULL) {
-      cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
-      progress->total_extra_passes++; /* count file input as separate pass */
-    }
-    source->pub.get_pixel_rows = load_interlaced_image;
-  } else {
-    source->pub.get_pixel_rows = get_pixel_rows;
-  }
-
-  /* Create compressor input buffer. */
-  source->pub.buffer = (*cinfo->mem->alloc_sarray)
-    ((j_common_ptr) cinfo, JPOOL_IMAGE,
-     (JDIMENSION) width * NUMCOLORS, (JDIMENSION) 1);
-  source->pub.buffer_height = 1;
-
-  /* Return info about the image. */
-  cinfo->in_color_space = JCS_RGB;
-  cinfo->input_components = NUMCOLORS;
-  cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
-  cinfo->image_width = width;
-  cinfo->image_height = height;
-
-  TRACEMS3(cinfo, 1, JTRC_GIF, width, height, colormaplen);
-}
-
-
-/*
- * Read one row of pixels.
- * This version is used for noninterlaced GIF images:
- * we read directly from the GIF file.
- */
-
-METHODDEF(JDIMENSION)
-get_pixel_rows (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  gif_source_ptr source = (gif_source_ptr) sinfo;
-  register int c;
-  register JSAMPROW ptr;
-  register JDIMENSION col;
-  register JSAMPARRAY colormap = source->colormap;
-  
-  ptr = source->pub.buffer[0];
-  for (col = cinfo->image_width; col > 0; col--) {
-    c = LZWReadByte(source);
-    *ptr++ = colormap[CM_RED][c];
-    *ptr++ = colormap[CM_GREEN][c];
-    *ptr++ = colormap[CM_BLUE][c];
-  }
-  return 1;
-}
-
-
-/*
- * Read one row of pixels.
- * This version is used for the first call on get_pixel_rows when
- * reading an interlaced GIF file: we read the whole image into memory.
- */
-
-METHODDEF(JDIMENSION)
-load_interlaced_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  gif_source_ptr source = (gif_source_ptr) sinfo;
-  JSAMPARRAY image_ptr;
-  register JSAMPROW sptr;
-  register JDIMENSION col;
-  JDIMENSION row;
-  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
-
-  /* Read the interlaced image into the virtual array we've created. */
-  for (row = 0; row < cinfo->image_height; row++) {
-    if (progress != NULL) {
-      progress->pub.pass_counter = (long) row;
-      progress->pub.pass_limit = (long) cinfo->image_height;
-      (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
-    }
-    image_ptr = (*cinfo->mem->access_virt_sarray)
-      ((j_common_ptr) cinfo, source->interlaced_image,
-       row, (JDIMENSION) 1, TRUE);
-    sptr = image_ptr[0];
-    for (col = cinfo->image_width; col > 0; col--) {
-      *sptr++ = (JSAMPLE) LZWReadByte(source);
-    }
-  }
-  if (progress != NULL)
-    progress->completed_extra_passes++;
-
-  /* Replace method pointer so subsequent calls don't come here. */
-  source->pub.get_pixel_rows = get_interlaced_row;
-  /* Initialize for get_interlaced_row, and perform first call on it. */
-  source->cur_row_number = 0;
-  source->pass2_offset = (cinfo->image_height + 7) / 8;
-  source->pass3_offset = source->pass2_offset + (cinfo->image_height + 3) / 8;
-  source->pass4_offset = source->pass3_offset + (cinfo->image_height + 1) / 4;
-
-  return get_interlaced_row(cinfo, sinfo);
-}
-
-
-/*
- * Read one row of pixels.
- * This version is used for interlaced GIF images:
- * we read from the virtual array.
- */
-
-METHODDEF(JDIMENSION)
-get_interlaced_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  gif_source_ptr source = (gif_source_ptr) sinfo;
-  JSAMPARRAY image_ptr;
-  register int c;
-  register JSAMPROW sptr, ptr;
-  register JDIMENSION col;
-  register JSAMPARRAY colormap = source->colormap;
-  JDIMENSION irow;
-
-  /* Figure out which row of interlaced image is needed, and access it. */
-  switch ((int) (source->cur_row_number & 7)) {
-  case 0:			/* first-pass row */
-    irow = source->cur_row_number >> 3;
-    break;
-  case 4:			/* second-pass row */
-    irow = (source->cur_row_number >> 3) + source->pass2_offset;
-    break;
-  case 2:			/* third-pass row */
-  case 6:
-    irow = (source->cur_row_number >> 2) + source->pass3_offset;
-    break;
-  default:			/* fourth-pass row */
-    irow = (source->cur_row_number >> 1) + source->pass4_offset;
-    break;
-  }
-  image_ptr = (*cinfo->mem->access_virt_sarray)
-    ((j_common_ptr) cinfo, source->interlaced_image,
-     irow, (JDIMENSION) 1, FALSE);
-  /* Scan the row, expand colormap, and output */
-  sptr = image_ptr[0];
-  ptr = source->pub.buffer[0];
-  for (col = cinfo->image_width; col > 0; col--) {
-    c = GETJSAMPLE(*sptr++);
-    *ptr++ = colormap[CM_RED][c];
-    *ptr++ = colormap[CM_GREEN][c];
-    *ptr++ = colormap[CM_BLUE][c];
-  }
-  source->cur_row_number++;	/* for next time */
-  return 1;
-}
-
-
-/*
- * Finish up at the end of the file.
- */
-
-METHODDEF(void)
-finish_input_gif (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
-{
-  /* no work */
-}
-
-
 /*
  * The module selection routine for GIF format input.
  */
@@ -666,18 +30,9 @@
 GLOBAL(cjpeg_source_ptr)
 jinit_read_gif (j_compress_ptr cinfo)
 {
-  gif_source_ptr source;
-
-  /* Create module interface object */
-  source = (gif_source_ptr)
-      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				  SIZEOF(gif_source_struct));
-  source->cinfo = cinfo;	/* make back link for subroutines */
-  /* Fill in method ptrs, except get_pixel_rows which start_input sets */
-  source->pub.start_input = start_input_gif;
-  source->pub.finish_input = finish_input_gif;
-
-  return (cjpeg_source_ptr) source;
+  fprintf(stderr, "GIF input is unsupported for legal reasons.  Sorry.\n");
+  exit(EXIT_FAILURE);
+  return NULL;			/* keep compiler happy */
 }
 
 #endif /* GIF_SUPPORTED */
diff --git a/rdjpgcom.1 b/rdjpgcom.1
index 0de92bf..2bba04e 100644
--- a/rdjpgcom.1
+++ b/rdjpgcom.1
@@ -1,4 +1,4 @@
-.TH RDJPGCOM 1 "15 June 1995"
+.TH RDJPGCOM 1 "11 October 1997"
 .SH NAME
 rdjpgcom \- display text comments from a JPEG file
 .SH SYNOPSIS
@@ -36,6 +36,15 @@
 does not depend on the IJG JPEG library.  Its source code is intended as an
 illustration of the minimum amount of code required to parse a JPEG file
 header correctly.
+.PP
+In
+.B \-verbose
+mode,
+.B rdjpgcom
+will also attempt to print the contents of any "APP12" markers as text.
+Some digital cameras produce APP12 markers containing useful textual
+information.  If you like, you can modify the source code to print
+other APPn marker types as well.
 .SH SEE ALSO
 .BR cjpeg (1),
 .BR djpeg (1),
diff --git a/rdjpgcom.c b/rdjpgcom.c
index 95770ec..ffe6fc6 100644
--- a/rdjpgcom.c
+++ b/rdjpgcom.c
@@ -1,7 +1,7 @@
 /*
  * rdjpgcom.c
  *
- * Copyright (C) 1994-1995, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -34,8 +34,12 @@
 #ifdef DONT_USE_B_MODE		/* define mode parameters for fopen() */
 #define READ_BINARY	"r"
 #else
+#ifdef VMS			/* VMS is very nonstandard */
+#define READ_BINARY	"rb", "ctx=stm"
+#else				/* standard ANSI-compliant case */
 #define READ_BINARY	"rb"
 #endif
+#endif
 
 #ifndef EXIT_FAILURE		/* define exit() codes if not provided */
 #define EXIT_FAILURE  1
@@ -115,6 +119,8 @@
 #define M_SOI   0xD8		/* Start Of Image (beginning of datastream) */
 #define M_EOI   0xD9		/* End Of Image (end of datastream) */
 #define M_SOS   0xDA		/* Start Of Scan (begins compressed data) */
+#define M_APP0	0xE0		/* Application-specific marker, type N */
+#define M_APP12	0xEC		/* (we don't bother to list all 16 APPn's) */
 #define M_COM   0xFE		/* COMment */
 
 
@@ -208,7 +214,7 @@
 /*
  * Process a COM marker.
  * We want to print out the marker contents as legible text;
- * we must guard against random junk and varying newline representations.
+ * we must guard against non-text junk and varying newline representations.
  */
 
 static void
@@ -327,6 +333,9 @@
   for (;;) {
     marker = next_marker();
     switch (marker) {
+      /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be,
+       * treated as SOFn.  C4 in particular is actually DHT.
+       */
     case M_SOF0:		/* Baseline */
     case M_SOF1:		/* Extended sequential, Huffman */
     case M_SOF2:		/* Progressive, Huffman */
@@ -356,6 +365,17 @@
       process_COM();
       break;
 
+    case M_APP12:
+      /* Some digital camera makers put useful textual information into
+       * APP12 markers, so we print those out too when in -verbose mode.
+       */
+      if (verbose) {
+	printf("APP12 contains:\n");
+	process_COM();
+      } else
+	skip_variable();
+      break;
+
     default:			/* Anything else just gets skipped */
       skip_variable();		/* we assume it has a parameter count... */
       break;
diff --git a/rdppm.c b/rdppm.c
index e1c2a92..1df35c1 100644
--- a/rdppm.c
+++ b/rdppm.c
@@ -1,7 +1,7 @@
 /*
  * rdppm.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
@@ -303,7 +303,19 @@
   if (getc(source->pub.input_file) != 'P')
     ERREXIT(cinfo, JERR_PPM_NOT);
 
-  c = getc(source->pub.input_file); /* save format discriminator for a sec */
+  c = getc(source->pub.input_file); /* subformat discriminator character */
+
+  /* detect unsupported variants (ie, PBM) before trying to read header */
+  switch (c) {
+  case '2':			/* it's a text-format PGM file */
+  case '3':			/* it's a text-format PPM file */
+  case '5':			/* it's a raw-format PGM file */
+  case '6':			/* it's a raw-format PPM file */
+    break;
+  default:
+    ERREXIT(cinfo, JERR_PPM_NOT);
+    break;
+  }
 
   /* fetch the remaining header info */
   w = read_pbm_integer(cinfo, source->pub.input_file);
@@ -368,10 +380,6 @@
       source->pub.get_pixel_rows = get_scaled_rgb_row;
     }
     break;
-
-  default:
-    ERREXIT(cinfo, JERR_PPM_NOT);
-    break;
   }
 
   /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */
diff --git a/testimg.bmp b/testimg.bmp
new file mode 100644
index 0000000..8603d15
--- /dev/null
+++ b/testimg.bmp
Binary files differ
diff --git a/testimg.gif b/testimg.gif
deleted file mode 100644
index ca40361..0000000
--- a/testimg.gif
+++ /dev/null
Binary files differ
diff --git a/transupp.c b/transupp.c
new file mode 100644
index 0000000..e5ec564
--- /dev/null
+++ b/transupp.c
@@ -0,0 +1,928 @@
+/*
+ * transupp.c
+ *
+ * Copyright (C) 1997, 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 transformation routines and other utility code
+ * used by the jpegtran sample application.  These are NOT part of the core
+ * JPEG library.  But we keep these routines separate from jpegtran.c to
+ * ease the task of maintaining jpegtran-like programs that have other user
+ * interfaces.
+ */
+
+/* Although this file really shouldn't have access to the library internals,
+ * it's helpful to let it call jround_up() and jcopy_block_row().
+ */
+#define JPEG_INTERNALS
+
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "transupp.h"		/* My own external interface */
+
+
+#if TRANSFORMS_SUPPORTED
+
+/*
+ * Lossless image transformation routines.  These routines work on DCT
+ * coefficient arrays and thus do not require any lossy decompression
+ * or recompression of the image.
+ * Thanks to Guido Vollbeding for the initial design and code of this feature.
+ *
+ * Horizontal flipping is done in-place, using a single top-to-bottom
+ * pass through the virtual source array.  It will thus be much the
+ * fastest option for images larger than main memory.
+ *
+ * The other routines require a set of destination virtual arrays, so they
+ * need twice as much memory as jpegtran normally does.  The destination
+ * arrays are always written in normal scan order (top to bottom) because
+ * the virtual array manager expects this.  The source arrays will be scanned
+ * in the corresponding order, which means multiple passes through the source
+ * arrays for most of the transforms.  That could result in much thrashing
+ * if the image is larger than main memory.
+ *
+ * Some notes about the operating environment of the individual transform
+ * routines:
+ * 1. Both the source and destination virtual arrays are allocated from the
+ *    source JPEG object, and therefore should be manipulated by calling the
+ *    source's memory manager.
+ * 2. The destination's component count should be used.  It may be smaller
+ *    than the source's when forcing to grayscale.
+ * 3. Likewise the destination's sampling factors should be used.  When
+ *    forcing to grayscale the destination's sampling factors will be all 1,
+ *    and we may as well take that as the effective iMCU size.
+ * 4. When "trim" is in effect, the destination's dimensions will be the
+ *    trimmed values but the source's will be untrimmed.
+ * 5. All the routines assume that the source and destination buffers are
+ *    padded out to a full iMCU boundary.  This is true, although for the
+ *    source buffer it is an undocumented property of jdcoefct.c.
+ * Notes 2,3,4 boil down to this: generally we should use the destination's
+ * dimensions and ignore the source's.
+ */
+
+
+LOCAL(void)
+do_flip_h (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	   jvirt_barray_ptr *src_coef_arrays)
+/* Horizontal flip; done in-place, so no separate dest array is required */
+{
+  JDIMENSION MCU_cols, comp_width, blk_x, blk_y;
+  int ci, k, offset_y;
+  JBLOCKARRAY buffer;
+  JCOEFPTR ptr1, ptr2;
+  JCOEF temp1, temp2;
+  jpeg_component_info *compptr;
+
+  /* Horizontal mirroring of DCT blocks is accomplished by swapping
+   * pairs of blocks in-place.  Within a DCT block, we perform horizontal
+   * mirroring by changing the signs of odd-numbered columns.
+   * Partial iMCUs at the right edge are left untouched.
+   */
+  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    for (blk_y = 0; blk_y < compptr->height_in_blocks;
+	 blk_y += compptr->v_samp_factor) {
+      buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, src_coef_arrays[ci], blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	for (blk_x = 0; blk_x * 2 < comp_width; blk_x++) {
+	  ptr1 = buffer[offset_y][blk_x];
+	  ptr2 = buffer[offset_y][comp_width - blk_x - 1];
+	  /* this unrolled loop doesn't need to know which row it's on... */
+	  for (k = 0; k < DCTSIZE2; k += 2) {
+	    temp1 = *ptr1;	/* swap even column */
+	    temp2 = *ptr2;
+	    *ptr1++ = temp2;
+	    *ptr2++ = temp1;
+	    temp1 = *ptr1;	/* swap odd column with sign change */
+	    temp2 = *ptr2;
+	    *ptr1++ = -temp2;
+	    *ptr2++ = -temp1;
+	  }
+	}
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_flip_v (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	   jvirt_barray_ptr *src_coef_arrays,
+	   jvirt_barray_ptr *dst_coef_arrays)
+/* Vertical flip */
+{
+  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
+  int ci, i, j, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  JBLOCKROW src_row_ptr, dst_row_ptr;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  /* We output into a separate array because we can't touch different
+   * rows of the source virtual array simultaneously.  Otherwise, this
+   * is a pretty straightforward analog of horizontal flip.
+   * Within a DCT block, vertical mirroring is done by changing the signs
+   * of odd-numbered rows.
+   * Partial iMCUs at the bottom edge are copied verbatim.
+   */
+  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+	 dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      if (dst_blk_y < comp_height) {
+	/* Row is within the mirrorable area. */
+	src_buffer = (*srcinfo->mem->access_virt_barray)
+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
+	   comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
+      } else {
+	/* Bottom-edge blocks will be copied verbatim. */
+	src_buffer = (*srcinfo->mem->access_virt_barray)
+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
+      }
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	if (dst_blk_y < comp_height) {
+	  /* Row is within the mirrorable area. */
+	  dst_row_ptr = dst_buffer[offset_y];
+	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
+	  for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
+	       dst_blk_x++) {
+	    dst_ptr = dst_row_ptr[dst_blk_x];
+	    src_ptr = src_row_ptr[dst_blk_x];
+	    for (i = 0; i < DCTSIZE; i += 2) {
+	      /* copy even row */
+	      for (j = 0; j < DCTSIZE; j++)
+		*dst_ptr++ = *src_ptr++;
+	      /* copy odd row with sign change */
+	      for (j = 0; j < DCTSIZE; j++)
+		*dst_ptr++ = - *src_ptr++;
+	    }
+	  }
+	} else {
+	  /* Just copy row verbatim. */
+	  jcopy_block_row(src_buffer[offset_y], dst_buffer[offset_y],
+			  compptr->width_in_blocks);
+	}
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_transpose (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	      jvirt_barray_ptr *src_coef_arrays,
+	      jvirt_barray_ptr *dst_coef_arrays)
+/* Transpose source into destination */
+{
+  JDIMENSION dst_blk_x, dst_blk_y;
+  int ci, i, j, offset_x, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  /* Transposing pixels within a block just requires transposing the
+   * DCT coefficients.
+   * Partial iMCUs at the edges require no special treatment; we simply
+   * process all the available DCT blocks for every component.
+   */
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+	 dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
+	     dst_blk_x += compptr->h_samp_factor) {
+	  src_buffer = (*srcinfo->mem->access_virt_barray)
+	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
+	     (JDIMENSION) compptr->h_samp_factor, FALSE);
+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
+	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
+	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
+	    for (i = 0; i < DCTSIZE; i++)
+	      for (j = 0; j < DCTSIZE; j++)
+		dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+	  }
+	}
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_rot_90 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	   jvirt_barray_ptr *src_coef_arrays,
+	   jvirt_barray_ptr *dst_coef_arrays)
+/* 90 degree rotation is equivalent to
+ *   1. Transposing the image;
+ *   2. Horizontal mirroring.
+ * These two steps are merged into a single processing routine.
+ */
+{
+  JDIMENSION MCU_cols, comp_width, dst_blk_x, dst_blk_y;
+  int ci, i, j, offset_x, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  /* Because of the horizontal mirror step, we can't process partial iMCUs
+   * at the (output) right edge properly.  They just get transposed and
+   * not mirrored.
+   */
+  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+	 dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
+	     dst_blk_x += compptr->h_samp_factor) {
+	  src_buffer = (*srcinfo->mem->access_virt_barray)
+	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
+	     (JDIMENSION) compptr->h_samp_factor, FALSE);
+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
+	    src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
+	    if (dst_blk_x < comp_width) {
+	      /* Block is within the mirrorable area. */
+	      dst_ptr = dst_buffer[offset_y]
+		[comp_width - dst_blk_x - offset_x - 1];
+	      for (i = 0; i < DCTSIZE; i++) {
+		for (j = 0; j < DCTSIZE; j++)
+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+		i++;
+		for (j = 0; j < DCTSIZE; j++)
+		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
+	      }
+	    } else {
+	      /* Edge blocks are transposed but not mirrored. */
+	      dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
+	      for (i = 0; i < DCTSIZE; i++)
+		for (j = 0; j < DCTSIZE; j++)
+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+	    }
+	  }
+	}
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_rot_270 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	    jvirt_barray_ptr *src_coef_arrays,
+	    jvirt_barray_ptr *dst_coef_arrays)
+/* 270 degree rotation is equivalent to
+ *   1. Horizontal mirroring;
+ *   2. Transposing the image.
+ * These two steps are merged into a single processing routine.
+ */
+{
+  JDIMENSION MCU_rows, comp_height, dst_blk_x, dst_blk_y;
+  int ci, i, j, offset_x, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  /* Because of the horizontal mirror step, we can't process partial iMCUs
+   * at the (output) bottom edge properly.  They just get transposed and
+   * not mirrored.
+   */
+  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+	 dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
+	     dst_blk_x += compptr->h_samp_factor) {
+	  src_buffer = (*srcinfo->mem->access_virt_barray)
+	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
+	     (JDIMENSION) compptr->h_samp_factor, FALSE);
+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
+	    dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
+	    if (dst_blk_y < comp_height) {
+	      /* Block is within the mirrorable area. */
+	      src_ptr = src_buffer[offset_x]
+		[comp_height - dst_blk_y - offset_y - 1];
+	      for (i = 0; i < DCTSIZE; i++) {
+		for (j = 0; j < DCTSIZE; j++) {
+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+		  j++;
+		  dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
+		}
+	      }
+	    } else {
+	      /* Edge blocks are transposed but not mirrored. */
+	      src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
+	      for (i = 0; i < DCTSIZE; i++)
+		for (j = 0; j < DCTSIZE; j++)
+		  dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+	    }
+	  }
+	}
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_rot_180 (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	    jvirt_barray_ptr *src_coef_arrays,
+	    jvirt_barray_ptr *dst_coef_arrays)
+/* 180 degree rotation is equivalent to
+ *   1. Vertical mirroring;
+ *   2. Horizontal mirroring.
+ * These two steps are merged into a single processing routine.
+ */
+{
+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
+  int ci, i, j, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  JBLOCKROW src_row_ptr, dst_row_ptr;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
+  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+	 dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      if (dst_blk_y < comp_height) {
+	/* Row is within the vertically mirrorable area. */
+	src_buffer = (*srcinfo->mem->access_virt_barray)
+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci],
+	   comp_height - dst_blk_y - (JDIMENSION) compptr->v_samp_factor,
+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
+      } else {
+	/* Bottom-edge rows are only mirrored horizontally. */
+	src_buffer = (*srcinfo->mem->access_virt_barray)
+	  ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_y,
+	   (JDIMENSION) compptr->v_samp_factor, FALSE);
+      }
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	if (dst_blk_y < comp_height) {
+	  /* Row is within the mirrorable area. */
+	  dst_row_ptr = dst_buffer[offset_y];
+	  src_row_ptr = src_buffer[compptr->v_samp_factor - offset_y - 1];
+	  /* Process the blocks that can be mirrored both ways. */
+	  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
+	    dst_ptr = dst_row_ptr[dst_blk_x];
+	    src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
+	    for (i = 0; i < DCTSIZE; i += 2) {
+	      /* For even row, negate every odd column. */
+	      for (j = 0; j < DCTSIZE; j += 2) {
+		*dst_ptr++ = *src_ptr++;
+		*dst_ptr++ = - *src_ptr++;
+	      }
+	      /* For odd row, negate every even column. */
+	      for (j = 0; j < DCTSIZE; j += 2) {
+		*dst_ptr++ = - *src_ptr++;
+		*dst_ptr++ = *src_ptr++;
+	      }
+	    }
+	  }
+	  /* Any remaining right-edge blocks are only mirrored vertically. */
+	  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
+	    dst_ptr = dst_row_ptr[dst_blk_x];
+	    src_ptr = src_row_ptr[dst_blk_x];
+	    for (i = 0; i < DCTSIZE; i += 2) {
+	      for (j = 0; j < DCTSIZE; j++)
+		*dst_ptr++ = *src_ptr++;
+	      for (j = 0; j < DCTSIZE; j++)
+		*dst_ptr++ = - *src_ptr++;
+	    }
+	  }
+	} else {
+	  /* Remaining rows are just mirrored horizontally. */
+	  dst_row_ptr = dst_buffer[offset_y];
+	  src_row_ptr = src_buffer[offset_y];
+	  /* Process the blocks that can be mirrored. */
+	  for (dst_blk_x = 0; dst_blk_x < comp_width; dst_blk_x++) {
+	    dst_ptr = dst_row_ptr[dst_blk_x];
+	    src_ptr = src_row_ptr[comp_width - dst_blk_x - 1];
+	    for (i = 0; i < DCTSIZE2; i += 2) {
+	      *dst_ptr++ = *src_ptr++;
+	      *dst_ptr++ = - *src_ptr++;
+	    }
+	  }
+	  /* Any remaining right-edge blocks are only copied. */
+	  for (; dst_blk_x < compptr->width_in_blocks; dst_blk_x++) {
+	    dst_ptr = dst_row_ptr[dst_blk_x];
+	    src_ptr = src_row_ptr[dst_blk_x];
+	    for (i = 0; i < DCTSIZE2; i++)
+	      *dst_ptr++ = *src_ptr++;
+	  }
+	}
+      }
+    }
+  }
+}
+
+
+LOCAL(void)
+do_transverse (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	       jvirt_barray_ptr *src_coef_arrays,
+	       jvirt_barray_ptr *dst_coef_arrays)
+/* Transverse transpose is equivalent to
+ *   1. 180 degree rotation;
+ *   2. Transposition;
+ * or
+ *   1. Horizontal mirroring;
+ *   2. Transposition;
+ *   3. Horizontal mirroring.
+ * These steps are merged into a single processing routine.
+ */
+{
+  JDIMENSION MCU_cols, MCU_rows, comp_width, comp_height, dst_blk_x, dst_blk_y;
+  int ci, i, j, offset_x, offset_y;
+  JBLOCKARRAY src_buffer, dst_buffer;
+  JCOEFPTR src_ptr, dst_ptr;
+  jpeg_component_info *compptr;
+
+  MCU_cols = dstinfo->image_width / (dstinfo->max_h_samp_factor * DCTSIZE);
+  MCU_rows = dstinfo->image_height / (dstinfo->max_v_samp_factor * DCTSIZE);
+
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    comp_width = MCU_cols * compptr->h_samp_factor;
+    comp_height = MCU_rows * compptr->v_samp_factor;
+    for (dst_blk_y = 0; dst_blk_y < compptr->height_in_blocks;
+	 dst_blk_y += compptr->v_samp_factor) {
+      dst_buffer = (*srcinfo->mem->access_virt_barray)
+	((j_common_ptr) srcinfo, dst_coef_arrays[ci], dst_blk_y,
+	 (JDIMENSION) compptr->v_samp_factor, TRUE);
+      for (offset_y = 0; offset_y < compptr->v_samp_factor; offset_y++) {
+	for (dst_blk_x = 0; dst_blk_x < compptr->width_in_blocks;
+	     dst_blk_x += compptr->h_samp_factor) {
+	  src_buffer = (*srcinfo->mem->access_virt_barray)
+	    ((j_common_ptr) srcinfo, src_coef_arrays[ci], dst_blk_x,
+	     (JDIMENSION) compptr->h_samp_factor, FALSE);
+	  for (offset_x = 0; offset_x < compptr->h_samp_factor; offset_x++) {
+	    if (dst_blk_y < comp_height) {
+	      src_ptr = src_buffer[offset_x]
+		[comp_height - dst_blk_y - offset_y - 1];
+	      if (dst_blk_x < comp_width) {
+		/* Block is within the mirrorable area. */
+		dst_ptr = dst_buffer[offset_y]
+		  [comp_width - dst_blk_x - offset_x - 1];
+		for (i = 0; i < DCTSIZE; i++) {
+		  for (j = 0; j < DCTSIZE; j++) {
+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+		    j++;
+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
+		  }
+		  i++;
+		  for (j = 0; j < DCTSIZE; j++) {
+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
+		    j++;
+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+		  }
+		}
+	      } else {
+		/* Right-edge blocks are mirrored in y only */
+		dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
+		for (i = 0; i < DCTSIZE; i++) {
+		  for (j = 0; j < DCTSIZE; j++) {
+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+		    j++;
+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
+		  }
+		}
+	      }
+	    } else {
+	      src_ptr = src_buffer[offset_x][dst_blk_y + offset_y];
+	      if (dst_blk_x < comp_width) {
+		/* Bottom-edge blocks are mirrored in x only */
+		dst_ptr = dst_buffer[offset_y]
+		  [comp_width - dst_blk_x - offset_x - 1];
+		for (i = 0; i < DCTSIZE; i++) {
+		  for (j = 0; j < DCTSIZE; j++)
+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+		  i++;
+		  for (j = 0; j < DCTSIZE; j++)
+		    dst_ptr[j*DCTSIZE+i] = -src_ptr[i*DCTSIZE+j];
+		}
+	      } else {
+		/* At lower right corner, just transpose, no mirroring */
+		dst_ptr = dst_buffer[offset_y][dst_blk_x + offset_x];
+		for (i = 0; i < DCTSIZE; i++)
+		  for (j = 0; j < DCTSIZE; j++)
+		    dst_ptr[j*DCTSIZE+i] = src_ptr[i*DCTSIZE+j];
+	      }
+	    }
+	  }
+	}
+      }
+    }
+  }
+}
+
+
+/* Request any required workspace.
+ *
+ * We allocate the workspace virtual arrays from the source decompression
+ * object, so that all the arrays (both the original data and the workspace)
+ * will be taken into account while making memory management decisions.
+ * Hence, this routine must be called after jpeg_read_header (which reads
+ * the image dimensions) and before jpeg_read_coefficients (which realizes
+ * the source's virtual arrays).
+ */
+
+GLOBAL(void)
+jtransform_request_workspace (j_decompress_ptr srcinfo,
+			      jpeg_transform_info *info)
+{
+  jvirt_barray_ptr *coef_arrays = NULL;
+  jpeg_component_info *compptr;
+  int ci;
+
+  if (info->force_grayscale &&
+      srcinfo->jpeg_color_space == JCS_YCbCr &&
+      srcinfo->num_components == 3) {
+    /* We'll only process the first component */
+    info->num_components = 1;
+  } else {
+    /* Process all the components */
+    info->num_components = srcinfo->num_components;
+  }
+
+  switch (info->transform) {
+  case JXFORM_NONE:
+  case JXFORM_FLIP_H:
+    /* Don't need a workspace array */
+    break;
+  case JXFORM_FLIP_V:
+  case JXFORM_ROT_180:
+    /* Need workspace arrays having same dimensions as source image.
+     * Note that we allocate arrays padded out to the next iMCU boundary,
+     * so that transform routines need not worry about missing edge blocks.
+     */
+    coef_arrays = (jvirt_barray_ptr *)
+      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
+	SIZEOF(jvirt_barray_ptr) * info->num_components);
+    for (ci = 0; ci < info->num_components; ci++) {
+      compptr = srcinfo->comp_info + ci;
+      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
+	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
+	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+				(long) compptr->h_samp_factor),
+	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+				(long) compptr->v_samp_factor),
+	 (JDIMENSION) compptr->v_samp_factor);
+    }
+    break;
+  case JXFORM_TRANSPOSE:
+  case JXFORM_TRANSVERSE:
+  case JXFORM_ROT_90:
+  case JXFORM_ROT_270:
+    /* Need workspace arrays having transposed dimensions.
+     * Note that we allocate arrays padded out to the next iMCU boundary,
+     * so that transform routines need not worry about missing edge blocks.
+     */
+    coef_arrays = (jvirt_barray_ptr *)
+      (*srcinfo->mem->alloc_small) ((j_common_ptr) srcinfo, JPOOL_IMAGE,
+	SIZEOF(jvirt_barray_ptr) * info->num_components);
+    for (ci = 0; ci < info->num_components; ci++) {
+      compptr = srcinfo->comp_info + ci;
+      coef_arrays[ci] = (*srcinfo->mem->request_virt_barray)
+	((j_common_ptr) srcinfo, JPOOL_IMAGE, FALSE,
+	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+				(long) compptr->v_samp_factor),
+	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+				(long) compptr->h_samp_factor),
+	 (JDIMENSION) compptr->h_samp_factor);
+    }
+    break;
+  }
+  info->workspace_coef_arrays = coef_arrays;
+}
+
+
+/* Transpose destination image parameters */
+
+LOCAL(void)
+transpose_critical_parameters (j_compress_ptr dstinfo)
+{
+  int tblno, i, j, ci, itemp;
+  jpeg_component_info *compptr;
+  JQUANT_TBL *qtblptr;
+  JDIMENSION dtemp;
+  UINT16 qtemp;
+
+  /* Transpose basic image dimensions */
+  dtemp = dstinfo->image_width;
+  dstinfo->image_width = dstinfo->image_height;
+  dstinfo->image_height = dtemp;
+
+  /* Transpose sampling factors */
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    compptr = dstinfo->comp_info + ci;
+    itemp = compptr->h_samp_factor;
+    compptr->h_samp_factor = compptr->v_samp_factor;
+    compptr->v_samp_factor = itemp;
+  }
+
+  /* Transpose quantization tables */
+  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
+    qtblptr = dstinfo->quant_tbl_ptrs[tblno];
+    if (qtblptr != NULL) {
+      for (i = 0; i < DCTSIZE; i++) {
+	for (j = 0; j < i; j++) {
+	  qtemp = qtblptr->quantval[i*DCTSIZE+j];
+	  qtblptr->quantval[i*DCTSIZE+j] = qtblptr->quantval[j*DCTSIZE+i];
+	  qtblptr->quantval[j*DCTSIZE+i] = qtemp;
+	}
+      }
+    }
+  }
+}
+
+
+/* Trim off any partial iMCUs on the indicated destination edge */
+
+LOCAL(void)
+trim_right_edge (j_compress_ptr dstinfo)
+{
+  int ci, max_h_samp_factor;
+  JDIMENSION MCU_cols;
+
+  /* We have to compute max_h_samp_factor ourselves,
+   * because it hasn't been set yet in the destination
+   * (and we don't want to use the source's value).
+   */
+  max_h_samp_factor = 1;
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    int h_samp_factor = dstinfo->comp_info[ci].h_samp_factor;
+    max_h_samp_factor = MAX(max_h_samp_factor, h_samp_factor);
+  }
+  MCU_cols = dstinfo->image_width / (max_h_samp_factor * DCTSIZE);
+  if (MCU_cols > 0)		/* can't trim to 0 pixels */
+    dstinfo->image_width = MCU_cols * (max_h_samp_factor * DCTSIZE);
+}
+
+LOCAL(void)
+trim_bottom_edge (j_compress_ptr dstinfo)
+{
+  int ci, max_v_samp_factor;
+  JDIMENSION MCU_rows;
+
+  /* We have to compute max_v_samp_factor ourselves,
+   * because it hasn't been set yet in the destination
+   * (and we don't want to use the source's value).
+   */
+  max_v_samp_factor = 1;
+  for (ci = 0; ci < dstinfo->num_components; ci++) {
+    int v_samp_factor = dstinfo->comp_info[ci].v_samp_factor;
+    max_v_samp_factor = MAX(max_v_samp_factor, v_samp_factor);
+  }
+  MCU_rows = dstinfo->image_height / (max_v_samp_factor * DCTSIZE);
+  if (MCU_rows > 0)		/* can't trim to 0 pixels */
+    dstinfo->image_height = MCU_rows * (max_v_samp_factor * DCTSIZE);
+}
+
+
+/* Adjust output image parameters as needed.
+ *
+ * This must be called after jpeg_copy_critical_parameters()
+ * and before jpeg_write_coefficients().
+ *
+ * The return value is the set of virtual coefficient arrays to be written
+ * (either the ones allocated by jtransform_request_workspace, or the
+ * original source data arrays).  The caller will need to pass this value
+ * to jpeg_write_coefficients().
+ */
+
+GLOBAL(jvirt_barray_ptr *)
+jtransform_adjust_parameters (j_decompress_ptr srcinfo,
+			      j_compress_ptr dstinfo,
+			      jvirt_barray_ptr *src_coef_arrays,
+			      jpeg_transform_info *info)
+{
+  /* If force-to-grayscale is requested, adjust destination parameters */
+  if (info->force_grayscale) {
+    /* We use jpeg_set_colorspace to make sure subsidiary settings get fixed
+     * properly.  Among other things, the target h_samp_factor & v_samp_factor
+     * will get set to 1, which typically won't match the source.
+     * In fact we do this even if the source is already grayscale; that
+     * provides an easy way of coercing a grayscale JPEG with funny sampling
+     * factors to the customary 1,1.  (Some decoders fail on other factors.)
+     */
+    if ((dstinfo->jpeg_color_space == JCS_YCbCr &&
+	 dstinfo->num_components == 3) ||
+	(dstinfo->jpeg_color_space == JCS_GRAYSCALE &&
+	 dstinfo->num_components == 1)) {
+      /* We have to preserve the source's quantization table number. */
+      int sv_quant_tbl_no = dstinfo->comp_info[0].quant_tbl_no;
+      jpeg_set_colorspace(dstinfo, JCS_GRAYSCALE);
+      dstinfo->comp_info[0].quant_tbl_no = sv_quant_tbl_no;
+    } else {
+      /* Sorry, can't do it */
+      ERREXIT(dstinfo, JERR_CONVERSION_NOTIMPL);
+    }
+  }
+
+  /* Correct the destination's image dimensions etc if necessary */
+  switch (info->transform) {
+  case JXFORM_NONE:
+    /* Nothing to do */
+    break;
+  case JXFORM_FLIP_H:
+    if (info->trim)
+      trim_right_edge(dstinfo);
+    break;
+  case JXFORM_FLIP_V:
+    if (info->trim)
+      trim_bottom_edge(dstinfo);
+    break;
+  case JXFORM_TRANSPOSE:
+    transpose_critical_parameters(dstinfo);
+    /* transpose does NOT have to trim anything */
+    break;
+  case JXFORM_TRANSVERSE:
+    transpose_critical_parameters(dstinfo);
+    if (info->trim) {
+      trim_right_edge(dstinfo);
+      trim_bottom_edge(dstinfo);
+    }
+    break;
+  case JXFORM_ROT_90:
+    transpose_critical_parameters(dstinfo);
+    if (info->trim)
+      trim_right_edge(dstinfo);
+    break;
+  case JXFORM_ROT_180:
+    if (info->trim) {
+      trim_right_edge(dstinfo);
+      trim_bottom_edge(dstinfo);
+    }
+    break;
+  case JXFORM_ROT_270:
+    transpose_critical_parameters(dstinfo);
+    if (info->trim)
+      trim_bottom_edge(dstinfo);
+    break;
+  }
+
+  /* Return the appropriate output data set */
+  if (info->workspace_coef_arrays != NULL)
+    return info->workspace_coef_arrays;
+  return src_coef_arrays;
+}
+
+
+/* Execute the actual transformation, if any.
+ *
+ * This must be called *after* jpeg_write_coefficients, because it depends
+ * on jpeg_write_coefficients to have computed subsidiary values such as
+ * the per-component width and height fields in the destination object.
+ *
+ * Note that some transformations will modify the source data arrays!
+ */
+
+GLOBAL(void)
+jtransform_execute_transformation (j_decompress_ptr srcinfo,
+				   j_compress_ptr dstinfo,
+				   jvirt_barray_ptr *src_coef_arrays,
+				   jpeg_transform_info *info)
+{
+  jvirt_barray_ptr *dst_coef_arrays = info->workspace_coef_arrays;
+
+  switch (info->transform) {
+  case JXFORM_NONE:
+    break;
+  case JXFORM_FLIP_H:
+    do_flip_h(srcinfo, dstinfo, src_coef_arrays);
+    break;
+  case JXFORM_FLIP_V:
+    do_flip_v(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
+    break;
+  case JXFORM_TRANSPOSE:
+    do_transpose(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
+    break;
+  case JXFORM_TRANSVERSE:
+    do_transverse(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
+    break;
+  case JXFORM_ROT_90:
+    do_rot_90(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
+    break;
+  case JXFORM_ROT_180:
+    do_rot_180(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
+    break;
+  case JXFORM_ROT_270:
+    do_rot_270(srcinfo, dstinfo, src_coef_arrays, dst_coef_arrays);
+    break;
+  }
+}
+
+#endif /* TRANSFORMS_SUPPORTED */
+
+
+/* Setup decompression object to save desired markers in memory.
+ * This must be called before jpeg_read_header() to have the desired effect.
+ */
+
+GLOBAL(void)
+jcopy_markers_setup (j_decompress_ptr srcinfo, JCOPY_OPTION option)
+{
+#ifdef SAVE_MARKERS_SUPPORTED
+  int m;
+
+  /* Save comments except under NONE option */
+  if (option != JCOPYOPT_NONE) {
+    jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF);
+  }
+  /* Save all types of APPn markers iff ALL option */
+  if (option == JCOPYOPT_ALL) {
+    for (m = 0; m < 16; m++)
+      jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF);
+  }
+#endif /* SAVE_MARKERS_SUPPORTED */
+}
+
+/* Copy markers saved in the given source object to the destination object.
+ * This should be called just after jpeg_start_compress() or
+ * jpeg_write_coefficients().
+ * Note that those routines will have written the SOI, and also the
+ * JFIF APP0 or Adobe APP14 markers if selected.
+ */
+
+GLOBAL(void)
+jcopy_markers_execute (j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+		       JCOPY_OPTION option)
+{
+  jpeg_saved_marker_ptr marker;
+
+  /* In the current implementation, we don't actually need to examine the
+   * option flag here; we just copy everything that got saved.
+   * But to avoid confusion, we do not output JFIF and Adobe APP14 markers
+   * if the encoder library already wrote one.
+   */
+  for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) {
+    if (dstinfo->write_JFIF_header &&
+	marker->marker == JPEG_APP0 &&
+	marker->data_length >= 5 &&
+	GETJOCTET(marker->data[0]) == 0x4A &&
+	GETJOCTET(marker->data[1]) == 0x46 &&
+	GETJOCTET(marker->data[2]) == 0x49 &&
+	GETJOCTET(marker->data[3]) == 0x46 &&
+	GETJOCTET(marker->data[4]) == 0)
+      continue;			/* reject duplicate JFIF */
+    if (dstinfo->write_Adobe_marker &&
+	marker->marker == JPEG_APP0+14 &&
+	marker->data_length >= 5 &&
+	GETJOCTET(marker->data[0]) == 0x41 &&
+	GETJOCTET(marker->data[1]) == 0x64 &&
+	GETJOCTET(marker->data[2]) == 0x6F &&
+	GETJOCTET(marker->data[3]) == 0x62 &&
+	GETJOCTET(marker->data[4]) == 0x65)
+      continue;			/* reject duplicate Adobe */
+#ifdef NEED_FAR_POINTERS
+    /* We could use jpeg_write_marker if the data weren't FAR... */
+    {
+      unsigned int i;
+      jpeg_write_m_header(dstinfo, marker->marker, marker->data_length);
+      for (i = 0; i < marker->data_length; i++)
+	jpeg_write_m_byte(dstinfo, marker->data[i]);
+    }
+#else
+    jpeg_write_marker(dstinfo, marker->marker,
+		      marker->data, marker->data_length);
+#endif
+  }
+}
diff --git a/transupp.h b/transupp.h
new file mode 100644
index 0000000..5c2d32a
--- /dev/null
+++ b/transupp.h
@@ -0,0 +1,135 @@
+/*
+ * transupp.h
+ *
+ * Copyright (C) 1997, 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 declarations for image transformation routines and
+ * other utility code used by the jpegtran sample application.  These are
+ * NOT part of the core JPEG library.  But we keep these routines separate
+ * from jpegtran.c to ease the task of maintaining jpegtran-like programs
+ * that have other user interfaces.
+ *
+ * NOTE: all the routines declared here have very specific requirements
+ * about when they are to be executed during the reading and writing of the
+ * source and destination files.  See the comments in transupp.c, or see
+ * jpegtran.c for an example of correct usage.
+ */
+
+/* If you happen not to want the image transform support, disable it here */
+#ifndef TRANSFORMS_SUPPORTED
+#define TRANSFORMS_SUPPORTED 1		/* 0 disables transform code */
+#endif
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jtransform_request_workspace		jTrRequest
+#define jtransform_adjust_parameters		jTrAdjust
+#define jtransform_execute_transformation	jTrExec
+#define jcopy_markers_setup			jCMrkSetup
+#define jcopy_markers_execute			jCMrkExec
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/*
+ * Codes for supported types of image transformations.
+ */
+
+typedef enum {
+	JXFORM_NONE,		/* no transformation */
+	JXFORM_FLIP_H,		/* horizontal flip */
+	JXFORM_FLIP_V,		/* vertical flip */
+	JXFORM_TRANSPOSE,	/* transpose across UL-to-LR axis */
+	JXFORM_TRANSVERSE,	/* transpose across UR-to-LL axis */
+	JXFORM_ROT_90,		/* 90-degree clockwise rotation */
+	JXFORM_ROT_180,		/* 180-degree rotation */
+	JXFORM_ROT_270		/* 270-degree clockwise (or 90 ccw) */
+} JXFORM_CODE;
+
+/*
+ * Although rotating and flipping data expressed as DCT coefficients is not
+ * hard, there is an asymmetry in the JPEG format specification for images
+ * whose dimensions aren't multiples of the iMCU size.  The right and bottom
+ * image edges are padded out to the next iMCU boundary with junk data; but
+ * no padding is possible at the top and left edges.  If we were to flip
+ * the whole image including the pad data, then pad garbage would become
+ * visible at the top and/or left, and real pixels would disappear into the
+ * pad margins --- perhaps permanently, since encoders & decoders may not
+ * bother to preserve DCT blocks that appear to be completely outside the
+ * nominal image area.  So, we have to exclude any partial iMCUs from the
+ * basic transformation.
+ *
+ * Transpose is the only transformation that can handle partial iMCUs at the
+ * right and bottom edges completely cleanly.  flip_h can flip partial iMCUs
+ * at the bottom, but leaves any partial iMCUs at the right edge untouched.
+ * Similarly flip_v leaves any partial iMCUs at the bottom edge untouched.
+ * The other transforms are defined as combinations of these basic transforms
+ * and process edge blocks in a way that preserves the equivalence.
+ *
+ * The "trim" option causes untransformable partial iMCUs to be dropped;
+ * this is not strictly lossless, but it usually gives the best-looking
+ * result for odd-size images.  Note that when this option is active,
+ * the expected mathematical equivalences between the transforms may not hold.
+ * (For example, -rot 270 -trim trims only the bottom edge, but -rot 90 -trim
+ * followed by -rot 180 -trim trims both edges.)
+ *
+ * We also offer a "force to grayscale" option, which simply discards the
+ * chrominance channels of a YCbCr image.  This is lossless in the sense that
+ * the luminance channel is preserved exactly.  It's not the same kind of
+ * thing as the rotate/flip transformations, but it's convenient to handle it
+ * as part of this package, mainly because the transformation routines have to
+ * be aware of the option to know how many components to work on.
+ */
+
+typedef struct {
+  /* Options: set by caller */
+  JXFORM_CODE transform;	/* image transform operator */
+  boolean trim;			/* if TRUE, trim partial MCUs as needed */
+  boolean force_grayscale;	/* if TRUE, convert color image to grayscale */
+
+  /* Internal workspace: caller should not touch these */
+  int num_components;		/* # of components in workspace */
+  jvirt_barray_ptr * workspace_coef_arrays; /* workspace for transformations */
+} jpeg_transform_info;
+
+
+#if TRANSFORMS_SUPPORTED
+
+/* Request any required workspace */
+EXTERN(void) jtransform_request_workspace
+	JPP((j_decompress_ptr srcinfo, jpeg_transform_info *info));
+/* Adjust output image parameters */
+EXTERN(jvirt_barray_ptr *) jtransform_adjust_parameters
+	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	     jvirt_barray_ptr *src_coef_arrays,
+	     jpeg_transform_info *info));
+/* Execute the actual transformation, if any */
+EXTERN(void) jtransform_execute_transformation
+	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	     jvirt_barray_ptr *src_coef_arrays,
+	     jpeg_transform_info *info));
+
+#endif /* TRANSFORMS_SUPPORTED */
+
+
+/*
+ * Support for copying optional markers from source to destination file.
+ */
+
+typedef enum {
+	JCOPYOPT_NONE,		/* copy no optional markers */
+	JCOPYOPT_COMMENTS,	/* copy only comment (COM) markers */
+	JCOPYOPT_ALL		/* copy all optional markers */
+} JCOPY_OPTION;
+
+#define JCOPYOPT_DEFAULT  JCOPYOPT_COMMENTS	/* recommended default */
+
+/* Setup decompression object to save desired markers in memory */
+EXTERN(void) jcopy_markers_setup
+	JPP((j_decompress_ptr srcinfo, JCOPY_OPTION option));
+/* Copy markers saved in the given source object to the destination object */
+EXTERN(void) jcopy_markers_execute
+	JPP((j_decompress_ptr srcinfo, j_compress_ptr dstinfo,
+	     JCOPY_OPTION option));
diff --git a/usage.doc b/usage.doc
index 49f3d7f..8c4970a 100644
--- a/usage.doc
+++ b/usage.doc
@@ -57,7 +57,7 @@
 This syntax works on all systems, so it is useful for scripts.
 
 The currently supported image file formats are: PPM (PBMPLUS color format),
-PGM (PBMPLUS gray-scale format), BMP, GIF, Targa, and RLE (Utah Raster Toolkit
+PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster Toolkit
 format).  (RLE is supported only if the URT library is available.)
 cjpeg recognizes the input image format automatically, with the exception
 of some Targa-format files.  You have to tell djpeg which format to generate.
@@ -67,7 +67,7 @@
 
 All switch names may be abbreviated; for example, -grayscale may be written
 -gray or -gr.  Most of the "basic" switches can be abbreviated to as little as
-one letter.  Upper and lower case are equivalent (-GIF is the same as -gif).
+one letter.  Upper and lower case are equivalent (-BMP is the same as -bmp).
 British spellings are also accepted (e.g., -greyscale), though for brevity
 these are not mentioned below.
 
@@ -82,8 +82,8 @@
 
 	-grayscale	Create monochrome JPEG file from color input.
 			Be sure to use this switch when compressing a grayscale
-			GIF file, because cjpeg isn't bright enough to notice
-			whether a GIF file uses only shades of gray.  By
+			BMP file, because cjpeg isn't bright enough to notice
+			whether a BMP file uses only shades of gray.  By
 			saying -grayscale, you'll get a smaller JPEG file that
 			takes less time to process.
 
@@ -177,16 +177,19 @@
 will be transmitted across unreliable networks such as Usenet.
 
 The -smooth option filters the input to eliminate fine-scale noise.  This is
-often useful when converting GIF files to JPEG: a moderate smoothing factor of
-10 to 50 gets rid of dithering patterns in the input file, resulting in a
-smaller JPEG file and a better-looking image.  Too large a smoothing factor
-will visibly blur the image, however.
+often useful when converting dithered images to JPEG: a moderate smoothing
+factor of 10 to 50 gets rid of dithering patterns in the input file, resulting
+in a smaller JPEG file and a better-looking image.  Too large a smoothing
+factor will visibly blur the image, however.
 
 Switches for wizards:
 
-	-baseline	Force a baseline JPEG file to be generated.  This
-			clamps quantization values to 8 bits even at low
-			quality settings.
+	-baseline	Force baseline-compatible quantization tables to be
+			generated.  This clamps quantization values to 8 bits
+			even at low quality settings.  (This switch is poorly
+			named, since it does not ensure that the output is
+			actually baseline JPEG.  For example, you can use
+			-baseline and -progressive together.)
 
 	-qtables file	Use the quantization tables given in the specified
 			text file.
@@ -329,6 +332,10 @@
 is often a lot more than it is on larger files.  (At present, -optimize
 mode is always selected when generating progressive JPEG files.)
 
+GIF input files are no longer supported, to avoid the Unisys LZW patent.
+Use a Unisys-licensed program if you need to read a GIF file.  (Conversion
+of GIF files to JPEG is usually a bad idea anyway.)
+
 
 HINTS FOR DJPEG
 
@@ -354,6 +361,9 @@
 decompress, with some loss of image quality, by specifying -onepass for
 one-pass quantization.
 
+To avoid the Unisys LZW patent, djpeg produces uncompressed GIF files.  These
+are larger than they should be, but are readable by standard GIF decoders.
+
 
 HINTS FOR BOTH PROGRAMS
 
@@ -390,27 +400,104 @@
 
 JPEGTRAN
 
-jpegtran translates JPEG files from one variant of JPEG to another, for
-example from baseline JPEG to progressive JPEG or vice versa.  The
-transformation is lossless: no image degradation occurs, which would not
-be true if you used djpeg followed by cjpeg.  However, you cannot alter
-the image quality, because that would not be a lossless operation.
+jpegtran performs various useful transformations of JPEG files.
+It can translate the coded representation from one variant of JPEG to another,
+for example from baseline JPEG to progressive JPEG or vice versa.  It can also
+perform some rearrangements of the image data, for example turning an image
+from landscape to portrait format by rotation.
 
-jpegtran operates similarly to cjpeg, except that it reads a JPEG file
-and writes another JPEG file.
+jpegtran works by rearranging the compressed data (DCT coefficients), without
+ever fully decoding the image.  Therefore, its transformations are lossless:
+there is no image degradation at all, which would not be true if you used
+djpeg followed by cjpeg to accomplish the same conversion.  But by the same
+token, jpegtran cannot perform lossy operations such as changing the image
+quality.
 
+jpegtran uses a command line syntax similar to cjpeg or djpeg.
+On Unix-like systems, you say:
+	jpegtran [switches] [inputfile] >outputfile
+On most non-Unix systems, you say:
+	jpegtran [switches] inputfile outputfile
+where both the input and output files are JPEG files.
+
+To specify the coded JPEG representation used in the output file,
 jpegtran accepts a subset of the switches recognized by cjpeg:
+	-optimize	Perform optimization of entropy encoding parameters.
+	-progressive	Create progressive JPEG file.
+	-restart N	Emit a JPEG restart marker every N MCU rows, or every
+			N MCU blocks if "B" is attached to the number.
+	-scans file	Use the scan script given in the specified text file.
+See the previous discussion of cjpeg for more details about these switches.
+If you specify none of these switches, you get a plain baseline-JPEG output
+file.  The quality setting and so forth are determined by the input file.
+
+The image can be losslessly transformed by giving one of these switches:
+	-flip horizontal	Mirror image horizontally (left-right).
+	-flip vertical		Mirror image vertically (top-bottom).
+	-rotate 90		Rotate image 90 degrees clockwise.
+	-rotate 180		Rotate image 180 degrees.
+	-rotate 270		Rotate image 270 degrees clockwise (or 90 ccw).
+	-transpose		Transpose image (across UL-to-LR axis).
+	-transverse		Transverse transpose (across UR-to-LL axis).
+
+The transpose transformation has no restrictions regarding image dimensions.
+The other transformations operate rather oddly if the image dimensions are not
+a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
+transform complete blocks of DCT coefficient data in the desired way.
+
+jpegtran's default behavior when transforming an odd-size image is designed
+to preserve exact reversibility and mathematical consistency of the
+transformation set.  As stated, transpose is able to flip the entire image
+area.  Horizontal mirroring leaves any partial iMCU column at the right edge
+untouched, but is able to flip all rows of the image.  Similarly, vertical
+mirroring leaves any partial iMCU row at the bottom edge untouched, but is
+able to flip all columns.  The other transforms can be built up as sequences
+of transpose and flip operations; for consistency, their actions on edge
+pixels are defined to be the same as the end result of the corresponding
+transpose-and-flip sequence.
+
+For practical use, you may prefer to discard any untransformable edge pixels
+rather than having a strange-looking strip along the right and/or bottom edges
+of a transformed image.  To do this, add the -trim switch:
+	-trim		Drop non-transformable edge blocks.
+Obviously, a transformation with -trim is not reversible, so strictly speaking
+jpegtran with this switch is not lossless.  Also, the expected mathematical
+equivalences between the transformations no longer hold.  For example,
+"-rot 270 -trim" trims only the bottom edge, but "-rot 90 -trim" followed by
+"-rot 180 -trim" trims both edges.
+
+Another not-strictly-lossless transformation switch is:
+	-grayscale	Force grayscale output.
+This option discards the chrominance channels if the input image is YCbCr
+(ie, a standard color JPEG), resulting in a grayscale JPEG file.  The
+luminance channel is preserved exactly, so this is a better method of reducing
+to grayscale than decompression, conversion, and recompression.  This switch
+is particularly handy for fixing a monochrome picture that was mistakenly
+encoded as a color JPEG.  (In such a case, the space savings from getting rid
+of the near-empty chroma channels won't be large; but the decoding time for
+a grayscale JPEG is substantially less than that for a color JPEG.)
+
+jpegtran also recognizes these switches that control what to do with "extra"
+markers, such as comment blocks:
+	-copy none	Copy no extra markers from source file.  This setting
+			suppresses all comments and other excess baggage
+			present in the source file.
+	-copy comments	Copy only comment markers.  This setting copies
+			comments from the source file, but discards
+			any other inessential data. 
+	-copy all	Copy all extra markers.  This setting preserves
+			miscellaneous markers found in the source file, such
+			as JFIF thumbnails and Photoshop settings.  In some
+			files these extra markers can be sizable.
+The default behavior is -copy comments.  (Note: in IJG releases v6 and v6a,
+jpegtran always did the equivalent of -copy none.)
+
+Additional switches recognized by jpegtran are:
 	-outfile filename
-	-optimize
-	-progressive
-	-restart N
-	-scans file
 	-maxmemory N
 	-verbose
 	-debug
-See the previous discussion of cjpeg for details about these switches.
-
-If you specify no switches, you get a plain baseline-JPEG output file.
+These work the same as in cjpeg or djpeg.
 
 
 THE COMMENT UTILITIES
@@ -454,7 +541,7 @@
 wrjpgcom understands three switches:
 	-replace		 Delete any existing COM blocks from the file.
 	-comment "Comment text"	 Supply new COM text on command line.
-        -cfile name		 Read text for new COM block from named file.
+	-cfile name		 Read text for new COM block from named file.
 (Switch names can be abbreviated.)  If you have only one line of comment text
 to add, you can provide it on the command line with -comment.  The comment
 text must be surrounded with quotes so that it is treated as a single
diff --git a/wrgif.c b/wrgif.c
index 85cfaa8..5fe8328 100644
--- a/wrgif.c
+++ b/wrgif.c
@@ -1,17 +1,18 @@
 /*
  * wrgif.c
  *
- * Copyright (C) 1991-1996, Thomas G. Lane.
+ * Copyright (C) 1991-1997, 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.
  *
- **************************************************************************
- * WARNING: You will need an LZW patent license from Unisys in order to   *
- * use this file legally in any commercial or shareware application.      *
- **************************************************************************
- *
  * This file contains routines to write output images in GIF format.
  *
+ **************************************************************************
+ * NOTE: to avoid entanglements with Unisys' patent on LZW compression,   *
+ * this code has been modified to output "uncompressed GIF" files.        *
+ * There is no trace of the LZW algorithm in this file.                   *
+ **************************************************************************
+ *
  * These routines may need modification for non-Unix environments or
  * specialized applications.  As they stand, they assume output to
  * an ordinary stdio stream.
@@ -41,40 +42,6 @@
 #ifdef GIF_SUPPORTED
 
 
-#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 */
-
-#define MAXCODE(n_bits)	(((code_int) 1 << (n_bits)) - 1)
-
-
-/*
- * The LZW hash table consists of two parallel arrays:
- *   hash_code[i]	code of symbol in slot i, or 0 if empty slot
- *   hash_value[i]	symbol's value; undefined if empty slot
- * where slot values (i) range from 0 to HSIZE-1.  The symbol value is
- * its prefix symbol's code concatenated with its suffix character.
- *
- * 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_value[] table is allocated from FAR heap space since it would
- * use up rather a lot of the near data space in a PC.
- */
-
-typedef INT32 hash_entry;	/* must hold (code_int<<8) | byte */
-
-#define HASH_ENTRY(prefix,suffix)  ((((hash_entry) (prefix)) << 8) | (suffix))
-
-
 /* Private version of data destination object */
 
 typedef struct {
@@ -84,23 +51,14 @@
 
   /* State for packing variable-width codes into a bitstream */
   int n_bits;			/* current number of bits/code */
-  code_int maxcode;		/* maximum code, given n_bits */
-  int init_bits;		/* initial n_bits ... restored after clear */
+  int maxcode;			/* maximum code, given n_bits */
   INT32 cur_accum;		/* holds bits not yet output */
   int cur_bits;			/* # of bits in cur_accum */
 
-  /* LZW string construction */
-  code_int waiting_code;	/* symbol not yet output; may be extendable */
-  boolean first_byte;		/* if TRUE, waiting_code is not valid */
-
-  /* State for LZW code assignment */
-  code_int ClearCode;		/* clear code (doesn't change) */
-  code_int EOFCode;		/* EOF code (ditto) */
-  code_int free_code;		/* first not-yet-used symbol code */
-
-  /* LZW hash table */
-  code_int *hash_code;		/* => hash table of symbol codes */
-  hash_entry FAR *hash_value;	/* => hash table of symbol values */
+  /* State for GIF code assignment */
+  int ClearCode;		/* clear code (doesn't change) */
+  int EOFCode;			/* EOF code (ditto) */
+  int code_counter;		/* counts output symbols */
 
   /* GIF data packet construction buffer */
   int bytesinpkt;		/* # of bytes in current packet */
@@ -110,9 +68,12 @@
 
 typedef gif_dest_struct * gif_dest_ptr;
 
+/* Largest value that will fit in N bits */
+#define MAXCODE(n_bits)	((1 << (n_bits)) - 1)
+
 
 /*
- * Routines to package compressed data bytes into GIF data blocks.
+ * Routines to package finished data bytes into GIF data blocks.
  * A data block consists of a count byte (1..255) and that many data bytes.
  */
 
@@ -141,7 +102,7 @@
 /* Routine to convert variable-width codes into a byte stream */
 
 LOCAL(void)
-output (gif_dest_ptr dinfo, code_int code)
+output (gif_dest_ptr dinfo, int code)
 /* Emit a code of n_bits bits */
 /* Uses cur_accum and cur_bits to reblock into 8-bit bytes */
 {
@@ -153,123 +114,67 @@
     dinfo->cur_accum >>= 8;
     dinfo->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 (dinfo->free_code > dinfo->maxcode) {
-    dinfo->n_bits++;
-    if (dinfo->n_bits == MAX_LZW_BITS)
-      dinfo->maxcode = LZW_TABLE_SIZE; /* free_code will never exceed this */
-    else
-      dinfo->maxcode = MAXCODE(dinfo->n_bits);
-  }
 }
 
 
-/* The LZW algorithm proper */
-
-
-LOCAL(void)
-clear_hash (gif_dest_ptr dinfo)
-/* Fill the hash table with empty entries */
-{
-  /* It's sufficient to zero hash_code[] */
-  MEMZERO(dinfo->hash_code, HSIZE * SIZEOF(code_int));
-}
-
-
-LOCAL(void)
-clear_block (gif_dest_ptr dinfo)
-/* Reset compressor and issue a Clear code */
-{
-  clear_hash(dinfo);			/* delete all the symbols */
-  dinfo->free_code = dinfo->ClearCode + 2;
-  output(dinfo, dinfo->ClearCode);	/* inform decoder */
-  dinfo->n_bits = dinfo->init_bits;	/* reset code size */
-  dinfo->maxcode = MAXCODE(dinfo->n_bits);
-}
-
+/* The pseudo-compression algorithm.
+ *
+ * In this module we simply output each pixel value as a separate symbol;
+ * thus, no compression occurs.  In fact, there is expansion of one bit per
+ * pixel, because we use a symbol width one bit wider than the pixel width.
+ *
+ * GIF ordinarily uses variable-width symbols, and the decoder will expect
+ * to ratchet up the symbol width after a fixed number of symbols.
+ * To simplify the logic and keep the expansion penalty down, we emit a
+ * GIF Clear code to reset the decoder just before the width would ratchet up.
+ * Thus, all the symbols in the output file will have the same bit width.
+ * Note that emitting the Clear codes at the right times is a mere matter of
+ * counting output symbols and is in no way dependent on the LZW patent.
+ *
+ * With a small basic pixel width (low color count), Clear codes will be
+ * needed very frequently, causing the file to expand even more.  So this
+ * simplistic approach wouldn't work too well on bilevel images, for example.
+ * But for output of JPEG conversions the pixel width will usually be 8 bits
+ * (129 to 256 colors), so the overhead added by Clear symbols is only about
+ * one symbol in every 256.
+ */
 
 LOCAL(void)
 compress_init (gif_dest_ptr dinfo, int i_bits)
-/* Initialize LZW compressor */
+/* Initialize pseudo-compressor */
 {
   /* init all the state variables */
-  dinfo->n_bits = dinfo->init_bits = i_bits;
+  dinfo->n_bits = i_bits;
   dinfo->maxcode = MAXCODE(dinfo->n_bits);
-  dinfo->ClearCode = ((code_int) 1 << (i_bits - 1));
+  dinfo->ClearCode = (1 << (i_bits - 1));
   dinfo->EOFCode = dinfo->ClearCode + 1;
-  dinfo->free_code = dinfo->ClearCode + 2;
-  dinfo->first_byte = TRUE;	/* no waiting symbol yet */
+  dinfo->code_counter = dinfo->ClearCode + 2;
   /* init output buffering vars */
   dinfo->bytesinpkt = 0;
   dinfo->cur_accum = 0;
   dinfo->cur_bits = 0;
-  /* clear hash table */
-  clear_hash(dinfo);
   /* GIF specifies an initial Clear code */
   output(dinfo, dinfo->ClearCode);
 }
 
 
 LOCAL(void)
-compress_byte (gif_dest_ptr dinfo, int c)
-/* Accept and compress one 8-bit byte */
+compress_pixel (gif_dest_ptr dinfo, int c)
+/* Accept and "compress" one pixel value.
+ * The given value must be less than n_bits wide.
+ */
 {
-  register hash_int i;
-  register hash_int disp;
-  register hash_entry probe_value;
-
-  if (dinfo->first_byte) {	/* need to initialize waiting_code */
-    dinfo->waiting_code = c;
-    dinfo->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.
+  /* Output the given pixel value as a symbol. */
+  output(dinfo, c);
+  /* Issue Clear codes often enough to keep the reader from ratcheting up
+   * its symbol size.
    */
-  i = ((hash_int) c << (MAX_LZW_BITS-8)) + dinfo->waiting_code;
-  /* i is less than twice 2**MAX_LZW_BITS, therefore less than twice HSIZE */
-  if (i >= HSIZE)
-    i -= HSIZE;
-
-  probe_value = HASH_ENTRY(dinfo->waiting_code, c);
-  
-  if (dinfo->hash_code[i] != 0) { /* is first probed slot empty? */
-    if (dinfo->hash_value[i] == probe_value) {
-      dinfo->waiting_code = dinfo->hash_code[i];
-      return;
-    }
-    if (i == 0)			/* secondary hash (after G. Knott) */
-      disp = 1;
-    else
-      disp = HSIZE - i;
-    for (;;) {
-      i -= disp;
-      if (i < 0)
-	i += HSIZE;
-      if (dinfo->hash_code[i] == 0)
-	break;			/* hit empty slot */
-      if (dinfo->hash_value[i] == probe_value) {
-	dinfo->waiting_code = dinfo->hash_code[i];
-	return;
-      }
-    }
+  if (dinfo->code_counter < dinfo->maxcode) {
+    dinfo->code_counter++;
+  } else {
+    output(dinfo, dinfo->ClearCode);
+    dinfo->code_counter = dinfo->ClearCode + 2;	/* reset the counter */
   }
-
-  /* here when hashtable[i] is an empty slot; desired symbol not in table */
-  output(dinfo, dinfo->waiting_code);
-  if (dinfo->free_code < LZW_TABLE_SIZE) {
-    dinfo->hash_code[i] = dinfo->free_code++; /* add symbol to hashtable */
-    dinfo->hash_value[i] = probe_value;
-  } else
-    clear_block(dinfo);
-  dinfo->waiting_code = c;
 }
 
 
@@ -277,9 +182,6 @@
 compress_term (gif_dest_ptr dinfo)
 /* Clean up at end */
 {
-  /* Flush out the buffered code */
-  if (! dinfo->first_byte)
-    output(dinfo, dinfo->waiting_code);
   /* Send an EOF code */
   output(dinfo, dinfo->EOFCode);
   /* Flush the bit-packing buffer */
@@ -387,7 +289,7 @@
   /* Write Initial Code Size byte */
   putc(InitCodeSize, dinfo->pub.output_file);
 
-  /* Initialize for LZW compression of image data */
+  /* Initialize for "compression" of image data */
   compress_init(dinfo, InitCodeSize+1);
 }
 
@@ -423,7 +325,7 @@
 
   ptr = dest->pub.buffer[0];
   for (col = cinfo->output_width; col > 0; col--) {
-    compress_byte(dest, GETJSAMPLE(*ptr++));
+    compress_pixel(dest, GETJSAMPLE(*ptr++));
   }
 }
 
@@ -437,7 +339,7 @@
 {
   gif_dest_ptr dest = (gif_dest_ptr) dinfo;
 
-  /* Flush LZW mechanism */
+  /* Flush "compression" mechanism */
   compress_term(dest);
   /* Write a zero-length data block to end the series */
   putc(0, dest->pub.output_file);
@@ -491,14 +393,6 @@
     ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->output_width, (JDIMENSION) 1);
   dest->pub.buffer_height = 1;
 
-  /* Allocate space for hash table */
-  dest->hash_code = (code_int *)
-    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				HSIZE * SIZEOF(code_int));
-  dest->hash_value = (hash_entry FAR *)
-    (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
-				HSIZE * SIZEOF(hash_entry));
-
   return (djpeg_dest_ptr) dest;
 }
 
diff --git a/wrjpgcom.c b/wrjpgcom.c
index 3b6411c..8c04b05 100644
--- a/wrjpgcom.c
+++ b/wrjpgcom.c
@@ -1,7 +1,7 @@
 /*
  * wrjpgcom.c
  *
- * Copyright (C) 1994-1995, Thomas G. Lane.
+ * Copyright (C) 1994-1997, 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.
  *
@@ -38,9 +38,14 @@
 #define READ_BINARY	"r"
 #define WRITE_BINARY	"w"
 #else
+#ifdef VMS			/* VMS is very nonstandard */
+#define READ_BINARY	"rb", "ctx=stm"
+#define WRITE_BINARY	"wb", "ctx=stm"
+#else				/* standard ANSI-compliant case */
 #define READ_BINARY	"rb"
 #define WRITE_BINARY	"wb"
 #endif
+#endif
 
 #ifndef EXIT_FAILURE		/* define exit() codes if not provided */
 #define EXIT_FAILURE  1
@@ -58,7 +63,7 @@
  */
 
 #ifndef MAX_COM_LENGTH
-#define MAX_COM_LENGTH 65000	/* must be < 65534 in any case */
+#define MAX_COM_LENGTH 65000L	/* must be <= 65533 in any case */
 #endif
 
 
@@ -294,6 +299,9 @@
   for (;;) {
     marker = next_marker();
     switch (marker) {
+      /* Note that marker codes 0xC4, 0xC8, 0xCC are not, and must not be,
+       * treated as SOFn.  C4 in particular is actually DHT.
+       */
     case M_SOF0:		/* Baseline */
     case M_SOF1:		/* Extended sequential, Huffman */
     case M_SOF2:		/* Progressive, Huffman */
@@ -447,7 +455,7 @@
 	  ERREXIT("Insufficient memory");
 	strcpy(comment_arg, argv[argn]+1);
 	for (;;) {
-	  comment_length = strlen(comment_arg);
+	  comment_length = (unsigned int) strlen(comment_arg);
 	  if (comment_length > 0 && comment_arg[comment_length-1] == '"') {
 	    comment_arg[comment_length-1] = '\0'; /* zap terminating quote */
 	    break;
@@ -458,7 +466,7 @@
 	  strcat(comment_arg, argv[argn]);
 	}
       }
-      comment_length = strlen(comment_arg);
+      comment_length = (unsigned int) strlen(comment_arg);
     } else
       usage();
   }