[Wx Widget] Update jpeg to wxWidgets-2.8.12
This commit is contained in:
parent
8046b1a7f8
commit
85e4d0f08d
|
@ -0,0 +1,385 @@
|
|||
The Independent JPEG Group's JPEG software
|
||||
==========================================
|
||||
|
||||
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
|
||||
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
|
||||
|
||||
Serious users of this software (particularly those incorporating it into
|
||||
larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
|
||||
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, 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.
|
||||
|
||||
|
||||
DOCUMENTATION ROADMAP
|
||||
=====================
|
||||
|
||||
This file contains the following sections:
|
||||
|
||||
OVERVIEW General description of JPEG and the IJG software.
|
||||
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
|
||||
REFERENCES Where to learn more about JPEG.
|
||||
ARCHIVE LOCATIONS Where to find newer versions of this software.
|
||||
RELATED SOFTWARE Other stuff you should get.
|
||||
FILE FORMAT WARS Software *not* to get.
|
||||
TO DO Plans for future IJG releases.
|
||||
|
||||
Other documentation files in the distribution are:
|
||||
|
||||
User documentation:
|
||||
install.doc How to configure and install the IJG software.
|
||||
usage.doc Usage instructions for cjpeg, djpeg, jpegtran,
|
||||
rdjpgcom, and wrjpgcom.
|
||||
*.1 Unix-style man pages for programs (same info as usage.doc).
|
||||
wizard.doc Advanced usage instructions for JPEG wizards only.
|
||||
change.log Version-to-version change highlights.
|
||||
Programmer and internal documentation:
|
||||
libjpeg.doc How to use the JPEG library in your own programs.
|
||||
example.c Sample code for calling the JPEG library.
|
||||
structure.doc Overview of the JPEG library's internal structure.
|
||||
filelist.doc Road map of IJG files.
|
||||
coderules.doc Coding style rules --- please read if you contribute code.
|
||||
|
||||
Please read at least the files install.doc and usage.doc. Useful information
|
||||
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
|
||||
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
|
||||
|
||||
If you want to understand how the JPEG code works, we suggest reading one or
|
||||
more of the REFERENCES, then looking at the documentation files (in roughly
|
||||
the order listed) before diving into the code.
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
This package contains C software to implement JPEG image compression and
|
||||
decompression. JPEG (pronounced "jay-peg") is a standardized compression
|
||||
method for full-color and gray-scale images. JPEG is intended for compressing
|
||||
"real-world" scenes; line drawings, cartoons and other non-realistic images
|
||||
are not its strong suit. JPEG is lossy, meaning that the output image is not
|
||||
exactly identical to the input image. Hence you must not use JPEG if you
|
||||
have to have identical output bits. However, on typical photographic images,
|
||||
very good compression levels can be obtained with no visible change, and
|
||||
remarkably high compression levels are possible if you can tolerate a
|
||||
low-quality image. For more details, see the references, or just experiment
|
||||
with various compression settings.
|
||||
|
||||
This software implements JPEG baseline, extended-sequential, and progressive
|
||||
compression processes. Provision is made for supporting all variants of these
|
||||
processes, although some uncommon parameter settings aren't implemented yet.
|
||||
For legal reasons, we are not distributing code for the arithmetic-coding
|
||||
variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting
|
||||
the hierarchical or lossless processes defined in the standard.
|
||||
|
||||
We provide a set of library routines for reading and writing JPEG image files,
|
||||
plus two sample applications "cjpeg" and "djpeg", which use the library to
|
||||
perform conversion between JPEG and some other popular image file formats.
|
||||
The library is intended to be reused in other applications.
|
||||
|
||||
In order to support file conversion and viewing software, we have included
|
||||
considerable functionality beyond the bare JPEG coding/decoding capability;
|
||||
for example, the color quantization modules are not strictly part of JPEG
|
||||
decoding, but they are essential for output to colormapped file formats or
|
||||
colormapped displays. These extra functions can be compiled out of the
|
||||
library if not required for a particular application. We have also included
|
||||
"jpegtran", a utility for lossless transcoding between different JPEG
|
||||
processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
|
||||
inserting and extracting textual comments in JFIF files.
|
||||
|
||||
The emphasis in designing this software has been on achieving portability and
|
||||
flexibility, while also making it fast enough to be useful. In particular,
|
||||
the software is not intended to be read as a tutorial on JPEG. (See the
|
||||
REFERENCES section for introductory material.) Rather, it is intended to
|
||||
be reliable, portable, industrial-strength code. We do not claim to have
|
||||
achieved that goal in every aspect of the software, but we strive for it.
|
||||
|
||||
We welcome the use of this software as a component of commercial products.
|
||||
No royalty is required, but we do ask for an acknowledgement in product
|
||||
documentation, as described under LEGAL ISSUES.
|
||||
|
||||
|
||||
LEGAL ISSUES
|
||||
============
|
||||
|
||||
In plain English:
|
||||
|
||||
1. We don't promise that this software works. (But if you find any bugs,
|
||||
please let us know!)
|
||||
2. You can use this software for whatever you want. You don't have to pay us.
|
||||
3. You may not pretend that you wrote this software. If you use it in a
|
||||
program, you must acknowledge somewhere in your documentation that
|
||||
you've used the IJG code.
|
||||
|
||||
In legalese:
|
||||
|
||||
The authors make NO WARRANTY or representation, either express or implied,
|
||||
with respect to this software, its quality, accuracy, merchantability, or
|
||||
fitness for a particular purpose. This software is provided "AS IS", and you,
|
||||
its user, assume the entire risk as to its quality and accuracy.
|
||||
|
||||
This software is copyright (C) 1991-1998, Thomas G. Lane.
|
||||
All Rights Reserved except as specified below.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
software (or portions thereof) for any purpose, without fee, subject to these
|
||||
conditions:
|
||||
(1) If any part of the source code for this software is distributed, then this
|
||||
README file must be included, with this copyright and no-warranty notice
|
||||
unaltered; and any additions, deletions, or changes to the original files
|
||||
must be clearly indicated in accompanying documentation.
|
||||
(2) If only executable code is distributed, then the accompanying
|
||||
documentation must state that "this software is based in part on the work of
|
||||
the Independent JPEG Group".
|
||||
(3) Permission for use of this software is granted only if the user accepts
|
||||
full responsibility for any undesirable consequences; the authors accept
|
||||
NO LIABILITY for damages of any kind.
|
||||
|
||||
These conditions apply to any software derived from or based on the IJG code,
|
||||
not just to the unmodified library. If you use our work, you ought to
|
||||
acknowledge us.
|
||||
|
||||
Permission is NOT granted for the use of any IJG author's name or company name
|
||||
in advertising or publicity relating to this software or products derived from
|
||||
it. This software may be referred to only as "the Independent JPEG Group's
|
||||
software".
|
||||
|
||||
We specifically permit and encourage the use of this software as the basis of
|
||||
commercial products, provided that all warranty or liability claims are
|
||||
assumed by the product vendor.
|
||||
|
||||
|
||||
ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
|
||||
sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
|
||||
ansi2knr.c is NOT covered by the above copyright and conditions, but instead
|
||||
by the usual distribution terms of the Free Software Foundation; principally,
|
||||
that you must include source code if you redistribute it. (See the file
|
||||
ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
|
||||
of any program generated from the IJG code, this does not limit you more than
|
||||
the foregoing paragraphs do.
|
||||
|
||||
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
|
||||
legally be used without obtaining one or more licenses. For this reason,
|
||||
support for arithmetic coding has been removed from the free JPEG software.
|
||||
(Since arithmetic coding provides only a marginal gain over the unpatented
|
||||
Huffman mode, it is unlikely that very many implementations will support it.)
|
||||
So far as we are aware, there are no patent restrictions on the remaining
|
||||
code.
|
||||
|
||||
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
|
||||
CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
CompuServe Incorporated."
|
||||
|
||||
|
||||
REFERENCES
|
||||
==========
|
||||
|
||||
We highly recommend reading one or more of these references before trying to
|
||||
understand the innards of the JPEG software.
|
||||
|
||||
The best short technical introduction to the JPEG compression algorithm is
|
||||
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
|
||||
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
|
||||
(Adjacent articles in that issue discuss MPEG motion picture compression,
|
||||
applications of JPEG, and related topics.) If you don't have the CACM issue
|
||||
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.
|
||||
|
||||
A somewhat less technical, more leisurely introduction to JPEG can be found in
|
||||
"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
|
||||
by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
|
||||
The book includes the complete text of the ISO JPEG standards (DIS 10918-1
|
||||
and draft DIS 10918-2). This is by far the most complete exposition of JPEG
|
||||
in existence, and we highly recommend it.
|
||||
|
||||
The JPEG standard itself is not available electronically; you must order a
|
||||
paper copy through ISO or ITU. (Unless you feel a need to own a certified
|
||||
official copy, we recommend buying the Pennebaker and Mitchell book instead;
|
||||
it's much cheaper and includes a great deal of useful explanatory material.)
|
||||
In the USA, copies of the standard may be ordered from ANSI Sales at (212)
|
||||
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
|
||||
doesn't take credit card orders, but Global does.) It's not cheap: as of
|
||||
1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
|
||||
shipping/handling. The standard is divided into two parts, Part 1 being the
|
||||
actual specification, while Part 2 covers compliance testing methods. Part 1
|
||||
is titled "Digital Compression and Coding of Continuous-tone Still Images,
|
||||
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
|
||||
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
|
||||
Continuous-tone Still Images, Part 2: Compliance testing" and has document
|
||||
numbers ISO/IEC IS 10918-2, ITU-T T.83.
|
||||
|
||||
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
|
||||
1.02. A copy of the JFIF spec is available from:
|
||||
Literature Department
|
||||
C-Cube Microsystems, Inc.
|
||||
1778 McCarthy Blvd.
|
||||
Milpitas, CA 95035
|
||||
phone (408) 944-6300, fax (408) 944-6314
|
||||
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
|
||||
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 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 ftp://ftp.sgi.com/graphics/tiff/.
|
||||
|
||||
|
||||
ARCHIVE LOCATIONS
|
||||
=================
|
||||
|
||||
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 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://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.
|
||||
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
|
||||
|
||||
|
||||
RELATED SOFTWARE
|
||||
================
|
||||
|
||||
Numerous viewing and image manipulation programs now support JPEG. (Quite a
|
||||
few of them use this library to do so.) The JPEG FAQ described above lists
|
||||
some of the more popular free and shareware viewers, and tells where to
|
||||
obtain them on Internet.
|
||||
|
||||
If you are on a Unix machine, we highly recommend Jef Poskanzer's free
|
||||
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 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. (On the other hand, it doesn't do progressive JPEG.)
|
||||
|
||||
|
||||
FILE FORMAT WARS
|
||||
================
|
||||
|
||||
Some JPEG programs produce files that are not compatible with our library.
|
||||
The root of the problem is that the ISO JPEG committee failed to specify a
|
||||
concrete file format. Some vendors "filled in the blanks" on their own,
|
||||
creating proprietary formats that no one else could read. (For example, none
|
||||
of the early commercial JPEG implementations for the Macintosh were able to
|
||||
exchange compressed files.)
|
||||
|
||||
The file format we have adopted is called JFIF (see REFERENCES). This format
|
||||
has been agreed to by a number of major commercial JPEG vendors, and it has
|
||||
become the de facto standard. JFIF is a minimal or "low end" representation.
|
||||
We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
|
||||
Technical Note #2) for "high end" applications that need to record a lot of
|
||||
additional data about an image. TIFF/JPEG is fairly new and not yet widely
|
||||
supported, unfortunately.
|
||||
|
||||
The upcoming JPEG Part 3 standard defines a file format called SPIFF.
|
||||
SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
|
||||
be able to read the most common variant of SPIFF. SPIFF has some technical
|
||||
advantages over JFIF, but its major claim to fame is simply that it is an
|
||||
official standard rather than an informal one. At this point it is unclear
|
||||
whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
|
||||
standard. IJG intends to support SPIFF once the standard is frozen, but we
|
||||
have not decided whether it should become our default output format or not.
|
||||
(In any case, our decoder will remain capable of reading JFIF indefinitely.)
|
||||
|
||||
Various proprietary file formats incorporating JPEG compression also exist.
|
||||
We have little or no sympathy for the existence of these formats. Indeed,
|
||||
one of the original reasons for developing this free software was to help
|
||||
force convergence on common, open format standards for JPEG files. Don't
|
||||
use a proprietary file format!
|
||||
|
||||
|
||||
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.
|
||||
|
||||
As always, speeding things up is of great interest.
|
||||
|
||||
Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
|
|
@ -0,0 +1,693 @@
|
|||
/* ansi2knr.c */
|
||||
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
|
||||
|
||||
/*
|
||||
ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY. No author or distributor accepts responsibility to anyone for the
|
||||
consequences of using it or for whether it serves any particular purpose or
|
||||
works at all, unless he says so in writing. Refer to the GNU General Public
|
||||
License (the "GPL") for full details.
|
||||
|
||||
Everyone is granted permission to copy, modify and redistribute ansi2knr,
|
||||
but only under the conditions described in the GPL. A copy of this license
|
||||
is supposed to have been given to you along with ansi2knr so you can know
|
||||
your rights and responsibilities. It should be in a file named COPYLEFT.
|
||||
[In the IJG distribution, the GPL appears below, not in a separate file.]
|
||||
Among other things, the copyright notice and this notice must be preserved
|
||||
on all copies.
|
||||
|
||||
We explicitly state here what we believe is already implied by the GPL: if
|
||||
the ansi2knr program is distributed as a separate set of sources and a
|
||||
separate executable file which are aggregated on a storage medium together
|
||||
with another program, this in itself does not bring the other program under
|
||||
the GPL, nor does the mere fact that such a program or the procedures for
|
||||
constructing it invoke the ansi2knr executable bring any other part of the
|
||||
program under the GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
---------- Here is the GNU GPL file COPYLEFT, referred to above ----------
|
||||
----- These terms do NOT apply to the JPEG software itself; see README ------
|
||||
|
||||
GHOSTSCRIPT GENERAL PUBLIC LICENSE
|
||||
(Clarified 11 Feb 1988)
|
||||
|
||||
Copyright (C) 1988 Richard M. Stallman
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license, but changing it is not allowed. You can also use this wording
|
||||
to make the terms for other programs.
|
||||
|
||||
The license agreements of most software companies keep you at the
|
||||
mercy of those companies. By contrast, our general public license is
|
||||
intended to give everyone the right to share Ghostscript. To make sure
|
||||
that you get the rights we want you to have, we need to make
|
||||
restrictions that forbid anyone to deny you these rights or to ask you
|
||||
to surrender the rights. Hence this license agreement.
|
||||
|
||||
Specifically, we want to make sure that you have the right to give
|
||||
away copies of Ghostscript, that you receive source code or else can get
|
||||
it if you want it, that you can change Ghostscript or use pieces of it
|
||||
in new free programs, and that you know you can do these things.
|
||||
|
||||
To make sure that everyone has such rights, we have to forbid you to
|
||||
deprive anyone else of these rights. For example, if you distribute
|
||||
copies of Ghostscript, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must tell them their rights.
|
||||
|
||||
Also, for our own protection, we must make certain that everyone finds
|
||||
out that there is no warranty for Ghostscript. If Ghostscript is
|
||||
modified by someone else and passed on, we want its recipients to know
|
||||
that what they have is not what we distributed, so that any problems
|
||||
introduced by others will not reflect on our reputation.
|
||||
|
||||
Therefore we (Richard M. Stallman and the Free Software Foundation,
|
||||
Inc.) make the following terms which say what you must do to be allowed
|
||||
to distribute or change Ghostscript.
|
||||
|
||||
|
||||
COPYING POLICIES
|
||||
|
||||
1. You may copy and distribute verbatim copies of Ghostscript source
|
||||
code as you receive it, in any medium, provided that you conspicuously
|
||||
and appropriately publish on each copy a valid copyright and license
|
||||
notice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved.
|
||||
Distributed by Free Software Foundation, Inc." (or with whatever year is
|
||||
appropriate); keep intact the notices on all files that refer to this
|
||||
License Agreement and to the absence of any warranty; and give any other
|
||||
recipients of the Ghostscript program a copy of this License Agreement
|
||||
along with the program. You may charge a distribution fee for the
|
||||
physical act of transferring a copy.
|
||||
|
||||
2. You may modify your copy or copies of Ghostscript or any portion of
|
||||
it, and copy and distribute such modifications under the terms of
|
||||
Paragraph 1 above, provided that you also do the following:
|
||||
|
||||
a) cause the modified files to carry prominent notices stating
|
||||
that you changed the files and the date of any change; and
|
||||
|
||||
b) cause the whole of any work that you distribute or publish,
|
||||
that in whole or in part contains or is a derivative of Ghostscript
|
||||
or any part thereof, to be licensed at no charge to all third
|
||||
parties on terms identical to those contained in this License
|
||||
Agreement (except that you may choose to grant more extensive
|
||||
warranty protection to some or all third parties, at your option).
|
||||
|
||||
c) You may charge a distribution fee for the physical act of
|
||||
transferring a copy, and you may at your option offer warranty
|
||||
protection in exchange for a fee.
|
||||
|
||||
Mere aggregation of another unrelated program with this program (or its
|
||||
derivative) on a volume of a storage or distribution medium does not bring
|
||||
the other program under the scope of these terms.
|
||||
|
||||
3. You may copy and distribute Ghostscript (or a portion or derivative
|
||||
of it, under Paragraph 2) in object code or executable form under the
|
||||
terms of Paragraphs 1 and 2 above provided that you also do one of the
|
||||
following:
|
||||
|
||||
a) accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
b) accompany it with a written offer, valid for at least three
|
||||
years, to give any third party free (except for a nominal
|
||||
shipping charge) a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
c) accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
|
||||
For an executable file, complete source code means all the source code for
|
||||
all modules it contains; but, as a special exception, it need not include
|
||||
source code for modules which are standard libraries that accompany the
|
||||
operating system on which the executable file runs.
|
||||
|
||||
4. You may not copy, sublicense, distribute or transfer Ghostscript
|
||||
except as expressly provided under this License Agreement. Any attempt
|
||||
otherwise to copy, sublicense, distribute or transfer Ghostscript is
|
||||
void and your rights to use the program under this License agreement
|
||||
shall be automatically terminated. However, parties who have received
|
||||
computer software programs from you with this License Agreement will not
|
||||
have their licenses terminated so long as such parties remain in full
|
||||
compliance.
|
||||
|
||||
5. If you wish to incorporate parts of Ghostscript into other free
|
||||
programs whose distribution conditions are different, write to the Free
|
||||
Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not
|
||||
yet worked out a simple rule that can be stated here, but we will often
|
||||
permit this. We will be guided by the two goals of preserving the free
|
||||
status of all derivatives of our free software and of promoting the
|
||||
sharing and reuse of software.
|
||||
|
||||
Your comments and suggestions about our licensing policies and our
|
||||
software are welcome! Please contact the Free Software Foundation,
|
||||
Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
|
||||
NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
|
||||
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
|
||||
M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
|
||||
PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
|
||||
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
|
||||
YOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
|
||||
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
|
||||
ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
|
||||
GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
|
||||
ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
|
||||
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
|
||||
INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
|
||||
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
|
||||
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
|
||||
BY ANY OTHER PARTY.
|
||||
|
||||
-------------------- End of file COPYLEFT ------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Usage:
|
||||
ansi2knr input_file [output_file]
|
||||
* If no output_file is supplied, output goes to stdout.
|
||||
* There are no error messages.
|
||||
*
|
||||
* ansi2knr recognizes function definitions by seeing a non-keyword
|
||||
* identifier at the left margin, followed by a left parenthesis,
|
||||
* with a right parenthesis as the last character on the line,
|
||||
* and with a left brace as the first token on the following line
|
||||
* (ignoring possible intervening comments).
|
||||
* It will recognize a multi-line header provided that no intervening
|
||||
* line ends with a left or right brace or a semicolon.
|
||||
* These algorithms ignore whitespace and comments, except that
|
||||
* the function name must be the first thing on the line.
|
||||
* The following constructs will confuse it:
|
||||
* - Any other construct that starts at the left margin and
|
||||
* follows the above syntax (such as a macro or function call).
|
||||
* - Some macros that tinker with the syntax of the function header.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The original and principal author of ansi2knr is L. Peter Deutsch
|
||||
* <ghost@aladdin.com>. Other authors are noted in the change history
|
||||
* that follows (in reverse chronological order):
|
||||
lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with
|
||||
compilers that don't understand void, as suggested by
|
||||
Tom Lane
|
||||
lpd 96-01-15 changed to require that the first non-comment token
|
||||
on the line following a function header be a left brace,
|
||||
to reduce sensitivity to macros, as suggested by Tom Lane
|
||||
<tgl@sss.pgh.pa.us>
|
||||
lpd 95-06-22 removed #ifndefs whose sole purpose was to define
|
||||
undefined preprocessor symbols as 0; changed all #ifdefs
|
||||
for configuration symbols to #ifs
|
||||
lpd 95-04-05 changed copyright notice to make it clear that
|
||||
including ansi2knr in a program does not bring the entire
|
||||
program under the GPL
|
||||
lpd 94-12-18 added conditionals for systems where ctype macros
|
||||
don't handle 8-bit characters properly, suggested by
|
||||
Francois Pinard <pinard@iro.umontreal.ca>;
|
||||
removed --varargs switch (this is now the default)
|
||||
lpd 94-10-10 removed CONFIG_BROKETS conditional
|
||||
lpd 94-07-16 added some conditionals to help GNU `configure',
|
||||
suggested by Francois Pinard <pinard@iro.umontreal.ca>;
|
||||
properly erase prototype args in function parameters,
|
||||
contributed by Jim Avera <jima@netcom.com>;
|
||||
correct error in writeblanks (it shouldn't erase EOLs)
|
||||
lpd 89-xx-xx original version
|
||||
*/
|
||||
|
||||
/* Most of the conditionals here are to make ansi2knr work with */
|
||||
/* or without the GNU configure machinery. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
|
||||
/*
|
||||
For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
|
||||
This will define HAVE_CONFIG_H and so, activate the following lines.
|
||||
*/
|
||||
|
||||
# if STDC_HEADERS || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# else
|
||||
# include <strings.h>
|
||||
# endif
|
||||
|
||||
#else /* not HAVE_CONFIG_H */
|
||||
|
||||
/* Otherwise do it the hard way */
|
||||
|
||||
# ifdef BSD
|
||||
# include <strings.h>
|
||||
# else
|
||||
# ifdef VMS
|
||||
extern int strlen(), strncmp();
|
||||
# else
|
||||
# include <string.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif /* not HAVE_CONFIG_H */
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
/*
|
||||
malloc and free should be declared in stdlib.h,
|
||||
but if you've got a K&R compiler, they probably aren't.
|
||||
*/
|
||||
# ifdef MSDOS
|
||||
# include <malloc.h>
|
||||
# else
|
||||
# ifdef VMS
|
||||
extern char *malloc();
|
||||
extern void free();
|
||||
# else
|
||||
extern char *malloc();
|
||||
extern int free();
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The ctype macros don't always handle 8-bit characters correctly.
|
||||
* Compensate for this here.
|
||||
*/
|
||||
#ifdef isascii
|
||||
# undef HAVE_ISASCII /* just in case */
|
||||
# define HAVE_ISASCII 1
|
||||
#else
|
||||
#endif
|
||||
#if STDC_HEADERS || !HAVE_ISASCII
|
||||
# define is_ascii(c) 1
|
||||
#else
|
||||
# define is_ascii(c) isascii(c)
|
||||
#endif
|
||||
|
||||
#define is_space(c) (is_ascii(c) && isspace(c))
|
||||
#define is_alpha(c) (is_ascii(c) && isalpha(c))
|
||||
#define is_alnum(c) (is_ascii(c) && isalnum(c))
|
||||
|
||||
/* Scanning macros */
|
||||
#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
|
||||
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
|
||||
|
||||
/* Forward references */
|
||||
char *skipspace();
|
||||
int writeblanks();
|
||||
int test1();
|
||||
int convert1();
|
||||
|
||||
/* The main program */
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{ FILE *in, *out;
|
||||
#define bufsize 5000 /* arbitrary size */
|
||||
char *buf;
|
||||
char *line;
|
||||
char *more;
|
||||
/*
|
||||
* In previous versions, ansi2knr recognized a --varargs switch.
|
||||
* If this switch was supplied, ansi2knr would attempt to convert
|
||||
* a ... argument to va_alist and va_dcl; if this switch was not
|
||||
* supplied, ansi2knr would simply drop any such arguments.
|
||||
* Now, ansi2knr always does this conversion, and we only
|
||||
* check for this switch for backward compatibility.
|
||||
*/
|
||||
int convert_varargs = 1;
|
||||
|
||||
if ( argc > 1 && argv[1][0] == '-' )
|
||||
{ if ( !strcmp(argv[1], "--varargs") )
|
||||
{ convert_varargs = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
else
|
||||
{ fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
switch ( argc )
|
||||
{
|
||||
default:
|
||||
printf("Usage: ansi2knr input_file [output_file]\n");
|
||||
exit(0);
|
||||
case 2:
|
||||
out = stdout;
|
||||
break;
|
||||
case 3:
|
||||
out = fopen(argv[2], "w");
|
||||
if ( out == NULL )
|
||||
{ fprintf(stderr, "Cannot open output file %s\n", argv[2]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
in = fopen(argv[1], "r");
|
||||
if ( in == NULL )
|
||||
{ fprintf(stderr, "Cannot open input file %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(out, "#line 1 \"%s\"\n", argv[1]);
|
||||
buf = malloc(bufsize);
|
||||
line = buf;
|
||||
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
|
||||
{
|
||||
test: line += strlen(line);
|
||||
switch ( test1(buf) )
|
||||
{
|
||||
case 2: /* a function header */
|
||||
convert1(buf, out, 1, convert_varargs);
|
||||
break;
|
||||
case 1: /* a function */
|
||||
/* Check for a { at the start of the next line. */
|
||||
more = ++line;
|
||||
f: if ( line >= buf + (bufsize - 1) ) /* overflow check */
|
||||
goto wl;
|
||||
if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
|
||||
goto wl;
|
||||
switch ( *skipspace(more, 1) )
|
||||
{
|
||||
case '{':
|
||||
/* Definitely a function header. */
|
||||
convert1(buf, out, 0, convert_varargs);
|
||||
fputs(more, out);
|
||||
break;
|
||||
case 0:
|
||||
/* The next line was blank or a comment: */
|
||||
/* keep scanning for a non-comment. */
|
||||
line += strlen(line);
|
||||
goto f;
|
||||
default:
|
||||
/* buf isn't a function header, but */
|
||||
/* more might be. */
|
||||
fputs(buf, out);
|
||||
strcpy(buf, more);
|
||||
line = buf;
|
||||
goto test;
|
||||
}
|
||||
break;
|
||||
case -1: /* maybe the start of a function */
|
||||
if ( line != buf + (bufsize - 1) ) /* overflow check */
|
||||
continue;
|
||||
/* falls through */
|
||||
default: /* not a function */
|
||||
wl: fputs(buf, out);
|
||||
break;
|
||||
}
|
||||
line = buf;
|
||||
}
|
||||
if ( line != buf )
|
||||
fputs(buf, out);
|
||||
free(buf);
|
||||
fclose(out);
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Skip over space and comments, in either direction. */
|
||||
char *
|
||||
skipspace(p, dir)
|
||||
register char *p;
|
||||
register int dir; /* 1 for forward, -1 for backward */
|
||||
{ for ( ; ; )
|
||||
{ while ( is_space(*p) )
|
||||
p += dir;
|
||||
if ( !(*p == '/' && p[dir] == '*') )
|
||||
break;
|
||||
p += dir; p += dir;
|
||||
while ( !(*p == '*' && p[dir] == '/') )
|
||||
{ if ( *p == 0 )
|
||||
return p; /* multi-line comment?? */
|
||||
p += dir;
|
||||
}
|
||||
p += dir; p += dir;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write blanks over part of a string.
|
||||
* Don't overwrite end-of-line characters.
|
||||
*/
|
||||
int
|
||||
writeblanks(start, end)
|
||||
char *start;
|
||||
char *end;
|
||||
{ char *p;
|
||||
for ( p = start; p < end; p++ )
|
||||
if ( *p != '\r' && *p != '\n' )
|
||||
*p = ' ';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether the string in buf is a function definition.
|
||||
* The string may contain and/or end with a newline.
|
||||
* Return as follows:
|
||||
* 0 - definitely not a function definition;
|
||||
* 1 - definitely a function definition;
|
||||
* 2 - definitely a function prototype (NOT USED);
|
||||
* -1 - may be the beginning of a function definition,
|
||||
* append another line and look again.
|
||||
* The reason we don't attempt to convert function prototypes is that
|
||||
* Ghostscript's declaration-generating macros look too much like
|
||||
* prototypes, and confuse the algorithms.
|
||||
*/
|
||||
int
|
||||
test1(buf)
|
||||
char *buf;
|
||||
{ register char *p = buf;
|
||||
char *bend;
|
||||
char *endfn;
|
||||
int contin;
|
||||
|
||||
if ( !isidfirstchar(*p) )
|
||||
return 0; /* no name at left margin */
|
||||
bend = skipspace(buf + strlen(buf) - 1, -1);
|
||||
switch ( *bend )
|
||||
{
|
||||
case ';': contin = 0 /*2*/; break;
|
||||
case ')': contin = 1; break;
|
||||
case '{': return 0; /* not a function */
|
||||
case '}': return 0; /* not a function */
|
||||
default: contin = -1;
|
||||
}
|
||||
while ( isidchar(*p) )
|
||||
p++;
|
||||
endfn = p;
|
||||
p = skipspace(p, 1);
|
||||
if ( *p++ != '(' )
|
||||
return 0; /* not a function */
|
||||
p = skipspace(p, 1);
|
||||
if ( *p == ')' )
|
||||
return 0; /* no parameters */
|
||||
/* Check that the apparent function name isn't a keyword. */
|
||||
/* We only need to check for keywords that could be followed */
|
||||
/* by a left parenthesis (which, unfortunately, is most of them). */
|
||||
{ static char *words[] =
|
||||
{ "asm", "auto", "case", "char", "const", "double",
|
||||
"extern", "float", "for", "if", "int", "long",
|
||||
"register", "return", "short", "signed", "sizeof",
|
||||
"static", "switch", "typedef", "unsigned",
|
||||
"void", "volatile", "while", 0
|
||||
};
|
||||
char **key = words;
|
||||
char *kp;
|
||||
int len = endfn - buf;
|
||||
|
||||
while ( (kp = *key) != 0 )
|
||||
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
|
||||
return 0; /* name is a keyword */
|
||||
key++;
|
||||
}
|
||||
}
|
||||
return contin;
|
||||
}
|
||||
|
||||
/* Convert a recognized function definition or header to K&R syntax. */
|
||||
int
|
||||
convert1(buf, out, header, convert_varargs)
|
||||
char *buf;
|
||||
FILE *out;
|
||||
int header; /* Boolean */
|
||||
int convert_varargs; /* Boolean */
|
||||
{ char *endfn;
|
||||
register char *p;
|
||||
char **breaks;
|
||||
unsigned num_breaks = 2; /* for testing */
|
||||
char **btop;
|
||||
char **bp;
|
||||
char **ap;
|
||||
char *vararg = 0;
|
||||
|
||||
/* Pre-ANSI implementations don't agree on whether strchr */
|
||||
/* is called strchr or index, so we open-code it here. */
|
||||
for ( endfn = buf; *(endfn++) != '('; )
|
||||
;
|
||||
top: p = endfn;
|
||||
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
|
||||
if ( breaks == 0 )
|
||||
{ /* Couldn't allocate break table, give up */
|
||||
fprintf(stderr, "Unable to allocate break table!\n");
|
||||
fputs(buf, out);
|
||||
return -1;
|
||||
}
|
||||
btop = breaks + num_breaks * 2 - 2;
|
||||
bp = breaks;
|
||||
/* Parse the argument list */
|
||||
do
|
||||
{ int level = 0;
|
||||
char *lp = NULL;
|
||||
char *rp;
|
||||
char *end = NULL;
|
||||
|
||||
if ( bp >= btop )
|
||||
{ /* Filled up break table. */
|
||||
/* Allocate a bigger one and start over. */
|
||||
free((char *)breaks);
|
||||
num_breaks <<= 1;
|
||||
goto top;
|
||||
}
|
||||
*bp++ = p;
|
||||
/* Find the end of the argument */
|
||||
for ( ; end == NULL; p++ )
|
||||
{ switch(*p)
|
||||
{
|
||||
case ',':
|
||||
if ( !level ) end = p;
|
||||
break;
|
||||
case '(':
|
||||
if ( !level ) lp = p;
|
||||
level++;
|
||||
break;
|
||||
case ')':
|
||||
if ( --level < 0 ) end = p;
|
||||
else rp = p;
|
||||
break;
|
||||
case '/':
|
||||
p = skipspace(p, 1) - 1;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
/* Erase any embedded prototype parameters. */
|
||||
if ( lp )
|
||||
writeblanks(lp + 1, rp);
|
||||
p--; /* back up over terminator */
|
||||
/* Find the name being declared. */
|
||||
/* This is complicated because of procedure and */
|
||||
/* array modifiers. */
|
||||
for ( ; ; )
|
||||
{ p = skipspace(p - 1, -1);
|
||||
switch ( *p )
|
||||
{
|
||||
case ']': /* skip array dimension(s) */
|
||||
case ')': /* skip procedure args OR name */
|
||||
{ int level = 1;
|
||||
while ( level )
|
||||
switch ( *--p )
|
||||
{
|
||||
case ']': case ')': level++; break;
|
||||
case '[': case '(': level--; break;
|
||||
case '/': p = skipspace(p, -1) + 1; break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
|
||||
{ /* We found the name being declared */
|
||||
while ( !isidfirstchar(*p) )
|
||||
p = skipspace(p, 1) + 1;
|
||||
goto found;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
|
||||
{ if ( convert_varargs )
|
||||
{ *bp++ = "va_alist";
|
||||
vararg = p-2;
|
||||
}
|
||||
else
|
||||
{ p++;
|
||||
if ( bp == breaks + 1 ) /* sole argument */
|
||||
writeblanks(breaks[0], p);
|
||||
else
|
||||
writeblanks(bp[-1] - 1, p);
|
||||
bp--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ while ( isidchar(*p) ) p--;
|
||||
*bp++ = p+1;
|
||||
}
|
||||
p = end;
|
||||
}
|
||||
while ( *p++ == ',' );
|
||||
*bp = p;
|
||||
/* Make a special check for 'void' arglist */
|
||||
if ( bp == breaks+2 )
|
||||
{ p = skipspace(breaks[0], 1);
|
||||
if ( !strncmp(p, "void", 4) )
|
||||
{ p = skipspace(p+4, 1);
|
||||
if ( p == breaks[2] - 1 )
|
||||
{ bp = breaks; /* yup, pretend arglist is empty */
|
||||
writeblanks(breaks[0], p + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Put out the function name and left parenthesis. */
|
||||
p = buf;
|
||||
while ( p != endfn ) putc(*p, out), p++;
|
||||
/* Put out the declaration. */
|
||||
if ( header )
|
||||
{ fputs(");", out);
|
||||
for ( p = breaks[0]; *p; p++ )
|
||||
if ( *p == '\r' || *p == '\n' )
|
||||
putc(*p, out);
|
||||
}
|
||||
else
|
||||
{ for ( ap = breaks+1; ap < bp; ap += 2 )
|
||||
{ p = *ap;
|
||||
while ( isidchar(*p) )
|
||||
putc(*p, out), p++;
|
||||
if ( ap < bp - 1 )
|
||||
fputs(", ", out);
|
||||
}
|
||||
fputs(") ", out);
|
||||
/* Put out the argument declarations */
|
||||
for ( ap = breaks+2; ap <= bp; ap += 2 )
|
||||
(*ap)[-1] = ';';
|
||||
if ( vararg != 0 )
|
||||
{ *vararg = 0;
|
||||
fputs(breaks[0], out); /* any prior args */
|
||||
fputs("va_dcl", out); /* the final arg */
|
||||
fputs(bp[0], out);
|
||||
}
|
||||
else
|
||||
fputs(breaks[0], out);
|
||||
}
|
||||
free((char *)breaks);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
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
|
||||
--------------------
|
||||
|
||||
Library initialization sequence modified to detect version mismatches
|
||||
and struct field packing mismatches between library and calling application.
|
||||
This change requires applications to be recompiled, but does not require
|
||||
any application source code change.
|
||||
|
||||
All routine declarations changed to the style "GLOBAL(type) name ...",
|
||||
that is, GLOBAL, LOCAL, METHODDEF, EXTERN are now macros taking the
|
||||
routine's return type as an argument. This makes it possible to add
|
||||
Microsoft-style linkage keywords to all the routines by changing just
|
||||
these macros. Note that any application code that was using these macros
|
||||
will have to be changed.
|
||||
|
||||
DCT coefficient quantization tables are now stored in normal array order
|
||||
rather than zigzag order. Application code that calls jpeg_add_quant_table,
|
||||
or otherwise manipulates quantization tables directly, will need to be
|
||||
changed. If you need to make such code work with either older or newer
|
||||
versions of the library, a test like "#if JPEG_LIB_VERSION >= 61" is
|
||||
recommended.
|
||||
|
||||
djpeg's trace capability now dumps DQT tables in natural order, not zigzag
|
||||
order. This allows the trace output to be made into a "-qtables" file
|
||||
more easily.
|
||||
|
||||
New system-dependent memory manager module for use on Apple Macintosh.
|
||||
|
||||
Fix bug in cjpeg's -smooth option: last one or two scanlines would be
|
||||
duplicates of the prior line unless the image height mod 16 was 1 or 2.
|
||||
|
||||
Repair minor problems in VMS, BCC, MC6 makefiles.
|
||||
|
||||
New configure script based on latest GNU Autoconf.
|
||||
|
||||
Correct the list of include files needed by MetroWerks C for ccommand().
|
||||
|
||||
Numerous small documentation updates.
|
||||
|
||||
|
||||
Version 6 2-Aug-95
|
||||
-------------------
|
||||
|
||||
Progressive JPEG support: library can read and write full progressive JPEG
|
||||
files. A "buffered image" mode supports incremental decoding for on-the-fly
|
||||
display of progressive images. Simply recompiling an existing IJG-v5-based
|
||||
decoder with v6 should allow it to read progressive files, though of course
|
||||
without any special progressive display.
|
||||
|
||||
New "jpegtran" application performs lossless transcoding between different
|
||||
JPEG formats; primarily, it can be used to convert baseline to progressive
|
||||
JPEG and vice versa. In support of jpegtran, the library now allows lossless
|
||||
reading and writing of JPEG files as DCT coefficient arrays. This ability
|
||||
may be of use in other applications.
|
||||
|
||||
Notes for programmers:
|
||||
* We changed jpeg_start_decompress() to be able to suspend; this makes all
|
||||
decoding modes available to suspending-input applications. However,
|
||||
existing applications that use suspending input will need to be changed
|
||||
to check the return value from jpeg_start_decompress(). You don't need to
|
||||
do anything if you don't use a suspending data source.
|
||||
* We changed the interface to the virtual array routines: access_virt_array
|
||||
routines now take a count of the number of rows to access this time. The
|
||||
last parameter to request_virt_array routines is now interpreted as the
|
||||
maximum number of rows that may be accessed at once, but not necessarily
|
||||
the height of every access.
|
||||
|
||||
|
||||
Version 5b 15-Mar-95
|
||||
---------------------
|
||||
|
||||
Correct bugs with grayscale images having v_samp_factor > 1.
|
||||
|
||||
jpeg_write_raw_data() now supports output suspension.
|
||||
|
||||
Correct bugs in "configure" script for case of compiling in
|
||||
a directory other than the one containing the source files.
|
||||
|
||||
Repair bug in jquant1.c: sometimes didn't use as many colors as it could.
|
||||
|
||||
Borland C makefile and jconfig file work under either MS-DOS or OS/2.
|
||||
|
||||
Miscellaneous improvements to documentation.
|
||||
|
||||
|
||||
Version 5a 7-Dec-94
|
||||
--------------------
|
||||
|
||||
Changed color conversion roundoff behavior so that grayscale values are
|
||||
represented exactly. (This causes test image files to change.)
|
||||
|
||||
Make ordered dither use 16x16 instead of 4x4 pattern for a small quality
|
||||
improvement.
|
||||
|
||||
New configure script based on latest GNU Autoconf.
|
||||
Fix configure script to handle CFLAGS correctly.
|
||||
Rename *.auto files to *.cfg, so that configure script still works if
|
||||
file names have been truncated for DOS.
|
||||
|
||||
Fix bug in rdbmp.c: didn't allow for extra data between header and image.
|
||||
|
||||
Modify rdppm.c/wrppm.c to handle 2-byte raw PPM/PGM formats for 12-bit data.
|
||||
|
||||
Fix several bugs in rdrle.c.
|
||||
|
||||
NEED_SHORT_EXTERNAL_NAMES option was broken.
|
||||
|
||||
Revise jerror.h/jerror.c for more flexibility in message table.
|
||||
|
||||
Repair oversight in jmemname.c NO_MKTEMP case: file could be there
|
||||
but unreadable.
|
||||
|
||||
|
||||
Version 5 24-Sep-94
|
||||
--------------------
|
||||
|
||||
Version 5 represents a nearly complete redesign and rewrite of the IJG
|
||||
software. Major user-visible changes include:
|
||||
* Automatic configuration simplifies installation for most Unix systems.
|
||||
* A range of speed vs. image quality tradeoffs are supported.
|
||||
This includes resizing of an image during decompression: scaling down
|
||||
by a factor of 1/2, 1/4, or 1/8 is handled very efficiently.
|
||||
* New programs rdjpgcom and wrjpgcom allow insertion and extraction
|
||||
of text comments in a JPEG file.
|
||||
|
||||
The application programmer's interface to the library has changed completely.
|
||||
Notable improvements include:
|
||||
* We have eliminated the use of callback routines for handling the
|
||||
uncompressed image data. The application now sees the library as a
|
||||
set of routines that it calls to read or write image data on a
|
||||
scanline-by-scanline basis.
|
||||
* The application image data is represented in a conventional interleaved-
|
||||
pixel format, rather than as a separate array for each color channel.
|
||||
This can save a copying step in many programs.
|
||||
* The handling of compressed data has been cleaned up: the application can
|
||||
supply routines to source or sink the compressed data. It is possible to
|
||||
suspend processing on source/sink buffer overrun, although this is not
|
||||
supported in all operating modes.
|
||||
* All static state has been eliminated from the library, so that multiple
|
||||
instances of compression or decompression can be active concurrently.
|
||||
* JPEG abbreviated datastream formats are supported, ie, quantization and
|
||||
Huffman tables can be stored separately from the image data.
|
||||
* And not only that, but the documentation of the library has improved
|
||||
considerably!
|
||||
|
||||
|
||||
The last widely used release before the version 5 rewrite was version 4A of
|
||||
18-Feb-93. Change logs before that point have been discarded, since they
|
||||
are not of much interest after the rewrite.
|
|
@ -1,4 +1,8 @@
|
|||
#if defined(_WIN32) || defined(__OS2__)
|
||||
/* This test added by JACS as a quick fix. What should we do
|
||||
* to make it work with configure?
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__DMC__)
|
||||
#include "jconfig.vc"
|
||||
#else
|
||||
|
||||
|
@ -6,9 +10,39 @@
|
|||
/* jconfig.cfg --- source file edited by configure script */
|
||||
/* see jconfig.doc for explanations */
|
||||
|
||||
/* If using MetroWerks on Mac define __WXMAC__ if it isn't already
|
||||
FIXME: Is this necessary any longer? */
|
||||
#ifdef __MWERKS__
|
||||
#if (__MWERKS__ < 0x0900) || macintosh || defined ( __MACH__ )
|
||||
# ifndef __WXMAC__
|
||||
# define __WXMAC__
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* use wxWidgets' configure */
|
||||
#include "wx/setup.h"
|
||||
|
||||
/* If using Metrowerks and not using configure-generated setup */
|
||||
#if defined(__MWERKS__) && !defined(__WX_SETUP_H__)
|
||||
#if (__MWERKS__ < 0x0900) || macintosh || defined ( __MACH__ )
|
||||
|
||||
# define USE_MAC_MEMMGR
|
||||
|
||||
# ifdef __MACH__
|
||||
# include <ansi_prefix.mach.h>
|
||||
# include <msl_c_version.h>
|
||||
# include <stdint.h>
|
||||
# undef WCHAR_MAX
|
||||
# include <machine/ansi.h>
|
||||
# endif
|
||||
|
||||
/* automatically includes MacHeaders */
|
||||
#elif (__MWERKS__ >= 0x0900) && __INTEL__
|
||||
#define __WXMSW__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
|
@ -25,14 +59,8 @@
|
|||
#undef CHAR_IS_UNSIGNED
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STDDEF_H
|
||||
#define HAVE_STDDEF_H
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STDLIB_H
|
||||
#define HAVE_STDLIB_H
|
||||
#endif
|
||||
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* jmemansi.c
|
||||
*
|
||||
* Copyright (C) 1992-1996, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file provides a simple generic implementation of the system-
|
||||
* dependent portion of the JPEG memory manager. This implementation
|
||||
* assumes that you have the ANSI-standard library routine tmpfile().
|
||||
* Also, the problem of determining the amount of memory available
|
||||
* is shoved onto the user.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
|
||||
#define SEEK_SET 0 /* if not, assume 0 is correct */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: although we include FAR keywords in the routine declarations,
|
||||
* this file won't actually work in 80x86 small/medium model; at least,
|
||||
* you probably won't be able to process useful-size images in only 64KB.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* It's impossible to do this in a portable way; our current solution is
|
||||
* to make the user tell us (with a default value set at compile time).
|
||||
* If you can actually get the available space, it's a good idea to subtract
|
||||
* a slop factor of 5% or so.
|
||||
*/
|
||||
|
||||
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
|
||||
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
|
||||
#endif
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFREAD(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFWRITE(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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, "");
|
||||
info->read_backing_store = read_backing_store;
|
||||
info->write_backing_store = write_backing_store;
|
||||
info->close_backing_store = close_backing_store;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr cinfo)
|
||||
{
|
||||
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* no work */
|
||||
}
|
|
@ -0,0 +1,638 @@
|
|||
/*
|
||||
* jmemdos.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file provides an MS-DOS-compatible implementation of the system-
|
||||
* dependent portion of the JPEG memory manager. Temporary data can be
|
||||
* stored in extended or expanded memory as well as in regular DOS files.
|
||||
*
|
||||
* If you use this file, you must be sure that NEED_FAR_POINTERS is defined
|
||||
* if you compile in a small-data memory model; it should NOT be defined if
|
||||
* you use a large-data memory model. This file is not recommended if you
|
||||
* are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
|
||||
* Also, this code will NOT work if struct fields are aligned on greater than
|
||||
* 2-byte boundaries.
|
||||
*
|
||||
* Based on code contributed by Ge' Weijers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you have both extended and expanded memory, you may want to change the
|
||||
* order in which they are tried in jopen_backing_store. On a 286 machine
|
||||
* expanded memory is usually faster, since extended memory access involves
|
||||
* an expensive protected-mode-and-back switch. On 386 and better, extended
|
||||
* memory is usually faster. As distributed, the code tries extended memory
|
||||
* first (what? not everyone has a 386? :-).
|
||||
*
|
||||
* You can disable use of extended/expanded memory entirely by altering these
|
||||
* definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
|
||||
*/
|
||||
|
||||
#ifndef XMS_SUPPORTED
|
||||
#define XMS_SUPPORTED 1
|
||||
#endif
|
||||
#ifndef EMS_SUPPORTED
|
||||
#define EMS_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare these */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
extern char * getenv JPP((const char * name));
|
||||
#endif
|
||||
|
||||
#ifdef NEED_FAR_POINTERS
|
||||
|
||||
#ifdef __TURBOC__
|
||||
/* These definitions work for Borland C (Turbo C) */
|
||||
#include <alloc.h> /* need farmalloc(), farfree() */
|
||||
#define far_malloc(x) farmalloc(x)
|
||||
#define far_free(x) farfree(x)
|
||||
#else
|
||||
/* These definitions work for Microsoft C and compatible compilers */
|
||||
#include <malloc.h> /* need _fmalloc(), _ffree() */
|
||||
#define far_malloc(x) _fmalloc(x)
|
||||
#define far_free(x) _ffree(x)
|
||||
#endif
|
||||
|
||||
#else /* not NEED_FAR_POINTERS */
|
||||
|
||||
#define far_malloc(x) malloc(x)
|
||||
#define far_free(x) free(x)
|
||||
|
||||
#endif /* NEED_FAR_POINTERS */
|
||||
|
||||
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
|
||||
#define READ_BINARY "r"
|
||||
#else
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
* Declarations for assembly-language support routines (see jmemdosa.asm).
|
||||
*
|
||||
* The functions are declared "far" as are all their pointer arguments;
|
||||
* this ensures the assembly source code will work regardless of the
|
||||
* compiler memory model. We assume "short" is 16 bits, "long" is 32.
|
||||
*/
|
||||
|
||||
typedef void far * XMSDRIVER; /* actually a pointer to code */
|
||||
typedef struct { /* registers for calling XMS driver */
|
||||
unsigned short ax, dx, bx;
|
||||
void far * ds_si;
|
||||
} XMScontext;
|
||||
typedef struct { /* registers for calling EMS driver */
|
||||
unsigned short ax, dx, bx;
|
||||
void far * ds_si;
|
||||
} EMScontext;
|
||||
|
||||
extern short far jdos_open JPP((short far * handle, char far * filename));
|
||||
extern short far jdos_close JPP((short handle));
|
||||
extern short far jdos_seek JPP((short handle, long offset));
|
||||
extern short far jdos_read JPP((short handle, void far * buffer,
|
||||
unsigned short count));
|
||||
extern short far jdos_write JPP((short handle, void far * buffer,
|
||||
unsigned short count));
|
||||
extern void far jxms_getdriver JPP((XMSDRIVER far *));
|
||||
extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
|
||||
extern short far jems_available JPP((void));
|
||||
extern void far jems_calldriver JPP((EMScontext far *));
|
||||
|
||||
|
||||
/*
|
||||
* Selection of a file name for a temporary file.
|
||||
* This is highly system-dependent, and you may want to customize it.
|
||||
*/
|
||||
|
||||
static int next_file_num; /* to distinguish among several temp files */
|
||||
|
||||
LOCAL(void)
|
||||
select_file_name (char * fname)
|
||||
{
|
||||
const char * env;
|
||||
char * ptr;
|
||||
FILE * tfile;
|
||||
|
||||
/* Keep generating file names till we find one that's not in use */
|
||||
for (;;) {
|
||||
/* Get temp directory name from environment TMP or TEMP variable;
|
||||
* if none, use "."
|
||||
*/
|
||||
if ((env = (const char *) getenv("TMP")) == NULL)
|
||||
if ((env = (const char *) getenv("TEMP")) == NULL)
|
||||
env = ".";
|
||||
if (*env == '\0') /* null string means "." */
|
||||
env = ".";
|
||||
ptr = fname; /* copy name to fname */
|
||||
while (*env != '\0')
|
||||
*ptr++ = *env++;
|
||||
if (ptr[-1] != '\\' && ptr[-1] != '/')
|
||||
*ptr++ = '\\'; /* append backslash if not in env variable */
|
||||
/* Append a suitable file name */
|
||||
next_file_num++; /* advance counter */
|
||||
sprintf(ptr, "JPG%03d.TMP", next_file_num);
|
||||
/* Probe to see if file name is already in use */
|
||||
if ((tfile = fopen(fname, READ_BINARY)) == NULL)
|
||||
break;
|
||||
fclose(tfile); /* oops, it's there; close tfile & try again */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Near-memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are allocated in far memory, if possible
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) far_malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
far_free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* It's impossible to do this in a portable way; our current solution is
|
||||
* to make the user tell us (with a default value set at compile time).
|
||||
* If you can actually get the available space, it's a good idea to subtract
|
||||
* a slop factor of 5% or so.
|
||||
*/
|
||||
|
||||
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
|
||||
#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */
|
||||
#endif
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For MS-DOS we support three types of backing storage:
|
||||
* 1. Conventional DOS files. We access these by direct DOS calls rather
|
||||
* than via the stdio package. This provides a bit better performance,
|
||||
* but the real reason is that the buffers to be read or written are FAR.
|
||||
* The stdio library for small-data memory models can't cope with that.
|
||||
* 2. Extended memory, accessed per the XMS V2.0 specification.
|
||||
* 3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
|
||||
* You'll need copies of those specs to make sense of the related code.
|
||||
* The specs are available by Internet FTP from the SIMTEL archives
|
||||
* (oak.oakland.edu and its various mirror sites). See files
|
||||
* pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Access methods for a DOS file.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_file_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (jdos_seek(info->handle.file_handle, file_offset))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
|
||||
if (byte_count > 65535L) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
|
||||
if (jdos_read(info->handle.file_handle, buffer_address,
|
||||
(unsigned short) byte_count))
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_file_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (jdos_seek(info->handle.file_handle, file_offset))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
|
||||
if (byte_count > 65535L) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
|
||||
if (jdos_write(info->handle.file_handle, buffer_address,
|
||||
(unsigned short) byte_count))
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_file_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
jdos_close(info->handle.file_handle); /* close the file */
|
||||
remove(info->temp_name); /* delete the file */
|
||||
/* If your system doesn't have remove(), try unlink() instead.
|
||||
* remove() is the ANSI-standard name for this function, but
|
||||
* unlink() was more common in pre-ANSI systems.
|
||||
*/
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
|
||||
}
|
||||
|
||||
|
||||
LOCAL(wxjpeg_boolean)
|
||||
open_file_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
short handle;
|
||||
|
||||
select_file_name(info->temp_name);
|
||||
if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
|
||||
/* might as well exit since jpeg_open_backing_store will fail anyway */
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
|
||||
return FALSE;
|
||||
}
|
||||
info->handle.file_handle = handle;
|
||||
info->read_backing_store = read_file_store;
|
||||
info->write_backing_store = write_file_store;
|
||||
info->close_backing_store = close_file_store;
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
|
||||
return TRUE; /* succeeded */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Access methods for extended memory.
|
||||
*/
|
||||
|
||||
#if XMS_SUPPORTED
|
||||
|
||||
static XMSDRIVER xms_driver; /* saved address of XMS driver */
|
||||
|
||||
typedef union { /* either long offset or real-mode pointer */
|
||||
long offset;
|
||||
void far * ptr;
|
||||
} XMSPTR;
|
||||
|
||||
typedef struct { /* XMS move specification structure */
|
||||
long length;
|
||||
XMSH src_handle;
|
||||
XMSPTR src;
|
||||
XMSH dst_handle;
|
||||
XMSPTR dst;
|
||||
} XMSspec;
|
||||
|
||||
#define ODD(X) (((X) & 1L) != 0)
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
XMScontext ctx;
|
||||
XMSspec spec;
|
||||
char endbuffer[2];
|
||||
|
||||
/* The XMS driver can't cope with an odd length, so handle the last byte
|
||||
* specially if byte_count is odd. We don't expect this to be common.
|
||||
*/
|
||||
|
||||
spec.length = byte_count & (~ 1L);
|
||||
spec.src_handle = info->handle.xms_handle;
|
||||
spec.src.offset = file_offset;
|
||||
spec.dst_handle = 0;
|
||||
spec.dst.ptr = buffer_address;
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x0b00; /* EMB move */
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax != 1)
|
||||
ERREXIT(cinfo, JERR_XMS_READ);
|
||||
|
||||
if (ODD(byte_count)) {
|
||||
read_xms_store(cinfo, info, (void FAR *) endbuffer,
|
||||
file_offset + byte_count - 1L, 2L);
|
||||
((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
XMScontext ctx;
|
||||
XMSspec spec;
|
||||
char endbuffer[2];
|
||||
|
||||
/* The XMS driver can't cope with an odd length, so handle the last byte
|
||||
* specially if byte_count is odd. We don't expect this to be common.
|
||||
*/
|
||||
|
||||
spec.length = byte_count & (~ 1L);
|
||||
spec.src_handle = 0;
|
||||
spec.src.ptr = buffer_address;
|
||||
spec.dst_handle = info->handle.xms_handle;
|
||||
spec.dst.offset = file_offset;
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x0b00; /* EMB move */
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax != 1)
|
||||
ERREXIT(cinfo, JERR_XMS_WRITE);
|
||||
|
||||
if (ODD(byte_count)) {
|
||||
read_xms_store(cinfo, info, (void FAR *) endbuffer,
|
||||
file_offset + byte_count - 1L, 2L);
|
||||
endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
|
||||
write_xms_store(cinfo, info, (void FAR *) endbuffer,
|
||||
file_offset + byte_count - 1L, 2L);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
XMScontext ctx;
|
||||
|
||||
ctx.dx = info->handle.xms_handle;
|
||||
ctx.ax = 0x0a00;
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
|
||||
/* we ignore any error return from the driver */
|
||||
}
|
||||
|
||||
|
||||
LOCAL(wxjpeg_boolean)
|
||||
open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
XMScontext ctx;
|
||||
|
||||
/* Get address of XMS driver */
|
||||
jxms_getdriver((XMSDRIVER far *) & xms_driver);
|
||||
if (xms_driver == NULL)
|
||||
return FALSE; /* no driver to be had */
|
||||
|
||||
/* Get version number, must be >= 2.00 */
|
||||
ctx.ax = 0x0000;
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax < (unsigned short) 0x0200)
|
||||
return FALSE;
|
||||
|
||||
/* Try to get space (expressed in kilobytes) */
|
||||
ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
|
||||
ctx.ax = 0x0900;
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax != 1)
|
||||
return FALSE;
|
||||
|
||||
/* Succeeded, save the handle and away we go */
|
||||
info->handle.xms_handle = ctx.dx;
|
||||
info->read_backing_store = read_xms_store;
|
||||
info->write_backing_store = write_xms_store;
|
||||
info->close_backing_store = close_xms_store;
|
||||
TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
|
||||
return TRUE; /* succeeded */
|
||||
}
|
||||
|
||||
#endif /* XMS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Access methods for expanded memory.
|
||||
*/
|
||||
|
||||
#if EMS_SUPPORTED
|
||||
|
||||
/* The EMS move specification structure requires word and long fields aligned
|
||||
* at odd byte boundaries. Some compilers will align struct fields at even
|
||||
* byte boundaries. While it's usually possible to force byte alignment,
|
||||
* that causes an overall performance penalty and may pose problems in merging
|
||||
* JPEG into a larger application. Instead we accept some rather dirty code
|
||||
* here. Note this code would fail if the hardware did not allow odd-byte
|
||||
* word & long accesses, but all 80x86 CPUs do.
|
||||
*/
|
||||
|
||||
typedef void far * EMSPTR;
|
||||
|
||||
typedef union { /* EMS move specification structure */
|
||||
long length; /* It's easy to access first 4 bytes */
|
||||
char bytes[18]; /* Misaligned fields in here! */
|
||||
} EMSspec;
|
||||
|
||||
/* Macros for accessing misaligned fields */
|
||||
#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset])))
|
||||
#define SRC_TYPE(spec) FIELD_AT(spec,4,char)
|
||||
#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH)
|
||||
#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short)
|
||||
#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short)
|
||||
#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR)
|
||||
#define DST_TYPE(spec) FIELD_AT(spec,11,char)
|
||||
#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH)
|
||||
#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short)
|
||||
#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short)
|
||||
#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR)
|
||||
|
||||
#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */
|
||||
|
||||
#define HIBYTE(W) (((W) >> 8) & 0xFF)
|
||||
#define LOBYTE(W) ((W) & 0xFF)
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
EMScontext ctx;
|
||||
EMSspec spec;
|
||||
|
||||
spec.length = byte_count;
|
||||
SRC_TYPE(spec) = 1;
|
||||
SRC_HANDLE(spec) = info->handle.ems_handle;
|
||||
SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
|
||||
SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
|
||||
DST_TYPE(spec) = 0;
|
||||
DST_HANDLE(spec) = 0;
|
||||
DST_PTR(spec) = buffer_address;
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x5700; /* move memory region */
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
ERREXIT(cinfo, JERR_EMS_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
EMScontext ctx;
|
||||
EMSspec spec;
|
||||
|
||||
spec.length = byte_count;
|
||||
SRC_TYPE(spec) = 0;
|
||||
SRC_HANDLE(spec) = 0;
|
||||
SRC_PTR(spec) = buffer_address;
|
||||
DST_TYPE(spec) = 1;
|
||||
DST_HANDLE(spec) = info->handle.ems_handle;
|
||||
DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
|
||||
DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x5700; /* move memory region */
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
ERREXIT(cinfo, JERR_EMS_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
EMScontext ctx;
|
||||
|
||||
ctx.ax = 0x4500;
|
||||
ctx.dx = info->handle.ems_handle;
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
|
||||
/* we ignore any error return from the driver */
|
||||
}
|
||||
|
||||
|
||||
LOCAL(wxjpeg_boolean)
|
||||
open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
EMScontext ctx;
|
||||
|
||||
/* Is EMS driver there? */
|
||||
if (! jems_available())
|
||||
return FALSE;
|
||||
|
||||
/* Get status, make sure EMS is OK */
|
||||
ctx.ax = 0x4000;
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
return FALSE;
|
||||
|
||||
/* Get version, must be >= 4.0 */
|
||||
ctx.ax = 0x4600;
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
|
||||
return FALSE;
|
||||
|
||||
/* Try to allocate requested space */
|
||||
ctx.ax = 0x4300;
|
||||
ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
return FALSE;
|
||||
|
||||
/* Succeeded, save the handle and away we go */
|
||||
info->handle.ems_handle = ctx.dx;
|
||||
info->read_backing_store = read_ems_store;
|
||||
info->write_backing_store = write_ems_store;
|
||||
info->close_backing_store = close_ems_store;
|
||||
TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
|
||||
return TRUE; /* succeeded */
|
||||
}
|
||||
|
||||
#endif /* EMS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
/* Try extended memory, then expanded memory, then regular file. */
|
||||
#if XMS_SUPPORTED
|
||||
if (open_xms_store(cinfo, info, total_bytes_needed))
|
||||
return;
|
||||
#endif
|
||||
#if EMS_SUPPORTED
|
||||
if (open_ems_store(cinfo, info, total_bytes_needed))
|
||||
return;
|
||||
#endif
|
||||
if (open_file_store(cinfo, info, total_bytes_needed))
|
||||
return;
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr cinfo)
|
||||
{
|
||||
next_file_num = 0; /* initialize temp file name generator */
|
||||
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* Microsoft C, at least in v6.00A, will not successfully reclaim freed
|
||||
* blocks of size > 32Kbytes unless we give it a kick in the rear, like so:
|
||||
*/
|
||||
#ifdef NEED_FHEAPMIN
|
||||
_fheapmin();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* jmemmac.c
|
||||
*
|
||||
* 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
|
||||
* own devices, this code can chew up all available space in the
|
||||
* application's zone, with the exception of the rather small "slop"
|
||||
* 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 and System 7.0+'s
|
||||
* temporary folder functionality.
|
||||
*
|
||||
* 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 */
|
||||
|
||||
#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
|
||||
* routines NewPtr() and DisposePtr(), which allocate fixed-address
|
||||
* storage. Unfortunately, the IJG library isn't smart enough to cope
|
||||
* with relocatable storage.
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) NewPtr(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
DisposePtr((Ptr) object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: we include FAR keywords in the routine declarations simply for
|
||||
* consistency with the rest of the IJG code; FAR should expand to empty
|
||||
* on rational architectures like the Mac.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) NewPtr(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
DisposePtr((Ptr) object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
long limit = cinfo->mem->max_memory_to_use - already_allocated;
|
||||
long slop, mem;
|
||||
|
||||
/* Don't ask for more than what application has told us we may use */
|
||||
if (max_bytes_needed > limit && limit > 0)
|
||||
max_bytes_needed = limit;
|
||||
/* Find whether there's a big enough free block in the heap.
|
||||
* CompactMem tries to create a contiguous block of the requested size,
|
||||
* and then returns the size of the largest free block (which could be
|
||||
* much more or much less than we asked for).
|
||||
* We add some slop to ensure we don't use up all available memory.
|
||||
*/
|
||||
slop = max_bytes_needed / 16 + 32768L;
|
||||
mem = CompactMem(max_bytes_needed + slop) - slop;
|
||||
if (mem < 0)
|
||||
mem = 0; /* sigh, couldn't even get the slop */
|
||||
/* Don't take more than the application says we can have */
|
||||
if (mem > limit && limit > 0)
|
||||
mem = limit;
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
long bytes = byte_count;
|
||||
long retVal;
|
||||
|
||||
if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
|
||||
retVal = FSRead ( info->temp_file, &bytes,
|
||||
(unsigned char *) buffer_address );
|
||||
if ( retVal != noErr || bytes != byte_count )
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
long bytes = byte_count;
|
||||
long retVal;
|
||||
|
||||
if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
|
||||
retVal = FSWrite ( info->temp_file, &bytes,
|
||||
(unsigned char *) buffer_address );
|
||||
if ( retVal != noErr || bytes != byte_count )
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
FSClose ( info->temp_file );
|
||||
FSpDelete ( &(info->tempSpec) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
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.
|
||||
* Note that FreeMem returns the total number of free bytes;
|
||||
* it may not be possible to allocate a single block of this size.
|
||||
*/
|
||||
return FreeMem();
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* no work */
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* jmemname.c
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file provides a generic implementation of the system-dependent
|
||||
* portion of the JPEG memory manager. This implementation assumes that
|
||||
* you must explicitly construct a name for each temp file.
|
||||
* Also, the problem of determining the amount of memory available
|
||||
* is shoved onto the user.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
|
||||
#define SEEK_SET 0 /* if not, assume 0 is correct */
|
||||
#endif
|
||||
|
||||
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
|
||||
#define READ_BINARY "r"
|
||||
#define RW_BINARY "w+"
|
||||
#else
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
* Selection of a file name for a temporary file.
|
||||
* This is system-dependent!
|
||||
*
|
||||
* The code as given is suitable for most Unix systems, and it is easily
|
||||
* modified for most non-Unix systems. Some notes:
|
||||
* 1. The temp file is created in the directory named by TEMP_DIRECTORY.
|
||||
* The default value is /usr/tmp, which is the conventional place for
|
||||
* creating large temp files on Unix. On other systems you'll probably
|
||||
* want to change the file location. You can do this by editing the
|
||||
* #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h.
|
||||
*
|
||||
* 2. If you need to change the file name as well as its location,
|
||||
* you can override the TEMP_FILE_NAME macro. (Note that this is
|
||||
* actually a printf format string; it must contain %s and %d.)
|
||||
* Few people should need to do this.
|
||||
*
|
||||
* 3. mktemp() is used to ensure that multiple processes running
|
||||
* simultaneously won't select the same file names. If your system
|
||||
* doesn't have mktemp(), define NO_MKTEMP to do it the hard way.
|
||||
* (If you don't have <errno.h>, also define NO_ERRNO_H.)
|
||||
*
|
||||
* 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c
|
||||
* will cause the temp files to be removed if you stop the program early.
|
||||
*/
|
||||
|
||||
#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */
|
||||
#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */
|
||||
#endif
|
||||
|
||||
static int next_file_num; /* to distinguish among several temp files */
|
||||
|
||||
#ifdef NO_MKTEMP
|
||||
|
||||
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
|
||||
#define TEMP_FILE_NAME "%sJPG%03d.TMP"
|
||||
#endif
|
||||
|
||||
#ifndef NO_ERRNO_H
|
||||
#include <errno.h> /* to define ENOENT */
|
||||
#endif
|
||||
|
||||
/* ANSI C specifies that errno is a macro, but on older systems it's more
|
||||
* likely to be a plain int variable. And not all versions of errno.h
|
||||
* bother to declare it, so we have to in order to be most portable. Thus:
|
||||
*/
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
select_file_name (char * fname)
|
||||
{
|
||||
FILE * tfile;
|
||||
|
||||
/* Keep generating file names till we find one that's not in use */
|
||||
for (;;) {
|
||||
next_file_num++; /* advance counter */
|
||||
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
|
||||
if ((tfile = fopen(fname, READ_BINARY)) == NULL) {
|
||||
/* fopen could have failed for a reason other than the file not
|
||||
* being there; for example, file there but unreadable.
|
||||
* If <errno.h> isn't available, then we cannot test the cause.
|
||||
*/
|
||||
#ifdef ENOENT
|
||||
if (errno != ENOENT)
|
||||
continue;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
fclose(tfile); /* oops, it's there; close tfile & try again */
|
||||
}
|
||||
}
|
||||
|
||||
#else /* ! NO_MKTEMP */
|
||||
|
||||
/* Note that mktemp() requires the initial filename to end in six X's */
|
||||
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
|
||||
#define TEMP_FILE_NAME "%sJPG%dXXXXXX"
|
||||
#endif
|
||||
|
||||
LOCAL(void)
|
||||
select_file_name (char * fname)
|
||||
{
|
||||
next_file_num++; /* advance counter */
|
||||
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
|
||||
mktemp(fname); /* make sure file name is unique */
|
||||
/* mktemp replaces the trailing XXXXXX with a unique string of characters */
|
||||
}
|
||||
|
||||
#endif /* NO_MKTEMP */
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: although we include FAR keywords in the routine declarations,
|
||||
* this file won't actually work in 80x86 small/medium model; at least,
|
||||
* you probably won't be able to process useful-size images in only 64KB.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* It's impossible to do this in a portable way; our current solution is
|
||||
* to make the user tell us (with a default value set at compile time).
|
||||
* If you can actually get the available space, it's a good idea to subtract
|
||||
* a slop factor of 5% or so.
|
||||
*/
|
||||
|
||||
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
|
||||
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
|
||||
#endif
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFREAD(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFWRITE(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
fclose(info->temp_file); /* close the file */
|
||||
unlink(info->temp_name); /* delete the file */
|
||||
/* If your system doesn't have unlink(), use remove() instead.
|
||||
* remove() is the ANSI-standard name for this function, but if
|
||||
* your system was ANSI you'd be using jmemansi.c, right?
|
||||
*/
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
select_file_name(info->temp_name);
|
||||
if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL)
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr cinfo)
|
||||
{
|
||||
next_file_num = 0; /* initialize temp file name generator */
|
||||
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* no work */
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// Special configuration file for building jpeg under CodeWarrior
|
||||
|
||||
|
||||
//#define HAVE_BOOLEAN
|
||||
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
|
||||
#include "jconfig.h" /* widely used configuration options */
|
||||
#include "../src/jpeg/jconfig.h" /* widely used configuration options */
|
||||
#endif
|
||||
#include "jmorecfg.h" /* seldom changed options */
|
||||
|
||||
|
|
|
@ -0,0 +1,504 @@
|
|||
/*
|
||||
* jpegtran.c
|
||||
*
|
||||
* 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. 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 */
|
||||
#ifdef __MWERKS__
|
||||
#include <SIOUX.h> /* Metrowerks needs this */
|
||||
#include <console.h> /* ... and this */
|
||||
#endif
|
||||
#ifdef THINK_C
|
||||
#include <console.h> /* Think declares it here */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Argument-parsing code.
|
||||
* The switch parser is designed to be useful with DOS-style command line
|
||||
* syntax, ie, intermixed switches and file names, where only the switches
|
||||
* to the left of a given file name affect processing of that file.
|
||||
* The main program in this file doesn't actually use this capability...
|
||||
*/
|
||||
|
||||
|
||||
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)
|
||||
usage (void)
|
||||
/* complain about bad command line */
|
||||
{
|
||||
fprintf(stderr, "usage: %s [switches] ", progname);
|
||||
#ifdef TWO_FILE_COMMANDLINE
|
||||
fprintf(stderr, "inputfile outputfile\n");
|
||||
#else
|
||||
fprintf(stderr, "[inputfile]\n");
|
||||
#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");
|
||||
fprintf(stderr, " -outfile name Specify name for output file\n");
|
||||
fprintf(stderr, " -verbose or -debug Emit debug output\n");
|
||||
fprintf(stderr, "Switches for wizards:\n");
|
||||
#ifdef C_ARITH_CODING_SUPPORTED
|
||||
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
|
||||
#endif
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n");
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
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, wxjpeg_boolean for_real)
|
||||
/* Parse optional switches.
|
||||
* Returns argv[] index of first file-name argument (== argc if none).
|
||||
* Any file names with indexes <= last_file_arg_seen are ignored;
|
||||
* they have presumably been processed in a previous iteration.
|
||||
* (Pass 0 for last_file_arg_seen on the first or only iteration.)
|
||||
* for_real is FALSE on the first (dummy) pass; we may skip any expensive
|
||||
* processing.
|
||||
*/
|
||||
{
|
||||
int argn;
|
||||
char * arg;
|
||||
wxjpeg_boolean simple_progressive;
|
||||
char * scansarg = NULL; /* saves -scans parm if any */
|
||||
|
||||
/* 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 */
|
||||
|
||||
for (argn = 1; argn < argc; argn++) {
|
||||
arg = argv[argn];
|
||||
if (*arg != '-') {
|
||||
/* Not a switch, must be a file name argument */
|
||||
if (argn <= last_file_arg_seen) {
|
||||
outfilename = NULL; /* -outfile applies to just one input file */
|
||||
continue; /* ignore this name if previously processed */
|
||||
}
|
||||
break; /* else done parsing switches */
|
||||
}
|
||||
arg++; /* advance past switch marker character */
|
||||
|
||||
if (keymatch(arg, "arithmetic", 1)) {
|
||||
/* Use arithmetic coding. */
|
||||
#ifdef C_ARITH_CODING_SUPPORTED
|
||||
cinfo->arith_code = TRUE;
|
||||
#else
|
||||
fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
|
||||
progname);
|
||||
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 */
|
||||
static wxjpeg_boolean printed_version = FALSE;
|
||||
|
||||
if (! printed_version) {
|
||||
fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n",
|
||||
JVERSION, JCOPYRIGHT);
|
||||
printed_version = TRUE;
|
||||
}
|
||||
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;
|
||||
char ch = 'x';
|
||||
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
usage();
|
||||
if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
|
||||
usage();
|
||||
if (ch == 'm' || ch == 'M')
|
||||
lval *= 1000L;
|
||||
cinfo->mem->max_memory_to_use = lval * 1000L;
|
||||
|
||||
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
|
||||
/* Enable entropy parm optimization. */
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
cinfo->optimize_coding = TRUE;
|
||||
#else
|
||||
fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
|
||||
progname);
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
|
||||
} else if (keymatch(arg, "outfile", 4)) {
|
||||
/* Set output file name. */
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
usage();
|
||||
outfilename = argv[argn]; /* save it away for later use */
|
||||
|
||||
} else if (keymatch(arg, "progressive", 1)) {
|
||||
/* Select simple progressive mode. */
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
simple_progressive = TRUE;
|
||||
/* We must postpone execution until num_components is known. */
|
||||
#else
|
||||
fprintf(stderr, "%s: sorry, progressive output was not compiled\n",
|
||||
progname);
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
|
||||
} else if (keymatch(arg, "restart", 1)) {
|
||||
/* Restart interval in MCU rows (or in MCUs with 'b'). */
|
||||
long lval;
|
||||
char ch = 'x';
|
||||
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
usage();
|
||||
if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
|
||||
usage();
|
||||
if (lval < 0 || lval > 65535L)
|
||||
usage();
|
||||
if (ch == 'b' || ch == 'B') {
|
||||
cinfo->restart_interval = (unsigned int) lval;
|
||||
cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */
|
||||
} else {
|
||||
cinfo->restart_in_rows = (int) lval;
|
||||
/* restart_interval will be computed during startup */
|
||||
}
|
||||
|
||||
} 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 */
|
||||
usage();
|
||||
scansarg = argv[argn];
|
||||
/* We must postpone reading the file in case -progressive appears. */
|
||||
#else
|
||||
fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n",
|
||||
progname);
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
||||
/* Post-switch-scanning cleanup */
|
||||
|
||||
if (for_real) {
|
||||
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
if (simple_progressive) /* process -progressive; -scans can override */
|
||||
jpeg_simple_progression(cinfo);
|
||||
#endif
|
||||
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
if (scansarg != NULL) /* process -scans if it was present */
|
||||
if (! read_scan_script(cinfo, scansarg))
|
||||
usage();
|
||||
#endif
|
||||
}
|
||||
|
||||
return argn; /* return index of next arg (file name) */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The main program.
|
||||
*/
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
struct jpeg_decompress_struct srcinfo;
|
||||
struct jpeg_compress_struct dstinfo;
|
||||
struct jpeg_error_mgr jsrcerr, jdsterr;
|
||||
#ifdef PROGRESS_REPORT
|
||||
struct cdjpeg_progress_mgr progress;
|
||||
#endif
|
||||
jvirt_barray_ptr * src_coef_arrays;
|
||||
jvirt_barray_ptr * dst_coef_arrays;
|
||||
int file_index;
|
||||
FILE * input_file;
|
||||
FILE * output_file;
|
||||
|
||||
/* On Mac, fetch a command line. */
|
||||
#ifdef USE_CCOMMAND
|
||||
argc = ccommand(&argv);
|
||||
#endif
|
||||
|
||||
progname = argv[0];
|
||||
if (progname == NULL || progname[0] == 0)
|
||||
progname = "jpegtran"; /* in case C library doesn't provide it */
|
||||
|
||||
/* Initialize the JPEG decompression object with default error handling. */
|
||||
srcinfo.err = jpeg_std_error(&jsrcerr);
|
||||
jpeg_create_decompress(&srcinfo);
|
||||
/* Initialize the JPEG compression object with default error handling. */
|
||||
dstinfo.err = jpeg_std_error(&jdsterr);
|
||||
jpeg_create_compress(&dstinfo);
|
||||
|
||||
/* Now safe to enable signal catcher.
|
||||
* Note: we assume only the decompression object will have virtual arrays.
|
||||
*/
|
||||
#ifdef NEED_SIGNAL_CATCHER
|
||||
enable_signal_catcher((j_common_ptr) &srcinfo);
|
||||
#endif
|
||||
|
||||
/* Scan command line to find file names.
|
||||
* It is convenient to use just one switch-parsing routine, but the switch
|
||||
* 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);
|
||||
jsrcerr.trace_level = jdsterr.trace_level;
|
||||
srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;
|
||||
|
||||
#ifdef TWO_FILE_COMMANDLINE
|
||||
/* Must have either -outfile switch or explicit output file name */
|
||||
if (outfilename == NULL) {
|
||||
if (file_index != argc-2) {
|
||||
fprintf(stderr, "%s: must name one input and one output file\n",
|
||||
progname);
|
||||
usage();
|
||||
}
|
||||
outfilename = argv[file_index+1];
|
||||
} else {
|
||||
if (file_index != argc-1) {
|
||||
fprintf(stderr, "%s: must name one input and one output file\n",
|
||||
progname);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Unix style: expect zero or one file name */
|
||||
if (file_index < argc-1) {
|
||||
fprintf(stderr, "%s: only one input file\n", progname);
|
||||
usage();
|
||||
}
|
||||
#endif /* TWO_FILE_COMMANDLINE */
|
||||
|
||||
/* Open the input file. */
|
||||
if (file_index < argc) {
|
||||
if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
|
||||
fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
/* default input file is stdin */
|
||||
input_file = read_stdin();
|
||||
}
|
||||
|
||||
/* Open the output file. */
|
||||
if (outfilename != NULL) {
|
||||
if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
|
||||
fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
/* default output file is stdout */
|
||||
output_file = write_stdout();
|
||||
}
|
||||
|
||||
#ifdef PROGRESS_REPORT
|
||||
start_progress_monitor((j_common_ptr) &dstinfo, &progress);
|
||||
#endif
|
||||
|
||||
/* 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 */
|
||||
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 (note no image data is actually written here) */
|
||||
jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
|
||||
|
||||
/* 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);
|
||||
jpeg_destroy_compress(&dstinfo);
|
||||
(void) jpeg_finish_decompress(&srcinfo);
|
||||
jpeg_destroy_decompress(&srcinfo);
|
||||
|
||||
/* Close files, if we opened them */
|
||||
if (input_file != stdin)
|
||||
fclose(input_file);
|
||||
if (output_file != stdout)
|
||||
fclose(output_file);
|
||||
|
||||
#ifdef PROGRESS_REPORT
|
||||
end_progress_monitor((j_common_ptr) &dstinfo);
|
||||
#endif
|
||||
|
||||
/* All done. */
|
||||
exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS);
|
||||
return 0; /* suppress no-return-value warnings */
|
||||
}
|
Loading…
Reference in New Issue