Compare commits

...

10 Commits

Author SHA1 Message Date
Guido Vollbeding
5829cb2398 The Independent JPEG Group's JPEG software v8d 2015-07-27 13:50:34 -05:00
Guido Vollbeding
c39ec149e8 The Independent JPEG Group's JPEG software v8c 2015-07-27 13:49:31 -05:00
Guido Vollbeding
a4ecaacde6 The Independent JPEG Group's JPEG software v8b 2015-07-27 13:48:40 -05:00
Guido Vollbeding
f18f81b7e2 The Independent JPEG Group's JPEG software v8a 2015-07-27 13:46:36 -05:00
Guido Vollbeding
989630f70c The Independent JPEG Group's JPEG software v8 2015-07-27 13:45:31 -05:00
Guido Vollbeding
5996a25e2f The Independent JPEG Group's JPEG software v7 2015-07-27 13:44:25 -05:00
Guido Vollbeding
1e247ac854 The Independent JPEG Group's JPEG software v6b with arithmetic coding support 2015-07-27 14:40:46 -05:00
Thomas G. Lane
5ead57a34a The Independent JPEG Group's JPEG software v6b 2015-07-27 13:43:00 -05:00
Thomas G. Lane
489583f516 The Independent JPEG Group's JPEG software v6a 2015-07-29 15:32:35 -05:00
Thomas G. Lane
bc79e0680a The Independent JPEG Group's JPEG software v6 2015-07-29 15:31:30 -05:00
180 changed files with 75018 additions and 9175 deletions

134
Makefile.am Normal file
View File

@@ -0,0 +1,134 @@
## Process this file with automake to produce Makefile.in
#
# Automake Makefile for the JPEG library
#
# This file is written by Bob Friesenhahn, Guido Vollbeding
#
# Sources to build library
LIBSOURCES = jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c \
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
jcomapi.c jcparam.c jcprepct.c jcsample.c jctrans.c jdapimin.c \
jdapistd.c jdarith.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmerge.c jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c \
jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jquant1.c \
jquant2.c jutils.c jmemmgr.c @MEMORYMGR@.c
# System dependent sources
SYSDEPSOURCES = jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
# Headers which are installed to support the library
INSTINCLUDES = jerror.h jmorecfg.h jpeglib.h
# Headers which are not installed
OTHERINCLUDES = cderror.h cdjpeg.h jdct.h jinclude.h jmemsys.h jpegint.h \
jversion.h transupp.h
# Manual pages (Automake uses 'MANS' for itself)
DISTMANS= cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1
# Other documentation files
DOCS= README install.txt usage.txt wizard.txt example.c libjpeg.txt \
structure.txt coderules.txt filelist.txt change.log
# Makefiles for various systems
MKFILES= configure Makefile.in makefile.ansi makefile.unix makefile.bcc \
makefile.mc6 makefile.dj makefile.wat makefile.vc makejdsw.vc6 \
makeadsw.vc6 makejdep.vc6 makejdsp.vc6 makejmak.vc6 makecdep.vc6 \
makecdsp.vc6 makecmak.vc6 makeddep.vc6 makeddsp.vc6 makedmak.vc6 \
maketdep.vc6 maketdsp.vc6 maketmak.vc6 makerdep.vc6 makerdsp.vc6 \
makermak.vc6 makewdep.vc6 makewdsp.vc6 makewmak.vc6 makejsln.v10 \
makeasln.v10 makejvcx.v10 makejfil.v10 makecvcx.v10 makecfil.v10 \
makedvcx.v10 makedfil.v10 maketvcx.v10 maketfil.v10 makervcx.v10 \
makerfil.v10 makewvcx.v10 makewfil.v10 makeproj.mac makcjpeg.st \
makdjpeg.st makljpeg.st maktjpeg.st makefile.manx makefile.sas \
makefile.mms makefile.vms makvms.opt
# Configuration files
CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
jconfig.vms
# Support scripts for configure
CONFIGUREFILES= config.guess config.sub install-sh ltmain.sh depcomp missing
# Miscellaneous support files
OTHERFILES= jconfig.txt ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm \
libjpeg.map
# Test support files
TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
testimgp.jpg
# libtool libraries to build
lib_LTLIBRARIES = libjpeg.la
# Library sources for libjpeg.la
libjpeg_la_SOURCES = $(LIBSOURCES)
# LDFLAGS for libjpeg.la
libjpeg_la_LDFLAGS = -no-undefined \
-version-info $(JPEG_LIB_VERSION)
if HAVE_LD_VERSION_SCRIPT
libjpeg_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libjpeg.map
endif
# Executables to build
bin_PROGRAMS = cjpeg djpeg jpegtran rdjpgcom wrjpgcom
# Executable sources & libs
cjpeg_SOURCES = cjpeg.c rdppm.c rdgif.c rdtarga.c rdrle.c rdbmp.c \
rdswitch.c cdjpeg.c
cjpeg_LDADD = libjpeg.la
djpeg_SOURCES = djpeg.c wrppm.c wrgif.c wrtarga.c wrrle.c wrbmp.c \
rdcolmap.c cdjpeg.c
djpeg_LDADD = libjpeg.la
jpegtran_SOURCES = jpegtran.c rdswitch.c cdjpeg.c transupp.c
jpegtran_LDADD = libjpeg.la
rdjpgcom_SOURCES = rdjpgcom.c
wrjpgcom_SOURCES = wrjpgcom.c
# Manual pages to install
man_MANS = $(DISTMANS)
# Headers to install
include_HEADERS = $(INSTINCLUDES)
# Other distributed headers
noinst_HEADERS = $(OTHERINCLUDES)
# Other distributed files
EXTRA_DIST = $(DOCS) $(DISTMANS) $(MKFILES) $(CONFIGFILES) $(SYSDEPSOURCES) \
$(OTHERFILES) $(TESTFILES)
# Files to be cleaned
CLEANFILES = testout.ppm testout.bmp testout.jpg testoutp.ppm testoutp.jpg \
testoutt.jpg
# Install jconfig.h
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(includedir)
$(INSTALL_HEADER) jconfig.h $(DESTDIR)$(includedir)/jconfig.h
# Uninstall jconfig.h
uninstall-local:
rm -f $(DESTDIR)$(includedir)/jconfig.h
# Run tests
test: check-local
check-local:
rm -f testout*
./djpeg -dct int -ppm -outfile testout.ppm $(srcdir)/testorig.jpg
./djpeg -dct int -bmp -colors 256 -outfile testout.bmp $(srcdir)/testorig.jpg
./cjpeg -dct int -outfile testout.jpg $(srcdir)/testimg.ppm
./djpeg -dct int -ppm -outfile testoutp.ppm $(srcdir)/testprog.jpg
./cjpeg -dct int -progressive -opt -outfile testoutp.jpg $(srcdir)/testimg.ppm
./jpegtran -outfile testoutt.jpg $(srcdir)/testprog.jpg
cmp $(srcdir)/testimg.ppm testout.ppm
cmp $(srcdir)/testimg.bmp testout.bmp
cmp $(srcdir)/testimg.jpg testout.jpg
cmp $(srcdir)/testimg.ppm testoutp.ppm
cmp $(srcdir)/testimgp.jpg testoutp.jpg
cmp $(srcdir)/testorig.jpg testoutt.jpg

1094
Makefile.in Normal file

File diff suppressed because it is too large Load Diff

363
README
View File

@@ -1,23 +1,20 @@
The Independent JPEG Group's JPEG software
==========================================
README for release 5b of 15-Mar-95
==================================
README for release 8d of 15-Jan-2012
====================================
This distribution contains the fifth public release of the Independent JPEG
This distribution contains the eighth 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, Guido Vollbeding, Philip Gladstone,
Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
and other members of the Independent JPEG Group.
This software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim
Boucher, Lee Crocker, George Phillips, Davide Rossi, Ge' Weijers, and other
members of the Independent JPEG Group.
IJG is not associated with the official ISO JPEG standards committee.
IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
(also known as JPEG, together with ITU-T SG16).
DOCUMENTATION ROADMAP
@@ -29,25 +26,27 @@ 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.
ACKNOWLEDGMENTS Special thanks.
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, rdjpgcom, wrjpgcom.
*.1 Unix-style man pages for programs (same info as usage.doc).
install.txt How to configure and install the IJG software.
usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
rdjpgcom, and wrjpgcom.
*.1 Unix-style man pages for programs (same info as usage.txt).
wizard.txt 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.
libjpeg.txt 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.
structure.txt Overview of the JPEG library's internal structure.
filelist.txt Road map of IJG files.
coderules.txt Coding style rules --- please read if you contribute code.
Please read at least the files install.doc and usage.doc. Useful information
Please read at least the files install.txt and usage.txt. Some 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.
@@ -59,46 +58,38 @@ 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; cartoons and other non-realistic images are not its
strong suit. JPEG is lossy, meaning that the output image is not necessarily
identical to the input image. Hence you must not use JPEG if you have to have
identical output bits. However, on typical images of real-world scenes, very
good compression levels can be obtained with no visible change, and amazingly
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 package contains C software to implement JPEG image encoding, decoding,
and transcoding. JPEG (pronounced "jay-peg") is a standardized compression
method for full-color and gray-scale images.
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.
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 simple applications "cjpeg" and "djpeg", which use the library to
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.
This software implements JPEG baseline and extended-sequential compression
processes. Provision is made for supporting all variants of these processes,
although some uncommon parameter settings aren't implemented yet. For legal
reasons, we are not distributing code for the arithmetic-coding process; see
LEGAL ISSUES. At present we have made no provision for supporting the
progressive, hierarchical, or lossless processes defined in the standard.
(Support for progressive mode will be offered in a future release.)
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
two simple applications for inserting and extracting textual comments in
JFIF files.
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.) While we hope that the entire
package will someday be industrial-strength code, much remains to be done in
performance tuning and in improving the capabilities of individual modules.
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
@@ -124,7 +115,7 @@ 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, 1992, 1993, 1994, 1995, Thomas G. Lane.
This software is copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
@@ -164,25 +155,18 @@ 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 configuration script "configure" was produced with GNU Autoconf. It
is copyright by the Free Software Foundation but is freely distributable.
The Unix configuration script "configure" was produced with GNU Autoconf.
It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub,
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
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.
WARNING: Unisys has begun to enforce their patent on LZW compression against
GIF encoders and decoders. You will need a license from Unisys to use the
included rdgif.c or wrgif.c files in a commercial or shareware application.
At this time, Unisys is not enforcing their patent against freeware, so
distribution of this package remains legal. However, we intend to remove
GIF support from the IJG package as soon as a suitable replacement format
becomes reasonably popular.
The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent, GIF reading support has
been removed altogether, and the GIF writer has been simplified to produce
"uncompressed GIFs". This technique does not use the LZW algorithm; the
resulting GIF files are larger than usual, but are readable by all standard
GIF decoders.
We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of
@@ -193,7 +177,7 @@ We are required to state that
REFERENCES
==========
We highly recommend reading one or more of these references before trying to
We 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
@@ -201,158 +185,167 @@ The best short technical introduction to the JPEG compression algorithm is
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
(Adjacent articles in that issue discuss MPEG motion picture compression,
applications of JPEG, and related topics.) If you don't have the CACM issue
handy, a PostScript file containing a revised version of Wallace's article
is available at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually
handy, a PostScript file containing a revised version of Wallace's article is
available at http://www.ijg.org/files/wallace.ps.gz. The file (actually
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
omits the sample images that appeared in CACM, but it includes corrections
and some added material. Note: the Wallace article is copyright ACM and
IEEE, and it may not be used for commercial purposes.
and some added material. Note: the Wallace article is copyright ACM and IEEE,
and it may not be used for commercial purposes.
A somewhat less technical, more leisurely introduction to JPEG can be found in
"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood
City, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and
example C code for a multitude of compression methods including JPEG. It is
an excellent source if you are comfortable reading C code but don't know much
about data compression in general. The book's JPEG sample code is far from
industrial-strength, but when you are ready to look at a full implementation,
you've got one here...
"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
good explanations and example C code for a multitude of compression methods
including JPEG. It is an excellent source if you are comfortable reading C
code but don't know much about data compression in general. The book's JPEG
sample code is far from industrial-strength, but when you are ready to look
at a full implementation, you've got one here...
The best full description of JPEG is the textbook "JPEG Still Image Data
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
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 best currently available 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).
Although this is by far the most detailed and comprehensive exposition of
JPEG publicly available, we point out that it is still missing an explanation
of the most essential properties and algorithms of the underlying DCT
technology.
If you think that you know about DCT-based JPEG after reading this book,
then you are in delusion. The real fundamentals and corresponding potential
of DCT-based JPEG are not publicly known so far, and that is the reason for
all the mistaken developments taking place in the image coding domain.
The JPEG standard itself is not available electronically; you must order a
paper copy through ISO. (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 US,
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 number ISO/IEC IS 10918-1. As of mid-1994,
Part 2 is still at Draft International Standard status. It is titled "Digital
Compression and Coding of Continuous-tone Still Images, Part 2: Compliance
testing" and has document number ISO/IEC DIS 10918-2. (The document number
will change to IS 10918-2 when final approval is obtained.) A Part 3,
covering extensions, is likely to appear in draft form in late 1994.
The original JPEG 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.
IJG JPEG 8 introduces an implementation of the JPEG SmartScale extension
which is specified in two documents: A contributed document at ITU and ISO
with title "ITU-T JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced
Image Coding", April 2006, Geneva, Switzerland. The latest version of this
document is Revision 3. And a contributed document ISO/IEC JTC1/SC29/WG1 N
5799 with title "Evolution of JPEG", June/July 2011, Berlin, Germany.
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 at ftp.uu.net, file
graphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube
mail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg"
to the server to obtain the JFIF document; send the message "help" if you have
trouble.
1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report
and thus received a formal publication status. It is available as a free
download in PDF format from
http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
A PostScript version of the JFIF document is available at
http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at
http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
The TIFF 6.0 file format specification can be obtained by FTP from sgi.com
(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed copy
from Aldus Corp. at (206) 628-6593. It should be noted that the TIFF 6.0 spec
of 3-June-92 has a number of serious problems in its JPEG features. A
redesign effort is currently underway to correct these problems; it is
expected to result in a new, incompatible, spec. IJG intends to support the
corrected version of TIFF when the new spec is issued.
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
http://www.ijg.org/files/. 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.
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 graphics/jpeg/jpegsrc.v5b.tar.gz. If you are on the Internet, you
can retrieve files from ftp.uu.net by standard anonymous FTP. If you don't
have FTP access, UUNET's archives are also available via UUCP; contact
help@uunet.uu.net for information on retrieving files that way.
The "official" archive site for this software is www.ijg.org.
The most recent released version can always be found there in
directory "files". This particular version will be archived as
http://www.ijg.org/files/jpegsrc.v8d.tar.gz, and in Windows-compatible
"zip" archive format as http://www.ijg.org/files/jpegsr8d.zip.
Numerous Internet sites maintain copies of the UUNET files; in particular,
you can probably find a copy at any site that archives comp.sources.misc
submissions. However, only ftp.uu.net is guaranteed to have the latest
official version.
You can also obtain this software from CompuServe, in the GRAPHSUPPORT forum
(GO GRAPHSUP), library 12 "JPEG Tools". Again, CompuServe is not guaranteed
to have the very latest version.
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, news.answers, and other groups. You can
always obtain the latest version from the news.answers archive at
rtfm.mit.edu. By FTP, fetch /pub/usenet/news.answers/jpeg-faq/part1 and
.../part2. If you don't have FTP, send e-mail to mail-server@rtfm.mit.edu
The JPEG FAQ (Frequently Asked Questions) article is a source of some
general information about JPEG.
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
================
ACKNOWLEDGMENTS
===============
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.
Thank to Juergen Bruder for providing me with a copy of the common DCT
algorithm article, only to find out that I had come to the same result
in a more direct and comprehensible way with a more generative approach.
If you are on a Unix machine, we highly recommend Jef Poskanzer's free
PBMPLUS image software, which provides many useful operations on PPM-format
image files. In particular, it can convert PPM images to and from a wide
range of other formats. You can obtain this package by FTP from ftp.x.org
(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also
a newer update of this package called NETPBM, available from
wuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/.
Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software
is; you are likely to have difficulty making it work on any non-Unix machine.
Thank to Istvan Sebestyen and Joan L. Mitchell for inviting me to the
ITU JPEG (Study Group 16) meeting in Geneva, Switzerland.
A different free JPEG implementation, written by the PVRG group at Stanford,
is available from havefun.stanford.edu in directory pub/jpeg. This program
is designed for research and experimentation rather than production use;
it is slower, harder to use, and less portable than the IJG code, but it
implements a larger subset of the JPEG standard. In particular, it supports
lossless JPEG.
Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
Thank to Thomas Richter and Daniel Lee for inviting me to the
ISO/IEC JTC1/SC29/WG1 (also known as JPEG, together with ITU-T SG16)
meeting in Berlin, Germany.
Thank to John Korejwa and Massimo Ballerini for inviting me to
fruitful consultations in Boston, MA and Milan, Italy.
Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther
Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel
for corresponding business development.
Thank to Nico Zschach and Dirk Stelling of the technical support team
at the Digital Images company in Halle for providing me with extra
equipment for configuration tests.
Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful
communication about JPEG configuration in Sigma Photo Pro software.
Thank to Andrew Finkenstadt for hosting the ijg.org site.
Last but not least special thank to Thomas G. Lane for the original
design and development of this singular software package.
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 ISO/IEC JTC1/SC29/WG1 standards committee (also known as JPEG, together
with ITU-T SG16) currently promotes different formats containing the name
"JPEG" which is misleading because these formats are incompatible with
original DCT-based JPEG and are based on faulty technologies.
IJG therefore does not and will not support such momentary mistakes
(see REFERENCES).
There exist also distributions under the name "OpenJPEG" promoting such
kind of formats which is misleading because they don't support original
JPEG images.
We have no sympathy for the promotion of inferior formats. Indeed, one of
the original reasons for developing this free software was to help force
convergence on common, interoperable format standards for JPEG files.
Don't use an incompatible file format!
(In any case, our decoder will remain capable of reading existing JPEG
image files indefinitely.)
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.
Work is also going forward to incorporate JPEG compression into the TIFF
standard, for use in "high end" applications that need to record a lot of
additional data about an image. We intend to support TIFF in the future.
We hope that these two formats will be sufficient and that other,
incompatible JPEG file formats will not proliferate.
Furthermore, the ISO committee pretends to be "responsible for the popular
JPEG" in their public reports which is not true because they don't respond to
actual requirements for the maintenance of the original JPEG specification.
Indeed, part of the reason for developing and releasing this free software is
to help force rapid convergence to de facto standards for JPEG file formats.
SUPPORT STANDARD, NON-PROPRIETARY FORMATS: demand JFIF or TIFF/JPEG!
There are currently distributions in circulation containing the name
"libjpeg" which claim to be a "derivative" or "fork" of the original
libjpeg, but don't have the features and are incompatible with formats
supported by actual IJG libjpeg distributions. Furthermore, they
violate the license conditions as described under LEGAL ISSUES above.
We have no sympathy for the release of misleading and illegal
distributions derived from obsolete code bases.
Don't use an obsolete code base!
TO DO
=====
In future versions, we are considering supporting progressive JPEG
compression, the upcoming JPEG Part 3 extensions, and other improvements.
Version 8 is the first release of a new generation JPEG standard
to overcome the limitations of the original JPEG specification.
More features are being prepared for coming releases...
As always, speeding things up is high on our priority list.
Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org.

9652
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,36 @@
.TH ANSI2KNR 1 "31 December 1990"
.TH ANSI2KNR 1 "19 Jan 1996"
.SH NAME
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
.SH SYNOPSIS
.I ansi2knr
input_file output_file
[--varargs] input_file [output_file]
.SH DESCRIPTION
If no output_file is supplied, output goes to stdout.
.br
There are no error messages.
.sp
.I ansi2knr
recognizes functions by seeing a non-keyword identifier at the left margin, followed by a left parenthesis, with a right parenthesis as the last character on the line. It will recognize a multi-line header if the last character on each line but the last is a left parenthesis or comma. These algorithms ignore whitespace and comments, except that the function name must be the first thing on the line.
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.
.sp
The following constructs will confuse it:
.br
- Any other construct that starts at the left margin and follows the above syntax (such as a macro or function call).
- Any other construct that starts at the left margin and follows the
above syntax (such as a macro or function call).
.br
- Macros that tinker with the syntax of the function header.
- Some macros that tinker with the syntax of the function header.
.sp
The --varargs switch is obsolete, and is recognized only for
backwards compatibility. The present version of
.I ansi2knr
will always attempt to convert a ... argument to va_alist and va_dcl.
.SH AUTHOR
L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
continues to maintain the current version; most of the code in the current
version is his work. ansi2knr also includes contributions by Francois
Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.

View File

@@ -1,178 +1,160 @@
/* Copyright (C) 1989, 1991, 1993 Aladdin Enterprises. All rights reserved. */
/* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. */
/* ansi2knr.c */
/* Convert ANSI function declarations to K&R syntax */
/*$Id: ansi2knr.c,v 1.14 2003/09/06 05:36:56 eggert Exp $*/
/* 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 for full details.
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 GNU
General Public License. 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 COPYING. Among other
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,
or, if there is no file named COPYLEFT, a file named COPYING. 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 COPYING, referred to above ----------
----- These terms do NOT apply to the JPEG software itself; see README ------
GHOSTSCRIPT GENERAL PUBLIC LICENSE
(Clarified 11 Feb 1988)
Copyright (C) 1988 Richard M. Stallman
Everyone is permitted to copy and distribute verbatim copies of this
license, but changing it is not allowed. You can also use this wording
to make the terms for other programs.
The license agreements of most software companies keep you at the
mercy of those companies. By contrast, our general public license is
intended to give everyone the right to share Ghostscript. To make sure
that you get the rights we want you to have, we need to make
restrictions that forbid anyone to deny you these rights or to ask you
to surrender the rights. Hence this license agreement.
Specifically, we want to make sure that you have the right to give
away copies of Ghostscript, that you receive source code or else can get
it if you want it, that you can change Ghostscript or use pieces of it
in new free programs, and that you know you can do these things.
To make sure that everyone has such rights, we have to forbid you to
deprive anyone else of these rights. For example, if you distribute
copies of Ghostscript, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights.
Also, for our own protection, we must make certain that everyone finds
out that there is no warranty for Ghostscript. If Ghostscript is
modified by someone else and passed on, we want its recipients to know
that what they have is not what we distributed, so that any problems
introduced by others will not reflect on our reputation.
Therefore we (Richard M. Stallman and the Free Software Foundation,
Inc.) make the following terms which say what you must do to be allowed
to distribute or change Ghostscript.
COPYING POLICIES
1. You may copy and distribute verbatim copies of Ghostscript source
code as you receive it, in any medium, provided that you conspicuously
and appropriately publish on each copy a valid copyright and license
notice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved.
Distributed by Free Software Foundation, Inc." (or with whatever year is
appropriate); keep intact the notices on all files that refer to this
License Agreement and to the absence of any warranty; and give any other
recipients of the Ghostscript program a copy of this License Agreement
along with the program. You may charge a distribution fee for the
physical act of transferring a copy.
2. You may modify your copy or copies of Ghostscript or any portion of
it, and copy and distribute such modifications under the terms of
Paragraph 1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating
that you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish,
that in whole or in part contains or is a derivative of Ghostscript
or any part thereof, to be licensed at no charge to all third
parties on terms identical to those contained in this License
Agreement (except that you may choose to grant more extensive
warranty protection to some or all third parties, at your option).
c) You may charge a distribution fee for the physical act of
transferring a copy, and you may at your option offer warranty
protection in exchange for a fee.
Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.
3. You may copy and distribute Ghostscript (or a portion or derivative
of it, under Paragraph 2) in object code or executable form under the
terms of Paragraphs 1 and 2 above provided that you also do one of the
following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal
shipping charge) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
For an executable file, complete source code means all the source code for
all modules it contains; but, as a special exception, it need not include
source code for modules which are standard libraries that accompany the
operating system on which the executable file runs.
4. You may not copy, sublicense, distribute or transfer Ghostscript
except as expressly provided under this License Agreement. Any attempt
otherwise to copy, sublicense, distribute or transfer Ghostscript is
void and your rights to use the program under this License agreement
shall be automatically terminated. However, parties who have received
computer software programs from you with this License Agreement will not
have their licenses terminated so long as such parties remain in full
compliance.
5. If you wish to incorporate parts of Ghostscript into other free
programs whose distribution conditions are different, write to the Free
Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not
yet worked out a simple rule that can be stated here, but we will often
permit this. We will be guided by the two goals of preserving the free
status of all derivatives of our free software and of promoting the
sharing and reuse of software.
Your comments and suggestions about our licensing policies and our
software are welcome! Please contact the Free Software Foundation,
Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
NO WARRANTY
BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
YOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
NECESSARY SERVICING, REPAIR OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
BY ANY OTHER PARTY.
-------------------- End of file COPYING ------------------------------
* Usage:
ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]
* --filename provides the file name for the #line directive in the output,
* overriding input_file (if present).
* If no input_file is supplied, input is read from stdin.
* 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 and/or preprocessor directives), except that a line
* consisting of only
* identifier1(identifier2)
* will not be considered a function definition unless identifier2 is
* the word "void", and a line consisting of
* identifier1(identifier2, <<arbitrary>>)
* will not be considered a function definition.
* ansi2knr 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, comments, and preprocessor directives, 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 function headers.
*/
/*
* 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 2000-04-12 backs out Eggert's changes because of bugs:
- concatlits didn't declare the type of its bufend argument;
- concatlits didn't recognize when it was inside a comment;
- scanstring could scan backward past the beginning of the string; when
- the check for \ + newline in scanstring was unnecessary.
2000-03-05 Paul Eggert <eggert@twinsun.com>
Add support for concatenated string literals.
* ansi2knr.c (concatlits): New decl.
(main): Invoke concatlits to concatenate string literals.
(scanstring): Handle backslash-newline correctly. Work with
character constants. Fix bug when scanning backwards through
backslash-quote. Check for unterminated strings.
(convert1): Parse character constants, too.
(appendline, concatlits): New functions.
* ansi2knr.1: Document this.
lpd 1999-08-17 added code to allow preprocessor directives
wherever comments are allowed
lpd 1999-04-12 added minor fixes from Pavel Roskin
<pavel_roskin@geocities.com> for clean compilation with
gcc -W -Wall
lpd 1999-03-22 added hack to recognize lines consisting of
identifier1(identifier2, xxx) as *not* being procedures
lpd 1999-02-03 made indentation of preprocessor commands consistent
lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
endless loop; quoted strings within an argument list
confused the parser
lpd 1999-01-24 added a check for write errors on the output,
suggested by Jim Meyering <meyering@ascend.com>
lpd 1998-11-09 added further hack to recognize identifier(void)
as being a procedure
lpd 1998-10-23 added hack to recognize lines consisting of
identifier1(identifier2) as *not* being procedures
lpd 1997-12-08 made input_file optional; only closes input and/or
output file if not stdin or stdout respectively; prints
usage message on stderr rather than stdout; adds
--filename switch (changes suggested by
<ceder@lysator.liu.se>)
lpd 1996-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 1996-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 1995-06-22 removed #ifndefs whose sole purpose was to define
undefined preprocessor symbols as 0; changed all #ifdefs
for configuration symbols to #ifs
lpd 1995-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 1994-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 1994-10-10 removed CONFIG_BROKETS conditional
lpd 1994-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 1989-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
@@ -183,8 +165,15 @@ BY ANY OTHER PARTY.
# endif
# endif
/* malloc and free should be declared in stdlib.h, */
/* but if you've got a K&R compiler, they probably aren't. */
#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
@@ -197,100 +186,244 @@ BY ANY OTHER PARTY.
# endif
# endif
/* Usage:
ansi2knr input_file [output_file]
* If no output_file is supplied, output goes to stdout.
* There are no error messages.
*
* ansi2knr recognizes functions by seeing a non-keyword identifier
* at the left margin, followed by a left parenthesis,
* with a right parenthesis as the last character on the line.
* It will recognize a multi-line header provided that the last character
* of the last line of the header is a right parenthesis,
* and no intervening line ends with a left 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).
* - Macros that tinker with the syntax of the function header.
#endif
/* Define NULL (for *very* old compilers). */
#ifndef NULL
# define NULL (0)
#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) (isalnum(ch) || (ch) == '_')
#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
/* Forward references */
char *ppdirforward();
char *ppdirbackward();
char *skipspace();
char *scanstring();
int writeblanks();
int test1();
int convert1();
/* The main program */
int
main(argc, argv)
int argc;
char *argv[];
{ FILE *in, *out;
{ FILE *in = stdin;
FILE *out = stdout;
char *filename = 0;
char *program_name = argv[0];
char *output_name = 0;
#define bufsize 5000 /* arbitrary size */
char *buf;
char *line;
char *more;
char *usage =
"Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
/*
* 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;
int output_error;
while ( argc > 1 && argv[1][0] == '-' ) {
if ( !strcmp(argv[1], "--varargs") ) {
convert_varargs = 1;
argc--;
argv++;
continue;
}
if ( !strcmp(argv[1], "--filename") && argc > 2 ) {
filename = argv[2];
argc -= 2;
argv += 2;
continue;
}
fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
argv[1]);
fprintf(stderr, usage);
exit(1);
}
switch ( argc )
{
default:
printf("Usage: ansi2knr input_file [output_file]\n");
fprintf(stderr, usage);
exit(0);
case 2:
out = stdout; break;
case 3:
out = fopen(argv[2], "w");
if ( out == NULL )
{ fprintf(stderr, "Cannot open %s\n", argv[2]);
output_name = argv[2];
out = fopen(output_name, "w");
if ( out == NULL ) {
fprintf(stderr, "%s: Cannot open output file %s\n",
program_name, output_name);
exit(1);
}
}
/* falls through */
case 2:
in = fopen(argv[1], "r");
if ( in == NULL )
{ fprintf(stderr, "Cannot open %s\n", argv[1]);
if ( in == NULL ) {
fprintf(stderr, "%s: Cannot open input file %s\n",
program_name, argv[1]);
exit(1);
}
fprintf(out, "#line 1 \"%s\"\n", argv[1]);
if ( filename == 0 )
filename = argv[1];
/* falls through */
case 1:
break;
}
if ( filename )
fprintf(out, "#line 1 \"%s\"\n", filename);
buf = malloc(bufsize);
if ( buf == NULL )
{
fprintf(stderr, "Unable to allocate read buffer!\n");
exit(1);
}
line = buf;
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
{ switch ( test1(buf) )
{
test: line += strlen(line);
switch ( test1(buf) )
{
case 2: /* a function header */
convert1(buf, out, 1, convert_varargs);
break;
case 1: /* a function */
convert1(buf, out);
/* 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(ppdirforward(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 */
line = buf + strlen(buf);
if ( line != buf + (bufsize - 1) ) /* overflow check */
continue;
/* falls through */
default: /* not a function */
fputs(buf, out);
wl: fputs(buf, out);
break;
}
line = buf;
}
if ( line != buf ) fputs(buf, out);
if ( line != buf )
fputs(buf, out);
free(buf);
fclose(out);
if ( output_name ) {
output_error = ferror(out);
output_error |= fclose(out);
} else { /* out == stdout */
fflush(out);
output_error = ferror(out);
}
if ( output_error ) {
fprintf(stderr, "%s: error writing to %s\n", program_name,
(output_name ? output_name : "stdout"));
exit(1);
}
if ( in != stdin )
fclose(in);
return 0;
}
/* Skip over space and comments, in either direction. */
/*
* Skip forward or backward over one or more preprocessor directives.
*/
char *
ppdirforward(p)
char *p;
{
for (; *p == '#'; ++p) {
for (; *p != '\r' && *p != '\n'; ++p)
if (*p == 0)
return p;
if (*p == '\r' && p[1] == '\n')
++p;
}
return p;
}
char *
ppdirbackward(p, limit)
char *p;
char *limit;
{
char *np = p;
for (;; p = --np) {
if (*np == '\n' && np[-1] == '\r')
--np;
for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np)
if (np[-1] == 0)
return np;
if (*np != '#')
return p;
}
}
/*
* Skip over whitespace, comments, and preprocessor directives,
* in either direction.
*/
char *
skipspace(p, dir)
register char *p;
register int dir; /* 1 for forward, -1 for backward */
{ for ( ; ; )
{ while ( isspace(*p) ) p += dir;
if ( !(*p == '/' && p[dir] == '*') ) break;
char *p;
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?? */
while ( !(*p == '*' && p[dir] == '/') ) {
if ( *p == 0 )
return p; /* multi-line comment?? */
p += dir;
}
p += dir; p += dir;
@@ -298,15 +431,29 @@ skipspace(p, dir)
return p;
}
/* Scan over a quoted string, in either direction. */
char *
scanstring(p, dir)
char *p;
int dir;
{
for (p += dir; ; p += dir)
if (*p == '"' && p[-dir] != '\\')
return p + dir;
}
/*
* 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++ ) *p = ' ';
for ( p = start; p < end; p++ )
if ( *p != '\r' && *p != '\n' )
*p = ' ';
return 0;
}
@@ -316,27 +463,34 @@ writeblanks(start, end)
* 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 *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);
bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1);
switch ( *bend )
{
case ';': contin = 0 /*2*/; break;
case ')': contin = 1; break;
case '{':
case ';': return 0; /* not a function */
case '{': return 0; /* not a function */
case '}': return 0; /* not a function */
default: contin = -1;
}
while ( isidchar(*p) ) p++;
while ( isidchar(*p) )
p++;
endfn = p;
p = skipspace(p, 1);
if ( *p++ != '(' )
@@ -356,33 +510,74 @@ test1(buf)
};
char **key = words;
char *kp;
int len = endfn - buf;
unsigned len = endfn - buf;
while ( (kp = *key) != 0 )
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
return 0; /* name is a keyword */
key++;
}
}
{
char *id = p;
int len;
/*
* Check for identifier1(identifier2) and not
* identifier1(void), or identifier1(identifier2, xxxx).
*/
while ( isidchar(*p) )
p++;
len = p - id;
p = skipspace(p, 1);
if (*p == ',' ||
(*p == ')' && (len != 4 || strncmp(id, "void", 4)))
)
return 0; /* not a function */
}
/*
* If the last significant character was a ), we need to count
* parentheses, because it might be part of a formal parameter
* that is a procedure.
*/
if (contin > 0) {
int level = 0;
for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
if (level > 0)
contin = -1;
}
return contin;
}
/* Convert a recognized function definition or header to K&R syntax. */
int
convert1(buf, out)
convert1(buf, out, header, convert_varargs)
char *buf;
FILE *out;
int header; /* Boolean */
int convert_varargs; /* Boolean */
{ char *endfn;
register char *p;
char *p;
/*
* The breaks table contains pointers to the beginning and end
* of each argument.
*/
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++) != '('; ) ;
for ( endfn = buf; *(endfn++) != '('; )
;
top: p = endfn;
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
if ( breaks == 0 )
if ( breaks == NULL )
{ /* Couldn't allocate break table, give up */
fprintf(stderr, "Unable to allocate break table!\n");
fputs(buf, out);
@@ -393,7 +588,10 @@ top: p = endfn;
/* Parse the argument list */
do
{ int level = 0;
char *lp = NULL;
char *rp = NULL;
char *end = NULL;
if ( bp >= btop )
{ /* Filled up break table. */
/* Allocate a bigger one and start over. */
@@ -406,13 +604,31 @@ top: p = endfn;
for ( ; end == NULL; p++ )
{ switch(*p)
{
case ',': if ( !level ) end = p; break;
case '(': level++; break;
case ')': if ( --level < 0 ) end = p; break;
case '/': p = skipspace(p, 1) - 1; break;
default: ;
case ',':
if ( !level ) end = p;
break;
case '(':
if ( !level ) lp = p;
level++;
break;
case ')':
if ( --level < 0 ) end = p;
else rp = p;
break;
case '/':
if (p[1] == '*')
p = skipspace(p, 1) - 1;
break;
case '"':
p = scanstring(p, 1) - 1;
break;
default:
;
}
}
/* Erase any embedded prototype parameters. */
if ( lp && rp )
writeblanks(lp + 1, rp);
p--; /* back up over terminator */
/* Find the name being declared. */
/* This is complicated because of procedure and */
@@ -427,9 +643,19 @@ top: p = endfn;
while ( level )
switch ( *--p )
{
case ']': case ')': level++; break;
case '[': case '(': level--; break;
case '/': p = skipspace(p, -1) + 1; break;
case ']': case ')':
level++;
break;
case '[': case '(':
level--;
break;
case '/':
if (p > buf && p[-1] == '*')
p = skipspace(p, -1) + 1;
break;
case '"':
p = scanstring(p, -1) + 1;
break;
default: ;
}
}
@@ -440,10 +666,16 @@ top: p = endfn;
goto found;
}
break;
default: goto found;
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);
@@ -451,6 +683,7 @@ found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
writeblanks(bp[-1] - 1, p);
bp--;
}
}
else
{ while ( isidchar(*p) ) p--;
*bp++ = p+1;
@@ -470,19 +703,37 @@ found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
}
}
}
/* Put out the function name */
/* Put out the function name and left parenthesis. */
p = buf;
while ( p != endfn ) putc(*p, out), p++;
/* Put out the declaration */
for ( ap = breaks+1; ap < bp; ap += 2 )
/* 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);
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] = ';';
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;
}

View File

@@ -1,7 +1,8 @@
/*
* cderror.h
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -45,6 +46,7 @@ JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
@@ -72,7 +74,7 @@ JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
#ifdef PPM_SUPPORTED
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
JMESSAGE(JERR_PPM_NOT, "Not a PPM file")
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
JMESSAGE(JTRC_PPM, "%ux%u PPM image")

181
cdjpeg.c Normal file
View File

@@ -0,0 +1,181 @@
/*
* cdjpeg.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains common support routines used by the IJG application
* programs (cjpeg, djpeg, jpegtran).
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include <ctype.h> /* to declare isupper(), tolower() */
#ifdef NEED_SIGNAL_CATCHER
#include <signal.h> /* to declare signal() */
#endif
#ifdef USE_SETMODE
#include <fcntl.h> /* to declare setmode()'s parameter macros */
/* If you have setmode() but not <io.h>, just delete this line: */
#include <io.h> /* to declare setmode() */
#endif
/*
* Signal catcher to ensure that temporary files are removed before aborting.
* NB: for Amiga Manx C this is actually a global routine named _abort();
* we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus...
*/
#ifdef NEED_SIGNAL_CATCHER
static j_common_ptr sig_cinfo;
void /* must be global for Manx C */
signal_catcher (int signum)
{
if (sig_cinfo != NULL) {
if (sig_cinfo->err != NULL) /* turn off trace output */
sig_cinfo->err->trace_level = 0;
jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */
}
exit(EXIT_FAILURE);
}
GLOBAL(void)
enable_signal_catcher (j_common_ptr cinfo)
{
sig_cinfo = cinfo;
#ifdef SIGINT /* not all systems have SIGINT */
signal(SIGINT, signal_catcher);
#endif
#ifdef SIGTERM /* not all systems have SIGTERM */
signal(SIGTERM, signal_catcher);
#endif
}
#endif
/*
* Optional progress monitor: display a percent-done figure on stderr.
*/
#ifdef PROGRESS_REPORT
METHODDEF(void)
progress_monitor (j_common_ptr cinfo)
{
cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress;
int total_passes = prog->pub.total_passes + prog->total_extra_passes;
int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit);
if (percent_done != prog->percent_done) {
prog->percent_done = percent_done;
if (total_passes > 1) {
fprintf(stderr, "\rPass %d/%d: %3d%% ",
prog->pub.completed_passes + prog->completed_extra_passes + 1,
total_passes, percent_done);
} else {
fprintf(stderr, "\r %3d%% ", percent_done);
}
fflush(stderr);
}
}
GLOBAL(void)
start_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress)
{
/* Enable progress display, unless trace output is on */
if (cinfo->err->trace_level == 0) {
progress->pub.progress_monitor = progress_monitor;
progress->completed_extra_passes = 0;
progress->total_extra_passes = 0;
progress->percent_done = -1;
cinfo->progress = &progress->pub;
}
}
GLOBAL(void)
end_progress_monitor (j_common_ptr cinfo)
{
/* Clear away progress display */
if (cinfo->err->trace_level == 0) {
fprintf(stderr, "\r \r");
fflush(stderr);
}
}
#endif
/*
* Case-insensitive matching of possibly-abbreviated keyword switches.
* keyword is the constant keyword (must be lower case already),
* minchars is length of minimum legal abbreviation.
*/
GLOBAL(boolean)
keymatch (char * arg, const char * keyword, int minchars)
{
register int ca, ck;
register int nmatched = 0;
while ((ca = *arg++) != '\0') {
if ((ck = *keyword++) == '\0')
return FALSE; /* arg longer than keyword, no good */
if (isupper(ca)) /* force arg to lcase (assume ck is already) */
ca = tolower(ca);
if (ca != ck)
return FALSE; /* no good */
nmatched++; /* count matched characters */
}
/* reached end of argument; fail if it's too short for unique abbrev */
if (nmatched < minchars)
return FALSE;
return TRUE; /* A-OK */
}
/*
* Routines to establish binary I/O mode for stdin and stdout.
* Non-Unix systems often require some hacking to get out of text mode.
*/
GLOBAL(FILE *)
read_stdin (void)
{
FILE * input_file = stdin;
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdin), O_BINARY);
#endif
#ifdef USE_FDOPEN /* need to re-open in binary mode? */
if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) {
fprintf(stderr, "Cannot reopen stdin\n");
exit(EXIT_FAILURE);
}
#endif
return input_file;
}
GLOBAL(FILE *)
write_stdout (void)
{
FILE * output_file = stdout;
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdout), O_BINARY);
#endif
#ifdef USE_FDOPEN /* need to re-open in binary mode? */
if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) {
fprintf(stderr, "Cannot reopen stdout\n");
exit(EXIT_FAILURE);
}
#endif
return output_file;
}

View File

@@ -1,7 +1,7 @@
/*
* cdjpeg.h
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -102,23 +102,86 @@ typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
#define jinit_write_rle jIWrRLE
#define jinit_read_targa jIRdTarga
#define jinit_write_targa jIWrTarga
#define read_quant_tables RdQTables
#define read_scan_script RdScnScript
#define set_quality_ratings SetQRates
#define set_quant_slots SetQSlots
#define set_sample_factors SetSFacts
#define read_color_map RdCMap
#define enable_signal_catcher EnSigCatcher
#define start_progress_monitor StProgMon
#define end_progress_monitor EnProgMon
#define read_stdin RdStdin
#define write_stdout WrStdout
#endif /* NEED_SHORT_EXTERNAL_NAMES */
/* Module selection routines for I/O modules. */
EXTERN cjpeg_source_ptr jinit_read_bmp JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_bmp JPP((j_decompress_ptr cinfo,
EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo,
boolean is_os2));
EXTERN cjpeg_source_ptr jinit_read_gif JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_gif JPP((j_decompress_ptr cinfo));
EXTERN cjpeg_source_ptr jinit_read_ppm JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_ppm JPP((j_decompress_ptr cinfo));
EXTERN cjpeg_source_ptr jinit_read_rle JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_rle JPP((j_decompress_ptr cinfo));
EXTERN cjpeg_source_ptr jinit_read_targa JPP((j_compress_ptr cinfo));
EXTERN djpeg_dest_ptr jinit_write_targa JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_targa JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo));
/* Other global routines */
/* cjpeg support routines (in rdswitch.c) */
EXTERN void read_color_map JPP((j_decompress_ptr cinfo, FILE * infile));
EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
boolean force_baseline));
EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
EXTERN(boolean) set_quality_ratings JPP((j_compress_ptr cinfo, char *arg,
boolean force_baseline));
EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
/* djpeg support routines (in rdcolmap.c) */
EXTERN(void) read_color_map JPP((j_decompress_ptr cinfo, FILE * infile));
/* common support routines (in cdjpeg.c) */
EXTERN(void) enable_signal_catcher JPP((j_common_ptr cinfo));
EXTERN(void) start_progress_monitor JPP((j_common_ptr cinfo,
cd_progress_ptr progress));
EXTERN(void) end_progress_monitor JPP((j_common_ptr cinfo));
EXTERN(boolean) keymatch JPP((char * arg, const char * keyword, int minchars));
EXTERN(FILE *) read_stdin JPP((void));
EXTERN(FILE *) write_stdout JPP((void));
/* miscellaneous useful macros */
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#define WRITE_BINARY "w"
#else
#ifdef VMS /* VMS is very nonstandard */
#define READ_BINARY "rb", "ctx=stm"
#define WRITE_BINARY "wb", "ctx=stm"
#else /* standard ANSI-compliant case */
#define READ_BINARY "rb"
#define WRITE_BINARY "wb"
#endif
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#ifdef VMS
#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
#else
#define EXIT_SUCCESS 0
#endif
#endif
#ifndef EXIT_WARNING
#ifdef VMS
#define EXIT_WARNING 1 /* VMS is very nonstandard */
#else
#define EXIT_WARNING 2
#endif
#endif

View File

@@ -1,6 +1,268 @@
CHANGE LOG for Independent JPEG Group's JPEG software
Version 8d 15-Jan-2012
-----------------------
Add cjpeg -rgb option to create RGB JPEG files.
Using this switch suppresses the conversion from RGB
colorspace input to the default YCbCr JPEG colorspace.
This feature allows true lossless JPEG coding of RGB color images.
The recommended command for this purpose is currently
cjpeg -rgb -block 1 -arithmetic.
SmartScale capable decoder (introduced with IJG JPEG 8) required.
Thank to Michael Koch for the initial suggestion.
Add option to disable the region adjustment in the transupp crop code.
Thank to Jeffrey Friedl for the suggestion.
Thank to Richard Jones and Edd Dawson for various minor corrections.
Thank to Akim Demaille for configure.ac cleanup.
Version 8c 16-Jan-2011
-----------------------
Add option to compression library and cjpeg (-block N) to use
different DCT block size.
All N from 1 to 16 are possible. Default is 8 (baseline format).
Larger values produce higher compression,
smaller values produce higher quality.
SmartScale capable decoder (introduced with IJG JPEG 8) required.
Version 8b 16-May-2010
-----------------------
Repair problem in new memory source manager with corrupt JPEG data.
Thank to Ted Campbell and Samuel Chun for the report.
Repair problem in Makefile.am test target.
Thank to anonymous user for the report.
Support MinGW installation with automatic configure.
Thank to Volker Grabsch for the suggestion.
Version 8a 28-Feb-2010
-----------------------
Writing tables-only datastreams via jpeg_write_tables works again.
Support 32-bit BMPs (RGB image with Alpha channel) for read in cjpeg.
Thank to Brett Blackham for the suggestion.
Improve accuracy in floating point IDCT calculation.
Thank to Robert Hooke for the hint.
Version 8 10-Jan-2010
----------------------
jpegtran now supports the same -scale option as djpeg for "lossless" resize.
An implementation of the JPEG SmartScale extension is required for this
feature. A (draft) specification of the JPEG SmartScale extension is
available as a contributed document at ITU and ISO. Revision 2 or later
of the document is required (latest document version is Revision 3).
The SmartScale extension will enable more features beside lossless resize
in future implementations, as described in the document (new compression
options).
Add sanity check in BMP reader module to avoid cjpeg crash for empty input
image (thank to Isaev Ildar of ISP RAS, Moscow, RU for reporting this error).
Add data source and destination managers for read from and write to
memory buffers. New API functions jpeg_mem_src and jpeg_mem_dest.
Thank to Roberto Boni from Italy for the suggestion.
Version 7 27-Jun-2009
----------------------
New scaled DCTs implemented.
djpeg now supports scalings N/8 with all N from 1 to 16.
cjpeg now supports scalings 8/N with all N from 1 to 16.
Scaled DCTs with size larger than 8 are now also used for resolving the
common 2x2 chroma subsampling case without additional spatial resampling.
Separate spatial resampling for those kind of files is now only necessary
for N>8 scaling cases.
Furthermore, separate scaled DCT functions are provided for direct resolving
of the common asymmetric subsampling cases (2x1 and 1x2) without additional
spatial resampling.
cjpeg -quality option has been extended for support of separate quality
settings for luminance and chrominance (or in general, for every provided
quantization table slot).
New API function jpeg_default_qtables() and q_scale_factor array in library.
Added -nosmooth option to cjpeg, complementary to djpeg.
New variable "do_fancy_downsampling" in library, complement to fancy
upsampling. Fancy upsampling now uses direct DCT scaling with sizes
larger than 8. The old method is not reversible and has been removed.
Support arithmetic entropy encoding and decoding.
Added files jaricom.c, jcarith.c, jdarith.c.
Straighten the file structure:
Removed files jidctred.c, jcphuff.c, jchuff.h, jdphuff.c, jdhuff.h.
jpegtran has a new "lossless" cropping feature.
Implement -perfect option in jpegtran, new API function
jtransform_perfect_transform() in transupp. (DP 204_perfect.dpatch)
Better error messages for jpegtran fopen failure.
(DP 203_jpegtran_errmsg.dpatch)
Fix byte order issue with 16bit PPM/PGM files in rdppm.c/wrppm.c:
according to Netpbm, the de facto standard implementation of the PNM formats,
the most significant byte is first. (DP 203_rdppm.dpatch)
Add -raw option to rdjpgcom not to mangle the output.
(DP 205_rdjpgcom_raw.dpatch)
Make rdjpgcom locale aware. (DP 201_rdjpgcom_locale.dpatch)
Add extern "C" to jpeglib.h.
This avoids the need to put extern "C" { ... } around #include "jpeglib.h"
in your C++ application. Defining the symbol DONT_USE_EXTERN_C in the
configuration prevents this. (DP 202_jpeglib.h_c++.dpatch)
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
---------------------

156
cjpeg.1
View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "12 December 1994"
.TH CJPEG 1 "28 August 2011"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
@@ -16,7 +16,7 @@ cjpeg \- compress an image file to a JPEG file
compresses the named image file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output.
The currently supported input file formats are: PPM (PBMPLUS color
format), PGM (PBMPLUS gray-scale format), BMP, GIF, Targa, and RLE (Utah Raster
format), PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster
Toolkit format). (RLE is supported only if the URT library is available.)
.SH OPTIONS
All switch names may be abbreviated; for example,
@@ -27,28 +27,36 @@ or
.BR \-gr .
Most of the "basic" switches can be abbreviated to as little as one letter.
Upper and lower case are equivalent (thus
.B \-GIF
.B \-BMP
is the same as
.BR \-gif ).
.BR \-bmp ).
British spellings are also accepted (e.g.,
.BR \-greyscale ),
though for brevity these are not mentioned below.
.PP
The basic switches are:
.TP
.BI \-quality " N"
.BI \-quality " N[,...]"
Scale quantization tables to adjust image quality. Quality is 0 (worst) to
100 (best); default is 75. (See below for more info.)
.TP
.B \-grayscale
Create monochrome JPEG file from color input. Be sure to use this switch when
compressing a grayscale GIF file, because
compressing a grayscale BMP file, because
.B cjpeg
isn't bright enough to notice whether a GIF file uses only shades of gray.
isn't bright enough to notice whether a BMP file uses only shades of gray.
By saying
.BR \-grayscale ,
you'll get a smaller JPEG file that takes less time to process.
.TP
.B \-rgb
Create RGB JPEG file.
Using this switch suppresses the conversion from RGB
colorspace input to the default YCbCr JPEG colorspace.
Use this switch in combination with the
.BI \-block " N"
switch (see below) for lossless JPEG coding.
.TP
.B \-optimize
Perform optimization of entropy encoding parameters. Without this, default
encoding parameters are used.
@@ -59,6 +67,16 @@ runs somewhat slower and needs much more memory. Image quality and speed of
decompression are unaffected by
.BR \-optimize .
.TP
.B \-progressive
Create progressive JPEG file (see below).
.TP
.BI \-scale " M/N"
Scale the output image by a factor M/N. Currently supported scale factors are
M/N with all N from 1 to 16, where M is the destination DCT size, which is 8
by default (see
.BI \-block " N"
switch below).
.TP
.B \-targa
Input file is Targa format. Targa files that contain an "identification"
field will not be automatically recognized by
@@ -84,7 +102,7 @@ often about right. If you see defects at
image. (The optimal setting will vary from one image to another.)
.PP
.B \-quality
100 will generate a quantization table of all 1's, eliminating loss in the
100 will generate a quantization table of all 1's, minimizing loss in the
quantization step (but there is still information loss in subsampling, as well
as roundoff error). This setting is mainly of interest for experimental
purposes. Quality values above about 95 are
@@ -101,12 +119,68 @@ values below about 25 generate 2-byte quantization tables, which are
considered optional in the JPEG standard.
.B cjpeg
emits a warning message when you give such a quality value, because some
commercial JPEG programs may be unable to decode the resulting file. Use
other JPEG programs may be unable to decode the resulting file. Use
.B \-baseline
if you need to ensure compatibility at low quality values.)
.PP
The
.B \-quality
option has been extended in IJG version 7 for support of separate quality
settings for luminance and chrominance (or in general, for every provided
quantization table slot). This feature is useful for high-quality
applications which cannot accept the damage of color data by coarse
subsampling settings. You can now easily reduce the color data amount more
smoothly with finer control without separate subsampling. The resulting file
is fully compliant with standard JPEG decoders.
Note that the
.B \-quality
ratings refer to the quantization table slots, and that the last value is
replicated if there are more q-table slots than parameters. The default
q-table slots are 0 for luminance and 1 for chrominance with default tables as
given in the JPEG standard. This is compatible with the old behaviour in case
that only one parameter is given, which is then used for both luminance and
chrominance (slots 0 and 1). More or custom quantization tables can be set
with
.B \-qtables
and assigned to components with
.B \-qslots
parameter (see the "wizard" switches below).
.B Caution:
You must explicitly add
.BI \-sample " 1x1"
for efficient separate color
quality selection, since the default value used by library is 2x2!
.PP
The
.B \-progressive
switch creates a "progressive JPEG" file. In this type of JPEG file, the data
is stored in multiple scans of increasing quality. If the file is being
transmitted over a slow communications link, the decoder can use the first
scan to display a low-quality image very quickly, and can then improve the
display with each subsequent scan. The final image is exactly equivalent to a
standard JPEG file of the same quality setting, and the total file size is
about the same --- often a little smaller.
.PP
Switches for advanced users:
.TP
.B \-arithmetic
Use arithmetic coding.
.B Caution:
arithmetic coded JPEG is not yet widely implemented, so many decoders will be
unable to view an arithmetic coded JPEG file at all.
.TP
.BI \-block " N"
Set DCT block size. All N from 1 to 16 are possible.
Default is 8 (baseline format).
Larger values produce higher compression,
smaller values produce higher quality
(exact DCT stage possible with 1 or 2; with the default quality of 75 and
default Luminance qtable the DCT+Quantization stage is lossless for N=1).
.B Caution:
An implementation of the JPEG SmartScale extension is required for this
feature. SmartScale enabled JPEG is not yet widely implemented, so many
decoders will be unable to view a SmartScale extended JPEG file at all.
.TP
.B \-dct int
Use integer DCT method (default).
.TP
@@ -121,6 +195,9 @@ note that results of the floating-point method may vary slightly across
machines, while the integer methods should give the same results everywhere.
The fast integer method is much less accurate than the other two.
.TP
.B \-nosmooth
Don't use high-quality downsampling.
.TP
.BI \-restart " N"
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
attached to the number.
@@ -164,49 +241,38 @@ for images that will be transmitted across unreliable networks such as Usenet.
The
.B \-smooth
option filters the input to eliminate fine-scale noise. This is often useful
when converting GIF files to JPEG: a moderate smoothing factor of 10 to 50
gets rid of dithering patterns in the input file, resulting in a smaller JPEG
file and a better-looking image. Too large a smoothing factor will visibly
blur the image, however.
when converting dithered images to JPEG: a moderate smoothing factor of 10 to
50 gets rid of dithering patterns in the input file, resulting in a smaller
JPEG file and a better-looking image. Too large a smoothing factor will
visibly blur the image, however.
.PP
Switches for wizards:
.TP
.B \-arithmetic
Use arithmetic coding rather than Huffman coding. (Not currently
supported for legal reasons.)
.TP
.B \-baseline
Force a baseline JPEG file to be generated. This clamps quantization values
to 8 bits even at low quality settings.
.TP
.B \-nointerleave
Generate noninterleaved JPEG file (not yet supported).
Force baseline-compatible quantization tables to be generated. This clamps
quantization values to 8 bits even at low quality settings. (This switch is
poorly named, since it does not ensure that the output is actually baseline
JPEG. For example, you can use
.B \-baseline
and
.B \-progressive
together.)
.TP
.BI \-qtables " file"
Use the quantization tables given in the specified file. The file should
contain one to four tables (64 values each) as plain text. Comments preceded
by '#' may be included in the file. The tables are implicitly numbered
0,1,etc. If
.BI \-quality " N"
is also specified, the values in the file are scaled according to
.BR cjpeg 's
quality scaling curve.
Use the quantization tables given in the specified text file.
.TP
.BI \-qslots " N[,...]"
Select which quantization table to use for each color component. By default,
table 0 is used for luminance and table 1 for chrominance components.
Select which quantization table to use for each color component.
.TP
.BI \-sample " HxV[,...]"
Set JPEG sampling factors. If you specify fewer H/V pairs than there are
components, the remaining components are set to 1x1 sampling. The default
setting is equivalent to \fB\-sample 2x2\fR.
Set JPEG sampling factors for each color component.
.TP
.BI \-scans " file"
Use the scan script given in the specified text file.
.PP
The "wizard" switches are intended for experimentation with JPEG. If you
don't know what you are doing, \fBdon't use them\fR. You can easily produce
files with worse image quality and/or poorer compression than you'll get from
the default settings. Furthermore, these switches should not be used when
making files intended for general use, because not all JPEG implementations
will support unusual JPEG parameter settings.
don't know what you are doing, \fBdon't use them\fR. These switches are
documented further in the file wizard.txt.
.SH EXAMPLES
.LP
This example compresses the PPM file foo.ppm with a quality factor of
@@ -243,7 +309,9 @@ option to
is worth using when you are making a "final" version for posting or archiving.
It's also a win when you are using low quality settings to make very small
JPEG files; the percentage improvement is often a lot more than it is on
larger files.
larger files. (At present,
.B \-optimize
mode is always selected when generating progressive JPEG files.)
.SH ENVIRONMENT
.TP
.B JPEGMEM
@@ -257,6 +325,7 @@ itself is overridden by an explicit
.BR \-maxmemory .
.SH SEE ALSO
.BR djpeg (1),
.BR jpegtran (1),
.BR rdjpgcom (1),
.BR wrjpgcom (1)
.br
@@ -268,7 +337,8 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
Arithmetic coding is not supported for legal reasons.
GIF input files are no longer supported, to avoid the Unisys LZW patent.
(Conversion of GIF files to JPEG is usually a bad idea anyway.)
.PP
Not all variants of BMP and Targa file formats are supported.
.PP
@@ -276,5 +346,3 @@ The
.B \-targa
switch is not a bug, it's a feature. (It would be a bug if the Targa format
designers had not been clueless.)
.PP
Still not as fast as we'd like.

484
cjpeg.c
View File

@@ -1,7 +1,8 @@
/*
* cjpeg.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -26,51 +27,16 @@
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include <ctype.h> /* to declare isupper(), tolower() */
#ifdef NEED_SIGNAL_CATCHER
#include <signal.h> /* to declare signal() */
#endif
#ifdef USE_SETMODE
#include <fcntl.h> /* to declare setmode()'s parameter macros */
/* If you have setmode() but not <io.h>, just delete this line: */
#include <io.h> /* to declare setmode() */
#endif
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks declares it here */
#include <SIOUX.h> /* Metrowerks needs this */
#include <console.h> /* ... and this */
#endif
#ifdef THINK_C
#include <console.h> /* Think declares it here */
#endif
#endif
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#define WRITE_BINARY "w"
#else
#define READ_BINARY "rb"
#define WRITE_BINARY "wb"
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#ifdef VMS
#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
#else
#define EXIT_SUCCESS 0
#endif
#endif
#ifndef EXIT_WARNING
#ifdef VMS
#define EXIT_WARNING 1 /* VMS is very nonstandard */
#else
#define EXIT_WARNING 2
#endif
#endif
/* Create the add-on message string table. */
@@ -111,7 +77,7 @@ static const char * const cdjpeg_message_table[] = {
static boolean is_targa; /* records user -targa switch */
LOCAL cjpeg_source_ptr
LOCAL(cjpeg_source_ptr)
select_file_type (j_compress_ptr cinfo, FILE * infile)
{
int c;
@@ -159,59 +125,6 @@ select_file_type (j_compress_ptr cinfo, FILE * infile)
}
/*
* Signal catcher to ensure that temporary files are removed before aborting.
* NB: for Amiga Manx C this is actually a global routine named _abort();
* we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus...
*/
#ifdef NEED_SIGNAL_CATCHER
static j_common_ptr sig_cinfo;
GLOBAL void
signal_catcher (int signum)
{
if (sig_cinfo != NULL) {
if (sig_cinfo->err != NULL) /* turn off trace output */
sig_cinfo->err->trace_level = 0;
jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */
}
exit(EXIT_FAILURE);
}
#endif
/*
* Optional routine to display a percent-done figure on stderr.
*/
#ifdef PROGRESS_REPORT
METHODDEF void
progress_monitor (j_common_ptr cinfo)
{
cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress;
int total_passes = prog->pub.total_passes + prog->total_extra_passes;
int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit);
if (percent_done != prog->percent_done) {
prog->percent_done = percent_done;
if (total_passes > 1) {
fprintf(stderr, "\rPass %d/%d: %3d%% ",
prog->pub.completed_passes + prog->completed_extra_passes + 1,
total_passes, percent_done);
} else {
fprintf(stderr, "\r %3d%% ", percent_done);
}
fflush(stderr);
}
}
#endif
/*
* Argument-parsing code.
* The switch parser is designed to be useful with DOS-style command line
@@ -225,7 +138,7 @@ static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */
LOCAL void
LOCAL(void)
usage (void)
/* complain about bad command line */
{
@@ -237,15 +150,28 @@ usage (void)
#endif
fprintf(stderr, "Switches (names may be abbreviated):\n");
fprintf(stderr, " -quality N Compression quality (0..100; 5-95 is useful range)\n");
fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is useful range)\n");
fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
fprintf(stderr, " -rgb Create RGB JPEG file\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
#ifdef DCT_SCALING_SUPPORTED
fprintf(stderr, " -scale M/N Scale image by fraction M/N, eg, 1/2\n");
#endif
#ifdef TARGA_SUPPORTED
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
#endif
fprintf(stderr, "Switches for advanced users:\n");
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
#ifdef DCT_SCALING_SUPPORTED
fprintf(stderr, " -block N DCT block size (1..16; default is 8)\n");
#endif
#ifdef DCT_ISLOW_SUPPORTED
fprintf(stderr, " -dct int Use integer DCT method%s\n",
(JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
@@ -258,6 +184,7 @@ usage (void)
fprintf(stderr, " -dct float Use floating-point DCT method%s\n",
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif
fprintf(stderr, " -nosmooth Don't use high-quality downsampling\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
#ifdef INPUT_SMOOTHING_SUPPORTED
fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
@@ -266,217 +193,18 @@ usage (void)
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
fprintf(stderr, " -baseline Force baseline output\n");
#ifdef C_MULTISCAN_FILES_SUPPORTED
fprintf(stderr, " -nointerleave Create noninterleaved JPEG file\n");
#endif
fprintf(stderr, " -baseline Force baseline quantization tables\n");
fprintf(stderr, " -qtables file Use quantization tables given in file\n");
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
#ifdef C_MULTISCAN_FILES_SUPPORTED
fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n");
#endif
exit(EXIT_FAILURE);
}
LOCAL boolean
keymatch (char * arg, const char * keyword, int minchars)
/* Case-insensitive matching of (possibly abbreviated) keyword switches. */
/* keyword is the constant keyword (must be lower case already), */
/* minchars is length of minimum legal abbreviation. */
{
register int ca, ck;
register int nmatched = 0;
while ((ca = *arg++) != '\0') {
if ((ck = *keyword++) == '\0')
return FALSE; /* arg longer than keyword, no good */
if (isupper(ca)) /* force arg to lcase (assume ck is already) */
ca = tolower(ca);
if (ca != ck)
return FALSE; /* no good */
nmatched++; /* count matched characters */
}
/* reached end of argument; fail if it's too short for unique abbrev */
if (nmatched < minchars)
return FALSE;
return TRUE; /* A-OK */
}
LOCAL int
qt_getc (FILE * file)
/* Read next char, skipping over any comments (# to end of line) */
/* A comment/newline sequence is returned as a newline */
{
register int ch;
ch = getc(file);
if (ch == '#') {
do {
ch = getc(file);
} while (ch != '\n' && ch != EOF);
}
return ch;
}
LOCAL long
read_qt_integer (FILE * file)
/* Read an unsigned decimal integer from a quantization-table file */
/* Swallows one trailing character after the integer */
{
register int ch;
register long val;
/* Skip any leading whitespace, detect EOF */
do {
ch = qt_getc(file);
if (ch == EOF)
return EOF;
} while (isspace(ch));
if (! isdigit(ch)) {
fprintf(stderr, "%s: bogus data in quantization file\n", progname);
exit(EXIT_FAILURE);
}
val = ch - '0';
while (ch = qt_getc(file), isdigit(ch)) {
val *= 10;
val += ch - '0';
}
return val;
}
LOCAL void
read_quant_tables (j_compress_ptr cinfo, char * filename, int scale_factor,
boolean force_baseline)
/* Read a set of quantization tables from the specified file.
* The file is plain ASCII text: decimal numbers with whitespace between.
* Comments preceded by '#' may be included in the file.
* There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values.
* The tables are implicitly numbered 0,1,etc.
* NOTE: does not affect the qslots mapping, which will default to selecting
* table 0 for luminance (or primary) components, 1 for chrominance components.
* You must use -qslots if you want a different component->table mapping.
*/
{
/* ZIG[i] is the zigzag-order position of the i'th element of a DCT block */
/* read in natural order (left to right, top to bottom). */
static const int ZIG[DCTSIZE2] = {
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
FILE * fp;
int tblno, i;
long val;
unsigned int table[DCTSIZE2];
if ((fp = fopen(filename, "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", progname, filename);
exit(EXIT_FAILURE);
}
tblno = 0;
while ((val = read_qt_integer(fp)) != EOF) { /* read 1st element of table */
if (tblno >= NUM_QUANT_TBLS) {
fprintf(stderr, "%s: too many tables in file %s\n", progname, filename);
exit(EXIT_FAILURE);
}
table[0] = (unsigned int) val;
for (i = 1; i < DCTSIZE2; i++) {
if ((val = read_qt_integer(fp)) == EOF) {
fprintf(stderr, "%s: incomplete table in file %s\n", progname, filename);
exit(EXIT_FAILURE);
}
table[ZIG[i]] = (unsigned int) val;
}
jpeg_add_quant_table(cinfo, tblno, table, scale_factor, force_baseline);
tblno++;
}
fclose(fp);
}
LOCAL void
set_quant_slots (j_compress_ptr cinfo, char *arg)
/* Process a quantization-table-selectors parameter string, of the form
* N[,N,...]
* If there are more components than parameters, the last value is replicated.
*/
{
int val = 0; /* default table # */
int ci;
char ch;
for (ci = 0; ci < MAX_COMPONENTS; ci++) {
if (*arg) {
ch = ','; /* if not set by sscanf, will be ',' */
if (sscanf(arg, "%d%c", &val, &ch) < 1)
usage();
if (ch != ',')
usage(); /* syntax check */
if (val < 0 || val >= NUM_QUANT_TBLS) {
fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
NUM_QUANT_TBLS-1);
exit(EXIT_FAILURE);
}
cinfo->comp_info[ci].quant_tbl_no = val;
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
;
} else {
/* reached end of parameter, set remaining components to last table */
cinfo->comp_info[ci].quant_tbl_no = val;
}
}
}
LOCAL void
set_sample_factors (j_compress_ptr cinfo, char *arg)
/* Process a sample-factors parameter string, of the form
* HxV[,HxV,...]
* If there are more components than parameters, "1x1" is assumed.
*/
{
int ci, val1, val2;
char ch1, ch2;
for (ci = 0; ci < MAX_COMPONENTS; ci++) {
if (*arg) {
ch2 = ','; /* if not set by sscanf, will be ',' */
if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
usage();
if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',')
usage(); /* syntax check */
if (val1 <= 0 || val1 > 4 || val2 <= 0 || val2 > 4) {
fprintf(stderr, "JPEG sampling factors must be 1..4\n");
exit(EXIT_FAILURE);
}
cinfo->comp_info[ci].h_samp_factor = val1;
cinfo->comp_info[ci].v_samp_factor = val2;
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
;
} else {
/* reached end of parameter, set remaining components to 1x1 sampling */
cinfo->comp_info[ci].h_samp_factor = 1;
cinfo->comp_info[ci].v_samp_factor = 1;
}
}
}
LOCAL int
LOCAL(int)
parse_switches (j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
/* Parse optional switches.
@@ -490,20 +218,18 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
{
int argn;
char * arg;
int quality; /* -quality parameter */
int q_scale_factor; /* scaling percentage for -qtables */
boolean force_baseline;
boolean simple_progressive;
char * qualityarg = NULL; /* saves -quality parm if any */
char * qtablefile = NULL; /* saves -qtables filename if any */
char * qslotsarg = NULL; /* saves -qslots parm if any */
char * samplearg = NULL; /* saves -sample parm if any */
char * scansarg = NULL; /* saves -scans parm if any */
/* Set up default JPEG parameters. */
/* Note that default -quality level need not, and does not,
* match the default scaling for an explicit -qtables argument.
*/
quality = 75; /* default -quality value */
q_scale_factor = 100; /* default to no scaling for -qtables */
force_baseline = FALSE; /* by default, allow 16-bit quantizers */
simple_progressive = FALSE;
is_targa = FALSE;
outfilename = NULL;
cinfo->err->trace_level = 0;
@@ -532,10 +258,29 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "baseline", 1)) {
/* Force baseline output (8-bit quantizer values). */
} else if (keymatch(arg, "baseline", 2)) {
/* Force baseline-compatible output (8-bit quantizer values). */
force_baseline = TRUE;
} else if (keymatch(arg, "block", 2)) {
/* Set DCT block size. */
#if defined DCT_SCALING_SUPPORTED && JPEG_LIB_VERSION_MAJOR >= 8 && \
(JPEG_LIB_VERSION_MAJOR > 8 || JPEG_LIB_VERSION_MINOR >= 3)
int val;
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d", &val) != 1)
usage();
if (val < 1 || val > 16)
usage();
cinfo->block_size = val;
#else
fprintf(stderr, "%s: sorry, block size setting not supported\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "dct", 2)) {
/* Select DCT algorithm. */
if (++argn >= argc) /* advance to next argument */
@@ -565,6 +310,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Force a monochrome JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
} else if (keymatch(arg, "rgb", 3)) {
/* Force an RGB JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_RGB);
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
long lval;
@@ -578,15 +327,9 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
lval *= 1000L;
cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "nointerleave", 3)) {
/* Create noninterleaved file. */
#ifdef C_MULTISCAN_FILES_SUPPORTED
cinfo->interleave = FALSE;
#else
fprintf(stderr, "%s: sorry, multiple-scan support was not compiled\n",
progname);
exit(EXIT_FAILURE);
#endif
} else if (keymatch(arg, "nosmooth", 3)) {
/* Suppress fancy downsampling */
cinfo->do_fancy_downsampling = FALSE;
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
/* Enable entropy parm optimization. */
@@ -604,14 +347,22 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
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, "quality", 1)) {
/* Quality factor (quantization table scaling factor). */
/* Quality ratings (quantization table scaling factors). */
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d", &quality) != 1)
usage();
/* Change scale factor in case -qtables is present. */
q_scale_factor = jpeg_quality_scaling(quality);
qualityarg = argv[argn];
} else if (keymatch(arg, "qslots", 2)) {
/* Quantization table slot numbers. */
@@ -659,6 +410,27 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
* default sampling factors.
*/
} else if (keymatch(arg, "scale", 4)) {
/* Scale the image by a fraction M/N. */
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d/%d",
&cinfo->scale_num, &cinfo->scale_denom) != 2)
usage();
} else if (keymatch(arg, "scans", 4)) {
/* 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, "smooth", 2)) {
/* Set input smoothing factor. */
int val;
@@ -686,17 +458,32 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Set quantization tables for selected quality. */
/* Some or all may be overridden if -qtables is present. */
jpeg_set_quality(cinfo, quality, force_baseline);
if (qualityarg != NULL) /* process -quality if it was present */
if (! set_quality_ratings(cinfo, qualityarg, force_baseline))
usage();
if (qtablefile != NULL) /* process -qtables if it was present */
read_quant_tables(cinfo, qtablefile, q_scale_factor, force_baseline);
if (! read_quant_tables(cinfo, qtablefile, force_baseline))
usage();
if (qslotsarg != NULL) /* process -qslots if it was present */
set_quant_slots(cinfo, qslotsarg);
if (! set_quant_slots(cinfo, qslotsarg))
usage();
if (samplearg != NULL) /* process -sample if it was present */
set_sample_factors(cinfo, samplearg);
if (! set_sample_factors(cinfo, samplearg))
usage();
#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) */
@@ -707,7 +494,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
* The main program.
*/
GLOBAL int
int
main (int argc, char **argv)
{
struct jpeg_compress_struct cinfo;
@@ -740,11 +527,7 @@ main (int argc, char **argv)
/* Now safe to enable signal catcher. */
#ifdef NEED_SIGNAL_CATCHER
sig_cinfo = (j_common_ptr) &cinfo;
signal(SIGINT, signal_catcher);
#ifdef SIGTERM /* not all systems have SIGTERM */
signal(SIGTERM, signal_catcher);
#endif
enable_signal_catcher((j_common_ptr) &cinfo);
#endif
/* Initialize JPEG parameters.
@@ -796,17 +579,7 @@ main (int argc, char **argv)
}
} else {
/* default input file is stdin */
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdin), O_BINARY);
#endif
#ifdef USE_FDOPEN /* need to re-open in binary mode? */
if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open stdin\n", progname);
exit(EXIT_FAILURE);
}
#else
input_file = stdin;
#endif
input_file = read_stdin();
}
/* Open the output file. */
@@ -817,28 +590,11 @@ main (int argc, char **argv)
}
} else {
/* default output file is stdout */
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdout), O_BINARY);
#endif
#ifdef USE_FDOPEN /* need to re-open in binary mode? */
if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open stdout\n", progname);
exit(EXIT_FAILURE);
}
#else
output_file = stdout;
#endif
output_file = write_stdout();
}
#ifdef PROGRESS_REPORT
/* Enable progress display, unless trace output is on */
if (jerr.trace_level == 0) {
progress.pub.progress_monitor = progress_monitor;
progress.completed_extra_passes = 0;
progress.total_extra_passes = 0;
progress.percent_done = -1;
cinfo.progress = &progress.pub;
}
start_progress_monitor((j_common_ptr) &cinfo, &progress);
#endif
/* Figure out the input file format, and set up to read it. */
@@ -878,11 +634,7 @@ main (int argc, char **argv)
fclose(output_file);
#ifdef PROGRESS_REPORT
/* Clear away progress display */
if (jerr.trace_level == 0) {
fprintf(stderr, "\r \r");
fflush(stderr);
}
end_progress_monitor((j_common_ptr) &cinfo);
#endif
/* All done. */

View File

@@ -301,7 +301,7 @@ int main (argc, argv)
/* Write out all the info */
fprintf(outfile, "/* jconfig.h --- generated by ckconfig.c */\n");
fprintf(outfile, "/* see jconfig.doc for explanations */\n\n");
fprintf(outfile, "/* see jconfig.txt for explanations */\n\n");
#ifdef HAVE_PROTOTYPES
fprintf(outfile, "#define HAVE_PROTOTYPES\n");
#else

View File

@@ -1,6 +1,6 @@
IJG JPEG LIBRARY: CODING RULES
Copyright (C) 1991-1994, Thomas G. Lane.
Copyright (C) 1991-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.
@@ -43,17 +43,17 @@ ansi2knr is not very bright, so it imposes a format requirement on function
declarations: the function name MUST BEGIN IN COLUMN 1. Thus all functions
should be written in the following style:
LOCAL int *
LOCAL(int *)
function_name (int a, char *b)
{
code...
}
Note that each function definition is prefixed with GLOBAL, LOCAL, or
METHODDEF. These macros expand to "static" or nothing as appropriate.
They provide a readable indication of the routine's usage and can readily be
changed for special needs. (For instance, all routines can be made global for
use with debuggers or code profilers that require it.)
Note that each function definition must begin with GLOBAL(type), LOCAL(type),
or METHODDEF(type). These macros expand to "static type" or just "type" as
appropriate. They provide a readable indication of the routine's usage and
can readily be changed for special needs. (For instance, special linkage
keywords can be inserted for use in Windows DLLs.)
ansi2knr does not transform method declarations (function pointers in
structs). We handle these with a macro JMETHOD, defined as
@@ -69,8 +69,8 @@ which is used like this:
};
Note the set of parentheses surrounding the parameter list.
A similar solution is used for external function declarations (see the JPP
macro).
A similar solution is used for forward and external function declarations
(see the EXTERN and JPP macros).
If the code is to work on non-ANSI compilers, we cannot rely on a prototype
declaration to coerce actual parameters into the right types. Therefore, use
@@ -103,7 +103,7 @@ should be in the common data structures.
4. Don't use static variables except for read-only constant tables. Variables
that should be private to a module can be placed into private structures (see
the system architecture document, structure.doc).
the system architecture document, structure.txt).
5. Source file names should begin with "j" for files that are part of the
library proper; source files that are not part of the library, such as cjpeg.c

1522
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1771
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

16370
configure vendored

File diff suppressed because it is too large Load Diff

356
configure.ac Normal file
View File

@@ -0,0 +1,356 @@
# IJG auto-configuration source file.
# Process this file with autoconf to produce a configure script.
#
# Configure script for IJG libjpeg
#
AC_INIT([libjpeg], [8.4.0])
# Directory where autotools helper scripts lives.
AC_CONFIG_AUX_DIR([.])
# Generate configuration headers.
AC_CONFIG_HEADERS([jconfig.h:jconfig.cfg])
# Hack: disable autoheader so that it doesn't overwrite our cfg template.
AUTOHEADER="echo autoheader ignored"
# Check system type
AC_CANONICAL_TARGET
# Initialize Automake
# Don't require all the GNU mandated files
AM_INIT_AUTOMAKE([-Wall -Werror -Wno-obsolete ansi2knr no-dist foreign])
# Make --enable-silent-rules the default.
# To get verbose build output you may configure
# with --disable-silent-rules or use "make V=1".
AM_SILENT_RULES([yes])
# This is required when using the de-ANSI-fication feature.
AM_C_PROTOTYPES
# Add configure option --enable-maintainer-mode which enables
# dependency checking and generation useful to package maintainers.
# This is made an option to avoid confusing end users.
AM_MAINTAINER_MODE
# Check for programs
AC_PROG_CC
AC_PROG_CC_STDC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_LN_S
# Check if LD supports linker scripts,
# and define automake conditional HAVE_LD_VERSION_SCRIPT if so.
AC_ARG_ENABLE([ld-version-script],
AS_HELP_STRING([--enable-ld-version-script],
[enable linker version script (default is enabled when possible)]),
[have_ld_version_script=$enableval], [])
if test -z "$have_ld_version_script"; then
AC_MSG_CHECKING([if LD -Wl,--version-script works])
save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
cat > conftest.map <<EOF
VERS_1 {
global: sym;
};
VERS_2 {
global: sym;
} VERS_1;
EOF
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
[have_ld_version_script=yes], [have_ld_version_script=no])
rm -f conftest.map
LDFLAGS="$save_LDFLAGS"
AC_MSG_RESULT($have_ld_version_script)
fi
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
# See if compiler supports prototypes.
AC_MSG_CHECKING([for function prototypes])
AC_CACHE_VAL([ijg_cv_have_prototypes],
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
int testfunction (int arg1, int * arg2); /* check prototypes */
struct methods_struct { /* check method-pointer declarations */
int (*error_exit) (char *msgtext);
int (*trace_message) (char *msgtext);
int (*another_method) (void);
};
int testfunction (int arg1, int * arg2) /* check definitions */
{ return arg2[arg1]; }
int test2function (void) /* check void arg list */
{ return 0; }
]])],
[ijg_cv_have_prototypes=yes],
[ijg_cv_have_prototypes=no])])
AC_MSG_RESULT([$ijg_cv_have_prototypes])
if test $ijg_cv_have_prototypes = yes; then
AC_DEFINE([HAVE_PROTOTYPES],[1],[Compiler supports function prototypes.])
else
AC_MSG_WARN([Your compiler does not seem to know about function prototypes.
Perhaps it needs a special switch to enable ANSI C mode.
If so, we recommend running configure like this:
./configure CC='cc -switch'
where -switch is the proper switch.])
fi
# Check header files
AC_CHECK_HEADERS([stddef.h stdlib.h locale.h])
AC_CHECK_HEADER([string.h], [],
[AC_DEFINE([NEED_BSD_STRINGS], [1],
[Compiler has <strings.h> rather than standard <string.h>.])])
# See whether type size_t is defined in any ANSI-standard places;
# if not, perhaps it is defined in <sys/types.h>.
AC_MSG_CHECKING([for size_t])
AC_TRY_COMPILE([
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdio.h>
#ifdef NEED_BSD_STRINGS
#include <strings.h>
#else
#include <string.h>
#endif
typedef size_t my_size_t;
],
[ my_size_t foovar; ],
[ijg_size_t_ok=yes],
[ijg_size_t_ok="not ANSI, perhaps it is in sys/types.h"])
AC_MSG_RESULT([$ijg_size_t_ok])
if test "$ijg_size_t_ok" != yes; then
AC_CHECK_HEADER([sys/types.h],
[AC_DEFINE([NEED_SYS_TYPES_H], [1],
[Need to include <sys/types.h> in order to obtain size_t.])
AC_EGREP_CPP([size_t], [#include <sys/types.h>],
[ijg_size_t_ok="size_t is in sys/types.h"],
[ijg_size_t_ok=no])],
[ijg_size_t_ok=no])
AC_MSG_RESULT([$ijg_size_t_ok])
if test "$ijg_size_t_ok" = no; then
AC_MSG_WARN([Type size_t is not defined in any of the usual places.
Try putting '"typedef unsigned int size_t;"' in jconfig.h.])
fi
fi
# Check compiler characteristics
AC_MSG_CHECKING([for type unsigned char])
AC_TRY_COMPILE([], [ unsigned char un_char; ],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_UNSIGNED_CHAR], [1],
[Compiler supports 'unsigned char'.])],
[AC_MSG_RESULT(no)])
AC_MSG_CHECKING([for type unsigned short])
AC_TRY_COMPILE([], [ unsigned short un_short; ],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_UNSIGNED_SHORT], [1],
[Compiler supports 'unsigned short'.])],
[AC_MSG_RESULT(no)])
AC_MSG_CHECKING([for type void])
AC_TRY_COMPILE([
/* Caution: a C++ compiler will insist on valid prototypes */
typedef void * void_ptr; /* check void * */
#ifdef HAVE_PROTOTYPES /* check ptr to function returning void */
typedef void (*void_func) (int a, int b);
#else
typedef void (*void_func) ();
#endif
#ifdef HAVE_PROTOTYPES /* check void function result */
void test3function (void_ptr arg1, void_func arg2)
#else
void test3function (arg1, arg2)
void_ptr arg1;
void_func arg2;
#endif
{
char * locptr = (char *) arg1; /* check casting to and from void * */
arg1 = (void *) locptr;
(*arg2) (1, 2); /* check call of fcn returning void */
}
], [ ],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)
AC_DEFINE([void], [char],
[Define 'void' as 'char' for archaic compilers
that don't understand it.])])
AC_C_CONST
# Check for non-broken inline under various spellings
AC_MSG_CHECKING([for inline])
ijg_cv_inline=""
AC_TRY_COMPILE([], [} __inline__ int foo() { return 0; }
int bar() { return foo();], ijg_cv_inline="__inline__",
[AC_TRY_COMPILE(, [} __inline int foo() { return 0; }
int bar() { return foo();], ijg_cv_inline="__inline",
[AC_TRY_COMPILE(, [} inline int foo() { return 0; }
int bar() { return foo();], ijg_cv_inline="inline")])])
AC_MSG_RESULT($ijg_cv_inline)
AC_DEFINE_UNQUOTED([INLINE], [$ijg_cv_inline],
[How to obtain function inlining.])
# We cannot check for bogus warnings, but at least we can check for errors
AC_MSG_CHECKING([for broken incomplete types])
AC_TRY_COMPILE([ typedef struct undefined_structure * undef_struct_ptr; ],
[],
[AC_MSG_RESULT(ok)],
[AC_MSG_RESULT(broken)
AC_DEFINE([INCOMPLETE_TYPES_BROKEN], [1],
[Compiler does not support pointers to unspecified
structures.])])
# Test whether global names are unique to at least 15 chars
AC_MSG_CHECKING([for short external names])
AC_TRY_LINK([
int possibly_duplicate_function () { return 0; }
int possibly_dupli_function () { return 1; }
], [],
[AC_MSG_RESULT(ok)],
[AC_MSG_RESULT(short)
AC_DEFINE([NEED_SHORT_EXTERNAL_NAMES], [1],
[Linker requires that global names be unique in
first 15 characters.])])
# Run-time checks
AC_MSG_CHECKING([to see if char is signed])
AC_TRY_RUN([
#ifdef HAVE_PROTOTYPES
int is_char_signed (int arg)
#else
int is_char_signed (arg)
int arg;
#endif
{
if (arg == 189) { /* expected result for unsigned char */
return 0; /* type char is unsigned */
}
else if (arg != -67) { /* expected result for signed char */
printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n");
printf("I fear the JPEG software will not work at all.\n\n");
}
return 1; /* assume char is signed otherwise */
}
char signed_char_check = (char) (-67);
int main() {
exit(is_char_signed((int) signed_char_check));
}], [AC_MSG_RESULT(no)
AC_DEFINE([CHAR_IS_UNSIGNED], [1],
[Characters are unsigned])],
[AC_MSG_RESULT(yes)],
[AC_MSG_WARN([Assuming that char is signed on target machine.
If it is unsigned, this will be a little bit inefficient.])
])
AC_MSG_CHECKING([to see if right shift is signed])
AC_TRY_RUN([
#ifdef HAVE_PROTOTYPES
int is_shifting_signed (long arg)
#else
int is_shifting_signed (arg)
long arg;
#endif
/* See whether right-shift on a long is signed or not. */
{
long res = arg >> 4;
if (res == -0x7F7E80CL) { /* expected result for signed shift */
return 1; /* right shift is signed */
}
/* see if unsigned-shift hack will fix it. */
/* we can't just test exact value since it depends on width of long... */
res |= (~0L) << (32-4);
if (res == -0x7F7E80CL) { /* expected result now? */
return 0; /* right shift is unsigned */
}
printf("Right shift isn't acting as I expect it to.\n");
printf("I fear the JPEG software will not work at all.\n\n");
return 0; /* try it with unsigned anyway */
}
int main() {
exit(is_shifting_signed(-0x7F7E80B1L));
}],
[AC_MSG_RESULT(no)
AC_DEFINE([RIGHT_SHIFT_IS_UNSIGNED], [1],
[Broken compiler shifts signed values as an unsigned shift.])],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(Assuming that right shift is signed on target machine.)])
AC_MSG_CHECKING([to see if fopen accepts b spec])
AC_TRY_RUN([
#include <stdio.h>
int main() {
if (fopen("conftestdata", "wb") != NULL)
exit(0);
exit(1);
}],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)
AC_DEFINE([DONT_USE_B_MODE], [1],
[Don't open files in binary mode.])],
[AC_MSG_RESULT(Assuming that it does.)])
# Configure libtool
AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
# Select memory manager depending on user input.
# If no "-enable-maxmem", use jmemnobs
MEMORYMGR='jmemnobs'
MAXMEM="no"
AC_ARG_ENABLE([maxmem],
[ --enable-maxmem[=N] enable use of temp files, set max mem usage to N MB],
[MAXMEM="$enableval"])
dnl [# support --with-maxmem for backwards compatibility with IJG V5.]
dnl AC_ARG_WITH(maxmem, , MAXMEM="$withval")
if test "x$MAXMEM" = xyes; then
MAXMEM=1
fi
if test "x$MAXMEM" != xno; then
if test -n "`echo $MAXMEM | sed 's/[[0-9]]//g'`"; then
AC_MSG_ERROR(non-numeric argument to --enable-maxmem)
fi
DEFAULTMAXMEM=`expr $MAXMEM \* 1048576`
AC_DEFINE_UNQUOTED([DEFAULT_MAX_MEM], [${DEFAULTMAXMEM}],
[Maximum data space library will allocate.])
AC_MSG_CHECKING([for 'tmpfile()'])
AC_TRY_LINK([#include <stdio.h>], [ FILE * tfile = tmpfile(); ],
[AC_MSG_RESULT(yes)
MEMORYMGR='jmemansi'],
[AC_MSG_RESULT(no)
dnl if tmpfile is not present, must use jmemname.
MEMORYMGR='jmemname'
# Test for the need to remove temporary files using a signal handler
# (for cjpeg/djpeg)
AC_DEFINE([NEED_SIGNAL_CATCHER], [1],
[Need signal handler to clean up temporary files.])
AC_MSG_CHECKING([for 'mktemp()'])
AC_TRY_LINK([], [ char fname[80]; mktemp(fname); ],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)
AC_DEFINE([NO_MKTEMP], [1],
[The mktemp() function is not available.])])])
fi
AC_SUBST([MEMORYMGR])
# Extract the library version IDs from jpeglib.h.
AC_MSG_CHECKING([libjpeg version number])
[major=`sed -ne 's/^#define JPEG_LIB_VERSION_MAJOR *\([0-9][0-9]*\).*$/\1/p' $srcdir/jpeglib.h`
minor=`sed -ne 's/^#define JPEG_LIB_VERSION_MINOR *\([0-9][0-9]*\).*$/\1/p' $srcdir/jpeglib.h`]
AC_SUBST([JPEG_LIB_VERSION],
[`expr $major + $minor`:0:$minor])
AC_MSG_RESULT([$JPEG_LIB_VERSION])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

688
depcomp Executable file
View File

@@ -0,0 +1,688 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2011-12-04.11; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
# 2011 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test "$stat" = 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/ \1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/ /
G
p
}' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

33
djpeg.1
View File

@@ -1,4 +1,4 @@
.TH DJPEG 1 "12 December 1994"
.TH DJPEG 1 "3 October 2009"
.SH NAME
djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS
@@ -26,9 +26,9 @@ or
.BR \-gr .
Most of the "basic" switches can be abbreviated to as little as one letter.
Upper and lower case are equivalent (thus
.B \-GIF
.B \-BMP
is the same as
.BR \-gif ).
.BR \-bmp ).
British spellings are also accepted (e.g.,
.BR \-greyscale ),
though for brevity these are not mentioned below.
@@ -61,9 +61,12 @@ monochrome displays; also,
runs noticeably faster in this mode.
.TP
.BI \-scale " M/N"
Scale the output image by a factor M/N. Currently the scale factor must be
1/1, 1/2, 1/4, or 1/8. Scaling is handy if the image is larger than your
screen; also,
Scale the output image by a factor M/N. Currently supported scale factors are
M/N with all M from 1 to 16, where N is the source DCT size, which is 8 for
baseline JPEG. If the /N part is omitted, then M specifies the DCT scaled
size to be applied on the given input. For baseline JPEG this is equivalent
to M/8 scaling, since the source DCT size for baseline JPEG is 8.
Scaling is handy if the image is larger than your screen; also,
.B djpeg
runs much faster when scaling down the output.
.TP
@@ -150,7 +153,7 @@ and
.BR \-onepass .
.TP
.B \-nosmooth
Use a faster, lower-quality upsampling routine.
Don't use high-quality upsampling.
.TP
.B \-onepass
Use one-pass instead of two-pass color quantization. The one-pass method is
@@ -182,13 +185,13 @@ Same as
.BR \-verbose .
.SH EXAMPLES
.LP
This example decompresses the JPEG file foo.jpg, automatically quantizes to
256 colors, and saves the output in GIF format in foo.gif:
This example decompresses the JPEG file foo.jpg, quantizes it to
256 colors, and saves the output in 8-bit BMP format in foo.bmp:
.IP
.B djpeg \-gif
.B djpeg \-colors 256 \-bmp
.I foo.jpg
.B >
.I foo.gif
.I foo.bmp
.SH HINTS
To get a quick preview of an image, use the
.B \-grayscale
@@ -231,6 +234,7 @@ itself is overridden by an explicit
.BR \-maxmemory .
.SH SEE ALSO
.BR cjpeg (1),
.BR jpegtran (1),
.BR rdjpgcom (1),
.BR wrjpgcom (1)
.br
@@ -242,6 +246,7 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
Arithmetic coding is not supported for legal reasons.
.PP
Still not as fast as we'd like.
To avoid the Unisys LZW patent,
.B djpeg
produces uncompressed GIF files. These are larger than they should be, but
are readable by standard GIF decoders.

205
djpeg.c
View File

@@ -1,7 +1,8 @@
/*
* djpeg.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -26,51 +27,18 @@
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include <ctype.h> /* to declare isupper(),tolower(),isprint() */
#ifdef NEED_SIGNAL_CATCHER
#include <signal.h> /* to declare signal() */
#endif
#ifdef USE_SETMODE
#include <fcntl.h> /* to declare setmode()'s parameter macros */
/* If you have setmode() but not <io.h>, just delete this line: */
#include <io.h> /* to declare setmode() */
#endif
#include <ctype.h> /* to declare isprint() */
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks declares it here */
#include <SIOUX.h> /* Metrowerks needs this */
#include <console.h> /* ... and this */
#endif
#ifdef THINK_C
#include <console.h> /* Think declares it here */
#endif
#endif
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#define WRITE_BINARY "w"
#else
#define READ_BINARY "rb"
#define WRITE_BINARY "wb"
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#ifdef VMS
#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
#else
#define EXIT_SUCCESS 0
#endif
#endif
#ifndef EXIT_WARNING
#ifdef VMS
#define EXIT_WARNING 1 /* VMS is very nonstandard */
#else
#define EXIT_WARNING 2
#endif
#endif
/* Create the add-on message string table. */
@@ -106,59 +74,6 @@ typedef enum {
static IMAGE_FORMATS requested_fmt;
/*
* Signal catcher to ensure that temporary files are removed before aborting.
* NB: for Amiga Manx C this is actually a global routine named _abort();
* we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus...
*/
#ifdef NEED_SIGNAL_CATCHER
static j_common_ptr sig_cinfo;
GLOBAL void
signal_catcher (int signum)
{
if (sig_cinfo != NULL) {
if (sig_cinfo->err != NULL) /* turn off trace output */
sig_cinfo->err->trace_level = 0;
jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */
}
exit(EXIT_FAILURE);
}
#endif
/*
* Optional routine to display a percent-done figure on stderr.
*/
#ifdef PROGRESS_REPORT
METHODDEF void
progress_monitor (j_common_ptr cinfo)
{
cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress;
int total_passes = prog->pub.total_passes + prog->total_extra_passes;
int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit);
if (percent_done != prog->percent_done) {
prog->percent_done = percent_done;
if (total_passes > 1) {
fprintf(stderr, "\rPass %d/%d: %3d%% ",
prog->pub.completed_passes + prog->completed_extra_passes + 1,
total_passes, percent_done);
} else {
fprintf(stderr, "\r %3d%% ", percent_done);
}
fflush(stderr);
}
}
#endif
/*
* Argument-parsing code.
* The switch parser is designed to be useful with DOS-style command line
@@ -172,7 +87,7 @@ static const char * progname; /* program name for error messages */
static char * outfilename; /* for -outfile switch */
LOCAL void
LOCAL(void)
usage (void)
/* complain about bad command line */
{
@@ -244,32 +159,7 @@ usage (void)
}
LOCAL boolean
keymatch (char * arg, const char * keyword, int minchars)
/* Case-insensitive matching of (possibly abbreviated) keyword switches. */
/* keyword is the constant keyword (must be lower case already), */
/* minchars is length of minimum legal abbreviation. */
{
register int ca, ck;
register int nmatched = 0;
while ((ca = *arg++) != '\0') {
if ((ck = *keyword++) == '\0')
return FALSE; /* arg longer than keyword, no good */
if (isupper(ca)) /* force arg to lcase (assume ck is already) */
ca = tolower(ca);
if (ca != ck)
return FALSE; /* no good */
nmatched++; /* count matched characters */
}
/* reached end of argument; fail if it's too short for unique abbrev */
if (nmatched < minchars)
return FALSE;
return TRUE; /* A-OK */
}
LOCAL int
LOCAL(int)
parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real)
/* Parse optional switches.
@@ -438,7 +328,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
if (++argn >= argc) /* advance to next argument */
usage();
if (sscanf(argv[argn], "%d/%d",
&cinfo->scale_num, &cinfo->scale_denom) != 2)
&cinfo->scale_num, &cinfo->scale_denom) < 1)
usage();
} else if (keymatch(arg, "targa", 1)) {
@@ -455,13 +345,13 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
/*
* Marker processor for COM markers.
* Marker processor for COM and interesting APPn markers.
* This replaces the library's built-in processor, which just skips the marker.
* We want to print out the marker as text, if possible.
* We want to print out the marker as text, to the extent possible.
* Note this code relies on a non-suspending data source.
*/
LOCAL unsigned int
LOCAL(unsigned int)
jpeg_getc (j_decompress_ptr cinfo)
/* Read next byte */
{
@@ -476,8 +366,8 @@ jpeg_getc (j_decompress_ptr cinfo)
}
METHODDEF boolean
COM_handler (j_decompress_ptr cinfo)
METHODDEF(boolean)
print_text_marker (j_decompress_ptr cinfo)
{
boolean traceit = (cinfo->err->trace_level >= 1);
INT32 length;
@@ -488,8 +378,13 @@ COM_handler (j_decompress_ptr cinfo)
length += jpeg_getc(cinfo);
length -= 2; /* discount the length word itself */
if (traceit)
if (traceit) {
if (cinfo->unread_marker == JPEG_COM)
fprintf(stderr, "Comment, length %ld:\n", (long) length);
else /* assume it is an APPn otherwise */
fprintf(stderr, "APP%d, length %ld:\n",
cinfo->unread_marker - JPEG_APP0, (long) length);
}
while (--length >= 0) {
ch = jpeg_getc(cinfo);
@@ -526,7 +421,7 @@ COM_handler (j_decompress_ptr cinfo)
* The main program.
*/
GLOBAL int
int
main (int argc, char **argv)
{
struct jpeg_decompress_struct cinfo;
@@ -556,16 +451,19 @@ main (int argc, char **argv)
jerr.addon_message_table = cdjpeg_message_table;
jerr.first_addon_message = JMSG_FIRSTADDONCODE;
jerr.last_addon_message = JMSG_LASTADDONCODE;
/* Insert custom COM marker processor. */
jpeg_set_marker_processor(&cinfo, JPEG_COM, COM_handler);
/* Insert custom marker processor for COM and APP12.
* APP12 is used by some digital camera makers for textual info,
* so we provide the ability to display it as text.
* If you like, additional APPn marker types can be selected for display,
* but don't try to override APP0 or APP14 this way (see libjpeg.doc).
*/
jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker);
jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker);
/* Now safe to enable signal catcher. */
#ifdef NEED_SIGNAL_CATCHER
sig_cinfo = (j_common_ptr) &cinfo;
signal(SIGINT, signal_catcher);
#ifdef SIGTERM /* not all systems have SIGTERM */
signal(SIGTERM, signal_catcher);
#endif
enable_signal_catcher((j_common_ptr) &cinfo);
#endif
/* Scan command line to find file names. */
@@ -610,17 +508,7 @@ main (int argc, char **argv)
}
} else {
/* default input file is stdin */
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdin), O_BINARY);
#endif
#ifdef USE_FDOPEN /* need to re-open in binary mode? */
if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open stdin\n", progname);
exit(EXIT_FAILURE);
}
#else
input_file = stdin;
#endif
input_file = read_stdin();
}
/* Open the output file. */
@@ -631,28 +519,11 @@ main (int argc, char **argv)
}
} else {
/* default output file is stdout */
#ifdef USE_SETMODE /* need to hack file mode? */
setmode(fileno(stdout), O_BINARY);
#endif
#ifdef USE_FDOPEN /* need to re-open in binary mode? */
if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open stdout\n", progname);
exit(EXIT_FAILURE);
}
#else
output_file = stdout;
#endif
output_file = write_stdout();
}
#ifdef PROGRESS_REPORT
/* Enable progress display, unless trace output is on */
if (jerr.trace_level == 0) {
progress.pub.progress_monitor = progress_monitor;
progress.completed_extra_passes = 0;
progress.total_extra_passes = 0;
progress.percent_done = -1;
cinfo.progress = &progress.pub;
}
start_progress_monitor((j_common_ptr) &cinfo, &progress);
#endif
/* Specify data source for decompression */
@@ -703,7 +574,7 @@ main (int argc, char **argv)
dest_mgr->output_file = output_file;
/* Start decompressor */
jpeg_start_decompress(&cinfo);
(void) jpeg_start_decompress(&cinfo);
/* Write output file header */
(*dest_mgr->start_output) (&cinfo, dest_mgr);
@@ -727,7 +598,7 @@ main (int argc, char **argv)
* of lifespan JPOOL_IMAGE; it needs to finish before releasing memory.
*/
(*dest_mgr->finish_output) (&cinfo, dest_mgr);
jpeg_finish_decompress(&cinfo);
(void) jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
/* Close files, if we opened them */
@@ -737,11 +608,7 @@ main (int argc, char **argv)
fclose(output_file);
#ifdef PROGRESS_REPORT
/* Clear away progress display */
if (jerr.trace_level == 0) {
fprintf(stderr, "\r \r");
fflush(stderr);
}
end_progress_monitor((j_common_ptr) &cinfo);
#endif
/* All done. */

View File

@@ -3,7 +3,7 @@
*
* This file illustrates how to use the IJG code as a subroutine library
* to read or write JPEG image files. You should look at this code in
* conjunction with the documentation file libjpeg.doc.
* conjunction with the documentation file libjpeg.txt.
*
* This code will not do anything useful as-is, but it may be helpful as a
* skeleton for constructing routines that call the JPEG library.
@@ -68,7 +68,7 @@ extern int image_width; /* Number of columns in image */
* and a compression quality factor are passed in.
*/
GLOBAL void
GLOBAL(void)
write_JPEG_file (char * filename, int quality)
{
/* This struct contains the JPEG compression parameters and pointers to
@@ -154,6 +154,10 @@ write_JPEG_file (char * filename, int quality)
row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height) {
/* jpeg_write_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could pass
* more than one scanline at a time if that's more convenient.
*/
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
@@ -188,11 +192,11 @@ write_JPEG_file (char * filename, int quality)
* (If you don't know what that's for, you don't need it.)
*
* If the compressor requires full-image buffers (for entropy-coding
* optimization or a noninterleaved JPEG file), it will create temporary
* optimization or a multi-scan JPEG file), it will create temporary
* files for anything that doesn't fit within the maximum-memory setting.
* (Note that temp files are NOT needed if you use the default parameters.)
* On some systems you may need to set up a signal handler to ensure that
* temporary files are deleted if the program is interrupted. See libjpeg.doc.
* temporary files are deleted if the program is interrupted. See libjpeg.txt.
*
* Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
* files to be compatible with everyone else's. If you cannot readily read
@@ -255,7 +259,7 @@ typedef struct my_error_mgr * my_error_ptr;
* Here's the routine that will replace the standard error_exit method:
*/
METHODDEF void
METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
@@ -276,7 +280,7 @@ my_error_exit (j_common_ptr cinfo)
*/
GLOBAL int
GLOBAL(int)
read_JPEG_file (char * filename)
{
/* This struct contains the JPEG decompression parameters and pointers to
@@ -331,7 +335,7 @@ read_JPEG_file (char * filename)
/* We can ignore the return value from jpeg_read_header since
* (a) suspension is not possible with the stdio data source, and
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
* See libjpeg.doc for more info.
* See libjpeg.txt for more info.
*/
/* Step 4: set parameters for decompression */
@@ -342,7 +346,10 @@ read_JPEG_file (char * filename)
/* Step 5: Start decompressor */
jpeg_start_decompress(&cinfo);
(void) jpeg_start_decompress(&cinfo);
/* We can ignore the return value since suspension is not possible
* with the stdio data source.
*/
/* We may need to do some setup of our own at this point before reading
* the data. After jpeg_start_decompress() we have the correct scaled
@@ -363,6 +370,10 @@ read_JPEG_file (char * filename)
* loop counter, so that we don't have to keep track ourselves.
*/
while (cinfo.output_scanline < cinfo.output_height) {
/* jpeg_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient.
*/
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
/* Assume put_scanline_someplace wants a pointer and sample count. */
put_scanline_someplace(buffer[0], row_stride);
@@ -402,14 +413,14 @@ read_JPEG_file (char * filename)
* In the above code, we ignored the return value of jpeg_read_scanlines,
* which is the number of scanlines actually read. We could get away with
* this because we asked for only one line at a time and we weren't using
* a suspending data source. See libjpeg.doc for more info.
* a suspending data source. See libjpeg.txt for more info.
*
* We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
* we should have done it beforehand to ensure that the space would be
* counted against the JPEG max_memory setting. In some systems the above
* code would risk an out-of-memory error. However, in general we don't
* know the output image dimensions before jpeg_start_decompress(), unless we
* call jpeg_calc_output_dimensions(). See libjpeg.doc for more about this.
* call jpeg_calc_output_dimensions(). See libjpeg.txt for more about this.
*
* Scanlines are returned in the same order as they appear in the JPEG file,
* which is standardly top-to-bottom. If you must emit data bottom-to-top,
@@ -418,5 +429,5 @@ read_JPEG_file (char * filename)
*
* As with compression, some operating modes may require temporary files.
* On some systems you may need to set up a signal handler to ensure that
* temporary files are deleted if the program is interrupted. See libjpeg.doc.
* temporary files are deleted if the program is interrupted. See libjpeg.txt.
*/

View File

@@ -1,6 +1,6 @@
IJG JPEG LIBRARY: FILE LIST
Copyright (C) 1994, Thomas G. Lane.
Copyright (C) 1994-2009, Thomas G. Lane, Guido Vollbeding.
This file is part of the Independent JPEG Group's software.
For conditions of distribution and use, see the accompanying README file.
@@ -8,8 +8,10 @@ For conditions of distribution and use, see the accompanying README file.
Here is a road map to the files in the IJG JPEG distribution. The
distribution includes the JPEG library proper, plus two application
programs ("cjpeg" and "djpeg") which use the library to convert JPEG
files to and from some other popular image formats. There are also
two stand-alone applications, "rdjpgcom" and "wrjpgcom".
files to and from some other popular image formats. A third application
"jpegtran" uses the library to do lossless conversion between different
variants of JPEG. There are also two stand-alone applications,
"rdjpgcom" and "wrjpgcom".
THE JPEG LIBRARY
@@ -23,7 +25,8 @@ jconfig.h Configuration declarations. Note: this file is not present
jmorecfg.h Additional configuration declarations; need not be changed
for a standard installation.
jerror.h Declares JPEG library's error and trace message codes.
jinclude.h Central include file used by library's .c files.
jinclude.h Central include file used by all IJG .c files to reference
system include files.
jpegint.h JPEG library's internal data structures.
jdct.h Private declarations for forward & reverse DCT subsystems.
jmemsys.h Private declarations for memory management subsystem.
@@ -33,7 +36,7 @@ Applications using the library should include jpeglib.h (which in turn
includes jconfig.h and jmorecfg.h). Optionally, jerror.h may be included
if the application needs to reference individual JPEG error codes. The
other include files are intended for internal use and would not normally
be included by an application program. (cjpeg/djpeg do use jinclude.h,
be included by an application program. (cjpeg/djpeg/etc do use jinclude.h,
since its function is to improve portability of the whole IJG distribution.
Most other applications will directly include the system include files they
want, and hence won't need jinclude.h.)
@@ -44,15 +47,20 @@ C source code files:
These files contain most of the functions intended to be called directly by
an application program:
jcapi.c Application program interface routines for compression.
jdapi.c Application program interface routines for decompression.
jcapimin.c Application program interface: core routines for compression.
jcapistd.c Application program interface: standard compression.
jdapimin.c Application program interface: core routines for decompression.
jdapistd.c Application program interface: standard decompression.
jcomapi.c Application program interface routines common to compression
and decompression.
jcparam.c Compression parameter setting helper routines.
jctrans.c API and library routines for transcoding compression.
jdtrans.c API and library routines for transcoding decompression.
Compression side of the library:
jcmaster.c Master control: determines which other modules to use.
jcinit.c Initialization: determines which other modules to use.
jcmaster.c Master control: setup and inter-pass sequencing logic.
jcmainct.c Main buffer controller (preprocessor => JPEG compressor).
jcprepct.c Preprocessor buffer controller.
jccoefct.c Buffer controller for DCT coefficient buffer.
@@ -63,32 +71,36 @@ jfdctint.c Forward DCT using slow-but-accurate integer method.
jfdctfst.c Forward DCT using faster, less accurate integer method.
jfdctflt.c Forward DCT using floating-point arithmetic.
jchuff.c Huffman entropy coding.
jcarith.c Arithmetic entropy coding.
jcmarker.c JPEG marker writing.
jdatadst.c Data destination manager for stdio output.
jdatadst.c Data destination managers for memory and stdio output.
Decompression side of the library:
jdmaster.c Master control: determines which other modules to use.
jdinput.c Input controller: controls input processing modules.
jdmainct.c Main buffer controller (JPEG decompressor => postprocessor).
jdcoefct.c Buffer controller for DCT coefficient buffer.
jdpostct.c Postprocessor buffer controller.
jdmarker.c JPEG marker reading.
jdhuff.c Huffman entropy decoding.
jdarith.c Arithmetic entropy decoding.
jddctmgr.c IDCT manager (IDCT implementation selection & control).
jidctint.c Inverse DCT using slow-but-accurate integer method.
jidctfst.c Inverse DCT using faster, less accurate integer method.
jidctflt.c Inverse DCT using floating-point arithmetic.
jidctred.c Inverse DCTs with reduced-size outputs.
jdsample.c Upsampling.
jdcolor.c Color space conversion.
jdmerge.c Merged upsampling/color conversion (faster, lower quality).
jquant1.c One-pass color quantization using a fixed-spacing colormap.
jquant2.c Two-pass color quantization using a custom-generated colormap.
Also handles one-pass quantization to an externally given map.
jdatasrc.c Data source manager for stdio input.
jdatasrc.c Data source managers for memory and stdio input.
Support files for both compression and decompression:
jaricom.c Tables for common use in arithmetic entropy encoding and
decoding routines.
jerror.c Standard error handling routines (application replaceable).
jmemmgr.c System-independent (more or less) memory management code.
jutils.c Miscellaneous utility routines.
@@ -100,11 +112,12 @@ module:
jmemnobs.c "No backing store": assumes adequate virtual memory exists.
jmemansi.c Makes temporary files with ANSI-standard routine tmpfile().
jmemname.c Makes temporary files with program-generated file names.
jmemdos.c Custom implementation for MS-DOS: knows about extended and
expanded memory as well as temporary files.
jmemdos.c Custom implementation for MS-DOS (16-bit environment only):
can use extended and expanded memory as well as temp files.
jmemmac.c Custom implementation for Apple Macintosh.
Exactly one of the system-dependent modules should be configured into an
installed JPEG library (see install.doc for hints about which one to use).
installed JPEG library (see install.txt for hints about which one to use).
On unusual systems you may find it worthwhile to make a special
system-dependent memory manager.
@@ -115,24 +128,30 @@ jmemdosa.asm 80x86 assembly code support for jmemdos.c; used only in
MS-DOS-specific configurations of the JPEG library.
CJPEG/DJPEG
===========
CJPEG/DJPEG/JPEGTRAN
====================
Include files:
cdjpeg.h Declarations shared by cjpeg/djpeg modules.
cderror.h Additional error and trace message codes for cjpeg/djpeg.
cdjpeg.h Declarations shared by cjpeg/djpeg/jpegtran modules.
cderror.h Additional error and trace message codes for cjpeg et al.
transupp.h Declarations for jpegtran support routines in transupp.c.
C source code files:
cjpeg.c Main program for cjpeg.
djpeg.c Main program for djpeg.
rdcolmap.c Code to read a colormap file for djpeg's "-map" option.
jpegtran.c Main program for jpegtran.
cdjpeg.c Utility routines used by all three programs.
rdcolmap.c Code to read a colormap file for djpeg's "-map" switch.
rdswitch.c Code to process some of cjpeg's more complex switches.
Also used by jpegtran.
transupp.c Support code for jpegtran: lossless image manipulations.
Image file reader modules for cjpeg:
rdbmp.c BMP file input.
rdgif.c GIF file input.
rdgif.c GIF file input (now just a stub).
rdppm.c PPM/PGM file input.
rdrle.c Utah RLE file input.
rdtarga.c Targa file input.
@@ -140,7 +159,7 @@ rdtarga.c Targa file input.
Image file writer modules for djpeg:
wrbmp.c BMP file output.
wrgif.c GIF file output.
wrgif.c GIF file output (a mere shadow of its former self).
wrppm.c PPM/PGM file output.
wrrle.c Utah RLE file output.
wrtarga.c Targa file output.
@@ -155,7 +174,7 @@ rdjpgcom.c Stand-alone rdjpgcom application.
wrjpgcom.c Stand-alone wrjpgcom application.
These programs do not depend on the IJG library. They do use
jconfig.h and jinclude.h, simply to improve portability.
jconfig.h and jinclude.h, only to improve portability.
ADDITIONAL FILES
@@ -164,22 +183,33 @@ ADDITIONAL FILES
Documentation (see README for a guide to the documentation files):
README Master documentation file.
*.doc Other documentation files.
*.txt Other documentation files.
*.1 Documentation in Unix man page format.
change.log Version-to-version change highlights.
example.c Sample code for calling JPEG library.
Configuration/installation files and programs (see install.doc for more info):
Configuration/installation files and programs (see install.txt for more info):
configure Unix shell script to perform automatic configuration.
configure.ac Source file for use with Autoconf to generate configure.
ltmain.sh Support scripts for configure (from GNU libtool).
config.guess
config.sub
depcomp
missing
install-sh Install shell script for those Unix systems lacking one.
Makefile.in Makefile input for configure.
Makefile.am Source file for use with Automake to generate Makefile.in.
ckconfig.c Program to generate jconfig.h on non-Unix systems.
jconfig.doc Template for making jconfig.h by hand.
makefile.* Sample makefiles for particular systems.
jconfig.txt Template for making jconfig.h by hand.
mak*.* Sample makefiles for particular systems.
jconfig.* Sample jconfig.h for particular systems.
libjpeg.map Script to generate shared library with versioned symbols.
aclocal.m4 M4 macro definitions for use with Autoconf.
ansi2knr.c De-ANSIfier for pre-ANSI C compilers (courtesy of
L. Peter Deutsch and Aladdin Enterprises).
Test files (see install.doc for test procedure):
Test files (see install.txt for test procedure):
test*.* Source and comparison files for confidence test.
These are binary image files, NOT text files.

527
install-sh Executable file
View File

@@ -0,0 +1,527 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-01-19.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for `test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for `test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@@ -1,6 +1,6 @@
INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
Copyright (C) 1991-1995, Thomas G. Lane.
Copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding.
This file is part of the Independent JPEG Group's software.
For conditions of distribution and use, see the accompanying README file.
@@ -94,6 +94,14 @@ Configure was created with GNU Autoconf and it follows the usual conventions
for GNU configure scripts. It makes a few assumptions that you may want to
override. You can do this by providing optional switches to configure:
* Configure will build both static and shared libraries, if possible.
If you want to build libjpeg only as a static library, say
./configure --disable-shared
If you want to build libjpeg only as a shared library, say
./configure --disable-static
Configure uses GNU libtool to take care of system-dependent shared library
building methods.
* Configure will use gcc (GNU C compiler) if it's available, otherwise cc.
To force a particular compiler to be selected, use the CC option, for example
./configure CC='cc'
@@ -102,8 +110,10 @@ For example, on HP-UX you probably want to say
./configure CC='cc -Aa'
to get HP's compiler to run in ANSI mode.
* The default CFLAGS setting is "-O". You can override this by saying,
for example, ./configure CFLAGS='-O2'.
* The default CFLAGS setting is "-g" for non-gcc compilers, "-g -O2" for gcc.
You can override this by saying, for example,
./configure CFLAGS='-O2'
if you want to compile without debugging support.
* Configure will set up the makefile so that "make install" will install files
into /usr/local/bin, /usr/local/man, etc. You can specify an installation
@@ -131,24 +141,29 @@ Makefile jconfig file System and/or compiler
makefile.manx jconfig.manx Amiga, Manx Aztec C
makefile.sas jconfig.sas Amiga, SAS C
makeproj.mac jconfig.mac Apple Macintosh, Metrowerks CodeWarrior
mak*jpeg.st jconfig.st Atari ST/STE/TT, Pure C or Turbo C
makefile.bcc jconfig.bcc MS-DOS or OS/2, Borland C
makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU C)
makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C version 6.x and up
makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C (16-bit only)
makefile.wat jconfig.wat MS-DOS, OS/2, or Windows NT, Watcom C
makefile.vc jconfig.vc Windows NT/95, MS Visual C++
make*.vc6 jconfig.vc Windows NT/95, MS Visual C++ 6
make*.v10 jconfig.vc Windows NT/95, MS Visual C++ 2010 (v10)
makefile.mms jconfig.vms Digital VMS, with MMS software
makefile.vms jconfig.vms Digital VMS, without MMS software
Copy the proper jconfig file to jconfig.h and the makefile to Makefile
(or whatever your system uses as the standard makefile name). For the
Atari, we provide three project files; see the Atari hints below.
Copy the proper jconfig file to jconfig.h and the makefile to Makefile (or
whatever your system uses as the standard makefile name). For more info see
the appropriate system-specific hints section near the end of this file.
Configuring the software by hand
--------------------------------
First, generate a jconfig.h file. If you are moderately familiar with C,
the comments in jconfig.doc should be enough information to do this; just
copy jconfig.doc to jconfig.h and edit it appropriately. Otherwise, you may
the comments in jconfig.txt should be enough information to do this; just
copy jconfig.txt to jconfig.h and edit it appropriately. Otherwise, you may
prefer to use the ckconfig.c program. You will need to compile and execute
ckconfig.c by hand --- we hope you know at least enough to do that.
ckconfig.c may not compile the first try (in fact, the whole idea is for it
@@ -176,14 +191,14 @@ ckconfig.c to work, make sure the same switches are in CFLAGS.
If you are on a system that doesn't use makefiles, you'll need to set up
project files (or whatever you do use) to compile all the source files and
link them into executable files cjpeg, djpeg, rdjpgcom, and wrjpgcom. See
the file lists in any of the makefiles to find out which files go into each
program. Note that the provided makefiles all make a "library" file libjpeg
first, but you don't have to do that if you don't want to; the file lists
identify which source files are actually needed for compression,
link them into executable files cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom.
See the file lists in any of the makefiles to find out which files go into
each program. Note that the provided makefiles all make a "library" file
libjpeg first, but you don't have to do that if you don't want to; the file
lists identify which source files are actually needed for compression,
decompression, or both. As a last resort, you can make a batch script that
just compiles everything and links it all together; makefile.vms is an
example of this (it's for VMS systems that have no make-like utility).
just compiles everything and links it all together; makefile.vms is an example
of this (it's for VMS systems that have no make-like utility).
Here are comments about some specific configuration decisions you'll
need to make:
@@ -191,7 +206,7 @@ need to make:
Command line style
------------------
cjpeg and djpeg can use a Unix-like command line style which supports
These programs can use a Unix-like command line style which supports
redirection and piping, like this:
cjpeg inputfile >outputfile
cjpeg <inputfile >outputfile
@@ -215,7 +230,7 @@ Selecting a memory manager
The IJG code is capable of working on images that are too big to fit in main
memory; data is swapped out to temporary files as necessary. However, the
code to do this is rather system-dependent. We provide four different
code to do this is rather system-dependent. We provide five different
memory managers:
* jmemansi.c This version uses the ANSI-standard library routine tmpfile(),
@@ -239,7 +254,10 @@ memory managers:
IMPORTANT: if you use this, define USE_MSDOS_MEMMGR in
jconfig.h, and include the assembly file jmemdosa.asm in the
programs. The supplied makefiles and jconfig files for
MS-DOS compilers already do both.
16-bit MS-DOS compilers already do both.
* jmemmac.c Custom version for Apple Macintosh; see the system-specific
notes for Macintosh for more info.
To use a particular memory manager, change the SYSDEPMEM variable in your
makefile to equal the corresponding object file name (for example, jmemansi.o
@@ -252,8 +270,8 @@ If yours doesn't, try jmemansi.c first. If that doesn't compile, you'll have
to use jmemname.c; be sure to adjust select_file_name() for local conditions.
You may also need to change unlink() to remove() in close_backing_store().
Except with jmemnobs.c, you need to adjust the DEFAULT_MAX_MEM setting to a
reasonable value for your system (either by adding a #define for
Except with jmemnobs.c or jmemmac.c, you need to adjust the DEFAULT_MAX_MEM
setting to a reasonable value for your system (either by adding a #define for
DEFAULT_MAX_MEM to jconfig.h, or by adding a -D switch to the Makefile).
This value limits the amount of data space the program will attempt to
allocate. Code and static data space isn't counted, so the actual memory
@@ -299,19 +317,21 @@ As a quick test of functionality we've included a small sample image in
several forms:
testorig.jpg Starting point for the djpeg tests.
testimg.ppm The output of djpeg testorig.jpg
testimg.gif The output of djpeg -gif testorig.jpg
testimg.bmp The output of djpeg -bmp -colors 256 testorig.jpg
testimg.jpg The output of cjpeg testimg.ppm
(The two .jpg files aren't identical since JPEG is lossy.) If you can
generate duplicates of the testimg.* files then you probably have working
programs.
testprog.jpg Progressive-mode equivalent of testorig.jpg.
testimgp.jpg The output of cjpeg -progressive -optimize testimg.ppm
(The first- and second-generation .jpg files aren't identical since the
default compression parameters are lossy.) If you can generate duplicates
of the testimg* files then you probably have working programs.
With most of the makefiles, "make test" will perform the necessary
comparisons.
If you're using a makefile that doesn't provide the test option, run djpeg
and cjpeg by hand to generate testout.ppm, testout.gif, and testout.jpg,
then compare these to testimg.* with whatever binary file comparison tool
you have. The files should be bit-for-bit identical.
and cjpeg by hand and compare the output files to testimg* with whatever
binary file comparison tool you have. The files should be bit-for-bit
identical.
If the programs complain "MAX_ALLOC_CHUNK is wrong, please fix", then you
need to reduce MAX_ALLOC_CHUNK to a value that fits in type size_t.
@@ -329,15 +349,14 @@ it's a good idea to check that binary I/O through stdin/stdout actually
works. You should get the same results from "djpeg <testorig.jpg >out.ppm"
as from "djpeg -outfile out.ppm testorig.jpg". Note that the makefiles all
use the latter style and therefore do not exercise stdin/stdout! If this
check fails, try recompiling cjpeg.c and djpeg.c with USE_SETMODE or
USE_FDOPEN. If it still doesn't work, better use two-file style.
(rdjpgcom.c and wrjpgcom.c will also need to be recompiled.)
check fails, try recompiling with USE_SETMODE or USE_FDOPEN defined.
If it still doesn't work, better use two-file style.
If you chose a memory manager other than jmemnobs.c, you should test that
temporary-file usage works. Try "djpeg -gif -max 0 testorig.jpg" and make
sure its output matches testimg.gif. If you have any really large images
handy, try compressing them with -optimize and/or decompressing with -gif to
make sure your DEFAULT_MAX_MEM setting is not too large.
temporary-file usage works. Try "djpeg -bmp -colors 256 -max 0 testorig.jpg"
and make sure its output matches testimg.bmp. If you have any really large
images handy, try compressing them with -optimize and/or decompressing with
-colors 256 to make sure your DEFAULT_MAX_MEM setting is not too large.
NOTE: this is far from an exhaustive test of the JPEG software; some modules,
such as 1-pass color quantization, are not exercised at all. It's just a
@@ -349,11 +368,12 @@ INSTALLING THE SOFTWARE
=======================
Once you're done with the above steps, you can install the software by
copying the executable files (cjpeg, djpeg, rdjpgcom, and wrjpgcom) to
wherever you normally install programs. On Unix systems, you'll also want
to put the man pages (cjpeg.1, djpeg.1, rdjpgcom.1, wrjpgcom.1) in the
man-page directory. The canned makefiles don't support this step since
there's such a wide variety of installation procedures on different systems.
copying the executable files (cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom)
to wherever you normally install programs. On Unix systems, you'll also want
to put the man pages (cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1)
in the man-page directory. The pre-fab makefiles don't support this step
since there's such a wide variety of installation procedures on different
systems.
If you generated a Makefile with the "configure" script, you can just say
make install
@@ -364,8 +384,13 @@ to see where configure thought the files should go. You may need to edit
the Makefile, particularly if your system's conventions for man page
filenames don't match what configure expects.
If you want to install the library file libjpeg.a and the include files j*.h
(for use in compiling other programs besides cjpeg/djpeg), then say
If you want to install the IJG library itself, for use in compiling other
programs besides ours, then you need to put the four include files
jpeglib.h jerror.h jconfig.h jmorecfg.h
into your include-file directory, and put the library file libjpeg.a
(extension may vary depending on system) wherever library files go.
If you generated a Makefile with "configure", it will do what it thinks
is the right thing if you say
make install-lib
@@ -375,9 +400,9 @@ OPTIONAL STUFF
Progress monitor:
If you like, you can #define PROGRESS_REPORT (in jconfig.h) to enable display
of percent-done progress reports. The routines provided in cjpeg.c/djpeg.c
merely print percentages to stderr, but you can customize them to do
something fancier.
of percent-done progress reports. The routine provided in cdjpeg.c merely
prints percentages to stderr, but you can customize it to do something
fancier.
Utah RLE file format support:
@@ -418,10 +443,10 @@ on our to-do list.)
The PPM reader (rdppm.c) can read 12-bit data from either text-format or
binary-format PPM and PGM files. Binary-format PPM/PGM files which have a
maxval greater than 255 are assumed to use 2 bytes per sample, LSB first
(little-endian order). As of early 1995, 2-byte binary format is not
officially supported by the PBMPLUS library, but it is expected that the
next release of PBMPLUS will support it. Note that the PPM reader will
maxval greater than 255 are assumed to use 2 bytes per sample, MSB first
(big-endian order). As of early 1995, 2-byte binary format is not
officially supported by the PBMPLUS library, but it is expected that a
future release of PBMPLUS will support it. Note that the PPM reader will
read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming
data is automatically rescaled to either maxval=255 or maxval=4095 as
appropriate for the cjpeg bit depth.
@@ -478,9 +503,9 @@ defining SHORTxSHORT_32 is fairly likely to work. When experimenting with
alternate definitions, be sure to test not only whether the code still works
(use the self-test), but also whether it is actually faster --- on some
compilers, alternate definitions may compute the right answer, yet be slower
than the default. Timing cjpeg on a large PPM input file is the best way to
check this, as the DCT will be the largest fraction of the runtime in that
mode. (Note: some of the distributed compiler-specific jconfig files
than the default. Timing cjpeg on a large PGM (grayscale) input file is the
best way to check this, as the DCT will be the largest fraction of the runtime
in that mode. (Note: some of the distributed compiler-specific jconfig files
already contain #define switches to select appropriate MULTIPLYxxx
definitions.)
@@ -492,7 +517,7 @@ that float DCT results may vary slightly across machines.) To do that, add
"#define JDCT_DEFAULT JDCT_FLOAT" to jconfig.h. Even if you don't change
the default, you should redefine JDCT_FASTEST, which is the method selected
by djpeg's -fast switch. Don't forget to update the documentation files
(usage.doc and/or cjpeg.1, djpeg.1) to agree with what you've done.
(usage.txt and/or cjpeg.1, djpeg.1) to agree with what you've done.
If access to "short" arrays is slow on your machine, it may be a win to
define type JCOEF as int rather than short. This will cost a good deal of
@@ -509,7 +534,7 @@ In general, it's worth trying the maximum optimization level of your compiler,
and experimenting with any optional optimizations such as loop unrolling.
(Unfortunately, far too many compilers have optimizer bugs ... be prepared to
back off if the code fails self-test.) If you do any experimentation along
these lines, please report the optimal settings to jpeg-info@uunet.uu.net so
these lines, please report the optimal settings to jpeg-info@jpegclub.org so
we can mention them in future releases. Be sure to specify your machine and
compiler version.
@@ -518,7 +543,7 @@ HINTS FOR SPECIFIC SYSTEMS
==========================
We welcome reports on changes needed for systems not mentioned here. Submit
'em to jpeg-info@uunet.uu.net. Also, if configure or ckconfig.c is wrong
'em to jpeg-info@jpegclub.org. Also, if configure or ckconfig.c is wrong
about how to configure the JPEG software for your system, please let us know.
@@ -539,7 +564,7 @@ Also add a new line '.c.o:; $(cc) $< $(cflags) -c -o $@'. Remove the
lines '$(RM) libjpeg.o' and '$(AR2) libjpeg.o' and the 'jconfig.h'
dependency section.
Copy jconfig.doc to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE
Copy jconfig.txt to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE
and CHAR_IS_UNSIGNED.
Run the makefile using !AMU not !Make. If you want to use the 'clean' and
@@ -559,37 +584,38 @@ manager, with temporary files being created on the device named by
Atari ST/STE/TT:
Copy the project files makcjpeg.st, makdjpeg.st, and makljpeg.st to cjpeg.prj,
djpeg.prj, and libjpeg.prj respectively. The project files should work as-is
with Pure C. For Turbo C, change library filenames "PC..." to "TC..." in
cjpeg.prj and djpeg.prj. Note that libjpeg.prj selects jmemansi.c as the
recommended memory manager. You'll probably want to adjust the
DEFAULT_MAX_MEM setting --- you want it to be a couple hundred K less than
your normal free memory. Put "#define DEFAULT_MAX_MEM nnnn" into jconfig.h
to do this.
Copy the project files makcjpeg.st, makdjpeg.st, maktjpeg.st, and makljpeg.st
to cjpeg.prj, djpeg.prj, jpegtran.prj, and libjpeg.prj respectively. The
project files should work as-is with Pure C. For Turbo C, change library
filenames "pc..." to "tc..." in each project file. Note that libjpeg.prj
selects jmemansi.c as the recommended memory manager. You'll probably want to
adjust the DEFAULT_MAX_MEM setting --- you want it to be a couple hundred K
less than your normal free memory. Put "#define DEFAULT_MAX_MEM nnnn" into
jconfig.h to do this.
To use the 68881/68882 coprocessor for the floating point DCT, add the
compiler option "-8" to the project files and replace PCFLTLIB.LIB with
PC881LIB.LIB in cjpeg.prj and djpeg.prj. Or if you don't have a
compiler option "-8" to the project files and replace pcfltlib.lib with
pc881lib.lib in cjpeg.prj and djpeg.prj. Or if you don't have a
coprocessor, you may prefer to remove the float DCT code by undefining
DCT_FLOAT_SUPPORTED in jmorecfg.h (since without a coprocessor, the float
code will be too slow to be useful). In that case, you can delete
PCFLTLIB.LIB from the project files.
pcfltlib.lib from the project files.
Note that you must make libjpeg.lib before making cjpeg.ttp or djpeg.ttp.
You'll have to perform the self-test by hand.
Note that you must make libjpeg.lib before making cjpeg.ttp, djpeg.ttp,
or jpegtran.ttp. You'll have to perform the self-test by hand.
We haven't bothered to include project files for rdjpgcom and wrjpgcom.
Those source files should just be compiled by themselves; they don't
depend on the JPEG library.
depend on the JPEG library. You can use the default.prj project file
of the Pure C distribution to make the programs.
There is a bug in some older versions of the Turbo C library which causes the
space used by temporary files created with "tmpfile()" not to be freed after
an abnormal program exit. If you check your disk afterwards, you will find
cluster chains that are allocated but not used by a file. This should not
happen in cjpeg or djpeg, since we enable a signal catcher to explicitly close
temp files before exiting. But if you use the JPEG library with your own
code, be sure to supply a signal catcher, or else use a different
happen in cjpeg/djpeg/jpegtran, since we enable a signal catcher to explicitly
close temp files before exiting. But if you use the JPEG library with your
own code, be sure to supply a signal catcher, or else use a different
system-dependent memory manager.
@@ -624,38 +650,69 @@ to A.08.07. If you get complaints about "not a typedef name", you'll have to
use makefile.unix, or run configure without the CC option.
Macintosh, MPW:
Macintosh, generic comments:
We don't directly support MPW in the current release, but Larry Rosenstein
ported an earlier version of the IJG code without very much trouble. There's
useful notes and conversion scripts in his kit for porting PBMPLUS to MPW.
You can obtain the kit by FTP to ftp.apple.com, files /pub/lsr/pbmplus-port*.
The supplied user-interface files (cjpeg.c, djpeg.c, etc) are set up to
provide a Unix-style command line interface. You can use this interface on
the Mac by means of the ccommand() library routine provided by Metrowerks
CodeWarrior or Think C. This is only appropriate for testing the library,
however; to make a user-friendly equivalent of cjpeg/djpeg you'd really want
to develop a Mac-style user interface. There isn't a complete example
available at the moment, but there are some helpful starting points:
1. Sam Bushell's free "To JPEG" applet provides drag-and-drop conversion to
JPEG under System 7 and later. This only illustrates how to use the
compression half of the library, but it does a very nice job of that part.
The CodeWarrior source code is available from http://www.pobox.com/~jsam.
2. Jim Brunner prepared a Mac-style user interface for both compression and
decompression. Unfortunately, it hasn't been updated since IJG v4, and
the library's API has changed considerably since then. Still it may be of
some help, particularly as a guide to compiling the IJG code under Think C.
Jim's code is available from the Info-Mac archives, at sumex-aim.stanford.edu
or mirrors thereof; see file /info-mac/dev/src/jpeg-convert-c.hqx.
jmemmac.c is the recommended memory manager back end for Macintosh. It uses
NewPtr/DisposePtr instead of malloc/free, and has a Mac-specific
implementation of jpeg_mem_available(). It also creates temporary files that
follow Mac conventions. (That part of the code relies on System-7-or-later OS
functions. See the comments in jmemmac.c if you need to run it on System 6.)
NOTE that USE_MAC_MEMMGR must be defined in jconfig.h to use jmemmac.c.
You can also use jmemnobs.c, if you don't care about handling images larger
than available memory. If you use any memory manager back end other than
jmemmac.c, we recommend replacing "malloc" and "free" by "NewPtr" and
"DisposePtr", because Mac C libraries often have peculiar implementations of
malloc/free. (For instance, free() may not return the freed space to the
Mac Memory Manager. This is undesirable for the IJG code because jmemmgr.c
already clumps space requests.)
Macintosh, Metrowerks CodeWarrior:
Metrowerks release DR2 has problems with the IJG code; don't use it. Release
DR3.5 or later should be OK.
The command-line-style interface can be used by defining USE_CCOMMAND and
TWO_FILE_COMMANDLINE (see next entry for more details).
The Unix-command-line-style interface can be used by defining USE_CCOMMAND.
You'll also need to define TWO_FILE_COMMANDLINE to avoid stdin/stdout.
This means that when using the cjpeg/djpeg programs, you'll have to type the
input and output file names in the "Arguments" text-edit box, rather than
using the file radio buttons. (Perhaps USE_FDOPEN or USE_SETMODE would
eliminate the problem, but I haven't heard from anyone who's tried it.)
On 680x0 Macs, Metrowerks defines type "double" as a 10-byte IEEE extended
float. jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power
of 2. Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
The supplied configuration file jconfig.mac can be used for your jconfig.h;
it includes all the recommended symbol definitions. If you have AppleScript
installed, you can run the supplied script makeproj.mac to create CodeWarrior
project files for the library and the testbed applications, then build the
library and applications. (Thanks to Dan Sears and Don Agro for this nifty
hack, which saves us from trying to maintain CodeWarrior project files as part
of the IJG distribution...)
Macintosh, Think C:
The supplied user-interface files (cjpeg.c and djpeg.c) are set up to provide
a Unix-style command line interface. You can use this interface on the Mac
by means of Think's ccommand() library routine. However, a much better
Mac-style user interface has been prepared by Jim Brunner. You can obtain
the additional source code needed for that user interface by FTP to
sumex-aim.stanford.edu, file /info-mac/dev/src/jpeg-convert-c.hqx. Jim's
documentation also includes more detailed build instructions for Think C.
(Jim is working on updating this code to work with v5 of the IJG library,
but it wasn't ready as of v5 release time. Should be out before too long.)
The documentation in Jim Brunner's "JPEG Convert" source code (see above)
includes detailed build instructions for Think C; it's probably somewhat
out of date for the current release, but may be helpful.
If you want to build the minimal command line version, proceed as follows.
You'll have to prepare project files for the programs; we don't include any
@@ -671,6 +728,9 @@ On 680x0 Macs, Think C defines type "double" as a 12-byte IEEE extended float.
jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power of 2.
Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
jconfig.mac should work as a jconfig.h configuration file for Think C,
but the makeproj.mac AppleScript script is specific to CodeWarrior. Sorry.
MIPS R3000:
@@ -681,7 +741,7 @@ Note that the R3000 chip is found in workstations from DEC and others.
MS-DOS, generic comments for 16-bit compilers:
The IJG code is designed to be compiled in 80x86 "small" or "medium" memory
The IJG code is designed to work well in 80x86 "small" or "medium" memory
models (i.e., data pointers are 16 bits unless explicitly declared "far";
code pointers can be either size). You may be able to use small model to
compile cjpeg or djpeg by itself, but you will probably have to use medium
@@ -697,7 +757,8 @@ The DOS-specific memory manager, jmemdos.c, should be used if possible.
It needs some assembly-code routines which are in jmemdosa.asm; make sure
your makefile assembles that file and includes it in the library. If you
don't have a suitable assembler, you can get pre-assembled object files for
jmemdosa by FTP from ftp.uu.net: graphics/jpeg/jdosaobj.zip.
jmemdosa by FTP from ftp.uu.net:/graphics/jpeg/jdosaobj.zip. (DOS-oriented
distributions of the IJG source code often include these object files.)
When using jmemdos.c, jconfig.h must define USE_MSDOS_MEMMGR and must set
MAX_ALLOC_CHUNK to less than 64K (65520L is a typical value). If your
@@ -742,30 +803,32 @@ See the last paragraph of the previous section.
MS-DOS, Borland C:
If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
jconfig.bcc includes #define USE_SETMODE. (fdopen does not work correctly.)
Be sure to convert all the source files to DOS text format (CR/LF newlines).
Although Borland C will often work OK with unmodified Unix (LF newlines)
source files, sometimes it will give bogus compile errors.
"Illegal character '#'" is the most common such error.
"Illegal character '#'" is the most common such error. (This is true with
Borland C 3.1, but perhaps is fixed in newer releases.)
MS-DOS, DJGPP:
Use a recent version of DJGPP (1.11 or better). If you prefer two-file
command line style, change the supplied jconfig.dj to define
TWO_FILE_COMMANDLINE. makefile.dj is set up to generate only COFF files
(cjpeg, djpeg, etc) when you say make. After testing, say "make exe" to
make executables with stub.exe, or "make standalone" if you want executables
that include go32. You will probably need to tweak the makefile's pointer to
go32.exe to do "make standalone".
If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
jconfig.bcc already includes #define USE_SETMODE to make this work.
(fdopen does not work correctly.)
MS-DOS, Microsoft C:
makefile.mc6 works with Microsoft C, DOS Visual C++, etc. It should only
be used if you want to build a 16-bit (small or medium memory model) program.
If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
jconfig.mc6 includes #define USE_SETMODE. (fdopen does not work correctly.)
jconfig.mc6 already includes #define USE_SETMODE to make this work.
(fdopen does not work correctly.)
Note that this makefile assumes that the working copy of itself is called
"makefile". If you want to call it something else, say "makefile.mak",
be sure to adjust the dependency line that reads "$(RFILE) : makefile".
Otherwise the make will fail because it doesn't know how to create "makefile".
Worse, some releases of Microsoft's make utilities give an incorrect error
message in this situation.
Old versions of MS C fail with an "out of macro expansion space" error
because they can't cope with the macro TRACEMS8 (defined in jerror.h).
@@ -777,15 +840,241 @@ Original MS C 6.0 is very buggy; it compiles incorrect code unless you turn
off optimization entirely (remove -O from CFLAGS). 6.00A is better, but it
still generates bad code if you enable loop optimizations (-Ol or -Ox).
MS C 8.0 reportedly fails to compile jquant1.c if optimization is turned off
(yes, off).
MS C 8.0 crashes when compiling jquant1.c with optimization switch /Oo ...
which is on by default. To work around this bug, compile that one file
with /Oo-.
Microsoft Windows (all versions), generic comments:
Some Windows system include files define typedef boolean as "unsigned char".
The IJG code also defines typedef boolean, but we make it "int" by default.
This doesn't affect the IJG programs because we don't import those Windows
include files. But if you use the JPEG library in your own program, and some
of your program's files import one definition of boolean while some import the
other, you can get all sorts of mysterious problems. A good preventive step
is to make the IJG library use "unsigned char" for boolean. To do that,
add something like this to your jconfig.h file:
/* Define "boolean" as unsigned char, not int, per Windows custom */
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
(This is already in jconfig.vc, by the way.)
windef.h contains the declarations
#define far
#define FAR far
Since jmorecfg.h tries to define FAR as empty, you may get a compiler
warning if you include both jpeglib.h and windef.h (which windows.h
includes). To suppress the warning, you can put "#ifndef FAR"/"#endif"
around the line "#define FAR" in jmorecfg.h.
(Something like this is already in jmorecfg.h, by the way.)
When using the library in a Windows application, you will almost certainly
want to modify or replace the error handler module jerror.c, since our
default error handler does a couple of inappropriate things:
1. it tries to write error and warning messages on stderr;
2. in event of a fatal error, it exits by calling exit().
A simple stopgap solution for problem 1 is to replace the line
fprintf(stderr, "%s\n", buffer);
(in output_message in jerror.c) with
MessageBox(GetActiveWindow(),buffer,"JPEG Error",MB_OK|MB_ICONERROR);
It's highly recommended that you at least do that much, since otherwise
error messages will disappear into nowhere. (Beginning with IJG v6b, this
code is already present in jerror.c; just define USE_WINDOWS_MESSAGEBOX in
jconfig.h to enable it.)
The proper solution for problem 2 is to return control to your calling
application after a library error. This can be done with the setjmp/longjmp
technique discussed in libjpeg.txt and illustrated in example.c. (NOTE:
some older Windows C compilers provide versions of setjmp/longjmp that
don't actually work under Windows. You may need to use the Windows system
functions Catch and Throw instead.)
The recommended memory manager under Windows is jmemnobs.c; in other words,
let Windows do any virtual memory management needed. You should NOT use
jmemdos.c nor jmemdosa.asm under Windows.
For Windows 3.1, we recommend compiling in medium or large memory model;
for newer Windows versions, use a 32-bit flat memory model. (See the MS-DOS
sections above for more info about memory models.) In the 16-bit memory
models only, you'll need to put
#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
into jconfig.h to limit allocation chunks to 64Kb. (Without that, you'd
have to use huge memory model, which slows things down unnecessarily.)
jmemnobs.c works without modification in large or flat memory models, but to
use medium model, you need to modify its jpeg_get_large and jpeg_free_large
routines to allocate far memory. In any case, you might like to replace
its calls to malloc and free with direct calls on Windows memory allocation
functions.
You may also want to modify jdatasrc.c and jdatadst.c to use Windows file
operations rather than fread/fwrite. This is only necessary if your C
compiler doesn't provide a competent implementation of C stdio functions.
You might want to tweak the RGB_xxx macros in jmorecfg.h so that the library
will accept or deliver color pixels in BGR sample order, not RGB; BGR order
is usually more convenient under Windows. Note that this change will break
the sample applications cjpeg/djpeg, but the library itself works fine.
Many people want to convert the IJG library into a DLL. This is reasonably
straightforward, but watch out for the following:
1. Don't try to compile as a DLL in small or medium memory model; use
large model, or even better, 32-bit flat model. Many places in the IJG code
assume the address of a local variable is an ordinary (not FAR) pointer;
that isn't true in a medium-model DLL.
2. Microsoft C cannot pass file pointers between applications and DLLs.
(See Microsoft Knowledge Base, PSS ID Number Q50336.) So jdatasrc.c and
jdatadst.c don't work if you open a file in your application and then pass
the pointer to the DLL. One workaround is to make jdatasrc.c/jdatadst.c
part of your main application rather than part of the DLL.
3. You'll probably need to modify the macros GLOBAL() and EXTERN() to
attach suitable linkage keywords to the exported routine names. Similarly,
you'll want to modify METHODDEF() and JMETHOD() to ensure function pointers
are declared in a way that lets application routines be called back through
the function pointers. These macros are in jmorecfg.h. Typical definitions
for a 16-bit DLL are:
#define GLOBAL(type) type _far _pascal _loadds _export
#define EXTERN(type) extern type _far _pascal _loadds
#define METHODDEF(type) static type _far _pascal
#define JMETHOD(type,methodname,arglist) \
type (_far _pascal *methodname) arglist
For a 32-bit DLL you may want something like
#define GLOBAL(type) __declspec(dllexport) type
#define EXTERN(type) extern __declspec(dllexport) type
Although not all the GLOBAL routines are actually intended to be called by
the application, the performance cost of making them all DLL entry points is
negligible.
The unmodified IJG library presents a very C-specific application interface,
so the resulting DLL is only usable from C or C++ applications. There has
been some talk of writing wrapper code that would present a simpler interface
usable from other languages, such as Visual Basic. This is on our to-do list
but hasn't been very high priority --- any volunteers out there?
Microsoft Windows, Borland C:
The provided jconfig.bcc should work OK in a 32-bit Windows environment,
but you'll need to tweak it in a 16-bit environment (you'd need to define
NEED_FAR_POINTERS and MAX_ALLOC_CHUNK). Beware that makefile.bcc will need
alteration if you want to use it for Windows --- in particular, you should
use jmemnobs.c not jmemdos.c under Windows.
Borland C++ 4.5 fails with an internal compiler error when trying to compile
jdmerge.c in 32-bit mode. If enough people complain, perhaps Borland will fix
it. In the meantime, the simplest known workaround is to add a redundant
definition of the variable range_limit in h2v1_merged_upsample(), at the head
of the block that handles odd image width (about line 268 in v6 jdmerge.c):
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
register JSAMPLE * range_limit = cinfo->sample_range_limit; /* ADD THIS */
cb = GETJSAMPLE(*inptr1);
Pretty bizarre, especially since the very similar routine h2v2_merged_upsample
doesn't trigger the bug.
Recent reports suggest that this bug does not occur with "bcc32a" (the
Pentium-optimized version of the compiler).
Another report from a user of Borland C 4.5 was that incorrect code (leading
to a color shift in processed images) was produced if any of the following
optimization switch combinations were used:
-Ot -Og
-Ot -Op
-Ot -Om
So try backing off on optimization if you see such a problem. (Are there
several different releases all numbered "4.5"??)
Microsoft Windows, Microsoft Visual C++:
jconfig.vc should work OK with any Microsoft compiler for a 32-bit memory
model. makefile.vc is intended for command-line use. (If you are using
the Developer Studio environment, you may prefer the DevStudio project
files; see below.)
IJG JPEG 7 adds extern "C" to jpeglib.h. This avoids the need to put
extern "C" { ... } around #include "jpeglib.h" in your C++ application.
You can also force VC++ to treat the library as C++ code by renaming
all the *.c files to *.cpp (and adjusting the makefile to match).
In this case you also need to define the symbol DONT_USE_EXTERN_C in
the configuration to prevent jpeglib.h from using extern "C".
Microsoft Windows, Microsoft Visual C++ 6 Developer Studio:
We include makefiles that should work as project files in DevStudio 6.0 or
later. There is a library makefile that builds the IJG library as a static
Win32 library, and application makefiles that build the sample applications
as Win32 console applications. (Even if you only want the library, we
recommend building the applications so that you can run the self-test.)
To use:
1. Open the command prompt, change to the main directory and execute the
command line
NMAKE /f makefile.vc setup-vc6
This will move jconfig.vc to jconfig.h and makefiles to project files.
(Note that the renaming is critical!)
2. Open the workspace file jpeg.dsw, build the library project.
(If you are using DevStudio more recent than 6.0, you'll probably
get a message saying that the project files are being updated.)
3. Open the workspace file apps.dsw, build the application projects.
4. To perform the self-test, execute the command line
NMAKE /f makefile.vc test-build
5. Move the application .exe files from `app`\Release to an
appropriate location on your path.
Microsoft Windows, Microsoft Visual C++ 2010 Developer Studio (v10):
We include makefiles that should work as project files in Visual Studio
2010 or later. There is a library makefile that builds the IJG library
as a static Win32 library, and application makefiles that build the sample
applications as Win32 console applications. (Even if you only want the
library, we recommend building the applications so that you can run the
self-test.)
To use:
1. Open the command prompt, change to the main directory and execute the
command line
NMAKE /f makefile.vc setup-v10
This will move jconfig.vc to jconfig.h and makefiles to project files.
(Note that the renaming is critical!)
2. Open the solution file jpeg.sln, build the library project.
(If you are using Visual Studio more recent than 2010 (v10), you'll
probably get a message saying that the project files are being updated.)
3. Open the solution file apps.sln, build the application projects.
4. To perform the self-test, execute the command line
NMAKE /f makefile.vc test-build
5. Move the application .exe files from `app`\Release to an
appropriate location on your path.
Note:
There seems to be an optimization bug in the compiler which causes the
self-test to fail with the color quantization option.
We have disabled optimization for the file jquant2.c in the library
project file which causes the self-test to pass properly.
OS/2, Borland C++:
Watch out for optimization bugs in older Borland compilers; you may need
to back off the optimization switch settings. See the comments in
makefile.bcc.
SGI:
Set "AR2= ar -ts" rather than "AR2= ranlib" in the Makefile. If you are
using configure, you should say
On some SGI systems, you may need to set "AR2= ar -ts" in the Makefile.
If you are using configure, you can do this by saying
./configure RANLIB='ar -ts'
This change is not needed on all SGIs. Use it only if the make fails at the
stage of linking the completed programs.
On the MIPS R4000 architecture (Indy, etc.), the compiler option "-mips2"
reportedly speeds up the float DCT method substantially, enough to make it
@@ -800,8 +1089,8 @@ On an Alpha/VMS system with MMS, be sure to use the "/Marco=Alpha=1"
qualifier with MMS when building the JPEG package.
VAX/VMS v5.5-1 may have problems with the test step of the build procedure
reporting differences when it compares the original and test GIF and JPG
images. If the error points to the last block of the files, it is most
likely bogus and may be safely ignored. It seems to be because the files
are Stream_LF and Backup/Compare has difficulty with the (presumably) null
padded files. This problem was not observed on VAX/VMS v6.1 or AXP/VMS v6.1.
reporting differences when it compares the original and test images. If the
error points to the last block of the files, it is most likely bogus and may
be safely ignored. It seems to be because the files are Stream_LF and
Backup/Compare has difficulty with the (presumably) null padded files.
This problem was not observed on VAX/VMS v6.1 or AXP/VMS v6.1.

153
jaricom.c Normal file
View File

@@ -0,0 +1,153 @@
/*
* jaricom.c
*
* Developed 1997-2011 by Guido Vollbeding.
* 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 probability estimation tables for common use in
* arithmetic entropy encoding and decoding routines.
*
* This data represents Table D.3 in the JPEG spec (D.2 in the draft),
* ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81, and Table 24
* in the JBIG spec, ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* The following #define specifies the packing of the four components
* into the compact INT32 representation.
* Note that this formula must match the actual arithmetic encoder
* and decoder implementation. The implementation has to be changed
* if this formula is changed.
* The current organization is leaned on Markus Kuhn's JBIG
* implementation (jbig_tab.c).
*/
#define V(i,a,b,c,d) (((INT32)a << 16) | ((INT32)c << 8) | ((INT32)d << 7) | b)
const INT32 jpeg_aritab[113+1] = {
/*
* Index, Qe_Value, Next_Index_LPS, Next_Index_MPS, Switch_MPS
*/
V( 0, 0x5a1d, 1, 1, 1 ),
V( 1, 0x2586, 14, 2, 0 ),
V( 2, 0x1114, 16, 3, 0 ),
V( 3, 0x080b, 18, 4, 0 ),
V( 4, 0x03d8, 20, 5, 0 ),
V( 5, 0x01da, 23, 6, 0 ),
V( 6, 0x00e5, 25, 7, 0 ),
V( 7, 0x006f, 28, 8, 0 ),
V( 8, 0x0036, 30, 9, 0 ),
V( 9, 0x001a, 33, 10, 0 ),
V( 10, 0x000d, 35, 11, 0 ),
V( 11, 0x0006, 9, 12, 0 ),
V( 12, 0x0003, 10, 13, 0 ),
V( 13, 0x0001, 12, 13, 0 ),
V( 14, 0x5a7f, 15, 15, 1 ),
V( 15, 0x3f25, 36, 16, 0 ),
V( 16, 0x2cf2, 38, 17, 0 ),
V( 17, 0x207c, 39, 18, 0 ),
V( 18, 0x17b9, 40, 19, 0 ),
V( 19, 0x1182, 42, 20, 0 ),
V( 20, 0x0cef, 43, 21, 0 ),
V( 21, 0x09a1, 45, 22, 0 ),
V( 22, 0x072f, 46, 23, 0 ),
V( 23, 0x055c, 48, 24, 0 ),
V( 24, 0x0406, 49, 25, 0 ),
V( 25, 0x0303, 51, 26, 0 ),
V( 26, 0x0240, 52, 27, 0 ),
V( 27, 0x01b1, 54, 28, 0 ),
V( 28, 0x0144, 56, 29, 0 ),
V( 29, 0x00f5, 57, 30, 0 ),
V( 30, 0x00b7, 59, 31, 0 ),
V( 31, 0x008a, 60, 32, 0 ),
V( 32, 0x0068, 62, 33, 0 ),
V( 33, 0x004e, 63, 34, 0 ),
V( 34, 0x003b, 32, 35, 0 ),
V( 35, 0x002c, 33, 9, 0 ),
V( 36, 0x5ae1, 37, 37, 1 ),
V( 37, 0x484c, 64, 38, 0 ),
V( 38, 0x3a0d, 65, 39, 0 ),
V( 39, 0x2ef1, 67, 40, 0 ),
V( 40, 0x261f, 68, 41, 0 ),
V( 41, 0x1f33, 69, 42, 0 ),
V( 42, 0x19a8, 70, 43, 0 ),
V( 43, 0x1518, 72, 44, 0 ),
V( 44, 0x1177, 73, 45, 0 ),
V( 45, 0x0e74, 74, 46, 0 ),
V( 46, 0x0bfb, 75, 47, 0 ),
V( 47, 0x09f8, 77, 48, 0 ),
V( 48, 0x0861, 78, 49, 0 ),
V( 49, 0x0706, 79, 50, 0 ),
V( 50, 0x05cd, 48, 51, 0 ),
V( 51, 0x04de, 50, 52, 0 ),
V( 52, 0x040f, 50, 53, 0 ),
V( 53, 0x0363, 51, 54, 0 ),
V( 54, 0x02d4, 52, 55, 0 ),
V( 55, 0x025c, 53, 56, 0 ),
V( 56, 0x01f8, 54, 57, 0 ),
V( 57, 0x01a4, 55, 58, 0 ),
V( 58, 0x0160, 56, 59, 0 ),
V( 59, 0x0125, 57, 60, 0 ),
V( 60, 0x00f6, 58, 61, 0 ),
V( 61, 0x00cb, 59, 62, 0 ),
V( 62, 0x00ab, 61, 63, 0 ),
V( 63, 0x008f, 61, 32, 0 ),
V( 64, 0x5b12, 65, 65, 1 ),
V( 65, 0x4d04, 80, 66, 0 ),
V( 66, 0x412c, 81, 67, 0 ),
V( 67, 0x37d8, 82, 68, 0 ),
V( 68, 0x2fe8, 83, 69, 0 ),
V( 69, 0x293c, 84, 70, 0 ),
V( 70, 0x2379, 86, 71, 0 ),
V( 71, 0x1edf, 87, 72, 0 ),
V( 72, 0x1aa9, 87, 73, 0 ),
V( 73, 0x174e, 72, 74, 0 ),
V( 74, 0x1424, 72, 75, 0 ),
V( 75, 0x119c, 74, 76, 0 ),
V( 76, 0x0f6b, 74, 77, 0 ),
V( 77, 0x0d51, 75, 78, 0 ),
V( 78, 0x0bb6, 77, 79, 0 ),
V( 79, 0x0a40, 77, 48, 0 ),
V( 80, 0x5832, 80, 81, 1 ),
V( 81, 0x4d1c, 88, 82, 0 ),
V( 82, 0x438e, 89, 83, 0 ),
V( 83, 0x3bdd, 90, 84, 0 ),
V( 84, 0x34ee, 91, 85, 0 ),
V( 85, 0x2eae, 92, 86, 0 ),
V( 86, 0x299a, 93, 87, 0 ),
V( 87, 0x2516, 86, 71, 0 ),
V( 88, 0x5570, 88, 89, 1 ),
V( 89, 0x4ca9, 95, 90, 0 ),
V( 90, 0x44d9, 96, 91, 0 ),
V( 91, 0x3e22, 97, 92, 0 ),
V( 92, 0x3824, 99, 93, 0 ),
V( 93, 0x32b4, 99, 94, 0 ),
V( 94, 0x2e17, 93, 86, 0 ),
V( 95, 0x56a8, 95, 96, 1 ),
V( 96, 0x4f46, 101, 97, 0 ),
V( 97, 0x47e5, 102, 98, 0 ),
V( 98, 0x41cf, 103, 99, 0 ),
V( 99, 0x3c3d, 104, 100, 0 ),
V( 100, 0x375e, 99, 93, 0 ),
V( 101, 0x5231, 105, 102, 0 ),
V( 102, 0x4c0f, 106, 103, 0 ),
V( 103, 0x4639, 107, 104, 0 ),
V( 104, 0x415e, 103, 99, 0 ),
V( 105, 0x5627, 105, 106, 1 ),
V( 106, 0x50e7, 108, 107, 0 ),
V( 107, 0x4b85, 109, 103, 0 ),
V( 108, 0x5597, 110, 109, 0 ),
V( 109, 0x504f, 111, 107, 0 ),
V( 110, 0x5a10, 110, 111, 1 ),
V( 111, 0x5522, 112, 109, 0 ),
V( 112, 0x59eb, 112, 111, 1 ),
/*
* This last entry is used for fixed probability estimate of 0.5
* as suggested in Section 10.3 Table 5 of ITU-T Rec. T.851.
*/
V( 113, 0x5a1d, 113, 113, 0 )
};

364
jcapi.c
View File

@@ -1,364 +0,0 @@
/*
* jcapi.c
*
* Copyright (C) 1994-1995, 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 application interface code for the compression half of
* the JPEG library. Most of the routines intended to be called directly by
* an application are in this file. But also see jcparam.c for
* parameter-setup helper routines, and jcomapi.c for routines shared by
* compression and decompression.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/*
* Initialization of a JPEG compression object.
* The error manager must already be set up (in case memory manager fails).
*/
GLOBAL void
jpeg_create_compress (j_compress_ptr cinfo)
{
int i;
/* For debugging purposes, zero the whole master structure.
* But error manager pointer is already there, so save and restore it.
*/
{
struct jpeg_error_mgr * err = cinfo->err;
MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
cinfo->err = err;
}
cinfo->is_decompressor = FALSE;
/* Initialize a memory manager instance for this object */
jinit_memory_mgr((j_common_ptr) cinfo);
/* Zero out pointers to permanent structures. */
cinfo->progress = NULL;
cinfo->dest = NULL;
cinfo->comp_info = NULL;
for (i = 0; i < NUM_QUANT_TBLS; i++)
cinfo->quant_tbl_ptrs[i] = NULL;
for (i = 0; i < NUM_HUFF_TBLS; i++) {
cinfo->dc_huff_tbl_ptrs[i] = NULL;
cinfo->ac_huff_tbl_ptrs[i] = NULL;
}
cinfo->input_gamma = 1.0; /* in case application forgets */
/* OK, I'm ready */
cinfo->global_state = CSTATE_START;
}
/*
* Destruction of a JPEG compression object
*/
GLOBAL void
jpeg_destroy_compress (j_compress_ptr cinfo)
{
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
}
/*
* Forcibly suppress or un-suppress all quantization and Huffman tables.
* Marks all currently defined tables as already written (if suppress)
* or not written (if !suppress). This will control whether they get emitted
* by a subsequent jpeg_start_compress call.
*
* This routine is exported for use by applications that want to produce
* abbreviated JPEG datastreams. It logically belongs in jcparam.c, but
* since it is called by jpeg_start_compress, we put it here --- otherwise
* jcparam.o would be linked whether the application used it or not.
*/
GLOBAL void
jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
{
int i;
JQUANT_TBL * qtbl;
JHUFF_TBL * htbl;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
qtbl->sent_table = suppress;
}
for (i = 0; i < NUM_HUFF_TBLS; i++) {
if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
htbl->sent_table = suppress;
if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
htbl->sent_table = suppress;
}
}
/*
* Compression initialization.
* Before calling this, all parameters and a data destination must be set up.
*
* We require a write_all_tables parameter as a failsafe check when writing
* multiple datastreams from the same compression object. Since prior runs
* will have left all the tables marked sent_table=TRUE, a subsequent run
* would emit an abbreviated stream (no tables) by default. This may be what
* is wanted, but for safety's sake it should not be the default behavior:
* programmers should have to make a deliberate choice to emit abbreviated
* images. Therefore the documentation and examples should encourage people
* to pass write_all_tables=TRUE; then it will take active thought to do the
* wrong thing.
*/
GLOBAL void
jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
{
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (write_all_tables)
jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
/* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->dest->init_destination) (cinfo);
/* Perform master selection of active modules */
jinit_master_compress(cinfo);
/* Set up for the first pass */
(*cinfo->master->prepare_for_pass) (cinfo);
/* Ready for application to drive first pass through jpeg_write_scanlines
* or jpeg_write_raw_data.
*/
cinfo->next_scanline = 0;
cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
}
/*
* Write some scanlines of data to the JPEG compressor.
*
* The return value will be the number of lines actually written.
* This should be less than the supplied num_lines only in case that
* the data destination module has requested suspension of the compressor,
* or if more than image_height scanlines are passed in.
*
* Note: we warn about excess calls to jpeg_write_scanlines() since
* this likely signals an application programmer error. However,
* excess scanlines passed in the last valid call are *silently* ignored,
* so that the application need not adjust num_lines for end-of-image
* when using a multiple-scanline buffer.
*/
GLOBAL JDIMENSION
jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
JDIMENSION num_lines)
{
JDIMENSION row_ctr, rows_left;
if (cinfo->global_state != CSTATE_SCANNING)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->next_scanline >= cinfo->image_height)
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
cinfo->progress->pass_limit = (long) cinfo->image_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Give master control module another chance if this is first call to
* jpeg_write_scanlines. This lets output of the frame/scan headers be
* delayed so that application can write COM, etc, markers between
* jpeg_start_compress and jpeg_write_scanlines.
*/
if (cinfo->master->call_pass_startup)
(*cinfo->master->pass_startup) (cinfo);
/* Ignore any extra scanlines at bottom of image. */
rows_left = cinfo->image_height - cinfo->next_scanline;
if (num_lines > rows_left)
num_lines = rows_left;
row_ctr = 0;
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
cinfo->next_scanline += row_ctr;
return row_ctr;
}
/*
* Alternate entry point to write raw data.
* Processes exactly one iMCU row per call, unless suspended.
*/
GLOBAL JDIMENSION
jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION num_lines)
{
JDIMENSION lines_per_iMCU_row;
if (cinfo->global_state != CSTATE_RAW_OK)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->next_scanline >= cinfo->image_height) {
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
return 0;
}
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
cinfo->progress->pass_limit = (long) cinfo->image_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Give master control module another chance if this is first call to
* jpeg_write_raw_data. This lets output of the frame/scan headers be
* delayed so that application can write COM, etc, markers between
* jpeg_start_compress and jpeg_write_raw_data.
*/
if (cinfo->master->call_pass_startup)
(*cinfo->master->pass_startup) (cinfo);
/* Verify that at least one iMCU row has been passed. */
lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
if (num_lines < lines_per_iMCU_row)
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Directly compress the row. */
if (! (*cinfo->coef->compress_data) (cinfo, data)) {
/* If compressor did not consume the whole row, suspend processing. */
return 0;
}
/* OK, we processed one iMCU row. */
cinfo->next_scanline += lines_per_iMCU_row;
return lines_per_iMCU_row;
}
/*
* Finish JPEG compression.
*
* If a multipass operating mode was selected, this may do a great deal of
* work including most of the actual output.
*/
GLOBAL void
jpeg_finish_compress (j_compress_ptr cinfo)
{
JDIMENSION iMCU_row;
if (cinfo->global_state != CSTATE_SCANNING &&
cinfo->global_state != CSTATE_RAW_OK)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->next_scanline < cinfo->image_height)
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
/* Terminate first pass */
(*cinfo->master->finish_pass) (cinfo);
/* Perform any remaining passes */
while (! cinfo->master->is_last_pass) {
(*cinfo->master->prepare_for_pass) (cinfo);
for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) iMCU_row;
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* We bypass the main controller and invoke coef controller directly;
* all work is being done from the coefficient buffer.
*/
if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
(*cinfo->master->finish_pass) (cinfo);
}
/* Write EOI, do final cleanup */
(*cinfo->marker->write_file_trailer) (cinfo);
(*cinfo->dest->term_destination) (cinfo);
/* We can use jpeg_abort to release memory and reset global_state */
jpeg_abort((j_common_ptr) cinfo);
}
/*
* Write a special marker.
* This is only recommended for writing COM or APPn markers.
* Must be called after jpeg_start_compress() and before
* first call to jpeg_write_scanlines() or jpeg_write_raw_data().
*/
GLOBAL void
jpeg_write_marker (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen)
{
if (cinfo->next_scanline != 0 ||
(cinfo->global_state != CSTATE_SCANNING &&
cinfo->global_state != CSTATE_RAW_OK))
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
(*cinfo->marker->write_any_marker) (cinfo, marker, dataptr, datalen);
}
/*
* Alternate compression function: just write an abbreviated table file.
* Before calling this, all parameters and a data destination must be set up.
*
* To produce a pair of files containing abbreviated tables and abbreviated
* image data, one would proceed as follows:
*
* initialize JPEG object
* set JPEG parameters
* set destination to table file
* jpeg_write_tables(cinfo);
* set destination to image file
* jpeg_start_compress(cinfo, FALSE);
* write data...
* jpeg_finish_compress(cinfo);
*
* jpeg_write_tables has the side effect of marking all tables written
* (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress
* will not re-emit the tables unless it is passed write_all_tables=TRUE.
*/
GLOBAL void
jpeg_write_tables (j_compress_ptr cinfo)
{
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->dest->init_destination) (cinfo);
/* Initialize the marker writer ... bit of a crock to do it here. */
jinit_marker_writer(cinfo);
/* Write them tables! */
(*cinfo->marker->write_tables_only) (cinfo);
/* And clean up. */
(*cinfo->dest->term_destination) (cinfo);
/* We can use jpeg_abort to release memory ... is this necessary? */
jpeg_abort((j_common_ptr) cinfo);
}
/*
* Abort processing of a JPEG compression operation,
* but don't destroy the object itself.
*/
GLOBAL void
jpeg_abort_compress (j_compress_ptr cinfo)
{
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
}

288
jcapimin.c Normal file
View File

@@ -0,0 +1,288 @@
/*
* jcapimin.c
*
* Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* 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 application interface code for the compression half
* of the JPEG library. These are the "minimum" API routines that may be
* needed in either the normal full-compression case or the transcoding-only
* case.
*
* Most of the routines intended to be called directly by an application
* are in this file or in jcapistd.c. But also see jcparam.c for
* parameter-setup helper routines, jcomapi.c for routines shared by
* compression and decompression, and jctrans.c for the transcoding case.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/*
* Initialization of a JPEG compression object.
* The error manager must already be set up (in case memory manager fails).
*/
GLOBAL(void)
jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
{
int i;
/* Guard against version mismatches between library and caller. */
cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
if (version != JPEG_LIB_VERSION)
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
if (structsize != SIZEOF(struct jpeg_compress_struct))
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
(int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
/* For debugging purposes, we zero the whole master structure.
* But the application has already set the err pointer, and may have set
* client_data, so we have to save and restore those fields.
* Note: if application hasn't set client_data, tools like Purify may
* complain here.
*/
{
struct jpeg_error_mgr * err = cinfo->err;
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
cinfo->err = err;
cinfo->client_data = client_data;
}
cinfo->is_decompressor = FALSE;
/* Initialize a memory manager instance for this object */
jinit_memory_mgr((j_common_ptr) cinfo);
/* Zero out pointers to permanent structures. */
cinfo->progress = NULL;
cinfo->dest = NULL;
cinfo->comp_info = NULL;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
cinfo->quant_tbl_ptrs[i] = NULL;
cinfo->q_scale_factor[i] = 100;
}
for (i = 0; i < NUM_HUFF_TBLS; i++) {
cinfo->dc_huff_tbl_ptrs[i] = NULL;
cinfo->ac_huff_tbl_ptrs[i] = NULL;
}
/* Must do it here for emit_dqt in case jpeg_write_tables is used */
cinfo->block_size = DCTSIZE;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
cinfo->script_space = NULL;
cinfo->input_gamma = 1.0; /* in case application forgets */
/* OK, I'm ready */
cinfo->global_state = CSTATE_START;
}
/*
* Destruction of a JPEG compression object
*/
GLOBAL(void)
jpeg_destroy_compress (j_compress_ptr cinfo)
{
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
}
/*
* Abort processing of a JPEG compression operation,
* but don't destroy the object itself.
*/
GLOBAL(void)
jpeg_abort_compress (j_compress_ptr cinfo)
{
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
}
/*
* Forcibly suppress or un-suppress all quantization and Huffman tables.
* Marks all currently defined tables as already written (if suppress)
* or not written (if !suppress). This will control whether they get emitted
* by a subsequent jpeg_start_compress call.
*
* This routine is exported for use by applications that want to produce
* abbreviated JPEG datastreams. It logically belongs in jcparam.c, but
* since it is called by jpeg_start_compress, we put it here --- otherwise
* jcparam.o would be linked whether the application used it or not.
*/
GLOBAL(void)
jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
{
int i;
JQUANT_TBL * qtbl;
JHUFF_TBL * htbl;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
qtbl->sent_table = suppress;
}
for (i = 0; i < NUM_HUFF_TBLS; i++) {
if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
htbl->sent_table = suppress;
if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
htbl->sent_table = suppress;
}
}
/*
* Finish JPEG compression.
*
* If a multipass operating mode was selected, this may do a great deal of
* work including most of the actual output.
*/
GLOBAL(void)
jpeg_finish_compress (j_compress_ptr cinfo)
{
JDIMENSION iMCU_row;
if (cinfo->global_state == CSTATE_SCANNING ||
cinfo->global_state == CSTATE_RAW_OK) {
/* Terminate first pass */
if (cinfo->next_scanline < cinfo->image_height)
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
(*cinfo->master->finish_pass) (cinfo);
} else if (cinfo->global_state != CSTATE_WRCOEFS)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Perform any remaining passes */
while (! cinfo->master->is_last_pass) {
(*cinfo->master->prepare_for_pass) (cinfo);
for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) iMCU_row;
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* We bypass the main controller and invoke coef controller directly;
* all work is being done from the coefficient buffer.
*/
if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
(*cinfo->master->finish_pass) (cinfo);
}
/* Write EOI, do final cleanup */
(*cinfo->marker->write_file_trailer) (cinfo);
(*cinfo->dest->term_destination) (cinfo);
/* We can use jpeg_abort to release memory and reset global_state */
jpeg_abort((j_common_ptr) cinfo);
}
/*
* Write a special marker.
* This is only recommended for writing COM or APPn markers.
* Must be called after jpeg_start_compress() and before
* first call to jpeg_write_scanlines() or jpeg_write_raw_data().
*/
GLOBAL(void)
jpeg_write_marker (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen)
{
JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val));
if (cinfo->next_scanline != 0 ||
(cinfo->global_state != CSTATE_SCANNING &&
cinfo->global_state != CSTATE_RAW_OK &&
cinfo->global_state != CSTATE_WRCOEFS))
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
while (datalen--) {
(*write_marker_byte) (cinfo, *dataptr);
dataptr++;
}
}
/* Same, but piecemeal. */
GLOBAL(void)
jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
{
if (cinfo->next_scanline != 0 ||
(cinfo->global_state != CSTATE_SCANNING &&
cinfo->global_state != CSTATE_RAW_OK &&
cinfo->global_state != CSTATE_WRCOEFS))
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
(*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
}
GLOBAL(void)
jpeg_write_m_byte (j_compress_ptr cinfo, int val)
{
(*cinfo->marker->write_marker_byte) (cinfo, val);
}
/*
* Alternate compression function: just write an abbreviated table file.
* Before calling this, all parameters and a data destination must be set up.
*
* To produce a pair of files containing abbreviated tables and abbreviated
* image data, one would proceed as follows:
*
* initialize JPEG object
* set JPEG parameters
* set destination to table file
* jpeg_write_tables(cinfo);
* set destination to image file
* jpeg_start_compress(cinfo, FALSE);
* write data...
* jpeg_finish_compress(cinfo);
*
* jpeg_write_tables has the side effect of marking all tables written
* (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress
* will not re-emit the tables unless it is passed write_all_tables=TRUE.
*/
GLOBAL(void)
jpeg_write_tables (j_compress_ptr cinfo)
{
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->dest->init_destination) (cinfo);
/* Initialize the marker writer ... bit of a crock to do it here. */
jinit_marker_writer(cinfo);
/* Write them tables! */
(*cinfo->marker->write_tables_only) (cinfo);
/* And clean up. */
(*cinfo->dest->term_destination) (cinfo);
/*
* In library releases up through v6a, we called jpeg_abort() here to free
* any working memory allocated by the destination manager and marker
* writer. Some applications had a problem with that: they allocated space
* of their own from the library memory manager, and didn't want it to go
* away during write_tables. So now we do nothing. This will cause a
* memory leak if an app calls write_tables repeatedly without doing a full
* compression cycle or otherwise resetting the JPEG object. However, that
* seems less bad than unexpectedly freeing memory in the normal case.
* An app that prefers the old behavior can call jpeg_abort for itself after
* each call to jpeg_write_tables().
*/
}

161
jcapistd.c Normal file
View File

@@ -0,0 +1,161 @@
/*
* jcapistd.c
*
* Copyright (C) 1994-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 contains application interface code for the compression half
* of the JPEG library. These are the "standard" API routines that are
* used in the normal full-compression case. They are not used by a
* transcoding-only application. Note that if an application links in
* jpeg_start_compress, it will end up linking in the entire compressor.
* We thus must separate this file from jcapimin.c to avoid linking the
* whole compression library into a transcoder.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/*
* Compression initialization.
* Before calling this, all parameters and a data destination must be set up.
*
* We require a write_all_tables parameter as a failsafe check when writing
* multiple datastreams from the same compression object. Since prior runs
* will have left all the tables marked sent_table=TRUE, a subsequent run
* would emit an abbreviated stream (no tables) by default. This may be what
* is wanted, but for safety's sake it should not be the default behavior:
* programmers should have to make a deliberate choice to emit abbreviated
* images. Therefore the documentation and examples should encourage people
* to pass write_all_tables=TRUE; then it will take active thought to do the
* wrong thing.
*/
GLOBAL(void)
jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
{
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (write_all_tables)
jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
/* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->dest->init_destination) (cinfo);
/* Perform master selection of active modules */
jinit_compress_master(cinfo);
/* Set up for the first pass */
(*cinfo->master->prepare_for_pass) (cinfo);
/* Ready for application to drive first pass through jpeg_write_scanlines
* or jpeg_write_raw_data.
*/
cinfo->next_scanline = 0;
cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
}
/*
* Write some scanlines of data to the JPEG compressor.
*
* The return value will be the number of lines actually written.
* This should be less than the supplied num_lines only in case that
* the data destination module has requested suspension of the compressor,
* or if more than image_height scanlines are passed in.
*
* Note: we warn about excess calls to jpeg_write_scanlines() since
* this likely signals an application programmer error. However,
* excess scanlines passed in the last valid call are *silently* ignored,
* so that the application need not adjust num_lines for end-of-image
* when using a multiple-scanline buffer.
*/
GLOBAL(JDIMENSION)
jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
JDIMENSION num_lines)
{
JDIMENSION row_ctr, rows_left;
if (cinfo->global_state != CSTATE_SCANNING)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->next_scanline >= cinfo->image_height)
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
cinfo->progress->pass_limit = (long) cinfo->image_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Give master control module another chance if this is first call to
* jpeg_write_scanlines. This lets output of the frame/scan headers be
* delayed so that application can write COM, etc, markers between
* jpeg_start_compress and jpeg_write_scanlines.
*/
if (cinfo->master->call_pass_startup)
(*cinfo->master->pass_startup) (cinfo);
/* Ignore any extra scanlines at bottom of image. */
rows_left = cinfo->image_height - cinfo->next_scanline;
if (num_lines > rows_left)
num_lines = rows_left;
row_ctr = 0;
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
cinfo->next_scanline += row_ctr;
return row_ctr;
}
/*
* Alternate entry point to write raw data.
* Processes exactly one iMCU row per call, unless suspended.
*/
GLOBAL(JDIMENSION)
jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION num_lines)
{
JDIMENSION lines_per_iMCU_row;
if (cinfo->global_state != CSTATE_RAW_OK)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->next_scanline >= cinfo->image_height) {
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
return 0;
}
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->next_scanline;
cinfo->progress->pass_limit = (long) cinfo->image_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Give master control module another chance if this is first call to
* jpeg_write_raw_data. This lets output of the frame/scan headers be
* delayed so that application can write COM, etc, markers between
* jpeg_start_compress and jpeg_write_raw_data.
*/
if (cinfo->master->call_pass_startup)
(*cinfo->master->pass_startup) (cinfo);
/* Verify that at least one iMCU row has been passed. */
lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
if (num_lines < lines_per_iMCU_row)
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Directly compress the row. */
if (! (*cinfo->coef->compress_data) (cinfo, data)) {
/* If compressor did not consume the whole row, suspend processing. */
return 0;
}
/* OK, we processed one iMCU row. */
cinfo->next_scanline += lines_per_iMCU_row;
return lines_per_iMCU_row;
}

937
jcarith.c Normal file
View File

@@ -0,0 +1,937 @@
/*
* jcarith.c
*
* Developed 1997-2011 by Guido Vollbeding.
* 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 portable arithmetic entropy encoding routines for JPEG
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
*
* Both sequential and progressive modes are supported in this single module.
*
* Suspension is not currently supported in this module.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Expanded entropy encoder object for arithmetic encoding. */
typedef struct {
struct jpeg_entropy_encoder pub; /* public fields */
INT32 c; /* C register, base of coding interval, layout as in sec. D.1.3 */
INT32 a; /* A register, normalized size of coding interval */
INT32 sc; /* counter for stacked 0xFF values which might overflow */
INT32 zc; /* counter for pending 0x00 output values which might *
* be discarded at the end ("Pacman" termination) */
int ct; /* bit shift counter, determines when next byte will be written */
int buffer; /* buffer for most recent output byte != 0xFF */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
int next_restart_num; /* next restart number to write (0-7) */
/* Pointers to statistics areas (these workspaces have image lifespan) */
unsigned char * dc_stats[NUM_ARITH_TBLS];
unsigned char * ac_stats[NUM_ARITH_TBLS];
/* Statistics bin for coding with fixed probability 0.5 */
unsigned char fixed_bin[4];
} arith_entropy_encoder;
typedef arith_entropy_encoder * arith_entropy_ptr;
/* The following two definitions specify the allocation chunk size
* for the statistics area.
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
*
* We use a compact representation with 1 byte per statistics bin,
* thus the numbers directly represent byte sizes.
* This 1 byte per statistics bin contains the meaning of the MPS
* (more probable symbol) in the highest bit (mask 0x80), and the
* index into the probability estimation state machine table
* in the lower bits (mask 0x7F).
*/
#define DC_STAT_BINS 64
#define AC_STAT_BINS 256
/* NOTE: Uncomment the following #define if you want to use the
* given formula for calculating the AC conditioning parameter Kx
* for spectral selection progressive coding in section G.1.3.2
* of the spec (Kx = Kmin + SRL (8 + Se - Kmin) 4).
* Although the spec and P&M authors claim that this "has proven
* to give good results for 8 bit precision samples", I'm not
* convinced yet that this is really beneficial.
* Early tests gave only very marginal compression enhancements
* (a few - around 5 or so - bytes even for very large files),
* which would turn out rather negative if we'd suppress the
* DAC (Define Arithmetic Conditioning) marker segments for
* the default parameters in the future.
* Note that currently the marker writing module emits 12-byte
* DAC segments for a full-component scan in a color image.
* This is not worth worrying about IMHO. However, since the
* spec defines the default values to be used if the tables
* are omitted (unlike Huffman tables, which are required
* anyway), one might optimize this behaviour in the future,
* and then it would be disadvantageous to use custom tables if
* they don't provide sufficient gain to exceed the DAC size.
*
* On the other hand, I'd consider it as a reasonable result
* that the conditioning has no significant influence on the
* compression performance. This means that the basic
* statistical model is already rather stable.
*
* Thus, at the moment, we use the default conditioning values
* anyway, and do not use the custom formula.
*
#define CALCULATE_SPECTRAL_CONDITIONING
*/
/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
* We assume that int right shift is unsigned if INT32 right shift is,
* which should be safe.
*/
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define ISHIFT_TEMPS int ishift_temp;
#define IRIGHT_SHIFT(x,shft) \
((ishift_temp = (x)) < 0 ? \
(ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
(ishift_temp >> (shft)))
#else
#define ISHIFT_TEMPS
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
#endif
LOCAL(void)
emit_byte (int val, j_compress_ptr cinfo)
/* Write next output byte; we do not support suspension in this module. */
{
struct jpeg_destination_mgr * dest = cinfo->dest;
*dest->next_output_byte++ = (JOCTET) val;
if (--dest->free_in_buffer == 0)
if (! (*dest->empty_output_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
/*
* Finish up at the end of an arithmetic-compressed scan.
*/
METHODDEF(void)
finish_pass (j_compress_ptr cinfo)
{
arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
INT32 temp;
/* Section D.1.8: Termination of encoding */
/* Find the e->c in the coding interval with the largest
* number of trailing zero bits */
if ((temp = (e->a - 1 + e->c) & 0xFFFF0000L) < e->c)
e->c = temp + 0x8000L;
else
e->c = temp;
/* Send remaining bytes to output */
e->c <<= e->ct;
if (e->c & 0xF8000000L) {
/* One final overflow has to be handled */
if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer + 1, cinfo);
if (e->buffer + 1 == 0xFF)
emit_byte(0x00, cinfo);
}
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
e->sc = 0;
} else {
if (e->buffer == 0)
++e->zc;
else if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer, cinfo);
}
if (e->sc) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
do {
emit_byte(0xFF, cinfo);
emit_byte(0x00, cinfo);
} while (--e->sc);
}
}
/* Output final bytes only if they are not 0x00 */
if (e->c & 0x7FFF800L) {
if (e->zc) /* output final pending zero bytes */
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte((e->c >> 19) & 0xFF, cinfo);
if (((e->c >> 19) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
if (e->c & 0x7F800L) {
emit_byte((e->c >> 11) & 0xFF, cinfo);
if (((e->c >> 11) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
}
}
}
/*
* The core arithmetic encoding routine (common in JPEG and JBIG).
* This needs to go as fast as possible.
* Machine-dependent optimization facilities
* are not utilized in this portable implementation.
* However, this code should be fairly efficient and
* may be a good base for further optimizations anyway.
*
* Parameter 'val' to be encoded may be 0 or 1 (binary decision).
*
* Note: I've added full "Pacman" termination support to the
* byte output routines, which is equivalent to the optional
* Discard_final_zeros procedure (Figure D.15) in the spec.
* Thus, we always produce the shortest possible output
* stream compliant to the spec (no trailing zero bytes,
* except for FF stuffing).
*
* I've also introduced a new scheme for accessing
* the probability estimation state machine table,
* derived from Markus Kuhn's JBIG implementation.
*/
LOCAL(void)
arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
{
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
register unsigned char nl, nm;
register INT32 qe, temp;
register int sv;
/* Fetch values from our compact representation of Table D.3(D.2):
* Qe values and probability estimation state machine
*/
sv = *st;
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
/* Encode & estimation procedures per sections D.1.4 & D.1.5 */
e->a -= qe;
if (val != (sv >> 7)) {
/* Encode the less probable symbol */
if (e->a >= qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency, otherwise code the LPS
* as usual: */
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
} else {
/* Encode the more probable symbol */
if (e->a >= 0x8000L)
return; /* A >= 0x8000 -> ready, no renormalization required */
if (e->a < qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency: */
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
}
/* Renormalization & data output per section D.1.6 */
do {
e->a <<= 1;
e->c <<= 1;
if (--e->ct == 0) {
/* Another byte is ready for output */
temp = e->c >> 19;
if (temp > 0xFF) {
/* Handle overflow over all stacked 0xFF bytes */
if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer + 1, cinfo);
if (e->buffer + 1 == 0xFF)
emit_byte(0x00, cinfo);
}
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
e->sc = 0;
/* Note: The 3 spacer bits in the C register guarantee
* that the new buffer byte can't be 0xFF here
* (see page 160 in the P&M JPEG book). */
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
} else if (temp == 0xFF) {
++e->sc; /* stack 0xFF byte (which might overflow later) */
} else {
/* Output all stacked 0xFF bytes, they will not overflow any more */
if (e->buffer == 0)
++e->zc;
else if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer, cinfo);
}
if (e->sc) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
do {
emit_byte(0xFF, cinfo);
emit_byte(0x00, cinfo);
} while (--e->sc);
}
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
}
e->c &= 0x7FFFFL;
e->ct += 8;
}
} while (e->a < 0x8000L);
}
/*
* Emit a restart marker & resynchronize predictions.
*/
LOCAL(void)
emit_restart (j_compress_ptr cinfo, int restart_num)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci;
jpeg_component_info * compptr;
finish_pass(cinfo);
emit_byte(0xFF, cinfo);
emit_byte(JPEG_RST0 + restart_num, cinfo);
/* Re-initialize statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
/* Reset DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->Se) {
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
}
}
/* Reset arithmetic encoding variables */
entropy->c = 0;
entropy->a = 0x10000L;
entropy->sc = 0;
entropy->zc = 0;
entropy->ct = 11;
entropy->buffer = -1; /* empty */
}
/*
* MCU encoding for DC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl;
int v, v2, m;
ISHIFT_TEMPS
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
/* Compute the DC value after the required point transform by Al.
* This is simply an arithmetic right shift.
*/
m = IRIGHT_SHIFT((int) ((*block)[0]), cinfo->Al);
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.4: Encode_DC_DIFF */
if ((v = m - entropy->last_dc_val[ci]) == 0) {
arith_encode(cinfo, st, 0);
entropy->dc_context[ci] = 0; /* zero diff category */
} else {
entropy->last_dc_val[ci] = m;
arith_encode(cinfo, st, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
st += 2; /* Table F.4: SP = S0 + 2 */
entropy->dc_context[ci] = 4; /* small positive diff category */
} else {
v = -v;
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
st += 3; /* Table F.4: SN = S0 + 3 */
entropy->dc_context[ci] = 8; /* small negative diff category */
}
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
arith_encode(cinfo, st, 0);
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] += 8; /* large diff category */
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
}
return TRUE;
}
/*
* MCU encoding for AC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, k, ke;
int v, v2, m;
const int * natural_order;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
natural_order = cinfo->natural_order;
/* Encode the MCU data block */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--)
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value.
*/
if ((v = (*block)[natural_order[ke]]) >= 0) {
if (v >>= cinfo->Al) break;
} else {
v = -v;
if (v >>= cinfo->Al) break;
}
/* Figure F.5: Encode_AC_Coefficients */
for (k = cinfo->Ss; k <= ke; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) {
if ((v = (*block)[natural_order[k]]) >= 0) {
if (v >>= cinfo->Al) {
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 0);
break;
}
} else {
v = -v;
if (v >>= cinfo->Al) {
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 1);
break;
}
}
arith_encode(cinfo, st + 1, 0); st += 3; k++;
}
st += 2;
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
if (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
}
arith_encode(cinfo, st, 0);
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Encode EOB decision only if k <= cinfo->Se */
if (k <= cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 1);
}
return TRUE;
}
/*
* MCU encoding for DC successive approximation refinement scan.
*/
METHODDEF(boolean)
encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char *st;
int Al, blkn;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
st = entropy->fixed_bin; /* use fixed probability estimation */
Al = cinfo->Al;
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
/* We simply emit the Al'th bit of the DC coefficient value. */
arith_encode(cinfo, st, (MCU_data[blkn][0][0] >> Al) & 1);
}
return TRUE;
}
/*
* MCU encoding for AC successive approximation refinement scan.
*/
METHODDEF(boolean)
encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, k, ke, kex;
int v;
const int * natural_order;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
natural_order = cinfo->natural_order;
/* Encode the MCU data block */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Section G.1.3.3: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--)
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value.
*/
if ((v = (*block)[natural_order[ke]]) >= 0) {
if (v >>= cinfo->Al) break;
} else {
v = -v;
if (v >>= cinfo->Al) break;
}
/* Establish EOBx (previous stage end-of-block) index */
for (kex = ke; kex > 0; kex--)
if ((v = (*block)[natural_order[kex]]) >= 0) {
if (v >>= cinfo->Ah) break;
} else {
v = -v;
if (v >>= cinfo->Ah) break;
}
/* Figure G.10: Encode_AC_Coefficients_SA */
for (k = cinfo->Ss; k <= ke; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (k > kex)
arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) {
if ((v = (*block)[natural_order[k]]) >= 0) {
if (v >>= cinfo->Al) {
if (v >> 1) /* previously nonzero coef */
arith_encode(cinfo, st + 2, (v & 1));
else { /* newly nonzero coef */
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 0);
}
break;
}
} else {
v = -v;
if (v >>= cinfo->Al) {
if (v >> 1) /* previously nonzero coef */
arith_encode(cinfo, st + 2, (v & 1));
else { /* newly nonzero coef */
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 1);
}
break;
}
}
arith_encode(cinfo, st + 1, 0); st += 3; k++;
}
}
/* Encode EOB decision only if k <= cinfo->Se */
if (k <= cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 1);
}
return TRUE;
}
/*
* Encode and output one MCU's worth of arithmetic-compressed coefficients.
*/
METHODDEF(boolean)
encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
jpeg_component_info * compptr;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl, k, ke;
int v, v2, m;
const int * natural_order;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
natural_order = cinfo->natural_order;
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
tbl = compptr->dc_tbl_no;
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.4: Encode_DC_DIFF */
if ((v = (*block)[0] - entropy->last_dc_val[ci]) == 0) {
arith_encode(cinfo, st, 0);
entropy->dc_context[ci] = 0; /* zero diff category */
} else {
entropy->last_dc_val[ci] = (*block)[0];
arith_encode(cinfo, st, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
st += 2; /* Table F.4: SP = S0 + 2 */
entropy->dc_context[ci] = 4; /* small positive diff category */
} else {
v = -v;
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
st += 3; /* Table F.4: SN = S0 + 3 */
entropy->dc_context[ci] = 8; /* small negative diff category */
}
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
arith_encode(cinfo, st, 0);
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] += 8; /* large diff category */
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
if ((ke = cinfo->lim_Se) == 0) continue;
tbl = compptr->ac_tbl_no;
/* Establish EOB (end-of-block) index */
do {
if ((*block)[natural_order[ke]]) break;
} while (--ke);
/* Figure F.5: Encode_AC_Coefficients */
for (k = 0; k < ke;) {
st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 0); /* EOB decision */
while ((v = (*block)[natural_order[++k]]) == 0) {
arith_encode(cinfo, st + 1, 0);
st += 3;
}
arith_encode(cinfo, st + 1, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, entropy->fixed_bin, 0);
} else {
v = -v;
arith_encode(cinfo, entropy->fixed_bin, 1);
}
st += 2;
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
if (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
}
arith_encode(cinfo, st, 0);
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Encode EOB decision only if k < cinfo->lim_Se */
if (k < cinfo->lim_Se) {
st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 1);
}
}
return TRUE;
}
/*
* Initialize for an arithmetic-compressed scan.
*/
METHODDEF(void)
start_pass (j_compress_ptr cinfo, boolean gather_statistics)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci, tbl;
jpeg_component_info * compptr;
if (gather_statistics)
/* Make sure to avoid that in the master control logic!
* We are fully adaptive here and need no extra
* statistics gathering pass!
*/
ERREXIT(cinfo, JERR_NOT_COMPILED);
/* We assume jcmaster.c already validated the progressive scan parameters. */
/* Select execution routines */
if (cinfo->progressive_mode) {
if (cinfo->Ah == 0) {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_first;
else
entropy->pub.encode_mcu = encode_mcu_AC_first;
} else {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_refine;
else
entropy->pub.encode_mcu = encode_mcu_AC_refine;
}
} else
entropy->pub.encode_mcu = encode_mcu;
/* Allocate & initialize requested statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->dc_stats[tbl] == NULL)
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
/* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->Se) {
tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->ac_stats[tbl] == NULL)
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
#ifdef CALCULATE_SPECTRAL_CONDITIONING
if (cinfo->progressive_mode)
/* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
cinfo->arith_ac_K[tbl] = cinfo->Ss + ((8 + cinfo->Se - cinfo->Ss) >> 4);
#endif
}
}
/* Initialize arithmetic encoding variables */
entropy->c = 0;
entropy->a = 0x10000L;
entropy->sc = 0;
entropy->zc = 0;
entropy->ct = 11;
entropy->buffer = -1; /* empty */
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num = 0;
}
/*
* Module initialization routine for arithmetic entropy encoding.
*/
GLOBAL(void)
jinit_arith_encoder (j_compress_ptr cinfo)
{
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_encoder));
cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass;
/* Mark tables unallocated */
for (i = 0; i < NUM_ARITH_TBLS; i++) {
entropy->dc_stats[i] = NULL;
entropy->ac_stats[i] = NULL;
}
/* Initialize index for fixed probability estimation */
entropy->fixed_bin[0] = 113;
}

View File

@@ -1,7 +1,8 @@
/*
* jccoefct.c
*
* Copyright (C) 1994-1995, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -41,14 +42,14 @@ typedef struct {
/* For single-pass compression, it's sufficient to buffer just one MCU
* (although this may prove a bit slow in practice). We allocate a
* workspace of MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
* workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
* MCU constructed and sent. (On 80x86, the workspace is FAR even though
* it's not really very big; this is to keep the module interfaces unchanged
* when a large coefficient buffer is necessary.)
* In multi-pass modes, this array points to the current MCU's blocks
* within the virtual arrays.
*/
JBLOCKROW MCU_buffer[MAX_BLOCKS_IN_MCU];
JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
/* In multi-pass modes, we need a virtual block array for each component. */
jvirt_barray_ptr whole_image[MAX_COMPONENTS];
@@ -58,17 +59,17 @@ typedef my_coef_controller * my_coef_ptr;
/* Forward declarations */
METHODDEF boolean compress_data
METHODDEF(boolean) compress_data
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#ifdef FULL_COEF_BUFFER_SUPPORTED
METHODDEF boolean compress_first_pass
METHODDEF(boolean) compress_first_pass
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
METHODDEF boolean compress_output
METHODDEF(boolean) compress_output
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#endif
LOCAL void
LOCAL(void)
start_iMCU_row (j_compress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */
{
@@ -96,7 +97,7 @@ start_iMCU_row (j_compress_ptr cinfo)
* Initialize for a processing pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -135,11 +136,11 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* per call, ie, v_samp_factor block rows for each component in the image.
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
*
* NB: input_buf contains a plane for each component in image.
* For single pass, this is the same as the components in the scan.
* NB: input_buf contains a plane for each component in image,
* which we index according to the component's SOF position.
*/
METHODDEF boolean
METHODDEF(boolean)
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -149,6 +150,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
int blkn, bi, ci, yindex, yoffset, blockcnt;
JDIMENSION ypos, xpos;
jpeg_component_info *compptr;
forward_DCT_ptr forward_DCT;
/* Loop to write as much as one whole iMCU row */
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
@@ -167,19 +169,22 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
blkn = 0;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
forward_DCT = cinfo->fdct->forward_DCT[compptr->component_index];
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
: compptr->last_col_width;
xpos = MCU_col_num * compptr->MCU_sample_width;
ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
ypos = yoffset * compptr->DCT_v_scaled_size;
/* ypos == (yoffset+yindex) * DCTSIZE */
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (coef->iMCU_row_num < last_iMCU_row ||
yoffset+yindex < compptr->last_row_height) {
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[ci], coef->MCU_buffer[blkn],
(*forward_DCT) (cinfo, compptr,
input_buf[compptr->component_index],
coef->MCU_buffer[blkn],
ypos, xpos, (JDIMENSION) blockcnt);
if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
FMEMZERO((void FAR *) coef->MCU_buffer[blkn + blockcnt],
(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
@@ -187,14 +192,14 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
}
} else {
/* Create a row of dummy blocks at the bottom of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn],
FMEMZERO((void FAR *) coef->MCU_buffer[blkn],
compptr->MCU_width * SIZEOF(JBLOCK));
for (bi = 0; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
}
}
blkn += compptr->MCU_width;
ypos += DCTSIZE;
ypos += compptr->DCT_v_scaled_size;
}
}
/* Try to write the MCU. In event of a suspension failure, we will
@@ -240,7 +245,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* at the scan-dependent variables (MCU dimensions, etc).
*/
METHODDEF boolean
METHODDEF(boolean)
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -251,13 +256,15 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
jpeg_component_info *compptr;
JBLOCKARRAY buffer;
JBLOCKROW thisblockrow, lastblockrow;
forward_DCT_ptr forward_DCT;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Align the virtual buffer for this component. */
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[ci],
coef->iMCU_row_num * compptr->v_samp_factor, TRUE);
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
/* Count non-dummy DCT block rows in this iMCU row. */
if (coef->iMCU_row_num < last_iMCU_row)
block_rows = compptr->v_samp_factor;
@@ -272,19 +279,19 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
ndummy = (int) (blocks_across % h_samp_factor);
if (ndummy > 0)
ndummy = h_samp_factor - ndummy;
forward_DCT = cinfo->fdct->forward_DCT[ci];
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
* on forward_DCT processes a complete horizontal row of DCT blocks.
*/
for (block_row = 0; block_row < block_rows; block_row++) {
thisblockrow = buffer[block_row];
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[ci], thisblockrow,
(JDIMENSION) (block_row * DCTSIZE),
(*forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow,
(JDIMENSION) (block_row * compptr->DCT_v_scaled_size),
(JDIMENSION) 0, blocks_across);
if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */
jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
FMEMZERO((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
lastDC = thisblockrow[-1][0];
for (bi = 0; bi < ndummy; bi++) {
thisblockrow[bi][0] = lastDC;
@@ -303,7 +310,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
block_row++) {
thisblockrow = buffer[block_row];
lastblockrow = buffer[block_row-1];
jzero_far((void FAR *) thisblockrow,
FMEMZERO((void FAR *) thisblockrow,
(size_t) (blocks_across * SIZEOF(JBLOCK)));
for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
lastDC = lastblockrow[h_samp_factor-1][0];
@@ -335,7 +342,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* NB: input_buf is ignored; it is likely to be a NULL pointer.
*/
METHODDEF boolean
METHODDEF(boolean)
compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -354,7 +361,8 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
compptr = cinfo->cur_comp_info[ci];
buffer[ci] = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor, FALSE);
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, FALSE);
}
/* Loop to process one whole iMCU row */
@@ -398,13 +406,10 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* Initialize coefficient buffer controller.
*/
GLOBAL void
GLOBAL(void)
jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{
my_coef_ptr coef;
int ci, i;
jpeg_component_info *compptr;
JBLOCKROW buffer;
coef = (my_coef_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
@@ -417,14 +422,17 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
#ifdef FULL_COEF_BUFFER_SUPPORTED
/* Allocate a full-image virtual array for each component, */
/* padded to a multiple of samp_factor DCT blocks in each direction. */
/* Note memmgr implicitly pads the vertical direction. */
int ci;
jpeg_component_info *compptr;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
(long) compptr->h_samp_factor),
compptr->height_in_blocks,
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor),
(JDIMENSION) compptr->v_samp_factor);
}
#else
@@ -432,10 +440,13 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
#endif
} else {
/* We only need a single-MCU buffer. */
JBLOCKROW buffer;
int i;
buffer = (JBLOCKROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
for (i = 0; i < MAX_BLOCKS_IN_MCU; i++) {
C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
coef->MCU_buffer[i] = buffer + i;
}
coef->whole_image[0] = NULL; /* flag for no virtual arrays */

View File

@@ -1,7 +1,8 @@
/*
* jccolor.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -82,7 +83,7 @@ typedef my_color_converter * my_cconvert_ptr;
* Initialize for RGB->YCC colorspace conversion.
*/
METHODDEF void
METHODDEF(void)
rgb_ycc_start (j_compress_ptr cinfo)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
@@ -126,7 +127,7 @@ rgb_ycc_start (j_compress_ptr cinfo)
* offset required on that side.
*/
METHODDEF void
METHODDEF(void)
rgb_ycc_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
@@ -182,7 +183,7 @@ rgb_ycc_convert (j_compress_ptr cinfo,
* We assume rgb_ycc_start has been called (we only use the Y tables).
*/
METHODDEF void
METHODDEF(void)
rgb_gray_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
@@ -221,7 +222,7 @@ rgb_gray_convert (j_compress_ptr cinfo,
* We assume rgb_ycc_start has been called.
*/
METHODDEF void
METHODDEF(void)
cmyk_ycck_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
@@ -276,7 +277,7 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
* The source can be either plain grayscale or YCbCr (since Y == gray).
*/
METHODDEF void
METHODDEF(void)
grayscale_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
@@ -299,13 +300,46 @@ grayscale_convert (j_compress_ptr cinfo,
}
/*
* Convert some rows of samples to the JPEG colorspace.
* No colorspace conversion, but change from interleaved
* to separate-planes representation.
*/
METHODDEF(void)
rgb_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) {
inptr = *input_buf++;
outptr0 = output_buf[0][output_row];
outptr1 = output_buf[1][output_row];
outptr2 = output_buf[2][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr0[col] = inptr[RGB_RED];
outptr1[col] = inptr[RGB_GREEN];
outptr2[col] = inptr[RGB_BLUE];
inptr += RGB_PIXELSIZE;
}
}
}
/*
* Convert some rows of samples to the JPEG colorspace.
* This version handles multi-component colorspaces without conversion.
* We assume input_components == num_components.
*/
METHODDEF void
METHODDEF(void)
null_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
@@ -337,7 +371,7 @@ null_convert (j_compress_ptr cinfo,
* Empty method for start_pass.
*/
METHODDEF void
METHODDEF(void)
null_method (j_compress_ptr cinfo)
{
/* no work needed */
@@ -348,7 +382,7 @@ null_method (j_compress_ptr cinfo)
* Module initialization routine for input colorspace conversion.
*/
GLOBAL void
GLOBAL(void)
jinit_color_converter (j_compress_ptr cinfo)
{
my_cconvert_ptr cconvert;
@@ -368,11 +402,9 @@ jinit_color_converter (j_compress_ptr cinfo)
break;
case JCS_RGB:
#if RGB_PIXELSIZE != 3
if (cinfo->input_components != RGB_PIXELSIZE)
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
if (cinfo->input_components != 3)
@@ -396,22 +428,21 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_GRAYSCALE:
if (cinfo->num_components != 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_GRAYSCALE)
if (cinfo->in_color_space == JCS_GRAYSCALE ||
cinfo->in_color_space == JCS_YCbCr)
cconvert->pub.color_convert = grayscale_convert;
else if (cinfo->in_color_space == JCS_RGB) {
cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub.color_convert = rgb_gray_convert;
} else if (cinfo->in_color_space == JCS_YCbCr)
cconvert->pub.color_convert = grayscale_convert;
else
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
case JCS_RGB:
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
cconvert->pub.color_convert = null_convert;
if (cinfo->in_color_space == JCS_RGB)
cconvert->pub.color_convert = rgb_convert;
else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;

View File

@@ -1,7 +1,7 @@
/*
* jcdctmgr.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-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.
*
@@ -23,17 +23,17 @@ typedef struct {
struct jpeg_forward_dct pub; /* public fields */
/* Pointer to the DCT routine actually in use */
forward_DCT_method_ptr do_dct;
forward_DCT_method_ptr do_dct[MAX_COMPONENTS];
/* The actual post-DCT divisors --- not identical to the quant table
* entries, because of scaling (especially for an unnormalized DCT).
* Each table is given in zigzag order.
* Each table is given in normal array order.
*/
DCTELEM * divisors[NUM_QUANT_TBLS];
#ifdef DCT_FLOAT_SUPPORTED
/* Same as above for the floating-point case. */
float_DCT_method_ptr do_float_dct;
float_DCT_method_ptr do_float_dct[MAX_COMPONENTS];
FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
#endif
} my_fdct_controller;
@@ -41,143 +41,16 @@ typedef struct {
typedef my_fdct_controller * my_fdct_ptr;
/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
static const int ZAG[DCTSIZE2] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
/*
* Initialize for a processing pass.
* Verify that all referenced Q-tables are present, and set up
* the divisor table for each one.
* In the current implementation, DCT of all components is done during
* the first pass, even if only some components will be output in the
* first scan. Hence all components should be examined here.
/* The current scaled-DCT routines require ISLOW-style divisor tables,
* so be sure to compile that code if either ISLOW or SCALING is requested.
*/
METHODDEF void
start_pass_fdctmgr (j_compress_ptr cinfo)
{
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
int ci, qtblno, i;
jpeg_component_info *compptr;
JQUANT_TBL * qtbl;
DCTELEM * dtbl;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
qtblno = compptr->quant_tbl_no;
/* Make sure specified quantization table is present */
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
qtbl = cinfo->quant_tbl_ptrs[qtblno];
/* Compute divisors for this quant table */
/* We may do this more than once for same table, but it's not a big deal */
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
/* For LL&M IDCT method, divisors are equal to raw quantization
* coefficients multiplied by 8 (to counteract scaling).
*/
if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM));
}
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
}
break;
#define PROVIDE_ISLOW_TABLES
#else
#ifdef DCT_SCALING_SUPPORTED
#define PROVIDE_ISLOW_TABLES
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
{
/* For AA&N IDCT method, divisors are equal to quantization
* coefficients scaled by scalefactor[row]*scalefactor[col], where
* scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* We apply a further scale factor of 8.
*/
#define CONST_BITS 14
static const INT16 aanscales[DCTSIZE2] = {
/* precomputed values scaled up by 14 bits: in natural order */
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
};
SHIFT_TEMPS
if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM));
}
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = (DCTELEM)
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
(INT32) aanscales[ZAG[i]]),
CONST_BITS-3);
}
}
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
{
/* For float AA&N IDCT method, divisors are equal to quantization
* coefficients scaled by scalefactor[row]*scalefactor[col], where
* scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* We apply a further scale factor of 8.
* What's actually stored is 1/divisor so that the inner loop can
* use a multiplication rather than a division.
*/
FAST_FLOAT * fdtbl;
int row, col;
static const double aanscalefactor[DCTSIZE] = {
1.0, 1.387039845, 1.306562965, 1.175875602,
1.0, 0.785694958, 0.541196100, 0.275899379
};
if (fdct->float_divisors[qtblno] == NULL) {
fdct->float_divisors[qtblno] = (FAST_FLOAT *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(FAST_FLOAT));
}
fdtbl = fdct->float_divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
row = ZAG[i] >> 3;
col = ZAG[i] & 7;
fdtbl[i] = (FAST_FLOAT)
(1.0 / (((double) qtbl->quantval[i] *
aanscalefactor[row] * aanscalefactor[col] * 8.0)));
}
}
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
}
}
/*
@@ -185,10 +58,10 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
*
* The input samples are taken from the sample_data[] array starting at
* position start_row/start_col, and moving to the right for any additional
* blocks. The quantized, zigzagged coefficients are returned in coef_blocks[].
* blocks. The quantized coefficients are returned in coef_blocks[].
*/
METHODDEF void
METHODDEF(void)
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
@@ -197,43 +70,16 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
forward_DCT_method_ptr do_dct = fdct->do_dct;
forward_DCT_method_ptr do_dct = fdct->do_dct[compptr->component_index];
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
JDIMENSION bi;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */
{ register DCTELEM *workspaceptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
{ register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--) {
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
}
}
#endif
}
}
for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
/* Perform the DCT */
(*do_dct) (workspace);
(*do_dct) (workspace, sample_data, start_col);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register DCTELEM temp, qval;
@@ -242,7 +88,7 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
for (i = 0; i < DCTSIZE2; i++) {
qval = divisors[i];
temp = workspace[ZAG[i]];
temp = workspace[i];
/* Divide the coefficient value by qval, ensuring proper rounding.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
@@ -278,7 +124,7 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
#ifdef DCT_FLOAT_SUPPORTED
METHODDEF void
METHODDEF(void)
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
@@ -287,43 +133,16 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
float_DCT_method_ptr do_dct = fdct->do_float_dct;
float_DCT_method_ptr do_dct = fdct->do_float_dct[compptr->component_index];
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
JDIMENSION bi;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */
{ register FAST_FLOAT *workspaceptr;
register JSAMPROW elemptr;
register int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
{ register int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--) {
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
}
}
#endif
}
}
for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
/* Perform the DCT */
(*do_dct) (workspace);
(*do_dct) (workspace, sample_data, start_col);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register FAST_FLOAT temp;
@@ -332,7 +151,7 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
for (i = 0; i < DCTSIZE2; i++) {
/* Apply the quantization and scaling factor */
temp = workspace[ZAG[i]] * divisors[i];
temp = workspace[i] * divisors[i];
/* Round to nearest integer.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
@@ -348,11 +167,300 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
#endif /* DCT_FLOAT_SUPPORTED */
/*
* Initialize for a processing pass.
* Verify that all referenced Q-tables are present, and set up
* the divisor table for each one.
* In the current implementation, DCT of all components is done during
* the first pass, even if only some components will be output in the
* first scan. Hence all components should be examined here.
*/
METHODDEF(void)
start_pass_fdctmgr (j_compress_ptr cinfo)
{
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
int ci, qtblno, i;
jpeg_component_info *compptr;
int method = 0;
JQUANT_TBL * qtbl;
DCTELEM * dtbl;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Select the proper DCT routine for this component's scaling */
switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) {
#ifdef DCT_SCALING_SUPPORTED
case ((1 << 8) + 1):
fdct->do_dct[ci] = jpeg_fdct_1x1;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((2 << 8) + 2):
fdct->do_dct[ci] = jpeg_fdct_2x2;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((3 << 8) + 3):
fdct->do_dct[ci] = jpeg_fdct_3x3;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((4 << 8) + 4):
fdct->do_dct[ci] = jpeg_fdct_4x4;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((5 << 8) + 5):
fdct->do_dct[ci] = jpeg_fdct_5x5;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((6 << 8) + 6):
fdct->do_dct[ci] = jpeg_fdct_6x6;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((7 << 8) + 7):
fdct->do_dct[ci] = jpeg_fdct_7x7;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((9 << 8) + 9):
fdct->do_dct[ci] = jpeg_fdct_9x9;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((10 << 8) + 10):
fdct->do_dct[ci] = jpeg_fdct_10x10;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((11 << 8) + 11):
fdct->do_dct[ci] = jpeg_fdct_11x11;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((12 << 8) + 12):
fdct->do_dct[ci] = jpeg_fdct_12x12;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((13 << 8) + 13):
fdct->do_dct[ci] = jpeg_fdct_13x13;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((14 << 8) + 14):
fdct->do_dct[ci] = jpeg_fdct_14x14;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((15 << 8) + 15):
fdct->do_dct[ci] = jpeg_fdct_15x15;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((16 << 8) + 16):
fdct->do_dct[ci] = jpeg_fdct_16x16;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((16 << 8) + 8):
fdct->do_dct[ci] = jpeg_fdct_16x8;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((14 << 8) + 7):
fdct->do_dct[ci] = jpeg_fdct_14x7;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((12 << 8) + 6):
fdct->do_dct[ci] = jpeg_fdct_12x6;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((10 << 8) + 5):
fdct->do_dct[ci] = jpeg_fdct_10x5;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((8 << 8) + 4):
fdct->do_dct[ci] = jpeg_fdct_8x4;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((6 << 8) + 3):
fdct->do_dct[ci] = jpeg_fdct_6x3;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((4 << 8) + 2):
fdct->do_dct[ci] = jpeg_fdct_4x2;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((2 << 8) + 1):
fdct->do_dct[ci] = jpeg_fdct_2x1;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((8 << 8) + 16):
fdct->do_dct[ci] = jpeg_fdct_8x16;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((7 << 8) + 14):
fdct->do_dct[ci] = jpeg_fdct_7x14;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((6 << 8) + 12):
fdct->do_dct[ci] = jpeg_fdct_6x12;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((5 << 8) + 10):
fdct->do_dct[ci] = jpeg_fdct_5x10;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((4 << 8) + 8):
fdct->do_dct[ci] = jpeg_fdct_4x8;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((3 << 8) + 6):
fdct->do_dct[ci] = jpeg_fdct_3x6;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((2 << 8) + 4):
fdct->do_dct[ci] = jpeg_fdct_2x4;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((1 << 8) + 2):
fdct->do_dct[ci] = jpeg_fdct_1x2;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
#endif
case ((DCTSIZE << 8) + DCTSIZE):
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
fdct->do_dct[ci] = jpeg_fdct_islow;
method = JDCT_ISLOW;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
fdct->do_dct[ci] = jpeg_fdct_ifast;
method = JDCT_IFAST;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
fdct->do_float_dct[ci] = jpeg_fdct_float;
method = JDCT_FLOAT;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
break;
default:
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size);
break;
}
qtblno = compptr->quant_tbl_no;
/* Make sure specified quantization table is present */
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
qtbl = cinfo->quant_tbl_ptrs[qtblno];
/* Compute divisors for this quant table */
/* We may do this more than once for same table, but it's not a big deal */
switch (method) {
#ifdef PROVIDE_ISLOW_TABLES
case JDCT_ISLOW:
/* For LL&M IDCT method, divisors are equal to raw quantization
* coefficients multiplied by 8 (to counteract scaling).
*/
if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM));
}
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
}
fdct->pub.forward_DCT[ci] = forward_DCT;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
{
/* For AA&N IDCT method, divisors are equal to quantization
* coefficients scaled by scalefactor[row]*scalefactor[col], where
* scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* We apply a further scale factor of 8.
*/
#define CONST_BITS 14
static const INT16 aanscales[DCTSIZE2] = {
/* precomputed values scaled up by 14 bits */
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
};
SHIFT_TEMPS
if (fdct->divisors[qtblno] == NULL) {
fdct->divisors[qtblno] = (DCTELEM *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(DCTELEM));
}
dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = (DCTELEM)
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
(INT32) aanscales[i]),
CONST_BITS-3);
}
}
fdct->pub.forward_DCT[ci] = forward_DCT;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
{
/* For float AA&N IDCT method, divisors are equal to quantization
* coefficients scaled by scalefactor[row]*scalefactor[col], where
* scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* We apply a further scale factor of 8.
* What's actually stored is 1/divisor so that the inner loop can
* use a multiplication rather than a division.
*/
FAST_FLOAT * fdtbl;
int row, col;
static const double aanscalefactor[DCTSIZE] = {
1.0, 1.387039845, 1.306562965, 1.175875602,
1.0, 0.785694958, 0.541196100, 0.275899379
};
if (fdct->float_divisors[qtblno] == NULL) {
fdct->float_divisors[qtblno] = (FAST_FLOAT *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(FAST_FLOAT));
}
fdtbl = fdct->float_divisors[qtblno];
i = 0;
for (row = 0; row < DCTSIZE; row++) {
for (col = 0; col < DCTSIZE; col++) {
fdtbl[i] = (FAST_FLOAT)
(1.0 / (((double) qtbl->quantval[i] *
aanscalefactor[row] * aanscalefactor[col] * 8.0)));
i++;
}
}
}
fdct->pub.forward_DCT[ci] = forward_DCT_float;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
}
}
/*
* Initialize FDCT manager.
*/
GLOBAL void
GLOBAL(void)
jinit_forward_dct (j_compress_ptr cinfo)
{
my_fdct_ptr fdct;
@@ -364,30 +472,6 @@ jinit_forward_dct (j_compress_ptr cinfo)
cinfo->fdct = (struct jpeg_forward_dct *) fdct;
fdct->pub.start_pass = start_pass_fdctmgr;
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
fdct->pub.forward_DCT = forward_DCT;
fdct->do_dct = jpeg_fdct_islow;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
fdct->pub.forward_DCT = forward_DCT;
fdct->do_dct = jpeg_fdct_ifast;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
fdct->pub.forward_DCT = forward_DCT_float;
fdct->do_float_dct = jpeg_fdct_float;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
/* Mark divisor tables unallocated */
for (i = 0; i < NUM_QUANT_TBLS; i++) {
fdct->divisors[i] = NULL;

1123
jchuff.c

File diff suppressed because it is too large Load Diff

65
jcinit.c Normal file
View File

@@ -0,0 +1,65 @@
/*
* jcinit.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains initialization logic for the JPEG compressor.
* This routine is in charge of selecting the modules to be executed and
* making an initialization call to each one.
*
* Logically, this code belongs in jcmaster.c. It's split out because
* linking this routine implies linking the entire compression library.
* For a transcoding-only application, we want to be able to use jcmaster.c
* without linking in the whole library.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/*
* Master selection of compression modules.
* This is done once at the start of processing an image. We determine
* which modules will be used and give them appropriate initialization calls.
*/
GLOBAL(void)
jinit_compress_master (j_compress_ptr cinfo)
{
/* Initialize master control (includes parameter checking/processing) */
jinit_c_master_control(cinfo, FALSE /* full compression */);
/* Preprocessing */
if (! cinfo->raw_data_in) {
jinit_color_converter(cinfo);
jinit_downsampler(cinfo);
jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
}
/* Forward DCT */
jinit_forward_dct(cinfo);
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code)
jinit_arith_encoder(cinfo);
else {
jinit_huff_encoder(cinfo);
}
/* Need a full-image coefficient buffer in any multi-pass mode. */
jinit_c_coef_controller(cinfo,
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo);
/* We can now tell the memory manager to allocate virtual arrays. */
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
/* Write the datastream header (SOI) immediately.
* Frame and scan headers are postponed till later.
* This lets application insert special markers after the SOI.
*/
(*cinfo->marker->write_file_header) (cinfo);
}

View File

@@ -1,7 +1,7 @@
/*
* jcmainct.c
*
* Copyright (C) 1994-1995, Thomas G. Lane.
* Copyright (C) 1994-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.
*
@@ -51,11 +51,11 @@ typedef my_main_controller * my_main_ptr;
/* Forward declarations */
METHODDEF void process_data_simple_main
METHODDEF(void) process_data_simple_main
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
#ifdef FULL_MAIN_BUFFER_SUPPORTED
METHODDEF void process_data_buffer_main
METHODDEF(void) process_data_buffer_main
JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
#endif
@@ -65,7 +65,7 @@ METHODDEF void process_data_buffer_main
* Initialize for a processing pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_main_ptr main = (my_main_ptr) cinfo->main;
@@ -109,7 +109,7 @@ start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* where we have only a strip buffer.
*/
METHODDEF void
METHODDEF(void)
process_data_simple_main (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail)
@@ -118,17 +118,17 @@ process_data_simple_main (j_compress_ptr cinfo,
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
/* Read input data if we haven't filled the main buffer yet */
if (main->rowgroup_ctr < DCTSIZE)
if (main->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
(*cinfo->prep->pre_process_data) (cinfo,
input_buf, in_row_ctr, in_rows_avail,
main->buffer, &main->rowgroup_ctr,
(JDIMENSION) DCTSIZE);
(JDIMENSION) cinfo->min_DCT_v_scaled_size);
/* If we don't have a full iMCU row buffered, return to application for
* more data. Note that preprocessor will always pad to fill the iMCU row
* at the bottom of the image.
*/
if (main->rowgroup_ctr != DCTSIZE)
if (main->rowgroup_ctr != (JDIMENSION) cinfo->min_DCT_v_scaled_size)
return;
/* Send the completed row to the compressor */
@@ -165,7 +165,7 @@ process_data_simple_main (j_compress_ptr cinfo,
* This routine handles all of the modes that use a full-size buffer.
*/
METHODDEF void
METHODDEF(void)
process_data_buffer_main (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail)
@@ -182,7 +182,8 @@ process_data_buffer_main (j_compress_ptr cinfo,
ci++, compptr++) {
main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, main->whole_image[ci],
main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), writing);
main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
}
/* In a read pass, pretend we just read some source data. */
if (! writing) {
@@ -240,7 +241,7 @@ process_data_buffer_main (j_compress_ptr cinfo,
* Initialize main buffer controller.
*/
GLOBAL void
GLOBAL(void)
jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{
my_main_ptr main;
@@ -263,14 +264,15 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
if (need_full_buffer) {
#ifdef FULL_MAIN_BUFFER_SUPPORTED
/* Allocate a full-image virtual array for each component */
/* Note we implicitly pad the bottom to a multiple of the iMCU height */
/* Note we pad the bottom to a multiple of the iMCU height */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * DCTSIZE,
compptr->height_in_blocks * DCTSIZE,
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor) * DCTSIZE,
(JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
}
#else
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
@@ -284,8 +286,8 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
ci++, compptr++) {
main->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * DCTSIZE,
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
(JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
}
}
}

View File

@@ -1,7 +1,8 @@
/*
* jcmarker.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -81,6 +82,17 @@ typedef enum { /* JPEG marker codes */
} JPEG_MARKER;
/* Private state */
typedef struct {
struct jpeg_marker_writer pub; /* public fields */
unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
} my_marker_writer;
typedef my_marker_writer * my_marker_ptr;
/*
* Basic output routines.
*
@@ -93,7 +105,7 @@ typedef enum { /* JPEG marker codes */
* points where markers will be written.
*/
LOCAL void
LOCAL(void)
emit_byte (j_compress_ptr cinfo, int val)
/* Emit a byte */
{
@@ -107,7 +119,7 @@ emit_byte (j_compress_ptr cinfo, int val)
}
LOCAL void
LOCAL(void)
emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
/* Emit a marker code */
{
@@ -116,7 +128,7 @@ emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
}
LOCAL void
LOCAL(void)
emit_2bytes (j_compress_ptr cinfo, int value)
/* Emit a 2-byte integer; these are always MSB first in JPEG files */
{
@@ -129,7 +141,7 @@ emit_2bytes (j_compress_ptr cinfo, int value)
* Routines to write specific marker types.
*/
LOCAL int
LOCAL(int)
emit_dqt (j_compress_ptr cinfo, int index)
/* Emit a DQT marker */
/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
@@ -142,22 +154,25 @@ emit_dqt (j_compress_ptr cinfo, int index)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
prec = 0;
for (i = 0; i < DCTSIZE2; i++) {
if (qtbl->quantval[i] > 255)
for (i = 0; i <= cinfo->lim_Se; i++) {
if (qtbl->quantval[cinfo->natural_order[i]] > 255)
prec = 1;
}
if (! qtbl->sent_table) {
emit_marker(cinfo, M_DQT);
emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
emit_2bytes(cinfo,
prec ? cinfo->lim_Se * 2 + 2 + 1 + 2 : cinfo->lim_Se + 1 + 1 + 2);
emit_byte(cinfo, index + (prec<<4));
for (i = 0; i < DCTSIZE2; i++) {
for (i = 0; i <= cinfo->lim_Se; i++) {
/* The table entries must be emitted in zigzag order. */
unsigned int qval = qtbl->quantval[cinfo->natural_order[i]];
if (prec)
emit_byte(cinfo, qtbl->quantval[i] >> 8);
emit_byte(cinfo, qtbl->quantval[i] & 0xFF);
emit_byte(cinfo, (int) (qval >> 8));
emit_byte(cinfo, (int) (qval & 0xFF));
}
qtbl->sent_table = TRUE;
@@ -167,7 +182,7 @@ emit_dqt (j_compress_ptr cinfo, int index)
}
LOCAL void
LOCAL(void)
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
/* Emit a DHT marker */
{
@@ -205,7 +220,7 @@ emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
}
LOCAL void
LOCAL(void)
emit_dac (j_compress_ptr cinfo)
/* Emit a DAC marker */
/* Since the useful info is so small, we want to emit all the tables in */
@@ -222,7 +237,11 @@ emit_dac (j_compress_ptr cinfo)
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0)
dc_in_use[compptr->dc_tbl_no] = 1;
/* AC needs no table when not present */
if (cinfo->Se)
ac_in_use[compptr->ac_tbl_no] = 1;
}
@@ -230,6 +249,7 @@ emit_dac (j_compress_ptr cinfo)
for (i = 0; i < NUM_ARITH_TBLS; i++)
length += dc_in_use[i] + ac_in_use[i];
if (length) {
emit_marker(cinfo, M_DAC);
emit_2bytes(cinfo, length*2 + 2);
@@ -244,11 +264,12 @@ emit_dac (j_compress_ptr cinfo)
emit_byte(cinfo, cinfo->arith_ac_K[i]);
}
}
}
#endif /* C_ARITH_CODING_SUPPORTED */
}
LOCAL void
LOCAL(void)
emit_dri (j_compress_ptr cinfo)
/* Emit a DRI marker */
{
@@ -260,7 +281,7 @@ emit_dri (j_compress_ptr cinfo)
}
LOCAL void
LOCAL(void)
emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
/* Emit a SOF marker */
{
@@ -272,13 +293,13 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
/* Make sure image isn't bigger than SOF field can handle */
if ((long) cinfo->image_height > 65535L ||
(long) cinfo->image_width > 65535L)
if ((long) cinfo->jpeg_height > 65535L ||
(long) cinfo->jpeg_width > 65535L)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
emit_byte(cinfo, cinfo->data_precision);
emit_2bytes(cinfo, (int) cinfo->image_height);
emit_2bytes(cinfo, (int) cinfo->image_width);
emit_2bytes(cinfo, (int) cinfo->jpeg_height);
emit_2bytes(cinfo, (int) cinfo->jpeg_width);
emit_byte(cinfo, cinfo->num_components);
@@ -291,11 +312,11 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
}
LOCAL void
LOCAL(void)
emit_sos (j_compress_ptr cinfo)
/* Emit a SOS marker */
{
int i;
int i, td, ta;
jpeg_component_info *compptr;
emit_marker(cinfo, M_SOS);
@@ -307,16 +328,42 @@ emit_sos (j_compress_ptr cinfo)
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
emit_byte(cinfo, compptr->component_id);
emit_byte(cinfo, (compptr->dc_tbl_no << 4) + compptr->ac_tbl_no);
/* We emit 0 for unused field(s); this is recommended by the P&M text
* but does not seem to be specified in the standard.
*/
/* DC needs no table for refinement scan */
td = cinfo->Ss == 0 && cinfo->Ah == 0 ? compptr->dc_tbl_no : 0;
/* AC needs no table when not present */
ta = cinfo->Se ? compptr->ac_tbl_no : 0;
emit_byte(cinfo, (td << 4) + ta);
}
emit_byte(cinfo, 0); /* Spectral selection start */
emit_byte(cinfo, DCTSIZE2-1); /* Spectral selection end */
emit_byte(cinfo, 0); /* Successive approximation */
emit_byte(cinfo, cinfo->Ss);
emit_byte(cinfo, cinfo->Se);
emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
}
LOCAL void
LOCAL(void)
emit_pseudo_sos (j_compress_ptr cinfo)
/* Emit a pseudo SOS marker */
{
emit_marker(cinfo, M_SOS);
emit_2bytes(cinfo, 2 + 1 + 3); /* length */
emit_byte(cinfo, 0); /* Ns */
emit_byte(cinfo, 0); /* Ss */
emit_byte(cinfo, cinfo->block_size * cinfo->block_size - 1); /* Se */
emit_byte(cinfo, 0); /* Ah/Al */
}
LOCAL(void)
emit_jfif_app0 (j_compress_ptr cinfo)
/* Emit a JFIF-compliant APP0 marker */
{
@@ -324,7 +371,7 @@ emit_jfif_app0 (j_compress_ptr cinfo)
* Length of APP0 block (2 bytes)
* Block ID (4 bytes - ASCII "JFIF")
* Zero byte (1 byte to terminate the ID string)
* Version Major, Minor (2 bytes - 0x01, 0x01)
* Version Major, Minor (2 bytes - major first)
* Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
* Xdpu (2 bytes - dots per unit horizontal)
* Ydpu (2 bytes - dots per unit vertical)
@@ -341,11 +388,8 @@ emit_jfif_app0 (j_compress_ptr cinfo)
emit_byte(cinfo, 0x49);
emit_byte(cinfo, 0x46);
emit_byte(cinfo, 0);
/* We currently emit version code 1.01 since we use no 1.02 features.
* This may avoid complaints from some older decoders.
*/
emit_byte(cinfo, 1); /* Major version */
emit_byte(cinfo, 1); /* Minor version */
emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
emit_byte(cinfo, cinfo->JFIF_minor_version);
emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
emit_2bytes(cinfo, (int) cinfo->X_density);
emit_2bytes(cinfo, (int) cinfo->Y_density);
@@ -354,7 +398,7 @@ emit_jfif_app0 (j_compress_ptr cinfo)
}
LOCAL void
LOCAL(void)
emit_adobe_app14 (j_compress_ptr cinfo)
/* Emit an Adobe APP14 marker */
{
@@ -401,28 +445,30 @@ emit_adobe_app14 (j_compress_ptr cinfo)
/*
* This routine is exported for possible use by applications.
* The intended use is to emit COM or APPn markers after calling
* jpeg_start_compress() and before the first jpeg_write_scanlines() call
* (hence, after write_file_header but before write_frame_header).
* These routines allow writing an arbitrary marker with parameters.
* The only intended use is to emit COM or APPn markers after calling
* write_file_header and before calling write_frame_header.
* Other uses are not guaranteed to produce desirable results.
* Counting the parameter bytes properly is the caller's responsibility.
*/
METHODDEF void
write_any_marker (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen)
/* Emit an arbitrary marker with parameters */
METHODDEF(void)
write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
/* Emit an arbitrary marker header */
{
if (datalen <= (unsigned int) 65533) { /* safety check */
if (datalen > (unsigned int) 65533) /* safety check */
ERREXIT(cinfo, JERR_BAD_LENGTH);
emit_marker(cinfo, (JPEG_MARKER) marker);
emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
}
while (datalen--) {
emit_byte(cinfo, *dataptr);
dataptr++;
}
}
METHODDEF(void)
write_marker_byte (j_compress_ptr cinfo, int val)
/* Emit one byte of marker parameters following write_marker_header */
{
emit_byte(cinfo, val);
}
@@ -434,14 +480,19 @@ write_any_marker (j_compress_ptr cinfo, int marker,
* be used for any other JPEG colorspace. The Adobe marker is helpful
* to distinguish RGB, CMYK, and YCCK colorspaces.
* Note that an application can write additional header markers after
* jpeg_start_decompress returns.
* jpeg_start_compress returns.
*/
METHODDEF void
METHODDEF(void)
write_file_header (j_compress_ptr cinfo)
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
emit_marker(cinfo, M_SOI); /* first the SOI */
/* SOI is defined to reset restart interval to 0 */
marker->last_restart_interval = 0;
if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
emit_jfif_app0(cinfo);
if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
@@ -451,13 +502,13 @@ write_file_header (j_compress_ptr cinfo)
/*
* Write frame header.
* This consists of DQT and SOFn markers.
* This consists of DQT and SOFn markers, and a conditional pseudo SOS marker.
* Note that we do not emit the SOF until we have emitted the DQT(s).
* This avoids compatibility problems with incorrect implementations that
* try to error-check the quant table numbers as soon as they see the SOF.
*/
METHODDEF void
METHODDEF(void)
write_frame_header (j_compress_ptr cinfo)
{
int ci, prec;
@@ -477,9 +528,11 @@ write_frame_header (j_compress_ptr cinfo)
/* Check for a non-baseline specification.
* Note we assume that Huffman table numbers won't be changed later.
*/
is_baseline = TRUE;
if (cinfo->arith_code || (cinfo->data_precision != 8))
if (cinfo->arith_code || cinfo->progressive_mode ||
cinfo->data_precision != 8 || cinfo->block_size != DCTSIZE) {
is_baseline = FALSE;
} else {
is_baseline = TRUE;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
@@ -490,16 +543,28 @@ write_frame_header (j_compress_ptr cinfo)
/* If it's baseline except for quantizer size, warn the user */
TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
}
}
/* Emit the proper SOF marker */
if (cinfo->arith_code)
emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
if (cinfo->arith_code) {
if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF10); /* SOF code for progressive arithmetic */
else
emit_sof(cinfo, M_SOF9); /* SOF code for sequential arithmetic */
} else {
if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
else if (is_baseline)
emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
else
emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
}
/* Check to emit pseudo SOS marker */
if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE)
emit_pseudo_sos(cinfo);
}
/*
* Write scan header.
@@ -507,9 +572,10 @@ write_frame_header (j_compress_ptr cinfo)
* Compressed data will be written following the SOS.
*/
METHODDEF void
METHODDEF(void)
write_scan_header (j_compress_ptr cinfo)
{
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
int i;
jpeg_component_info *compptr;
@@ -525,17 +591,22 @@ write_scan_header (j_compress_ptr cinfo)
*/
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0)
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
/* AC needs no table when not present */
if (cinfo->Se)
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
}
}
/* Emit DRI if required --- note that DRI value could change for each scan.
* If it doesn't, a tiny amount of space is wasted in multiple-scan files.
* We assume DRI will never be nonzero for one scan and zero for a later one.
* We avoid wasting space with unnecessary DRIs, however.
*/
if (cinfo->restart_interval)
if (cinfo->restart_interval != marker->last_restart_interval) {
emit_dri(cinfo);
marker->last_restart_interval = cinfo->restart_interval;
}
emit_sos(cinfo);
}
@@ -545,7 +616,7 @@ write_scan_header (j_compress_ptr cinfo)
* Write datastream trailer.
*/
METHODDEF void
METHODDEF(void)
write_file_trailer (j_compress_ptr cinfo)
{
emit_marker(cinfo, M_EOI);
@@ -559,7 +630,7 @@ write_file_trailer (j_compress_ptr cinfo)
* emitted. Note that all tables will be marked sent_table = TRUE at exit.
*/
METHODDEF void
METHODDEF(void)
write_tables_only (j_compress_ptr cinfo)
{
int i;
@@ -588,18 +659,24 @@ write_tables_only (j_compress_ptr cinfo)
* Initialize the marker writer module.
*/
GLOBAL void
GLOBAL(void)
jinit_marker_writer (j_compress_ptr cinfo)
{
my_marker_ptr marker;
/* Create the subobject */
cinfo->marker = (struct jpeg_marker_writer *)
marker = (my_marker_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(struct jpeg_marker_writer));
SIZEOF(my_marker_writer));
cinfo->marker = (struct jpeg_marker_writer *) marker;
/* Initialize method pointers */
cinfo->marker->write_any_marker = write_any_marker;
cinfo->marker->write_file_header = write_file_header;
cinfo->marker->write_frame_header = write_frame_header;
cinfo->marker->write_scan_header = write_scan_header;
cinfo->marker->write_file_trailer = write_file_trailer;
cinfo->marker->write_tables_only = write_tables_only;
marker->pub.write_file_header = write_file_header;
marker->pub.write_frame_header = write_frame_header;
marker->pub.write_scan_header = write_scan_header;
marker->pub.write_file_trailer = write_file_trailer;
marker->pub.write_tables_only = write_tables_only;
marker->pub.write_marker_header = write_marker_header;
marker->pub.write_marker_byte = write_marker_byte;
/* Initialize private state */
marker->last_restart_interval = 0;
}

View File

@@ -1,14 +1,15 @@
/*
* jcmaster.c
*
* Copyright (C) 1991-1995, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* 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 master control logic for the JPEG compressor.
* These routines are concerned with selecting the modules to be executed
* and with determining the number of passes and the work to be done in each
* pass.
* These routines are concerned with parameter validation, initial setup,
* and inter-pass control (determining the number of passes and the work
* to be done in each pass).
*/
#define JPEG_INTERNALS
@@ -18,10 +19,21 @@
/* Private state */
typedef enum {
main_pass, /* input data, also do first output step */
huff_opt_pass, /* Huffman code optimization pass */
output_pass /* data output pass */
} c_pass_type;
typedef struct {
struct jpeg_comp_master pub; /* public fields */
int pass_number; /* eventually need more complex state... */
c_pass_type pass_type; /* the type of the current pass */
int pass_number; /* # of passes completed */
int total_passes; /* total # of passes needed */
int scan_number; /* current index in scan_info[] */
} my_comp_master;
typedef my_comp_master * my_master_ptr;
@@ -31,23 +43,220 @@ typedef my_comp_master * my_master_ptr;
* Support routines that do various essential calculations.
*/
LOCAL void
initial_setup (j_compress_ptr cinfo)
/*
* Compute JPEG image dimensions and related values.
* NOTE: this is exported for possible use by application.
* Hence it mustn't do anything that can't be done twice.
*/
GLOBAL(void)
jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
/* Do computations that are needed before master selection phase */
{
int ci;
#ifdef DCT_SCALING_SUPPORTED
/* Sanity check on input image dimensions to prevent overflow in
* following calculation.
* We do check jpeg_width and jpeg_height in initial_setup below,
* but image_width and image_height can come from arbitrary data,
* and we need some space for multiplication by block_size.
*/
if (((long) cinfo->image_width >> 24) || ((long) cinfo->image_height >> 24))
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
/* Compute actual JPEG image dimensions and DCT scaling choices. */
if (cinfo->scale_num >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/1 scaling */
cinfo->jpeg_width = cinfo->image_width * cinfo->block_size;
cinfo->jpeg_height = cinfo->image_height * cinfo->block_size;
cinfo->min_DCT_h_scaled_size = 1;
cinfo->min_DCT_v_scaled_size = 1;
} else if (cinfo->scale_num * 2 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/2 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 2L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 2L);
cinfo->min_DCT_h_scaled_size = 2;
cinfo->min_DCT_v_scaled_size = 2;
} else if (cinfo->scale_num * 3 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/3 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 3L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 3L);
cinfo->min_DCT_h_scaled_size = 3;
cinfo->min_DCT_v_scaled_size = 3;
} else if (cinfo->scale_num * 4 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/4 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 4L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 4L);
cinfo->min_DCT_h_scaled_size = 4;
cinfo->min_DCT_v_scaled_size = 4;
} else if (cinfo->scale_num * 5 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/5 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 5L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 5L);
cinfo->min_DCT_h_scaled_size = 5;
cinfo->min_DCT_v_scaled_size = 5;
} else if (cinfo->scale_num * 6 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/6 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 6L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 6L);
cinfo->min_DCT_h_scaled_size = 6;
cinfo->min_DCT_v_scaled_size = 6;
} else if (cinfo->scale_num * 7 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/7 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 7L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 7L);
cinfo->min_DCT_h_scaled_size = 7;
cinfo->min_DCT_v_scaled_size = 7;
} else if (cinfo->scale_num * 8 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/8 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 8L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 8L);
cinfo->min_DCT_h_scaled_size = 8;
cinfo->min_DCT_v_scaled_size = 8;
} else if (cinfo->scale_num * 9 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/9 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 9L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 9L);
cinfo->min_DCT_h_scaled_size = 9;
cinfo->min_DCT_v_scaled_size = 9;
} else if (cinfo->scale_num * 10 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/10 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 10L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 10L);
cinfo->min_DCT_h_scaled_size = 10;
cinfo->min_DCT_v_scaled_size = 10;
} else if (cinfo->scale_num * 11 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/11 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 11L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 11L);
cinfo->min_DCT_h_scaled_size = 11;
cinfo->min_DCT_v_scaled_size = 11;
} else if (cinfo->scale_num * 12 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/12 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 12L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 12L);
cinfo->min_DCT_h_scaled_size = 12;
cinfo->min_DCT_v_scaled_size = 12;
} else if (cinfo->scale_num * 13 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/13 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 13L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 13L);
cinfo->min_DCT_h_scaled_size = 13;
cinfo->min_DCT_v_scaled_size = 13;
} else if (cinfo->scale_num * 14 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/14 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 14L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 14L);
cinfo->min_DCT_h_scaled_size = 14;
cinfo->min_DCT_v_scaled_size = 14;
} else if (cinfo->scale_num * 15 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/15 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 15L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 15L);
cinfo->min_DCT_h_scaled_size = 15;
cinfo->min_DCT_v_scaled_size = 15;
} else {
/* Provide block_size/16 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 16L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 16L);
cinfo->min_DCT_h_scaled_size = 16;
cinfo->min_DCT_v_scaled_size = 16;
}
#else /* !DCT_SCALING_SUPPORTED */
/* Hardwire it to "no scaling" */
cinfo->jpeg_width = cinfo->image_width;
cinfo->jpeg_height = cinfo->image_height;
cinfo->min_DCT_h_scaled_size = DCTSIZE;
cinfo->min_DCT_v_scaled_size = DCTSIZE;
#endif /* DCT_SCALING_SUPPORTED */
}
LOCAL(void)
jpeg_calc_trans_dimensions (j_compress_ptr cinfo)
{
if (cinfo->min_DCT_h_scaled_size != cinfo->min_DCT_v_scaled_size)
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
cinfo->min_DCT_h_scaled_size, cinfo->min_DCT_v_scaled_size);
cinfo->block_size = cinfo->min_DCT_h_scaled_size;
}
LOCAL(void)
initial_setup (j_compress_ptr cinfo, boolean transcode_only)
/* Do computations that are needed before master selection phase */
{
int ci, ssize;
jpeg_component_info *compptr;
long samplesperrow;
JDIMENSION jd_samplesperrow;
if (transcode_only)
jpeg_calc_trans_dimensions(cinfo);
else
jpeg_calc_jpeg_dimensions(cinfo);
/* Sanity check on block_size */
if (cinfo->block_size < 1 || cinfo->block_size > 16)
ERREXIT2(cinfo, JERR_BAD_DCTSIZE, cinfo->block_size, cinfo->block_size);
/* Derive natural_order from block_size */
switch (cinfo->block_size) {
case 2: cinfo->natural_order = jpeg_natural_order2; break;
case 3: cinfo->natural_order = jpeg_natural_order3; break;
case 4: cinfo->natural_order = jpeg_natural_order4; break;
case 5: cinfo->natural_order = jpeg_natural_order5; break;
case 6: cinfo->natural_order = jpeg_natural_order6; break;
case 7: cinfo->natural_order = jpeg_natural_order7; break;
default: cinfo->natural_order = jpeg_natural_order; break;
}
/* Derive lim_Se from block_size */
cinfo->lim_Se = cinfo->block_size < DCTSIZE ?
cinfo->block_size * cinfo->block_size - 1 : DCTSIZE2-1;
/* Sanity check on image dimensions */
if (cinfo->image_height <= 0 || cinfo->image_width <= 0
|| cinfo->num_components <= 0 || cinfo->input_components <= 0)
if (cinfo->jpeg_height <= 0 || cinfo->jpeg_width <= 0 ||
cinfo->num_components <= 0 || cinfo->input_components <= 0)
ERREXIT(cinfo, JERR_EMPTY_IMAGE);
/* Make sure image isn't bigger than I can handle */
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
if ((long) cinfo->jpeg_height > (long) JPEG_MAX_DIMENSION ||
(long) cinfo->jpeg_width > (long) JPEG_MAX_DIMENSION)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
/* Width of an input scanline must be representable as JDIMENSION. */
@@ -82,22 +291,54 @@ initial_setup (j_compress_ptr cinfo)
/* Compute dimensions of components */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* For compression, we never do DCT scaling. */
compptr->DCT_scaled_size = DCTSIZE;
/* Fill in the correct component_index value; don't rely on application */
compptr->component_index = ci;
/* In selecting the actual DCT scaling for each component, we try to
* scale down the chroma components via DCT scaling rather than downsampling.
* This saves time if the downsampler gets to use 1:1 scaling.
* Note this code adapts subsampling ratios which are powers of 2.
*/
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
/* We don't support DCT ratios larger than 2. */
if (compptr->DCT_h_scaled_size > compptr->DCT_v_scaled_size * 2)
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
/* Size in DCT blocks */
compptr->width_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
(long) (cinfo->max_h_samp_factor * DCTSIZE));
jdiv_round_up((long) cinfo->jpeg_width * (long) compptr->h_samp_factor,
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
compptr->height_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
(long) (cinfo->max_v_samp_factor * DCTSIZE));
jdiv_round_up((long) cinfo->jpeg_height * (long) compptr->v_samp_factor,
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
/* Size in samples */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
(long) cinfo->max_h_samp_factor);
jdiv_round_up((long) cinfo->jpeg_width *
(long) (compptr->h_samp_factor * compptr->DCT_h_scaled_size),
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
compptr->downsampled_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
(long) cinfo->max_v_samp_factor);
jdiv_round_up((long) cinfo->jpeg_height *
(long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size),
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
/* Mark component needed (this flag isn't actually used for compression) */
compptr->component_needed = TRUE;
}
@@ -106,12 +347,228 @@ initial_setup (j_compress_ptr cinfo)
* main controller will call coefficient controller).
*/
cinfo->total_iMCU_rows = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE));
jdiv_round_up((long) cinfo->jpeg_height,
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
}
LOCAL void
#ifdef C_MULTISCAN_FILES_SUPPORTED
LOCAL(void)
validate_script (j_compress_ptr cinfo)
/* Verify that the scan script in cinfo->scan_info[] is valid; also
* determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
*/
{
const jpeg_scan_info * scanptr;
int scanno, ncomps, ci, coefi, thisi;
int Ss, Se, Ah, Al;
boolean component_sent[MAX_COMPONENTS];
#ifdef C_PROGRESSIVE_SUPPORTED
int * last_bitpos_ptr;
int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
/* -1 until that coefficient has been seen; then last Al for it */
#endif
if (cinfo->num_scans <= 0)
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
/* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
* for progressive JPEG, no scan can have this.
*/
scanptr = cinfo->scan_info;
if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
#ifdef C_PROGRESSIVE_SUPPORTED
cinfo->progressive_mode = TRUE;
last_bitpos_ptr = & last_bitpos[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (coefi = 0; coefi < DCTSIZE2; coefi++)
*last_bitpos_ptr++ = -1;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
cinfo->progressive_mode = FALSE;
for (ci = 0; ci < cinfo->num_components; ci++)
component_sent[ci] = FALSE;
}
for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
/* Validate component indexes */
ncomps = scanptr->comps_in_scan;
if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
for (ci = 0; ci < ncomps; ci++) {
thisi = scanptr->component_index[ci];
if (thisi < 0 || thisi >= cinfo->num_components)
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
/* Components must appear in SOF order within each scan */
if (ci > 0 && thisi <= scanptr->component_index[ci-1])
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
}
/* Validate progression parameters */
Ss = scanptr->Ss;
Se = scanptr->Se;
Ah = scanptr->Ah;
Al = scanptr->Al;
if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED
/* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
* seems wrong: the upper bound ought to depend on data precision.
* Perhaps they really meant 0..N+1 for N-bit precision.
* Here we allow 0..10 for 8-bit data; Al larger than 10 results in
* out-of-range reconstructed DC values during the first DC scan,
* which might cause problems for some decoders.
*/
#if BITS_IN_JSAMPLE == 8
#define MAX_AH_AL 10
#else
#define MAX_AH_AL 13
#endif
if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
if (Ss == 0) {
if (Se != 0) /* DC and AC together not OK */
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
} else {
if (ncomps != 1) /* AC scans must be for only one component */
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
}
for (ci = 0; ci < ncomps; ci++) {
last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
for (coefi = Ss; coefi <= Se; coefi++) {
if (last_bitpos_ptr[coefi] < 0) {
/* first scan of this coefficient */
if (Ah != 0)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
} else {
/* not first scan */
if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
}
last_bitpos_ptr[coefi] = Al;
}
}
#endif
} else {
/* For sequential JPEG, all progression parameters must be these: */
if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
/* Make sure components are not sent twice */
for (ci = 0; ci < ncomps; ci++) {
thisi = scanptr->component_index[ci];
if (component_sent[thisi])
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
component_sent[thisi] = TRUE;
}
}
}
/* Now verify that everything got sent. */
if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED
/* For progressive mode, we only check that at least some DC data
* got sent for each component; the spec does not require that all bits
* of all coefficients be transmitted. Would it be wiser to enforce
* transmission of all coefficient bits??
*/
for (ci = 0; ci < cinfo->num_components; ci++) {
if (last_bitpos[ci][0] < 0)
ERREXIT(cinfo, JERR_MISSING_DATA);
}
#endif
} else {
for (ci = 0; ci < cinfo->num_components; ci++) {
if (! component_sent[ci])
ERREXIT(cinfo, JERR_MISSING_DATA);
}
}
}
LOCAL(void)
reduce_script (j_compress_ptr cinfo)
/* Adapt scan script for use with reduced block size;
* assume that script has been validated before.
*/
{
jpeg_scan_info * scanptr;
int idxout, idxin;
/* Circumvent const declaration for this function */
scanptr = (jpeg_scan_info *) cinfo->scan_info;
idxout = 0;
for (idxin = 0; idxin < cinfo->num_scans; idxin++) {
/* After skipping, idxout becomes smaller than idxin */
if (idxin != idxout)
/* Copy rest of data;
* note we stay in given chunk of allocated memory.
*/
scanptr[idxout] = scanptr[idxin];
if (scanptr[idxout].Ss > cinfo->lim_Se)
/* Entire scan out of range - skip this entry */
continue;
if (scanptr[idxout].Se > cinfo->lim_Se)
/* Limit scan to end of block */
scanptr[idxout].Se = cinfo->lim_Se;
idxout++;
}
cinfo->num_scans = idxout;
}
#endif /* C_MULTISCAN_FILES_SUPPORTED */
LOCAL(void)
select_scan_parameters (j_compress_ptr cinfo)
/* Set up the scan parameters for the current scan */
{
int ci;
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (cinfo->scan_info != NULL) {
/* Prepare for current scan --- the script is already validated */
my_master_ptr master = (my_master_ptr) cinfo->master;
const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
cinfo->comps_in_scan = scanptr->comps_in_scan;
for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
cinfo->cur_comp_info[ci] =
&cinfo->comp_info[scanptr->component_index[ci]];
}
if (cinfo->progressive_mode) {
cinfo->Ss = scanptr->Ss;
cinfo->Se = scanptr->Se;
cinfo->Ah = scanptr->Ah;
cinfo->Al = scanptr->Al;
return;
}
}
else
#endif
{
/* Prepare for single sequential-JPEG scan containing all components */
if (cinfo->num_components > MAX_COMPS_IN_SCAN)
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
MAX_COMPS_IN_SCAN);
cinfo->comps_in_scan = cinfo->num_components;
for (ci = 0; ci < cinfo->num_components; ci++) {
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
}
}
cinfo->Ss = 0;
cinfo->Se = cinfo->block_size * cinfo->block_size - 1;
cinfo->Ah = 0;
cinfo->Al = 0;
}
LOCAL(void)
per_scan_setup (j_compress_ptr cinfo)
/* Do computations that are needed before processing a JPEG scan */
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
@@ -132,7 +589,7 @@ per_scan_setup (j_compress_ptr cinfo)
compptr->MCU_width = 1;
compptr->MCU_height = 1;
compptr->MCU_blocks = 1;
compptr->MCU_sample_width = DCTSIZE;
compptr->MCU_sample_width = compptr->DCT_h_scaled_size;
compptr->last_col_width = 1;
/* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row.
@@ -154,11 +611,11 @@ per_scan_setup (j_compress_ptr cinfo)
/* Overall image size in MCUs */
cinfo->MCUs_per_row = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width,
(long) (cinfo->max_h_samp_factor*DCTSIZE));
jdiv_round_up((long) cinfo->jpeg_width,
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
cinfo->MCU_rows_in_scan = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE));
jdiv_round_up((long) cinfo->jpeg_height,
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
cinfo->blocks_in_MCU = 0;
@@ -168,7 +625,7 @@ per_scan_setup (j_compress_ptr cinfo)
compptr->MCU_width = compptr->h_samp_factor;
compptr->MCU_height = compptr->v_samp_factor;
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_h_scaled_size;
/* Figure number of non-dummy blocks in last MCU column & row */
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
if (tmp == 0) tmp = compptr->MCU_width;
@@ -178,7 +635,7 @@ per_scan_setup (j_compress_ptr cinfo)
compptr->last_row_height = tmp;
/* Prepare array describing MCU composition */
mcublks = compptr->MCU_blocks;
if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
while (mcublks-- > 0) {
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
@@ -196,59 +653,6 @@ per_scan_setup (j_compress_ptr cinfo)
}
/*
* Master selection of compression modules.
* This is done once at the start of processing an image. We determine
* which modules will be used and give them appropriate initialization calls.
*/
LOCAL void
master_selection (j_compress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
initial_setup(cinfo);
master->pass_number = 0;
/* There's not a lot of smarts here right now, but it'll get more
* complicated when we have multiple implementations available...
*/
/* Preprocessing */
if (! cinfo->raw_data_in) {
jinit_color_converter(cinfo);
jinit_downsampler(cinfo);
jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
}
/* Forward DCT */
jinit_forward_dct(cinfo);
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef C_ARITH_CODING_SUPPORTED
jinit_arith_encoder(cinfo);
#else
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else
jinit_huff_encoder(cinfo);
/* For now, a full buffer is needed only for Huffman optimization. */
jinit_c_coef_controller(cinfo, cinfo->optimize_coding);
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo);
/* We can now tell the memory manager to allocate virtual arrays. */
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
/* Write the datastream header (SOI) immediately.
* Frame and scan headers are postponed till later.
* This lets application insert special markers after the SOI.
*/
(*cinfo->marker->write_file_header) (cinfo);
}
/*
* Per-pass setup.
* This is called at the beginning of each pass. We determine which modules
@@ -257,79 +661,81 @@ master_selection (j_compress_ptr cinfo)
* required.
*/
METHODDEF void
METHODDEF(void)
prepare_for_pass (j_compress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
int ci;
int npasses;
/* ???? JUST A QUICK CROCK FOR NOW ??? */
/* For now, handle only single interleaved output scan; */
/* we support two passes for Huffman optimization. */
/* Prepare for single scan containing all components */
if (cinfo->num_components > MAX_COMPS_IN_SCAN)
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
MAX_COMPS_IN_SCAN);
cinfo->comps_in_scan = cinfo->num_components;
for (ci = 0; ci < cinfo->num_components; ci++) {
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
}
switch (master->pass_type) {
case main_pass:
/* Initial pass: will collect input data, and do either Huffman
* optimization or data output for the first scan.
*/
select_scan_parameters(cinfo);
per_scan_setup(cinfo);
if (! cinfo->optimize_coding) {
/* Standard single-pass case */
npasses = 1;
master->pub.call_pass_startup = TRUE;
master->pub.is_last_pass = TRUE;
if (! cinfo->raw_data_in) {
(*cinfo->cconvert->start_pass) (cinfo);
(*cinfo->downsample->start_pass) (cinfo);
(*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
}
(*cinfo->fdct->start_pass) (cinfo);
(*cinfo->entropy->start_pass) (cinfo, FALSE);
(*cinfo->coef->start_pass) (cinfo, JBUF_PASS_THRU);
(*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
(*cinfo->coef->start_pass) (cinfo,
(master->total_passes > 1 ?
JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
} else {
npasses = 2;
switch (master->pass_number) {
case 0:
/* Huffman optimization: run all modules, gather statistics */
if (cinfo->optimize_coding) {
/* No immediate data output; postpone writing frame/scan headers */
master->pub.call_pass_startup = FALSE;
master->pub.is_last_pass = FALSE;
if (! cinfo->raw_data_in) {
(*cinfo->cconvert->start_pass) (cinfo);
(*cinfo->downsample->start_pass) (cinfo);
(*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
} else {
/* Will write frame/scan headers at first jpeg_write_scanlines call */
master->pub.call_pass_startup = TRUE;
}
(*cinfo->fdct->start_pass) (cinfo);
(*cinfo->entropy->start_pass) (cinfo, TRUE);
(*cinfo->coef->start_pass) (cinfo, JBUF_SAVE_AND_PASS);
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
break;
case 1:
/* Second pass: reread data from coefficient buffer */
master->pub.is_last_pass = TRUE;
#ifdef ENTROPY_OPT_SUPPORTED
case huff_opt_pass:
/* Do Huffman optimization for a scan after the first one. */
select_scan_parameters(cinfo);
per_scan_setup(cinfo);
if (cinfo->Ss != 0 || cinfo->Ah == 0) {
(*cinfo->entropy->start_pass) (cinfo, TRUE);
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
master->pub.call_pass_startup = FALSE;
break;
}
/* Special case: Huffman DC refinement scans need no Huffman table
* and therefore we can skip the optimization pass for them.
*/
master->pass_type = output_pass;
master->pass_number++;
/*FALLTHROUGH*/
#endif
case output_pass:
/* Do a data-output pass. */
/* We need not repeat per-scan setup if prior optimization pass did it. */
if (! cinfo->optimize_coding) {
select_scan_parameters(cinfo);
per_scan_setup(cinfo);
}
(*cinfo->entropy->start_pass) (cinfo, FALSE);
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
/* We emit frame/scan headers now */
if (master->scan_number == 0)
(*cinfo->marker->write_frame_header) (cinfo);
(*cinfo->marker->write_scan_header) (cinfo);
master->pub.call_pass_startup = FALSE;
break;
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
}
}
master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
/* Set up progress monitor's pass info if present */
if (cinfo->progress != NULL) {
cinfo->progress->completed_passes = master->pass_number;
cinfo->progress->total_passes = npasses;
cinfo->progress->total_passes = master->total_passes;
}
master->pass_number++;
}
@@ -343,7 +749,7 @@ prepare_for_pass (j_compress_ptr cinfo)
* In multi-pass processing, this routine is not used.
*/
METHODDEF void
METHODDEF(void)
pass_startup (j_compress_ptr cinfo)
{
cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
@@ -357,26 +763,48 @@ pass_startup (j_compress_ptr cinfo)
* Finish up at end of pass.
*/
METHODDEF void
METHODDEF(void)
finish_pass_master (j_compress_ptr cinfo)
{
/* More complex logic later ??? */
my_master_ptr master = (my_master_ptr) cinfo->master;
/* The entropy coder needs an end-of-pass call, either to analyze
* statistics or to flush its output buffer.
/* The entropy coder always needs an end-of-pass call,
* either to analyze statistics or to flush its output buffer.
*/
(*cinfo->entropy->finish_pass) (cinfo);
/* Update state for next pass */
switch (master->pass_type) {
case main_pass:
/* next pass is either output of scan 0 (after optimization)
* or output of scan 1 (if no optimization).
*/
master->pass_type = output_pass;
if (! cinfo->optimize_coding)
master->scan_number++;
break;
case huff_opt_pass:
/* next pass is always output of current scan */
master->pass_type = output_pass;
break;
case output_pass:
/* next pass is either optimization or output of next scan */
if (cinfo->optimize_coding)
master->pass_type = huff_opt_pass;
master->scan_number++;
break;
}
master->pass_number++;
}
/*
* Initialize master compression control.
* This creates my own subrecord and also performs the master selection phase,
* which causes other modules to create their subrecords.
*/
GLOBAL void
jinit_master_compress (j_compress_ptr cinfo)
GLOBAL(void)
jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
{
my_master_ptr master;
@@ -387,6 +815,44 @@ jinit_master_compress (j_compress_ptr cinfo)
master->pub.prepare_for_pass = prepare_for_pass;
master->pub.pass_startup = pass_startup;
master->pub.finish_pass = finish_pass_master;
master->pub.is_last_pass = FALSE;
master_selection(cinfo);
/* Validate parameters, determine derived values */
initial_setup(cinfo, transcode_only);
if (cinfo->scan_info != NULL) {
#ifdef C_MULTISCAN_FILES_SUPPORTED
validate_script(cinfo);
if (cinfo->block_size < DCTSIZE)
reduce_script(cinfo);
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
cinfo->progressive_mode = FALSE;
cinfo->num_scans = 1;
}
if ((cinfo->progressive_mode || cinfo->block_size < DCTSIZE) &&
!cinfo->arith_code) /* TEMPORARY HACK ??? */
/* assume default tables no good for progressive or downscale mode */
cinfo->optimize_coding = TRUE;
/* Initialize my private state */
if (transcode_only) {
/* no main pass in transcoding */
if (cinfo->optimize_coding)
master->pass_type = huff_opt_pass;
else
master->pass_type = output_pass;
} else {
/* for normal compression, first pass is always this type: */
master->pass_type = main_pass;
}
master->scan_number = 0;
master->pass_number = 0;
if (cinfo->optimize_coding)
master->total_passes = cinfo->num_scans * 2;
else
master->total_passes = cinfo->num_scans;
}

View File

@@ -1,7 +1,7 @@
/*
* jcomapi.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -25,11 +25,15 @@
* responsibility.
*/
GLOBAL void
GLOBAL(void)
jpeg_abort (j_common_ptr cinfo)
{
int pool;
/* Do nothing if called on a not-initialized or destroyed JPEG object. */
if (cinfo->mem == NULL)
return;
/* Releasing pools in reverse order might help avoid fragmentation
* with some (brain-damaged) malloc libraries.
*/
@@ -38,7 +42,15 @@ jpeg_abort (j_common_ptr cinfo)
}
/* Reset overall state for possible reuse of object */
cinfo->global_state = (cinfo->is_decompressor ? DSTATE_START : CSTATE_START);
if (cinfo->is_decompressor) {
cinfo->global_state = DSTATE_START;
/* Try to keep application from accessing now-deleted marker list.
* A bit kludgy to do it here, but this is the most central place.
*/
((j_decompress_ptr) cinfo)->marker_list = NULL;
} else {
cinfo->global_state = CSTATE_START;
}
}
@@ -53,7 +65,7 @@ jpeg_abort (j_common_ptr cinfo)
* responsibility.
*/
GLOBAL void
GLOBAL(void)
jpeg_destroy (j_common_ptr cinfo)
{
/* We need only tell the memory manager to release everything. */
@@ -70,7 +82,7 @@ jpeg_destroy (j_common_ptr cinfo)
* (Would jutils.c be a more reasonable place to put these?)
*/
GLOBAL JQUANT_TBL *
GLOBAL(JQUANT_TBL *)
jpeg_alloc_quant_table (j_common_ptr cinfo)
{
JQUANT_TBL *tbl;
@@ -82,7 +94,7 @@ jpeg_alloc_quant_table (j_common_ptr cinfo)
}
GLOBAL JHUFF_TBL *
GLOBAL(JHUFF_TBL *)
jpeg_alloc_huff_table (j_common_ptr cinfo)
{
JHUFF_TBL *tbl;

View File

@@ -1,5 +1,5 @@
/* jconfig.bcc --- jconfig.h for Borland C (Turbo C) on MS-DOS or OS/2. */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR

View File

@@ -1,5 +1,5 @@
/* jconfig.cfg --- source file edited by configure script */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#undef HAVE_PROTOTYPES
#undef HAVE_UNSIGNED_CHAR
@@ -9,6 +9,7 @@
#undef CHAR_IS_UNSIGNED
#undef HAVE_STDDEF_H
#undef HAVE_STDLIB_H
#undef HAVE_LOCALE_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS
@@ -16,6 +17,14 @@
/* Define this if you get warnings about undefined structures. */
#undef INCOMPLETE_TYPES_BROKEN
/* Define "boolean" as unsigned char, not int, on Windows systems. */
#ifdef _WIN32
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
#endif
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED

View File

@@ -1,5 +1,5 @@
/* jconfig.dj --- jconfig.h for DJGPP (Delorie's GNU C port) on MS-DOS. */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR

43
jconfig.mac Normal file
View File

@@ -0,0 +1,43 @@
/* jconfig.mac --- jconfig.h for CodeWarrior on Apple Macintosh */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#define USE_MAC_MEMMGR /* Define this if you use jmemmac.c */
#define ALIGN_TYPE long /* Needed for 680x0 Macs */
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define USE_CCOMMAND /* Command line reader for Macintosh */
#define TWO_FILE_COMMANDLINE /* Binary I/O thru stdin/stdout doesn't work */
#undef NEED_SIGNAL_CATCHER
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,5 +1,5 @@
/* jconfig.manx --- jconfig.h for Amiga systems using Manx Aztec C ver 5.x. */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR

View File

@@ -1,5 +1,5 @@
/* jconfig.mc6 --- jconfig.h for Microsoft C on MS-DOS, version 6.00A & up. */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
@@ -30,7 +30,7 @@
#define SHORTxLCONST_32 /* enable compiler-specific DCT optimization */
/* Note: the above define is known to improve the code with Microsoft C 6.00A.
* I do not know whether it is good for later compiler versions.
* Please report any info on this point to jpeg-info@uunet.uu.net.
* Please report any info on this point to jpeg-info@jpegclub.org.
*/
#endif /* JPEG_INTERNALS */

View File

@@ -1,5 +1,5 @@
/* jconfig.sas --- jconfig.h for Amiga systems using SAS C 6.0 and up. */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR

View File

@@ -1,5 +1,5 @@
/* jconfig.st --- jconfig.h for Atari ST/STE/TT using Pure C or Turbo C. */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
@@ -32,6 +32,9 @@
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE /* optional -- undef if you like Unix style */
/* Note: if you undef TWO_FILE_COMMANDLINE, you may need to define
* USE_SETMODE. Some Atari compilers require it, some do not.
*/
#define NEED_SIGNAL_CATCHER /* needed if you use jmemname.c */
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */

View File

@@ -1,5 +1,5 @@
/*
* jconfig.doc
* jconfig.txt
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
@@ -24,7 +24,7 @@
*/
/* Does your compiler support function prototypes?
* (If not, you also need to use ansi2knr, see install.doc)
* (If not, you also need to use ansi2knr, see install.txt)
*/
#define HAVE_PROTOTYPES
@@ -91,6 +91,15 @@
*/
#undef INCOMPLETE_TYPES_BROKEN
/* Define "boolean" as unsigned char, not int, on Windows systems.
*/
#ifdef _WIN32
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
#endif
/*
* The following options affect code selection within the JPEG library,

45
jconfig.vc Normal file
View File

@@ -0,0 +1,45 @@
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
/* Define "boolean" as unsigned char, not int, per Windows custom */
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#define TWO_FILE_COMMANDLINE /* optional */
#define USE_SETMODE /* Microsoft has setmode() */
#undef NEED_SIGNAL_CATCHER
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

View File

@@ -1,5 +1,5 @@
/* jconfig.vms --- jconfig.h for use on Digital VMS. */
/* see jconfig.doc for explanations */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR

38
jconfig.wat Normal file
View File

@@ -0,0 +1,38 @@
/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */
/* see jconfig.txt for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#define CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */
#undef NEED_SHORT_EXTERNAL_NAMES
#undef INCOMPLETE_TYPES_BROKEN
#ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED
#endif /* JPEG_INTERNALS */
#ifdef JPEG_CJPEG_DJPEG
#define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
#undef RLE_SUPPORTED /* Utah RLE image file format */
#define TARGA_SUPPORTED /* Targa image file format */
#undef TWO_FILE_COMMANDLINE /* optional */
#define USE_SETMODE /* Needed to make one-file style work in Watcom */
#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */
#undef DONT_USE_B_MODE
#undef PROGRESS_REPORT /* optional */
#endif /* JPEG_CJPEG_DJPEG */

291
jcparam.c
View File

@@ -1,7 +1,8 @@
/*
* jcparam.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2008 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -19,7 +20,7 @@
* Quantization table setup routines
*/
GLOBAL void
GLOBAL(void)
jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table,
int scale_factor, boolean force_baseline)
@@ -29,7 +30,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
* are limited to 1..255 for JPEG baseline compatibility.
*/
{
JQUANT_TBL ** qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
JQUANT_TBL ** qtblptr;
int i;
long temp;
@@ -37,6 +38,11 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (which_tbl < 0 || which_tbl >= NUM_QUANT_TBLS)
ERREXIT1(cinfo, JERR_DQT_INDEX, which_tbl);
qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
if (*qtblptr == NULL)
*qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
@@ -55,7 +61,48 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
}
GLOBAL void
/* These are the sample quantization tables given in JPEG spec section K.1.
* The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality.
*/
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
};
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99,
47, 66, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
GLOBAL(void)
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables
* and straight percentage-scaling quality scales.
* This entry point allows different scalings for luminance and chrominance.
*/
{
/* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
cinfo->q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
cinfo->q_scale_factor[1], force_baseline);
}
GLOBAL(void)
jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables
@@ -64,32 +111,6 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
* applications that insist on a linear percentage scaling.
*/
{
/* This is the sample quantization table given in the JPEG spec section K.1,
* but expressed in zigzag order (as are all of our quant. tables).
* The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality.
*/
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
16, 11, 12, 14, 12, 10, 16, 14,
13, 14, 18, 17, 16, 19, 24, 40,
26, 24, 22, 22, 24, 49, 35, 37,
29, 40, 58, 51, 61, 60, 57, 51,
56, 55, 64, 72, 92, 78, 64, 68,
87, 69, 55, 56, 80, 109, 81, 87,
95, 98, 103, 104, 103, 62, 77, 113,
121, 112, 100, 120, 92, 101, 103, 99
};
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 18, 24, 21, 24, 47, 26,
26, 47, 99, 66, 56, 66, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99
};
/* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
scale_factor, force_baseline);
@@ -98,7 +119,7 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
}
GLOBAL int
GLOBAL(int)
jpeg_quality_scaling (int quality)
/* Convert a user-specified quality rating to a percentage scaling factor
* for an underlying quantization table, using our recommended scaling curve.
@@ -111,8 +132,8 @@ jpeg_quality_scaling (int quality)
/* The basic table is used as-is (scaling 100) for a quality of 50.
* Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
* note that at Q=100 the scaling is 0, which will cause j_add_quant_table
* to make all the table entries 1 (hence, no quantization loss).
* note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
* to make all the table entries 1 (hence, minimum quantization loss).
* Qualities 1..50 are converted to scaling percentage 5000/Q.
*/
if (quality < 50)
@@ -124,7 +145,7 @@ jpeg_quality_scaling (int quality)
}
GLOBAL void
GLOBAL(void)
jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables.
* This is the standard quality-adjusting entry point for typical user
@@ -144,23 +165,37 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
* Huffman table setup routines
*/
LOCAL void
LOCAL(void)
add_huff_table (j_compress_ptr cinfo,
JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
/* Define a Huffman table */
{
int nsymbols, len;
if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
/* Copy the number-of-symbols-of-each-code-length counts */
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
MEMCOPY((*htblptr)->huffval, val, SIZEOF((*htblptr)->huffval));
/* Validate the counts. We do this here mainly so we can copy the right
* number of symbols from the val[] array, without risking marching off
* the end of memory. jchuff.c will do a more thorough test later.
*/
nsymbols = 0;
for (len = 1; len <= 16; len++)
nsymbols += bits[len];
if (nsymbols < 1 || nsymbols > 256)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
/* Initialize sent_table FALSE so table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE;
}
LOCAL void
LOCAL(void)
std_huff_tables (j_compress_ptr cinfo)
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
/* IMPORTANT: these are only valid for 8-bit data precision! */
@@ -246,7 +281,7 @@ std_huff_tables (j_compress_ptr cinfo)
* your code will still work (they'll be set to reasonable defaults).
*/
GLOBAL void
GLOBAL(void)
jpeg_set_defaults (j_compress_ptr cinfo)
{
int i;
@@ -266,6 +301,8 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Initialize everything not dependent on the color space */
cinfo->scale_num = 1; /* 1:1 scaling */
cinfo->scale_denom = 1;
cinfo->data_precision = BITS_IN_JSAMPLE;
/* Set up two quantization tables using default quality of 75 */
jpeg_set_quality(cinfo, 75, TRUE);
@@ -279,15 +316,16 @@ jpeg_set_defaults (j_compress_ptr cinfo)
cinfo->arith_ac_K[i] = 5;
}
/* Default is no multiple-scan output */
cinfo->scan_info = NULL;
cinfo->num_scans = 0;
/* Expect normal source image, not raw downsampled data */
cinfo->raw_data_in = FALSE;
/* Use Huffman coding, not arithmetic coding, by default */
cinfo->arith_code = FALSE;
/* Color images are interleaved by default */
cinfo->interleave = TRUE;
/* By default, don't do extra passes to optimize entropy coding */
cinfo->optimize_coding = FALSE;
/* The standard Huffman tables are only valid for 8-bit data precision.
@@ -301,6 +339,9 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* By default, use the simpler non-cosited sampling alignment */
cinfo->CCIR601_sampling = FALSE;
/* By default, apply fancy downsampling */
cinfo->do_fancy_downsampling = TRUE;
/* No input smoothing */
cinfo->smoothing_factor = 0;
@@ -313,7 +354,15 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Fill in default JFIF marker parameters. Note that whether the marker
* will actually be written is determined by jpeg_set_colorspace.
*
* By default, the library emits JFIF version code 1.01.
* An application that wants to emit JFIF 1.02 extension markers should set
* JFIF_minor_version to 2. We could probably get away with just defaulting
* to 1.02, but there may still be some decoders in use that will complain
* about that; saying 1.01 should minimize compatibility problems.
*/
cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
cinfo->JFIF_minor_version = 1;
cinfo->density_unit = 0; /* Pixel size is unknown by default */
cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
cinfo->Y_density = 1;
@@ -328,7 +377,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
* Select an appropriate JPEG colorspace for in_color_space.
*/
GLOBAL void
GLOBAL(void)
jpeg_default_colorspace (j_compress_ptr cinfo)
{
switch (cinfo->in_color_space) {
@@ -360,7 +409,7 @@ jpeg_default_colorspace (j_compress_ptr cinfo)
* Set the JPEG colorspace, and choose colorspace-dependent default values.
*/
GLOBAL void
GLOBAL(void)
jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
{
jpeg_component_info * compptr;
@@ -368,7 +417,6 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \
(compptr = &cinfo->comp_info[index], \
compptr->component_index = (index), \
compptr->component_id = (id), \
compptr->h_samp_factor = (hsamp), \
compptr->v_samp_factor = (vsamp), \
@@ -399,9 +447,9 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
case JCS_RGB:
cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
cinfo->num_components = 3;
SET_COMP(0, 'R', 1,1, 0, 0,0);
SET_COMP(1, 'G', 1,1, 0, 0,0);
SET_COMP(2, 'B', 1,1, 0, 0,0);
SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
break;
case JCS_YCbCr:
cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
@@ -415,10 +463,10 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
case JCS_CMYK:
cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
cinfo->num_components = 4;
SET_COMP(0, 'C', 1,1, 0, 0,0);
SET_COMP(1, 'M', 1,1, 0, 0,0);
SET_COMP(2, 'Y', 1,1, 0, 0,0);
SET_COMP(3, 'K', 1,1, 0, 0,0);
SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0);
SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0);
SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0);
SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0);
break;
case JCS_YCCK:
cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
@@ -441,3 +489,144 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
}
}
#ifdef C_PROGRESSIVE_SUPPORTED
LOCAL(jpeg_scan_info *)
fill_a_scan (jpeg_scan_info * scanptr, int ci,
int Ss, int Se, int Ah, int Al)
/* Support routine: generate one scan for specified component */
{
scanptr->comps_in_scan = 1;
scanptr->component_index[0] = ci;
scanptr->Ss = Ss;
scanptr->Se = Se;
scanptr->Ah = Ah;
scanptr->Al = Al;
scanptr++;
return scanptr;
}
LOCAL(jpeg_scan_info *)
fill_scans (jpeg_scan_info * scanptr, int ncomps,
int Ss, int Se, int Ah, int Al)
/* Support routine: generate one scan for each component */
{
int ci;
for (ci = 0; ci < ncomps; ci++) {
scanptr->comps_in_scan = 1;
scanptr->component_index[0] = ci;
scanptr->Ss = Ss;
scanptr->Se = Se;
scanptr->Ah = Ah;
scanptr->Al = Al;
scanptr++;
}
return scanptr;
}
LOCAL(jpeg_scan_info *)
fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
/* Support routine: generate interleaved DC scan if possible, else N scans */
{
int ci;
if (ncomps <= MAX_COMPS_IN_SCAN) {
/* Single interleaved DC scan */
scanptr->comps_in_scan = ncomps;
for (ci = 0; ci < ncomps; ci++)
scanptr->component_index[ci] = ci;
scanptr->Ss = scanptr->Se = 0;
scanptr->Ah = Ah;
scanptr->Al = Al;
scanptr++;
} else {
/* Noninterleaved DC scan for each component */
scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al);
}
return scanptr;
}
/*
* Create a recommended progressive-JPEG script.
* cinfo->num_components and cinfo->jpeg_color_space must be correct.
*/
GLOBAL(void)
jpeg_simple_progression (j_compress_ptr cinfo)
{
int ncomps = cinfo->num_components;
int nscans;
jpeg_scan_info * scanptr;
/* Safety check to ensure start_compress not called yet. */
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Figure space needed for script. Calculation must match code below! */
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
/* Custom script for YCbCr color images. */
nscans = 10;
} else {
/* All-purpose script for other color spaces. */
if (ncomps > MAX_COMPS_IN_SCAN)
nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */
else
nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
}
/* Allocate space for script.
* We need to put it in the permanent pool in case the application performs
* multiple compressions without changing the settings. To avoid a memory
* leak if jpeg_simple_progression is called repeatedly for the same JPEG
* object, we try to re-use previously allocated space, and we allocate
* enough space to handle YCbCr even if initially asked for grayscale.
*/
if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
cinfo->script_space_size = MAX(nscans, 10);
cinfo->script_space = (jpeg_scan_info *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
cinfo->script_space_size * SIZEOF(jpeg_scan_info));
}
scanptr = cinfo->script_space;
cinfo->scan_info = scanptr;
cinfo->num_scans = nscans;
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
/* Custom script for YCbCr color images. */
/* Initial DC scan */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
/* Initial AC scan: get some luma data out in a hurry */
scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
/* Chroma data is too small to be worth expending many scans on */
scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
/* Complete spectral selection for luma AC */
scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
/* Refine next bit of luma AC */
scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
/* Finish DC successive approximation */
scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
/* Finish AC successive approximation */
scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
/* Luma bottom bit comes last since it's usually largest scan */
scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
} else {
/* All-purpose script for other color spaces. */
/* Successive approximation first pass */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
/* Successive approximation second pass */
scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
/* Successive approximation final pass */
scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
}
}
#endif /* C_PROGRESSIVE_SUPPORTED */

View File

@@ -1,7 +1,7 @@
/*
* jcprepct.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-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.
*
@@ -74,7 +74,7 @@ typedef my_prep_controller * my_prep_ptr;
* Initialize for a processing pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
@@ -102,7 +102,7 @@ start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* by duplicating the bottom row.
*/
LOCAL void
LOCAL(void)
expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
int input_rows, int output_rows)
{
@@ -124,7 +124,7 @@ expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
* input rows.
*/
METHODDEF void
METHODDEF(void)
pre_process_data (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail,
@@ -173,10 +173,12 @@ pre_process_data (j_compress_ptr cinfo,
*out_row_group_ctr < out_row_groups_avail) {
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
numrows = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size;
expand_bottom_edge(output_buf[ci],
compptr->width_in_blocks * DCTSIZE,
(int) (*out_row_group_ctr * compptr->v_samp_factor),
(int) (out_row_groups_avail * compptr->v_samp_factor));
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
(int) (*out_row_group_ctr * numrows),
(int) (out_row_groups_avail * numrows));
}
*out_row_group_ctr = out_row_groups_avail;
break; /* can exit outer loop without test */
@@ -191,7 +193,7 @@ pre_process_data (j_compress_ptr cinfo,
* Process some data in the context case.
*/
METHODDEF void
METHODDEF(void)
pre_process_context (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail,
@@ -202,7 +204,6 @@ pre_process_context (j_compress_ptr cinfo,
int numrows, ci;
int buf_height = cinfo->max_v_samp_factor * 3;
JDIMENSION inrows;
jpeg_component_info * compptr;
while (*out_row_group_ctr < out_row_groups_avail) {
if (*in_row_ctr < in_rows_avail) {
@@ -232,16 +233,15 @@ pre_process_context (j_compress_ptr cinfo,
/* Return for more data, unless we are at the bottom of the image. */
if (prep->rows_to_go != 0)
break;
}
/* If at bottom of image, pad to fill the conversion buffer. */
if (prep->rows_to_go == 0 &&
prep->next_buf_row < prep->next_buf_stop) {
/* When at bottom of image, pad to fill the conversion buffer. */
if (prep->next_buf_row < prep->next_buf_stop) {
for (ci = 0; ci < cinfo->num_components; ci++) {
expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
prep->next_buf_row, prep->next_buf_stop);
}
prep->next_buf_row = prep->next_buf_stop;
}
}
/* If we've gotten enough data, downsample a row group. */
if (prep->next_buf_row == prep->next_buf_stop) {
(*cinfo->downsample->downsample) (cinfo,
@@ -257,21 +257,6 @@ pre_process_context (j_compress_ptr cinfo,
prep->next_buf_row = 0;
prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
}
/* If at bottom of image, pad the output to a full iMCU height.
* Note we assume the caller is providing a one-iMCU-height output buffer!
*/
if (prep->rows_to_go == 0 &&
*out_row_group_ctr < out_row_groups_avail) {
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
expand_bottom_edge(output_buf[ci],
compptr->width_in_blocks * DCTSIZE,
(int) (*out_row_group_ctr * compptr->v_samp_factor),
(int) (out_row_groups_avail * compptr->v_samp_factor));
}
*out_row_group_ctr = out_row_groups_avail;
break; /* can exit outer loop without test */
}
}
}
@@ -280,7 +265,7 @@ pre_process_context (j_compress_ptr cinfo,
* Create the wrapped-around downsampling input buffer needed for context mode.
*/
LOCAL void
LOCAL(void)
create_context_buffer (j_compress_ptr cinfo)
{
my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
@@ -305,7 +290,8 @@ create_context_buffer (j_compress_ptr cinfo)
*/
true_buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
(JDIMENSION) (((long) compptr->width_in_blocks *
cinfo->min_DCT_h_scaled_size *
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
(JDIMENSION) (3 * rgroup_height));
/* Copy true buffer row pointers into the middle of the fake row array */
@@ -328,7 +314,7 @@ create_context_buffer (j_compress_ptr cinfo)
* Initialize preprocessing controller.
*/
GLOBAL void
GLOBAL(void)
jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{
my_prep_ptr prep;
@@ -363,7 +349,8 @@ jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
ci++, compptr++) {
prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
(JDIMENSION) (((long) compptr->width_in_blocks *
cinfo->min_DCT_h_scaled_size *
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
(JDIMENSION) cinfo->max_v_samp_factor);
}

View File

@@ -1,7 +1,7 @@
/*
* jcsample.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-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.
*
@@ -62,6 +62,15 @@ typedef struct {
/* Downsampling method pointers, one per component */
downsample1_ptr methods[MAX_COMPONENTS];
/* Height of an output row group for each component. */
int rowgroup_height[MAX_COMPONENTS];
/* These arrays save pixel expansion factors so that int_downsample need not
* recompute them each time. They are unused for other downsampling methods.
*/
UINT8 h_expand[MAX_COMPONENTS];
UINT8 v_expand[MAX_COMPONENTS];
} my_downsampler;
typedef my_downsampler * my_downsample_ptr;
@@ -71,7 +80,7 @@ typedef my_downsampler * my_downsample_ptr;
* Initialize for a downsampling pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_downsample (j_compress_ptr cinfo)
{
/* no work for now */
@@ -83,7 +92,7 @@ start_pass_downsample (j_compress_ptr cinfo)
* by duplicating the rightmost samples.
*/
LOCAL void
LOCAL(void)
expand_right_edge (JSAMPARRAY image_data, int num_rows,
JDIMENSION input_cols, JDIMENSION output_cols)
{
@@ -110,7 +119,7 @@ expand_right_edge (JSAMPARRAY image_data, int num_rows,
* In this version we simply downsample each component independently.
*/
METHODDEF void
METHODDEF(void)
sep_downsample (j_compress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_index,
JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
@@ -123,7 +132,8 @@ sep_downsample (j_compress_ptr cinfo,
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
in_ptr = input_buf[ci] + in_row_index;
out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
out_ptr = output_buf[ci] +
(out_row_group_index * downsample->rowgroup_height[ci]);
(*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
}
}
@@ -136,18 +146,19 @@ sep_downsample (j_compress_ptr cinfo,
* Note that this version is not actually used for customary sampling ratios.
*/
METHODDEF void
METHODDEF(void)
int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
JSAMPROW inptr, outptr;
INT32 outvalue;
h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
h_expand = downsample->h_expand[compptr->component_index];
v_expand = downsample->v_expand[compptr->component_index];
numpix = h_expand * v_expand;
numpix2 = numpix/2;
@@ -158,8 +169,8 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
expand_right_edge(input_data, cinfo->max_v_samp_factor,
cinfo->image_width, output_cols * h_expand);
inrow = 0;
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
inrow = outrow = 0;
while (inrow < cinfo->max_v_samp_factor) {
outptr = output_data[outrow];
for (outcol = 0, outcol_h = 0; outcol < output_cols;
outcol++, outcol_h += h_expand) {
@@ -173,6 +184,7 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
*outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
}
inrow += v_expand;
outrow++;
}
}
@@ -183,7 +195,7 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* without smoothing.
*/
METHODDEF void
METHODDEF(void)
fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
@@ -191,8 +203,8 @@ fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
jcopy_sample_rows(input_data, 0, output_data, 0,
cinfo->max_v_samp_factor, cinfo->image_width);
/* Edge-expand */
expand_right_edge(output_data, cinfo->max_v_samp_factor,
cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
expand_right_edge(output_data, cinfo->max_v_samp_factor, cinfo->image_width,
compptr->width_in_blocks * compptr->DCT_h_scaled_size);
}
@@ -208,13 +220,13 @@ fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* alternate pixel locations (a simple ordered dither pattern).
*/
METHODDEF void
METHODDEF(void)
h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
int outrow;
int inrow;
JDIMENSION outcol;
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
register JSAMPROW inptr, outptr;
register int bias;
@@ -225,9 +237,9 @@ h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
expand_right_edge(input_data, cinfo->max_v_samp_factor,
cinfo->image_width, output_cols * 2);
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
outptr = output_data[outrow];
inptr = input_data[outrow];
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
outptr = output_data[inrow];
inptr = input_data[inrow];
bias = 0; /* bias = 0,1,0,1,... for successive samples */
for (outcol = 0; outcol < output_cols; outcol++) {
*outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
@@ -245,13 +257,13 @@ h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* without smoothing.
*/
METHODDEF void
METHODDEF(void)
h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
int inrow, outrow;
JDIMENSION outcol;
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
register JSAMPROW inptr0, inptr1, outptr;
register int bias;
@@ -262,8 +274,8 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
expand_right_edge(input_data, cinfo->max_v_samp_factor,
cinfo->image_width, output_cols * 2);
inrow = 0;
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
inrow = outrow = 0;
while (inrow < cinfo->max_v_samp_factor) {
outptr = output_data[outrow];
inptr0 = input_data[inrow];
inptr1 = input_data[inrow+1];
@@ -276,6 +288,7 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
inptr0 += 2; inptr1 += 2;
}
inrow += 2;
outrow++;
}
}
@@ -288,13 +301,13 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* with smoothing. One row of context is required.
*/
METHODDEF void
METHODDEF(void)
h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
int inrow, outrow;
JDIMENSION colctr;
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
INT32 membersum, neighsum, memberscale, neighscale;
@@ -321,8 +334,8 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
inrow = 0;
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
inrow = outrow = 0;
while (inrow < cinfo->max_v_samp_factor) {
outptr = output_data[outrow];
inptr0 = input_data[inrow];
inptr1 = input_data[inrow+1];
@@ -378,6 +391,7 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
*outptr = (JSAMPLE) ((membersum + 32768) >> 16);
inrow += 2;
outrow++;
}
}
@@ -388,13 +402,13 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
* with smoothing. One row of context is required.
*/
METHODDEF void
METHODDEF(void)
fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
JSAMPARRAY input_data, JSAMPARRAY output_data)
{
int outrow;
int inrow;
JDIMENSION colctr;
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
register JSAMPROW inptr, above_ptr, below_ptr, outptr;
INT32 membersum, neighsum, memberscale, neighscale;
int colsum, lastcolsum, nextcolsum;
@@ -415,11 +429,11 @@ fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
outptr = output_data[outrow];
inptr = input_data[outrow];
above_ptr = input_data[outrow-1];
below_ptr = input_data[outrow+1];
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
outptr = output_data[inrow];
inptr = input_data[inrow];
above_ptr = input_data[inrow-1];
below_ptr = input_data[inrow+1];
/* Special case for first column */
colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
@@ -460,13 +474,14 @@ fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
* Note that we must select a routine for each component.
*/
GLOBAL void
GLOBAL(void)
jinit_downsampler (j_compress_ptr cinfo)
{
my_downsample_ptr downsample;
int ci;
jpeg_component_info * compptr;
boolean smoothok = TRUE;
int h_in_group, v_in_group, h_out_group, v_out_group;
downsample = (my_downsample_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
@@ -482,8 +497,17 @@ jinit_downsampler (j_compress_ptr cinfo)
/* Verify we can handle the sampling factors, and set up method pointers */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
compptr->v_samp_factor == cinfo->max_v_samp_factor) {
/* Compute size of an "output group" for DCT scaling. This many samples
* are to be converted from max_h_samp_factor * max_v_samp_factor pixels.
*/
h_out_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
cinfo->min_DCT_h_scaled_size;
v_out_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size;
h_in_group = cinfo->max_h_samp_factor;
v_in_group = cinfo->max_v_samp_factor;
downsample->rowgroup_height[ci] = v_out_group; /* save for use later */
if (h_in_group == h_out_group && v_in_group == v_out_group) {
#ifdef INPUT_SMOOTHING_SUPPORTED
if (cinfo->smoothing_factor) {
downsample->methods[ci] = fullsize_smooth_downsample;
@@ -491,12 +515,12 @@ jinit_downsampler (j_compress_ptr cinfo)
} else
#endif
downsample->methods[ci] = fullsize_downsample;
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
compptr->v_samp_factor == cinfo->max_v_samp_factor) {
} else if (h_in_group == h_out_group * 2 &&
v_in_group == v_out_group) {
smoothok = FALSE;
downsample->methods[ci] = h2v1_downsample;
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
} else if (h_in_group == h_out_group * 2 &&
v_in_group == v_out_group * 2) {
#ifdef INPUT_SMOOTHING_SUPPORTED
if (cinfo->smoothing_factor) {
downsample->methods[ci] = h2v2_smooth_downsample;
@@ -504,10 +528,12 @@ jinit_downsampler (j_compress_ptr cinfo)
} else
#endif
downsample->methods[ci] = h2v2_downsample;
} else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
(cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
} else if ((h_in_group % h_out_group) == 0 &&
(v_in_group % v_out_group) == 0) {
smoothok = FALSE;
downsample->methods[ci] = int_downsample;
downsample->h_expand[ci] = (UINT8) (h_in_group / h_out_group);
downsample->v_expand[ci] = (UINT8) (v_in_group / v_out_group);
} else
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
}

382
jctrans.c Normal file
View File

@@ -0,0 +1,382 @@
/*
* jctrans.c
*
* Copyright (C) 1995-1998, Thomas G. Lane.
* Modified 2000-2011 by Guido Vollbeding.
* 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 library routines for transcoding compression,
* that is, writing raw DCT coefficient arrays to an output JPEG file.
* The routines in jcapimin.c will also be needed by a transcoder.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Forward declarations */
LOCAL(void) transencode_master_selection
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
LOCAL(void) transencode_coef_controller
JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
/*
* Compression initialization for writing raw-coefficient data.
* Before calling this, all parameters and a data destination must be set up.
* Call jpeg_finish_compress() to actually write the data.
*
* The number of passed virtual arrays must match cinfo->num_components.
* Note that the virtual arrays need not be filled or even realized at
* the time write_coefficients is called; indeed, if the virtual arrays
* were requested from this compression object's memory manager, they
* typically will be realized during this routine and filled afterwards.
*/
GLOBAL(void)
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
{
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Mark all tables to be written */
jpeg_suppress_tables(cinfo, FALSE);
/* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->dest->init_destination) (cinfo);
/* Perform master selection of active modules */
transencode_master_selection(cinfo, coef_arrays);
/* Wait for jpeg_finish_compress() call */
cinfo->next_scanline = 0; /* so jpeg_write_marker works */
cinfo->global_state = CSTATE_WRCOEFS;
}
/*
* Initialize the compression object with default parameters,
* then copy from the source object all parameters needed for lossless
* transcoding. Parameters that can be varied without loss (such as
* scan script and Huffman optimization) are left in their default states.
*/
GLOBAL(void)
jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
j_compress_ptr dstinfo)
{
JQUANT_TBL ** qtblptr;
jpeg_component_info *incomp, *outcomp;
JQUANT_TBL *c_quant, *slot_quant;
int tblno, ci, coefi;
/* Safety check to ensure start_compress not called yet. */
if (dstinfo->global_state != CSTATE_START)
ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
/* Copy fundamental image dimensions */
dstinfo->image_width = srcinfo->image_width;
dstinfo->image_height = srcinfo->image_height;
dstinfo->input_components = srcinfo->num_components;
dstinfo->in_color_space = srcinfo->jpeg_color_space;
dstinfo->jpeg_width = srcinfo->output_width;
dstinfo->jpeg_height = srcinfo->output_height;
dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size;
dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size;
/* Initialize all parameters to default values */
jpeg_set_defaults(dstinfo);
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
* Fix it to get the right header markers for the image colorspace.
*/
jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
dstinfo->data_precision = srcinfo->data_precision;
dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
/* Copy the source's quantization tables. */
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
if (*qtblptr == NULL)
*qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
MEMCOPY((*qtblptr)->quantval,
srcinfo->quant_tbl_ptrs[tblno]->quantval,
SIZEOF((*qtblptr)->quantval));
(*qtblptr)->sent_table = FALSE;
}
}
/* Copy the source's per-component info.
* Note we assume jpeg_set_defaults has allocated the dest comp_info array.
*/
dstinfo->num_components = srcinfo->num_components;
if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
MAX_COMPONENTS);
for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
outcomp->component_id = incomp->component_id;
outcomp->h_samp_factor = incomp->h_samp_factor;
outcomp->v_samp_factor = incomp->v_samp_factor;
outcomp->quant_tbl_no = incomp->quant_tbl_no;
/* Make sure saved quantization table for component matches the qtable
* slot. If not, the input file re-used this qtable slot.
* IJG encoder currently cannot duplicate this.
*/
tblno = outcomp->quant_tbl_no;
if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
srcinfo->quant_tbl_ptrs[tblno] == NULL)
ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
slot_quant = srcinfo->quant_tbl_ptrs[tblno];
c_quant = incomp->quant_table;
if (c_quant != NULL) {
for (coefi = 0; coefi < DCTSIZE2; coefi++) {
if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
}
}
/* Note: we do not copy the source's Huffman table assignments;
* instead we rely on jpeg_set_colorspace to have made a suitable choice.
*/
}
/* Also copy JFIF version and resolution information, if available.
* Strictly speaking this isn't "critical" info, but it's nearly
* always appropriate to copy it if available. In particular,
* if the application chooses to copy JFIF 1.02 extension markers from
* the source file, we need to copy the version to make sure we don't
* emit a file that has 1.02 extensions but a claimed version of 1.01.
* We will *not*, however, copy version info from mislabeled "2.01" files.
*/
if (srcinfo->saw_JFIF_marker) {
if (srcinfo->JFIF_major_version == 1) {
dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
}
dstinfo->density_unit = srcinfo->density_unit;
dstinfo->X_density = srcinfo->X_density;
dstinfo->Y_density = srcinfo->Y_density;
}
}
/*
* Master selection of compression modules for transcoding.
* This substitutes for jcinit.c's initialization of the full compressor.
*/
LOCAL(void)
transencode_master_selection (j_compress_ptr cinfo,
jvirt_barray_ptr * coef_arrays)
{
/* Initialize master control (includes parameter checking/processing) */
jinit_c_master_control(cinfo, TRUE /* transcode only */);
/* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code)
jinit_arith_encoder(cinfo);
else {
jinit_huff_encoder(cinfo);
}
/* We need a special coefficient buffer controller. */
transencode_coef_controller(cinfo, coef_arrays);
jinit_marker_writer(cinfo);
/* We can now tell the memory manager to allocate virtual arrays. */
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
/* Write the datastream header (SOI, JFIF) immediately.
* Frame and scan headers are postponed till later.
* This lets application insert special markers after the SOI.
*/
(*cinfo->marker->write_file_header) (cinfo);
}
/*
* The rest of this file is a special implementation of the coefficient
* buffer controller. This is similar to jccoefct.c, but it handles only
* output from presupplied virtual arrays. Furthermore, we generate any
* dummy padding blocks on-the-fly rather than expecting them to be present
* in the arrays.
*/
/* Private buffer controller object */
typedef struct {
struct jpeg_c_coef_controller pub; /* public fields */
JDIMENSION iMCU_row_num; /* iMCU row # within image */
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
int MCU_vert_offset; /* counts MCU rows within iMCU row */
int MCU_rows_per_iMCU_row; /* number of such rows needed */
/* Virtual block array for each component. */
jvirt_barray_ptr * whole_image;
/* Workspace for constructing dummy blocks at right/bottom edges. */
JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
} my_coef_controller;
typedef my_coef_controller * my_coef_ptr;
LOCAL(void)
start_iMCU_row (j_compress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
/* In an interleaved scan, an MCU row is the same as an iMCU row.
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
* But at the bottom of the image, process only what's left.
*/
if (cinfo->comps_in_scan > 1) {
coef->MCU_rows_per_iMCU_row = 1;
} else {
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
else
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
}
coef->mcu_ctr = 0;
coef->MCU_vert_offset = 0;
}
/*
* Initialize for a processing pass.
*/
METHODDEF(void)
start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
if (pass_mode != JBUF_CRANK_DEST)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->iMCU_row_num = 0;
start_iMCU_row(cinfo);
}
/*
* Process some data.
* We process the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor block rows for each component in the scan.
* The data is obtained from the virtual arrays and fed to the entropy coder.
* Returns TRUE if the iMCU row is completed, FALSE if suspended.
*
* NB: input_buf is ignored; it is likely to be a NULL pointer.
*/
METHODDEF(boolean)
compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
int blkn, ci, xindex, yindex, yoffset, blockcnt;
JDIMENSION start_col;
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
JBLOCKROW buffer_ptr;
jpeg_component_info *compptr;
/* Align the virtual buffers for the components used in this scan. */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
buffer[ci] = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, FALSE);
}
/* Loop to process one whole iMCU row */
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
yoffset++) {
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
MCU_col_num++) {
/* Construct list of pointers to DCT blocks belonging to this MCU */
blkn = 0; /* index of current DCT block within MCU */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
start_col = MCU_col_num * compptr->MCU_width;
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
: compptr->last_col_width;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (coef->iMCU_row_num < last_iMCU_row ||
yindex+yoffset < compptr->last_row_height) {
/* Fill in pointers to real blocks in this row */
buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
for (xindex = 0; xindex < blockcnt; xindex++)
MCU_buffer[blkn++] = buffer_ptr++;
} else {
/* At bottom of image, need a whole row of dummy blocks */
xindex = 0;
}
/* Fill in any dummy blocks needed in this row.
* Dummy blocks are filled in the same way as in jccoefct.c:
* all zeroes in the AC entries, DC entries equal to previous
* block's DC value. The init routine has already zeroed the
* AC entries, so we need only set the DC entries correctly.
*/
for (; xindex < compptr->MCU_width; xindex++) {
MCU_buffer[blkn] = coef->dummy_buffer[blkn];
MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
blkn++;
}
}
}
/* Try to write the MCU. */
if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
/* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
coef->mcu_ctr = MCU_col_num;
return FALSE;
}
}
/* Completed an MCU row, but perhaps not an iMCU row */
coef->mcu_ctr = 0;
}
/* Completed the iMCU row, advance counters for next one */
coef->iMCU_row_num++;
start_iMCU_row(cinfo);
return TRUE;
}
/*
* Initialize coefficient buffer controller.
*
* Each passed coefficient array must be the right size for that
* coefficient: width_in_blocks wide and height_in_blocks high,
* with unitheight at least v_samp_factor.
*/
LOCAL(void)
transencode_coef_controller (j_compress_ptr cinfo,
jvirt_barray_ptr * coef_arrays)
{
my_coef_ptr coef;
JBLOCKROW buffer;
int i;
coef = (my_coef_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_coef_controller));
cinfo->coef = (struct jpeg_c_coef_controller *) coef;
coef->pub.start_pass = start_pass_coef;
coef->pub.compress_data = compress_output;
/* Save pointer to virtual arrays */
coef->whole_image = coef_arrays;
/* Allocate and pre-zero space for dummy DCT blocks. */
buffer = (JBLOCKROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
FMEMZERO((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
coef->dummy_buffer[i] = buffer + i;
}
}

View File

@@ -1,14 +1,20 @@
/*
* jdapi.c
* jdapimin.c
*
* Copyright (C) 1994-1995, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* 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 application interface code for the decompression half of
* the JPEG library. Most of the routines intended to be called directly by
* an application are in this file. But also see jcomapi.c for routines
* shared by compression and decompression.
* This file contains application interface code for the decompression half
* of the JPEG library. These are the "minimum" API routines that may be
* needed in either the normal full-decompression case or the
* transcoding-only case.
*
* Most of the routines intended to be called directly by an application
* are in this file or in jdapistd.c. But also see jcomapi.c for routines
* shared by compression and decompression, and jdtrans.c for the transcoding
* case.
*/
#define JPEG_INTERNALS
@@ -21,18 +27,31 @@
* The error manager must already be set up (in case memory manager fails).
*/
GLOBAL void
jpeg_create_decompress (j_decompress_ptr cinfo)
GLOBAL(void)
jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
{
int i;
/* For debugging purposes, zero the whole master structure.
* But error manager pointer is already there, so save and restore it.
/* Guard against version mismatches between library and caller. */
cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
if (version != JPEG_LIB_VERSION)
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
if (structsize != SIZEOF(struct jpeg_decompress_struct))
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
(int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
/* For debugging purposes, we zero the whole master structure.
* But the application has already set the err pointer, and may have set
* client_data, so we have to save and restore those fields.
* Note: if application hasn't set client_data, tools like Purify may
* complain here.
*/
{
struct jpeg_error_mgr * err = cinfo->err;
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
cinfo->err = err;
cinfo->client_data = client_data;
}
cinfo->is_decompressor = TRUE;
@@ -51,14 +70,15 @@ jpeg_create_decompress (j_decompress_ptr cinfo)
cinfo->ac_huff_tbl_ptrs[i] = NULL;
}
cinfo->sample_range_limit = NULL;
/* Initialize marker processor so application can override methods
* for COM, APPn markers before calling jpeg_read_header.
*/
cinfo->marker = NULL;
cinfo->marker_list = NULL;
jinit_marker_reader(cinfo);
/* And initialize the overall input controller. */
jinit_input_controller(cinfo);
/* OK, I'm ready */
cinfo->global_state = DSTATE_START;
}
@@ -68,7 +88,7 @@ jpeg_create_decompress (j_decompress_ptr cinfo)
* Destruction of a JPEG decompression object
*/
GLOBAL void
GLOBAL(void)
jpeg_destroy_decompress (j_decompress_ptr cinfo)
{
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
@@ -76,19 +96,14 @@ jpeg_destroy_decompress (j_decompress_ptr cinfo)
/*
* Install a special processing method for COM or APPn markers.
* Abort processing of a JPEG decompression operation,
* but don't destroy the object itself.
*/
GLOBAL void
jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
jpeg_marker_parser_method routine)
GLOBAL(void)
jpeg_abort_decompress (j_decompress_ptr cinfo)
{
if (marker_code == JPEG_COM)
cinfo->marker->process_COM = routine;
else if (marker_code >= JPEG_APP0 && marker_code <= JPEG_APP0+15)
cinfo->marker->process_APPn[marker_code-JPEG_APP0] = routine;
else
ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
}
@@ -96,7 +111,7 @@ jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
* Set default decompression parameters.
*/
LOCAL void
LOCAL(void)
default_decompress_parms (j_decompress_ptr cinfo)
{
/* Guess the input colorspace, and set output colorspace accordingly. */
@@ -171,19 +186,28 @@ default_decompress_parms (j_decompress_ptr cinfo)
}
/* Set defaults for other decompression parameters. */
cinfo->scale_num = 1; /* 1:1 scaling */
cinfo->scale_denom = 1;
cinfo->scale_num = cinfo->block_size; /* 1:1 scaling */
cinfo->scale_denom = cinfo->block_size;
cinfo->output_gamma = 1.0;
cinfo->buffered_image = FALSE;
cinfo->raw_data_out = FALSE;
cinfo->quantize_colors = FALSE;
/* We set these in case application only sets quantize_colors. */
cinfo->two_pass_quantize = TRUE;
cinfo->dither_mode = JDITHER_FS;
cinfo->desired_number_of_colors = 256;
cinfo->colormap = NULL;
/* DCT algorithm preference */
cinfo->dct_method = JDCT_DEFAULT;
cinfo->do_fancy_upsampling = TRUE;
cinfo->do_block_smoothing = TRUE;
cinfo->quantize_colors = FALSE;
/* We set these in case application only sets quantize_colors. */
cinfo->dither_mode = JDITHER_FS;
#ifdef QUANT_2PASS_SUPPORTED
cinfo->two_pass_quantize = TRUE;
#else
cinfo->two_pass_quantize = FALSE;
#endif
cinfo->desired_number_of_colors = 256;
cinfo->colormap = NULL;
/* Initialize for no mode change in buffered-image mode. */
cinfo->enable_1pass_quant = FALSE;
cinfo->enable_external_quant = FALSE;
cinfo->enable_2pass_quant = FALSE;
}
@@ -209,46 +233,37 @@ default_decompress_parms (j_decompress_ptr cinfo)
* processing.
* If a non-suspending data source is used and require_image is TRUE, then the
* return code need not be inspected since only JPEG_HEADER_OK is possible.
*
* This routine is now just a front end to jpeg_consume_input, with some
* extra error checking.
*/
GLOBAL int
GLOBAL(int)
jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
{
int retcode;
if (cinfo->global_state == DSTATE_START) {
/* First-time actions: reset appropriate modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->marker->reset_marker_reader) (cinfo);
(*cinfo->src->init_source) (cinfo);
cinfo->global_state = DSTATE_INHEADER;
} else if (cinfo->global_state != DSTATE_INHEADER) {
if (cinfo->global_state != DSTATE_START &&
cinfo->global_state != DSTATE_INHEADER)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
}
retcode = (*cinfo->marker->read_markers) (cinfo);
retcode = jpeg_consume_input(cinfo);
switch (retcode) {
case JPEG_HEADER_OK: /* Found SOS, prepare to decompress */
/* Set up default parameters based on header data */
default_decompress_parms(cinfo);
/* Set global state: ready for start_decompress */
cinfo->global_state = DSTATE_READY;
case JPEG_REACHED_SOS:
retcode = JPEG_HEADER_OK;
break;
case JPEG_HEADER_TABLES_ONLY: /* Found EOI before any SOS */
if (cinfo->marker->saw_SOF)
ERREXIT(cinfo, JERR_SOF_NO_SOS);
if (require_image) /* Complain if application wants an image */
case JPEG_REACHED_EOI:
if (require_image) /* Complain if application wanted an image */
ERREXIT(cinfo, JERR_NO_IMAGE);
/* We need not do any cleanup since only permanent storage (for DQT, DHT)
* has been allocated.
/* Reset to start state; it would be safer to require the application to
* call jpeg_abort, but we can't change it now for compatibility reasons.
* A side effect is to free any temporary memory (there shouldn't be any).
*/
/* Set global state: ready for a new datastream */
cinfo->global_state = DSTATE_START;
jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
retcode = JPEG_HEADER_TABLES_ONLY;
break;
case JPEG_SUSPENDED: /* Had to suspend before end of headers */
case JPEG_SUSPENDED:
/* no work */
break;
}
@@ -258,128 +273,87 @@ jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
/*
* Decompression initialization.
* jpeg_read_header must be completed before calling this.
* Consume data in advance of what the decompressor requires.
* This can be called at any time once the decompressor object has
* been created and a data source has been set up.
*
* If a multipass operating mode was selected, this will do all but the
* last pass, and thus may take a great deal of time.
* This routine is essentially a state machine that handles a couple
* of critical state-transition actions, namely initial setup and
* transition from header scanning to ready-for-start_decompress.
* All the actual input is done via the input controller's consume_input
* method.
*/
GLOBAL void
jpeg_start_decompress (j_decompress_ptr cinfo)
GLOBAL(int)
jpeg_consume_input (j_decompress_ptr cinfo)
{
JDIMENSION chunk_ctr, last_chunk_ctr;
int retcode = JPEG_SUSPENDED;
if (cinfo->global_state != DSTATE_READY)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Perform master selection of active modules */
jinit_master_decompress(cinfo);
/* Do all but the final (output) pass, and set up for that one. */
for (;;) {
(*cinfo->master->prepare_for_pass) (cinfo);
if (cinfo->master->is_last_pass)
/* NB: every possible DSTATE value should be listed in this switch */
switch (cinfo->global_state) {
case DSTATE_START:
/* Start-of-datastream actions: reset appropriate modules */
(*cinfo->inputctl->reset_input_controller) (cinfo);
/* Initialize application's data source module */
(*cinfo->src->init_source) (cinfo);
cinfo->global_state = DSTATE_INHEADER;
/*FALLTHROUGH*/
case DSTATE_INHEADER:
retcode = (*cinfo->inputctl->consume_input) (cinfo);
if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
/* Set up default parameters based on header data */
default_decompress_parms(cinfo);
/* Set global state: ready for start_decompress */
cinfo->global_state = DSTATE_READY;
}
break;
chunk_ctr = 0;
while (chunk_ctr < cinfo->main->num_chunks) {
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) chunk_ctr;
cinfo->progress->pass_limit = (long) cinfo->main->num_chunks;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
case DSTATE_READY:
/* Can't advance past first SOS until start_decompress is called */
retcode = JPEG_REACHED_SOS;
break;
case DSTATE_PRELOAD:
case DSTATE_PRESCAN:
case DSTATE_SCANNING:
case DSTATE_RAW_OK:
case DSTATE_BUFIMAGE:
case DSTATE_BUFPOST:
case DSTATE_STOPPING:
retcode = (*cinfo->inputctl->consume_input) (cinfo);
break;
default:
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
}
/* Process some data */
last_chunk_ctr = chunk_ctr;
(*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
&chunk_ctr, (JDIMENSION) 0);
if (chunk_ctr == last_chunk_ctr) /* check for failure to make progress */
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
(*cinfo->master->finish_pass) (cinfo);
}
/* Ready for application to drive last pass through jpeg_read_scanlines
* or jpeg_read_raw_data.
*/
cinfo->output_scanline = 0;
cinfo->global_state = (cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING);
return retcode;
}
/*
* Read some scanlines of data from the JPEG decompressor.
*
* The return value will be the number of lines actually read.
* This may be less than the number requested in several cases,
* including bottom of image, data source suspension, and operating
* modes that emit multiple scanlines at a time.
*
* Note: we warn about excess calls to jpeg_read_scanlines() since
* this likely signals an application programmer error. However,
* an oversize buffer (max_lines > scanlines remaining) is not an error.
* Have we finished reading the input file?
*/
GLOBAL JDIMENSION
jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
JDIMENSION max_lines)
GLOBAL(boolean)
jpeg_input_complete (j_decompress_ptr cinfo)
{
JDIMENSION row_ctr;
if (cinfo->global_state != DSTATE_SCANNING)
/* Check for valid jpeg object */
if (cinfo->global_state < DSTATE_START ||
cinfo->global_state > DSTATE_STOPPING)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->output_scanline >= cinfo->output_height)
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
cinfo->progress->pass_limit = (long) cinfo->output_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Process some data */
row_ctr = 0;
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
cinfo->output_scanline += row_ctr;
return row_ctr;
return cinfo->inputctl->eoi_reached;
}
/*
* Alternate entry point to read raw data.
* Processes exactly one iMCU row per call, unless suspended.
* Is there more than one scan?
*/
GLOBAL JDIMENSION
jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION max_lines)
GLOBAL(boolean)
jpeg_has_multiple_scans (j_decompress_ptr cinfo)
{
JDIMENSION lines_per_iMCU_row;
if (cinfo->global_state != DSTATE_RAW_OK)
/* Only valid after jpeg_read_header completes */
if (cinfo->global_state < DSTATE_READY ||
cinfo->global_state > DSTATE_STOPPING)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->output_scanline >= cinfo->output_height) {
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
return 0;
}
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
cinfo->progress->pass_limit = (long) cinfo->output_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Verify that at least one iMCU row can be returned. */
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
if (max_lines < lines_per_iMCU_row)
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Decompress directly into user's buffer. */
if (! (*cinfo->coef->decompress_data) (cinfo, data))
return 0; /* suspension forced, can do nothing more */
/* OK, we processed one iMCU row. */
cinfo->output_scanline += lines_per_iMCU_row;
return lines_per_iMCU_row;
return cinfo->inputctl->has_multiple_scans;
}
@@ -392,31 +366,27 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
* a suspending data source is used.
*/
GLOBAL boolean
GLOBAL(boolean)
jpeg_finish_decompress (j_decompress_ptr cinfo)
{
if (cinfo->global_state == DSTATE_SCANNING ||
cinfo->global_state == DSTATE_RAW_OK) {
/* Terminate final pass */
if ((cinfo->global_state == DSTATE_SCANNING ||
cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
/* Terminate final pass of non-buffered mode */
if (cinfo->output_scanline < cinfo->output_height)
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
(*cinfo->master->finish_pass) (cinfo);
(*cinfo->master->finish_output_pass) (cinfo);
cinfo->global_state = DSTATE_STOPPING;
} else if (cinfo->global_state == DSTATE_BUFIMAGE) {
/* Finishing after a buffered-image operation */
cinfo->global_state = DSTATE_STOPPING;
} else if (cinfo->global_state != DSTATE_STOPPING) {
/* Repeat call after a suspension? */
/* STOPPING = repeat call after a suspension, anything else is error */
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
}
/* Check for EOI in source file, unless master control already read it */
if (! cinfo->master->eoi_processed) {
switch ((*cinfo->marker->read_markers) (cinfo)) {
case JPEG_HEADER_OK: /* Found SOS!? */
ERREXIT(cinfo, JERR_EOI_EXPECTED);
break;
case JPEG_HEADER_TABLES_ONLY: /* Found EOI, A-OK */
break;
case JPEG_SUSPENDED: /* Suspend, come back later */
return FALSE;
}
/* Read until EOI */
while (! cinfo->inputctl->eoi_reached) {
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
return FALSE; /* Suspend, come back later */
}
/* Do final cleanup */
(*cinfo->src->term_source) (cinfo);
@@ -424,15 +394,3 @@ jpeg_finish_decompress (j_decompress_ptr cinfo)
jpeg_abort((j_common_ptr) cinfo);
return TRUE;
}
/*
* Abort processing of a JPEG decompression operation,
* but don't destroy the object itself.
*/
GLOBAL void
jpeg_abort_decompress (j_decompress_ptr cinfo)
{
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
}

275
jdapistd.c Normal file
View File

@@ -0,0 +1,275 @@
/*
* jdapistd.c
*
* Copyright (C) 1994-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 contains application interface code for the decompression half
* of the JPEG library. These are the "standard" API routines that are
* used in the normal full-decompression case. They are not used by a
* transcoding-only application. Note that if an application links in
* jpeg_start_decompress, it will end up linking in the entire decompressor.
* We thus must separate this file from jdapimin.c to avoid linking the
* whole decompression library into a transcoder.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Forward declarations */
LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
/*
* Decompression initialization.
* jpeg_read_header must be completed before calling this.
*
* If a multipass operating mode was selected, this will do all but the
* last pass, and thus may take a great deal of time.
*
* Returns FALSE if suspended. The return value need be inspected only if
* a suspending data source is used.
*/
GLOBAL(boolean)
jpeg_start_decompress (j_decompress_ptr cinfo)
{
if (cinfo->global_state == DSTATE_READY) {
/* First call: initialize master control, select active modules */
jinit_master_decompress(cinfo);
if (cinfo->buffered_image) {
/* No more work here; expecting jpeg_start_output next */
cinfo->global_state = DSTATE_BUFIMAGE;
return TRUE;
}
cinfo->global_state = DSTATE_PRELOAD;
}
if (cinfo->global_state == DSTATE_PRELOAD) {
/* If file has multiple scans, absorb them all into the coef buffer */
if (cinfo->inputctl->has_multiple_scans) {
#ifdef D_MULTISCAN_FILES_SUPPORTED
for (;;) {
int retcode;
/* Call progress monitor hook if present */
if (cinfo->progress != NULL)
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
/* Absorb some more input */
retcode = (*cinfo->inputctl->consume_input) (cinfo);
if (retcode == JPEG_SUSPENDED)
return FALSE;
if (retcode == JPEG_REACHED_EOI)
break;
/* Advance progress counter if appropriate */
if (cinfo->progress != NULL &&
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
/* jdmaster underestimated number of scans; ratchet up one scan */
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
}
}
}
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif /* D_MULTISCAN_FILES_SUPPORTED */
}
cinfo->output_scan_number = cinfo->input_scan_number;
} else if (cinfo->global_state != DSTATE_PRESCAN)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Perform any dummy output passes, and set up for the final pass */
return output_pass_setup(cinfo);
}
/*
* Set up for an output pass, and perform any dummy pass(es) needed.
* Common subroutine for jpeg_start_decompress and jpeg_start_output.
* Entry: global_state = DSTATE_PRESCAN only if previously suspended.
* Exit: If done, returns TRUE and sets global_state for proper output mode.
* If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
*/
LOCAL(boolean)
output_pass_setup (j_decompress_ptr cinfo)
{
if (cinfo->global_state != DSTATE_PRESCAN) {
/* First call: do pass setup */
(*cinfo->master->prepare_for_output_pass) (cinfo);
cinfo->output_scanline = 0;
cinfo->global_state = DSTATE_PRESCAN;
}
/* Loop over any required dummy passes */
while (cinfo->master->is_dummy_pass) {
#ifdef QUANT_2PASS_SUPPORTED
/* Crank through the dummy pass */
while (cinfo->output_scanline < cinfo->output_height) {
JDIMENSION last_scanline;
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
cinfo->progress->pass_limit = (long) cinfo->output_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Process some data */
last_scanline = cinfo->output_scanline;
(*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
&cinfo->output_scanline, (JDIMENSION) 0);
if (cinfo->output_scanline == last_scanline)
return FALSE; /* No progress made, must suspend */
}
/* Finish up dummy pass, and set up for another one */
(*cinfo->master->finish_output_pass) (cinfo);
(*cinfo->master->prepare_for_output_pass) (cinfo);
cinfo->output_scanline = 0;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif /* QUANT_2PASS_SUPPORTED */
}
/* Ready for application to drive output pass through
* jpeg_read_scanlines or jpeg_read_raw_data.
*/
cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
return TRUE;
}
/*
* Read some scanlines of data from the JPEG decompressor.
*
* The return value will be the number of lines actually read.
* This may be less than the number requested in several cases,
* including bottom of image, data source suspension, and operating
* modes that emit multiple scanlines at a time.
*
* Note: we warn about excess calls to jpeg_read_scanlines() since
* this likely signals an application programmer error. However,
* an oversize buffer (max_lines > scanlines remaining) is not an error.
*/
GLOBAL(JDIMENSION)
jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
JDIMENSION max_lines)
{
JDIMENSION row_ctr;
if (cinfo->global_state != DSTATE_SCANNING)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->output_scanline >= cinfo->output_height) {
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
return 0;
}
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
cinfo->progress->pass_limit = (long) cinfo->output_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Process some data */
row_ctr = 0;
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
cinfo->output_scanline += row_ctr;
return row_ctr;
}
/*
* Alternate entry point to read raw data.
* Processes exactly one iMCU row per call, unless suspended.
*/
GLOBAL(JDIMENSION)
jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION max_lines)
{
JDIMENSION lines_per_iMCU_row;
if (cinfo->global_state != DSTATE_RAW_OK)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->output_scanline >= cinfo->output_height) {
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
return 0;
}
/* Call progress monitor hook if present */
if (cinfo->progress != NULL) {
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
cinfo->progress->pass_limit = (long) cinfo->output_height;
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
}
/* Verify that at least one iMCU row can be returned. */
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_v_scaled_size;
if (max_lines < lines_per_iMCU_row)
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* Decompress directly into user's buffer. */
if (! (*cinfo->coef->decompress_data) (cinfo, data))
return 0; /* suspension forced, can do nothing more */
/* OK, we processed one iMCU row. */
cinfo->output_scanline += lines_per_iMCU_row;
return lines_per_iMCU_row;
}
/* Additional entry points for buffered-image mode. */
#ifdef D_MULTISCAN_FILES_SUPPORTED
/*
* Initialize for an output pass in buffered-image mode.
*/
GLOBAL(boolean)
jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
{
if (cinfo->global_state != DSTATE_BUFIMAGE &&
cinfo->global_state != DSTATE_PRESCAN)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Limit scan number to valid range */
if (scan_number <= 0)
scan_number = 1;
if (cinfo->inputctl->eoi_reached &&
scan_number > cinfo->input_scan_number)
scan_number = cinfo->input_scan_number;
cinfo->output_scan_number = scan_number;
/* Perform any dummy output passes, and set up for the real pass */
return output_pass_setup(cinfo);
}
/*
* Finish up after an output pass in buffered-image mode.
*
* Returns FALSE if suspended. The return value need be inspected only if
* a suspending data source is used.
*/
GLOBAL(boolean)
jpeg_finish_output (j_decompress_ptr cinfo)
{
if ((cinfo->global_state == DSTATE_SCANNING ||
cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
/* Terminate this pass. */
/* We do not require the whole pass to have been completed. */
(*cinfo->master->finish_output_pass) (cinfo);
cinfo->global_state = DSTATE_BUFPOST;
} else if (cinfo->global_state != DSTATE_BUFPOST) {
/* BUFPOST = repeat call after a suspension, anything else is error */
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
}
/* Read markers looking for SOS or EOI */
while (cinfo->input_scan_number <= cinfo->output_scan_number &&
! cinfo->inputctl->eoi_reached) {
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
return FALSE; /* Suspend, come back later */
}
cinfo->global_state = DSTATE_BUFIMAGE;
return TRUE;
}
#endif /* D_MULTISCAN_FILES_SUPPORTED */

776
jdarith.c Normal file
View File

@@ -0,0 +1,776 @@
/*
* jdarith.c
*
* Developed 1997-2011 by Guido Vollbeding.
* 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 portable arithmetic entropy decoding routines for JPEG
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
*
* Both sequential and progressive modes are supported in this single module.
*
* Suspension is not currently supported in this module.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Expanded entropy decoder object for arithmetic decoding. */
typedef struct {
struct jpeg_entropy_decoder pub; /* public fields */
INT32 c; /* C register, base of coding interval + input bit buffer */
INT32 a; /* A register, normalized size of coding interval */
int ct; /* bit shift counter, # of bits left in bit buffer part of C */
/* init: ct = -16 */
/* run: ct = 0..7 */
/* error: ct = -1 */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
/* Pointers to statistics areas (these workspaces have image lifespan) */
unsigned char * dc_stats[NUM_ARITH_TBLS];
unsigned char * ac_stats[NUM_ARITH_TBLS];
/* Statistics bin for coding with fixed probability 0.5 */
unsigned char fixed_bin[4];
} arith_entropy_decoder;
typedef arith_entropy_decoder * arith_entropy_ptr;
/* The following two definitions specify the allocation chunk size
* for the statistics area.
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
*
* We use a compact representation with 1 byte per statistics bin,
* thus the numbers directly represent byte sizes.
* This 1 byte per statistics bin contains the meaning of the MPS
* (more probable symbol) in the highest bit (mask 0x80), and the
* index into the probability estimation state machine table
* in the lower bits (mask 0x7F).
*/
#define DC_STAT_BINS 64
#define AC_STAT_BINS 256
LOCAL(int)
get_byte (j_decompress_ptr cinfo)
/* Read next input byte; we do not support suspension in this module. */
{
struct jpeg_source_mgr * src = cinfo->src;
if (src->bytes_in_buffer == 0)
if (! (*src->fill_input_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
src->bytes_in_buffer--;
return GETJOCTET(*src->next_input_byte++);
}
/*
* The core arithmetic decoding routine (common in JPEG and JBIG).
* This needs to go as fast as possible.
* Machine-dependent optimization facilities
* are not utilized in this portable implementation.
* However, this code should be fairly efficient and
* may be a good base for further optimizations anyway.
*
* Return value is 0 or 1 (binary decision).
*
* Note: I've changed the handling of the code base & bit
* buffer register C compared to other implementations
* based on the standards layout & procedures.
* While it also contains both the actual base of the
* coding interval (16 bits) and the next-bits buffer,
* the cut-point between these two parts is floating
* (instead of fixed) with the bit shift counter CT.
* Thus, we also need only one (variable instead of
* fixed size) shift for the LPS/MPS decision, and
* we can get away with any renormalization update
* of C (except for new data insertion, of course).
*
* I've also introduced a new scheme for accessing
* the probability estimation state machine table,
* derived from Markus Kuhn's JBIG implementation.
*/
LOCAL(int)
arith_decode (j_decompress_ptr cinfo, unsigned char *st)
{
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
register unsigned char nl, nm;
register INT32 qe, temp;
register int sv, data;
/* Renormalization & data input per section D.2.6 */
while (e->a < 0x8000L) {
if (--e->ct < 0) {
/* Need to fetch next data byte */
if (cinfo->unread_marker)
data = 0; /* stuff zero data */
else {
data = get_byte(cinfo); /* read next input byte */
if (data == 0xFF) { /* zero stuff or marker code */
do data = get_byte(cinfo);
while (data == 0xFF); /* swallow extra 0xFF bytes */
if (data == 0)
data = 0xFF; /* discard stuffed zero byte */
else {
/* Note: Different from the Huffman decoder, hitting
* a marker while processing the compressed data
* segment is legal in arithmetic coding.
* The convention is to supply zero data
* then until decoding is complete.
*/
cinfo->unread_marker = data;
data = 0;
}
}
}
e->c = (e->c << 8) | data; /* insert data into C register */
if ((e->ct += 8) < 0) /* update bit shift counter */
/* Need more initial bytes */
if (++e->ct == 0)
/* Got 2 initial bytes -> re-init A and exit loop */
e->a = 0x8000L; /* => e->a = 0x10000L after loop exit */
}
e->a <<= 1;
}
/* Fetch values from our compact representation of Table D.3(D.2):
* Qe values and probability estimation state machine
*/
sv = *st;
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
/* Decode & estimation procedures per sections D.2.4 & D.2.5 */
temp = e->a - qe;
e->a = temp;
temp <<= e->ct;
if (e->c >= temp) {
e->c -= temp;
/* Conditional LPS (less probable symbol) exchange */
if (e->a < qe) {
e->a = qe;
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
} else {
e->a = qe;
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
sv ^= 0x80; /* Exchange LPS/MPS */
}
} else if (e->a < 0x8000L) {
/* Conditional MPS (more probable symbol) exchange */
if (e->a < qe) {
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
sv ^= 0x80; /* Exchange LPS/MPS */
} else {
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
}
}
return sv >> 7;
}
/*
* Check for a restart marker & resynchronize decoder.
*/
LOCAL(void)
process_restart (j_decompress_ptr cinfo)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci;
jpeg_component_info * compptr;
/* Advance past the RSTn marker */
if (! (*cinfo->marker->read_restart_marker) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
/* Re-initialize statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
/* Reset DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
if ((! cinfo->progressive_mode && cinfo->lim_Se) ||
(cinfo->progressive_mode && cinfo->Ss)) {
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
}
}
/* Reset arithmetic decoding variables */
entropy->c = 0;
entropy->a = 0;
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
/* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
}
/*
* Arithmetic MCU decoding.
* Each of these routines decodes and returns one MCU's worth of
* arithmetic-compressed coefficients.
* The coefficients are reordered from zigzag order into natural array order,
* but are not dequantized.
*
* The i'th block of the MCU is stored into the block pointed to by
* MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
*/
/*
* MCU decoding for DC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl, sign;
int v, m;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.19: Decode_DC_DIFF */
if (arith_decode(cinfo, st) == 0)
entropy->dc_context[ci] = 0;
else {
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, st + 1);
st += 2; st += sign;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
else
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
entropy->last_dc_val[ci] += v;
}
/* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */
(*block)[0] = (JCOEF) (entropy->last_dc_val[ci] << cinfo->Al);
}
return TRUE;
}
/*
* MCU decoding for AC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, sign, k;
int v, m;
const int * natural_order;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
natural_order = cinfo->natural_order;
/* There is always only one block per MCU */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
/* Figure F.20: Decode_AC_coefficients */
for (k = cinfo->Ss; k <= cinfo->Se; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (arith_decode(cinfo, st)) break; /* EOB flag */
while (arith_decode(cinfo, st + 1) == 0) {
st += 3; k++;
if (k > cinfo->Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */
return TRUE;
}
}
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, entropy->fixed_bin);
st += 2;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
if (arith_decode(cinfo, st)) {
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
}
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
/* Scale and output coefficient in natural (dezigzagged) order */
(*block)[natural_order[k]] = (JCOEF) (v << cinfo->Al);
}
return TRUE;
}
/*
* MCU decoding for DC successive approximation refinement scan.
*/
METHODDEF(boolean)
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char *st;
int p1, blkn;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
st = entropy->fixed_bin; /* use fixed probability estimation */
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
/* Encoded data is simply the next bit of the two's-complement DC value */
if (arith_decode(cinfo, st))
MCU_data[blkn][0][0] |= p1;
}
return TRUE;
}
/*
* MCU decoding for AC successive approximation refinement scan.
*/
METHODDEF(boolean)
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
JCOEFPTR thiscoef;
unsigned char *st;
int tbl, k, kex;
int p1, m1;
const int * natural_order;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
natural_order = cinfo->natural_order;
/* There is always only one block per MCU */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
/* Establish EOBx (previous stage end-of-block) index */
for (kex = cinfo->Se; kex > 0; kex--)
if ((*block)[natural_order[kex]]) break;
for (k = cinfo->Ss; k <= cinfo->Se; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (k > kex)
if (arith_decode(cinfo, st)) break; /* EOB flag */
for (;;) {
thiscoef = *block + natural_order[k];
if (*thiscoef) { /* previously nonzero coef */
if (arith_decode(cinfo, st + 2)) {
if (*thiscoef < 0)
*thiscoef += m1;
else
*thiscoef += p1;
}
break;
}
if (arith_decode(cinfo, st + 1)) { /* newly nonzero coef */
if (arith_decode(cinfo, entropy->fixed_bin))
*thiscoef = m1;
else
*thiscoef = p1;
break;
}
st += 3; k++;
if (k > cinfo->Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */
return TRUE;
}
}
}
return TRUE;
}
/*
* Decode one MCU's worth of arithmetic-compressed coefficients.
*/
METHODDEF(boolean)
decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
jpeg_component_info * compptr;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl, sign, k;
int v, m;
const int * natural_order;
/* Process restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
process_restart(cinfo);
entropy->restarts_to_go--;
}
if (entropy->ct == -1) return TRUE; /* if error do nothing */
natural_order = cinfo->natural_order;
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
tbl = compptr->dc_tbl_no;
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.19: Decode_DC_DIFF */
if (arith_decode(cinfo, st) == 0)
entropy->dc_context[ci] = 0;
else {
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, st + 1);
st += 2; st += sign;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
else
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
entropy->last_dc_val[ci] += v;
}
(*block)[0] = (JCOEF) entropy->last_dc_val[ci];
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
if (cinfo->lim_Se == 0) continue;
tbl = compptr->ac_tbl_no;
k = 0;
/* Figure F.20: Decode_AC_coefficients */
do {
st = entropy->ac_stats[tbl] + 3 * k;
if (arith_decode(cinfo, st)) break; /* EOB flag */
for (;;) {
k++;
if (arith_decode(cinfo, st + 1)) break;
st += 3;
if (k >= cinfo->lim_Se) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* spectral overflow */
return TRUE;
}
}
/* Figure F.21: Decoding nonzero value v */
/* Figure F.22: Decoding the sign of v */
sign = arith_decode(cinfo, entropy->fixed_bin);
st += 2;
/* Figure F.23: Decoding the magnitude category of v */
if ((m = arith_decode(cinfo, st)) != 0) {
if (arith_decode(cinfo, st)) {
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (arith_decode(cinfo, st)) {
if ((m <<= 1) == 0x8000) {
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
entropy->ct = -1; /* magnitude overflow */
return TRUE;
}
st += 1;
}
}
}
v = m;
/* Figure F.24: Decoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v;
(*block)[natural_order[k]] = (JCOEF) v;
} while (k < cinfo->lim_Se);
}
return TRUE;
}
/*
* Initialize for an arithmetic-compressed scan.
*/
METHODDEF(void)
start_pass (j_decompress_ptr cinfo)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci, tbl;
jpeg_component_info * compptr;
if (cinfo->progressive_mode) {
/* Validate progressive scan parameters */
if (cinfo->Ss == 0) {
if (cinfo->Se != 0)
goto bad;
} else {
/* need not check Ss/Se < 0 since they came from unsigned bytes */
if (cinfo->Se < cinfo->Ss || cinfo->Se > cinfo->lim_Se)
goto bad;
/* AC scans may have only one component */
if (cinfo->comps_in_scan != 1)
goto bad;
}
if (cinfo->Ah != 0) {
/* Successive approximation refinement scan: must have Al = Ah-1. */
if (cinfo->Ah-1 != cinfo->Al)
goto bad;
}
if (cinfo->Al > 13) { /* need not check for < 0 */
bad:
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
}
/* Update progression status, and verify that scan order is legal.
* Note that inter-scan inconsistencies are treated as warnings
* not fatal errors ... not clear if this is right way to behave.
*/
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
int *coef_bit_ptr = & cinfo->coef_bits[cindex][0];
if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
if (cinfo->Ah != expected)
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
coef_bit_ptr[coefi] = cinfo->Al;
}
}
/* Select MCU decoding routine */
if (cinfo->Ah == 0) {
if (cinfo->Ss == 0)
entropy->pub.decode_mcu = decode_mcu_DC_first;
else
entropy->pub.decode_mcu = decode_mcu_AC_first;
} else {
if (cinfo->Ss == 0)
entropy->pub.decode_mcu = decode_mcu_DC_refine;
else
entropy->pub.decode_mcu = decode_mcu_AC_refine;
}
} else {
/* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
* This ought to be an error condition, but we make it a warning.
*/
if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 ||
(cinfo->Se < DCTSIZE2 && cinfo->Se != cinfo->lim_Se))
WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
/* Select MCU decoding routine */
entropy->pub.decode_mcu = decode_mcu;
}
/* Allocate & initialize requested statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->dc_stats[tbl] == NULL)
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
/* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
if ((! cinfo->progressive_mode && cinfo->lim_Se) ||
(cinfo->progressive_mode && cinfo->Ss)) {
tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->ac_stats[tbl] == NULL)
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
}
}
/* Initialize arithmetic decoding variables */
entropy->c = 0;
entropy->a = 0;
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
/* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
}
/*
* Module initialization routine for arithmetic entropy decoding.
*/
GLOBAL(void)
jinit_arith_decoder (j_decompress_ptr cinfo)
{
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_decoder));
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
entropy->pub.start_pass = start_pass;
/* Mark tables unallocated */
for (i = 0; i < NUM_ARITH_TBLS; i++) {
entropy->dc_stats[i] = NULL;
entropy->ac_stats[i] = NULL;
}
/* Initialize index for fixed probability estimation */
entropy->fixed_bin[0] = 113;
if (cinfo->progressive_mode) {
/* Create progression status table */
int *coef_bit_ptr, ci;
cinfo->coef_bits = (int (*)[DCTSIZE2])
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components*DCTSIZE2*SIZEOF(int));
coef_bit_ptr = & cinfo->coef_bits[0][0];
for (ci = 0; ci < cinfo->num_components; ci++)
for (i = 0; i < DCTSIZE2; i++)
*coef_bit_ptr++ = -1;
}
}

View File

@@ -1,14 +1,15 @@
/*
* jdatadst.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains compression data destination routines for the case of
* emitting JPEG data to a file (or any stdio stream). While these routines
* are sufficient for most applications, some will want to use a different
* destination manager.
* emitting JPEG data to memory or to a file (or any stdio stream).
* While these routines are sufficient for most applications,
* some will want to use a different destination manager.
* IMPORTANT: we assume that fwrite() will correctly transcribe an array of
* JOCTETs into 8-bit-wide elements on external storage. If char is wider
* than 8 bits on your machine, you may need to do some tweaking.
@@ -19,6 +20,11 @@
#include "jpeglib.h"
#include "jerror.h"
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
extern void * malloc JPP((size_t size));
extern void free JPP((void *ptr));
#endif
/* Expanded data destination object for stdio output */
@@ -34,12 +40,27 @@ typedef my_destination_mgr * my_dest_ptr;
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
/* Expanded data destination object for memory output */
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
unsigned char ** outbuffer; /* target buffer */
unsigned long * outsize;
unsigned char * newbuffer; /* newly allocated buffer */
JOCTET * buffer; /* start of buffer */
size_t bufsize;
} my_mem_destination_mgr;
typedef my_mem_destination_mgr * my_mem_dest_ptr;
/*
* Initialize destination --- called by jpeg_start_compress
* before any data is actually written.
*/
METHODDEF void
METHODDEF(void)
init_destination (j_compress_ptr cinfo)
{
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
@@ -53,6 +74,12 @@ init_destination (j_compress_ptr cinfo)
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}
METHODDEF(void)
init_mem_destination (j_compress_ptr cinfo)
{
/* no work necessary here */
}
/*
* Empty the output buffer --- called whenever buffer fills up.
@@ -77,7 +104,7 @@ init_destination (j_compress_ptr cinfo)
* write it out when emptying the buffer externally.
*/
METHODDEF boolean
METHODDEF(boolean)
empty_output_buffer (j_compress_ptr cinfo)
{
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
@@ -92,6 +119,36 @@ empty_output_buffer (j_compress_ptr cinfo)
return TRUE;
}
METHODDEF(boolean)
empty_mem_output_buffer (j_compress_ptr cinfo)
{
size_t nextsize;
JOCTET * nextbuffer;
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
/* Try to allocate new buffer with double size */
nextsize = dest->bufsize * 2;
nextbuffer = (JOCTET *) malloc(nextsize);
if (nextbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
if (dest->newbuffer != NULL)
free(dest->newbuffer);
dest->newbuffer = nextbuffer;
dest->pub.next_output_byte = nextbuffer + dest->bufsize;
dest->pub.free_in_buffer = dest->bufsize;
dest->buffer = nextbuffer;
dest->bufsize = nextsize;
return TRUE;
}
/*
* Terminate destination --- called by jpeg_finish_compress
@@ -102,7 +159,7 @@ empty_output_buffer (j_compress_ptr cinfo)
* for error exit.
*/
METHODDEF void
METHODDEF(void)
term_destination (j_compress_ptr cinfo)
{
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
@@ -119,6 +176,15 @@ term_destination (j_compress_ptr cinfo)
ERREXIT(cinfo, JERR_FILE_WRITE);
}
METHODDEF(void)
term_mem_destination (j_compress_ptr cinfo)
{
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
*dest->outbuffer = dest->buffer;
*dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
}
/*
* Prepare for output to a stdio stream.
@@ -126,7 +192,7 @@ term_destination (j_compress_ptr cinfo)
* for closing it after finishing compression.
*/
GLOBAL void
GLOBAL(void)
jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
{
my_dest_ptr dest;
@@ -149,3 +215,53 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
dest->pub.term_destination = term_destination;
dest->outfile = outfile;
}
/*
* Prepare for output to a memory buffer.
* The caller may supply an own initial buffer with appropriate size.
* Otherwise, or when the actual data output exceeds the given size,
* the library adapts the buffer size as necessary.
* The standard library functions malloc/free are used for allocating
* larger memory, so the buffer is available to the application after
* finishing compression, and then the application is responsible for
* freeing the requested memory.
*/
GLOBAL(void)
jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char ** outbuffer, unsigned long * outsize)
{
my_mem_dest_ptr dest;
if (outbuffer == NULL || outsize == NULL) /* sanity check */
ERREXIT(cinfo, JERR_BUFFER_SIZE);
/* The destination object is made permanent so that multiple JPEG images
* can be written to the same buffer without re-executing jpeg_mem_dest.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_mem_destination_mgr));
}
dest = (my_mem_dest_ptr) cinfo->dest;
dest->pub.init_destination = init_mem_destination;
dest->pub.empty_output_buffer = empty_mem_output_buffer;
dest->pub.term_destination = term_mem_destination;
dest->outbuffer = outbuffer;
dest->outsize = outsize;
dest->newbuffer = NULL;
if (*outbuffer == NULL || *outsize == 0) {
/* Allocate initial buffer */
dest->newbuffer = *outbuffer = (unsigned char *) malloc(OUTPUT_BUF_SIZE);
if (dest->newbuffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
*outsize = OUTPUT_BUF_SIZE;
}
dest->pub.next_output_byte = dest->buffer = *outbuffer;
dest->pub.free_in_buffer = dest->bufsize = *outsize;
}

View File

@@ -1,14 +1,15 @@
/*
* jdatasrc.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2009-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains decompression data source routines for the case of
* reading JPEG data from a file (or any stdio stream). While these routines
* are sufficient for most applications, some will want to use a different
* source manager.
* reading JPEG data from memory or from a file (or any stdio stream).
* While these routines are sufficient for most applications,
* some will want to use a different source manager.
* IMPORTANT: we assume that fread() will correctly transcribe an array of
* JOCTETs from 8-bit-wide elements on external storage. If char is wider
* than 8 bits on your machine, you may need to do some tweaking.
@@ -40,7 +41,7 @@ typedef my_source_mgr * my_src_ptr;
* before any data is actually read.
*/
METHODDEF void
METHODDEF(void)
init_source (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -52,6 +53,12 @@ init_source (j_decompress_ptr cinfo)
src->start_of_file = TRUE;
}
METHODDEF(void)
init_mem_source (j_decompress_ptr cinfo)
{
/* no work necessary here */
}
/*
* Fill the input buffer --- called whenever buffer is emptied.
@@ -86,7 +93,7 @@ init_source (j_decompress_ptr cinfo)
* the front of the buffer rather than discarding it.
*/
METHODDEF boolean
METHODDEF(boolean)
fill_input_buffer (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -111,6 +118,27 @@ fill_input_buffer (j_decompress_ptr cinfo)
return TRUE;
}
METHODDEF(boolean)
fill_mem_input_buffer (j_decompress_ptr cinfo)
{
static const JOCTET mybuffer[4] = {
(JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
};
/* The whole JPEG data is expected to reside in the supplied memory
* buffer, so any request for more data beyond the given buffer size
* is treated as an error.
*/
WARNMS(cinfo, JWRN_JPEG_EOF);
/* Insert a fake EOI marker */
cinfo->src->next_input_byte = mybuffer;
cinfo->src->bytes_in_buffer = 2;
return TRUE;
}
/*
* Skip data --- used to skip over a potentially large amount of
@@ -124,25 +152,25 @@ fill_input_buffer (j_decompress_ptr cinfo)
* buffer is the application writer's problem.
*/
METHODDEF void
METHODDEF(void)
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
struct jpeg_source_mgr * src = cinfo->src;
/* Just a dumb implementation for now. Could use fseek() except
* it doesn't work on pipes. Not clear that being smart is worth
* any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0) {
while (num_bytes > (long) src->pub.bytes_in_buffer) {
num_bytes -= (long) src->pub.bytes_in_buffer;
(void) fill_input_buffer(cinfo);
while (num_bytes > (long) src->bytes_in_buffer) {
num_bytes -= (long) src->bytes_in_buffer;
(void) (*src->fill_input_buffer) (cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
}
src->pub.next_input_byte += (size_t) num_bytes;
src->pub.bytes_in_buffer -= (size_t) num_bytes;
src->next_input_byte += (size_t) num_bytes;
src->bytes_in_buffer -= (size_t) num_bytes;
}
}
@@ -165,7 +193,7 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes)
* for error exit.
*/
METHODDEF void
METHODDEF(void)
term_source (j_decompress_ptr cinfo)
{
/* no work necessary here */
@@ -178,7 +206,7 @@ term_source (j_decompress_ptr cinfo)
* for closing it after finishing decompression.
*/
GLOBAL void
GLOBAL(void)
jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
{
my_src_ptr src;
@@ -210,3 +238,38 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
src->pub.next_input_byte = NULL; /* until buffer loaded */
}
/*
* Prepare for input from a supplied memory buffer.
* The buffer must contain the whole JPEG data.
*/
GLOBAL(void)
jpeg_mem_src (j_decompress_ptr cinfo,
unsigned char * inbuffer, unsigned long insize)
{
struct jpeg_source_mgr * src;
if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
ERREXIT(cinfo, JERR_INPUT_EMPTY);
/* The source object is made permanent so that a series of JPEG images
* can be read from the same buffer by calling jpeg_mem_src only before
* the first one.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(struct jpeg_source_mgr));
}
src = cinfo->src;
src->init_source = init_mem_source;
src->fill_input_buffer = fill_mem_input_buffer;
src->skip_input_data = skip_input_data;
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->term_source = term_source;
src->bytes_in_buffer = (size_t) insize;
src->next_input_byte = (JOCTET *) inbuffer;
}

View File

@@ -1,63 +1,84 @@
/*
* jdcoefct.c
*
* Copyright (C) 1994-1995, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2002-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains the coefficient buffer controller for decompression.
* This controller is the top level of the JPEG decompressor proper.
* The coefficient buffer lies between entropy decoding and inverse-DCT steps.
*
* In buffered-image mode, this controller is the interface between
* input-oriented processing and output-oriented processing.
* Also, the input side (only) is used when reading a file for transcoding.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Block smoothing is only applicable for progressive JPEG, so: */
#ifndef D_PROGRESSIVE_SUPPORTED
#undef BLOCK_SMOOTHING_SUPPORTED
#endif
/* Private buffer controller object */
typedef struct {
struct jpeg_d_coef_controller pub; /* public fields */
JDIMENSION iMCU_row_num; /* iMCU row # within image */
JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
/* These variables keep track of the current location of the input side. */
/* cinfo->input_iMCU_row is also used for this. */
JDIMENSION MCU_ctr; /* counts MCUs processed in current row */
int MCU_vert_offset; /* counts MCU rows within iMCU row */
int MCU_rows_per_iMCU_row; /* number of such rows needed */
/* In single-pass modes without block smoothing, it's sufficient to buffer
* just one MCU (although this may prove a bit slow in practice).
* We allocate a workspace of MAX_BLOCKS_IN_MCU coefficient blocks,
/* The output side's location is represented by cinfo->output_iMCU_row. */
/* In single-pass modes, it's sufficient to buffer just one MCU.
* We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
* and let the entropy decoder write into that workspace each time.
* (On 80x86, the workspace is FAR even though it's not really very big;
* this is to keep the module interfaces unchanged when a large coefficient
* buffer is necessary.)
* In multi-pass modes, this array points to the current MCU's blocks
* within the virtual arrays.
* within the virtual arrays; it is used only by the input side.
*/
JBLOCKROW MCU_buffer[MAX_BLOCKS_IN_MCU];
JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
#ifdef D_MULTISCAN_FILES_SUPPORTED
/* In multi-pass modes, we need a virtual block array for each component. */
jvirt_barray_ptr whole_image[MAX_COMPONENTS];
#endif
#ifdef BLOCK_SMOOTHING_SUPPORTED
/* When doing block smoothing, we latch coefficient Al values here */
int * coef_bits_latch;
#define SAVED_COEFS 6 /* we save coef_bits[0..5] */
#endif
} my_coef_controller;
typedef my_coef_controller * my_coef_ptr;
/* Forward declarations */
METHODDEF boolean decompress_data
METHODDEF(int) decompress_onepass
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#ifdef D_MULTISCAN_FILES_SUPPORTED
METHODDEF boolean decompress_read
METHODDEF(int) decompress_data
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
METHODDEF boolean decompress_output
#endif
#ifdef BLOCK_SMOOTHING_SUPPORTED
LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
METHODDEF(int) decompress_smooth_data
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#endif
LOCAL void
LOCAL(void)
start_iMCU_row (j_decompress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row */
/* Reset within-iMCU-row counters for a new row (input side) */
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
@@ -68,65 +89,63 @@ start_iMCU_row (j_decompress_ptr cinfo)
if (cinfo->comps_in_scan > 1) {
coef->MCU_rows_per_iMCU_row = 1;
} else {
if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
else
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
}
coef->mcu_ctr = 0;
coef->MCU_ctr = 0;
coef->MCU_vert_offset = 0;
}
/*
* Initialize for a processing pass.
* Initialize for an input processing pass.
*/
METHODDEF void
start_pass_coef (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
METHODDEF(void)
start_input_pass (j_decompress_ptr cinfo)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
coef->iMCU_row_num = 0;
cinfo->input_iMCU_row = 0;
start_iMCU_row(cinfo);
switch (pass_mode) {
case JBUF_PASS_THRU:
if (coef->whole_image[0] != NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub.decompress_data = decompress_data;
break;
#ifdef D_MULTISCAN_FILES_SUPPORTED
case JBUF_SAVE_SOURCE:
if (coef->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub.decompress_data = decompress_read;
break;
case JBUF_CRANK_DEST:
if (coef->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub.decompress_data = decompress_output;
break;
#endif
default:
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
break;
}
}
/*
* Process some data in the single-pass case.
* Always attempts to emit one fully interleaved MCU row ("iMCU" row).
* Returns TRUE if it completed a row, FALSE if not (suspension).
*
* NB: output_buf contains a plane for each component in image.
* For single pass, this is the same as the components in the scan.
* Initialize for an output processing pass.
*/
METHODDEF boolean
decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
METHODDEF(void)
start_output_pass (j_decompress_ptr cinfo)
{
#ifdef BLOCK_SMOOTHING_SUPPORTED
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
/* If multipass, check to see whether to use block smoothing on this pass */
if (coef->pub.coef_arrays != NULL) {
if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
coef->pub.decompress_data = decompress_smooth_data;
else
coef->pub.decompress_data = decompress_data;
}
#endif
cinfo->output_iMCU_row = 0;
}
/*
* Decompress and return some data in the single-pass case.
* Always attempts to emit one fully interleaved MCU row ("iMCU" row).
* Input and output must run in lockstep since we have only a one-MCU buffer.
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
*
* NB: output_buf contains a plane for each component in image,
* which we index according to the component's SOF position.
*/
METHODDEF(int)
decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */
@@ -141,16 +160,17 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
/* Loop to process as much as one whole iMCU row */
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
yoffset++) {
for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
MCU_col_num++) {
/* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
jzero_far((void FAR *) coef->MCU_buffer[0],
if (cinfo->lim_Se) /* can bypass in DC only case */
FMEMZERO((void FAR *) coef->MCU_buffer[0],
(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
/* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
coef->mcu_ctr = MCU_col_num;
return FALSE;
coef->MCU_ctr = MCU_col_num;
return JPEG_SUSPENDED;
}
/* Determine where data should go in output_buf and do the IDCT thing.
* We skip dummy blocks at the right and bottom edges (but blkn gets
@@ -168,51 +188,67 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
: compptr->last_col_width;
output_ptr = output_buf[ci] + yoffset * compptr->DCT_scaled_size;
output_ptr = output_buf[compptr->component_index] +
yoffset * compptr->DCT_v_scaled_size;
start_col = MCU_col_num * compptr->MCU_sample_width;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (coef->iMCU_row_num < last_iMCU_row ||
if (cinfo->input_iMCU_row < last_iMCU_row ||
yoffset+yindex < compptr->last_row_height) {
output_col = start_col;
for (xindex = 0; xindex < useful_width; xindex++) {
(*inverse_DCT) (cinfo, compptr,
(JCOEFPTR) coef->MCU_buffer[blkn+xindex],
output_ptr, output_col);
output_col += compptr->DCT_scaled_size;
output_col += compptr->DCT_h_scaled_size;
}
}
blkn += compptr->MCU_width;
output_ptr += compptr->DCT_scaled_size;
output_ptr += compptr->DCT_v_scaled_size;
}
}
}
/* Completed an MCU row, but perhaps not an iMCU row */
coef->mcu_ctr = 0;
coef->MCU_ctr = 0;
}
/* Completed the iMCU row, advance counters for next one */
coef->iMCU_row_num++;
cinfo->output_iMCU_row++;
if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
start_iMCU_row(cinfo);
return TRUE;
return JPEG_ROW_COMPLETED;
}
/* Completed the scan */
(*cinfo->inputctl->finish_input_pass) (cinfo);
return JPEG_SCAN_COMPLETED;
}
/*
* Dummy consume-input routine for single-pass operation.
*/
METHODDEF(int)
dummy_consume_data (j_decompress_ptr cinfo)
{
return JPEG_SUSPENDED; /* Always indicate nothing was done */
}
#ifdef D_MULTISCAN_FILES_SUPPORTED
/*
* Process some data: handle an input pass for a multiple-scan file.
* We read the equivalent of one fully interleaved MCU row ("iMCU" row)
* per call, ie, v_samp_factor block rows for each component in the scan.
* No data is returned; we just stash it in the virtual arrays.
* Returns TRUE if it completed a row, FALSE if not (suspension).
* Consume input data and store it in the full-image coefficient buffer.
* We read as much as one fully interleaved MCU row ("iMCU" row) per call,
* ie, v_samp_factor block rows for each component in the scan.
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
*/
METHODDEF boolean
decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
METHODDEF(int)
consume_data (j_decompress_ptr cinfo)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */
int blkn, ci, xindex, yindex, yoffset;
JDIMENSION total_width, start_col;
JDIMENSION start_col;
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
JBLOCKROW buffer_ptr;
jpeg_component_info *compptr;
@@ -222,20 +258,18 @@ decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
compptr = cinfo->cur_comp_info[ci];
buffer[ci] = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor, TRUE);
/* Entropy decoder expects buffer to be zeroed. */
total_width = (JDIMENSION) jround_up((long) compptr->width_in_blocks,
(long) compptr->h_samp_factor);
for (yindex = 0; yindex < compptr->v_samp_factor; yindex++) {
jzero_far((void FAR *) buffer[ci][yindex],
(size_t) (total_width * SIZEOF(JBLOCK)));
}
cinfo->input_iMCU_row * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
/* Note: entropy decoder expects buffer to be zeroed,
* but this is handled automatically by the memory manager
* because we requested a pre-zeroed array.
*/
}
/* Loop to process one whole iMCU row */
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
yoffset++) {
for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
MCU_col_num++) {
/* Construct list of pointers to DCT blocks belonging to this MCU */
blkn = 0; /* index of current DCT block within MCU */
@@ -253,30 +287,34 @@ decompress_read (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
/* Suspension forced; update state counters and exit */
coef->MCU_vert_offset = yoffset;
coef->mcu_ctr = MCU_col_num;
return FALSE;
coef->MCU_ctr = MCU_col_num;
return JPEG_SUSPENDED;
}
}
/* Completed an MCU row, but perhaps not an iMCU row */
coef->mcu_ctr = 0;
coef->MCU_ctr = 0;
}
/* Completed the iMCU row, advance counters for next one */
coef->iMCU_row_num++;
if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
start_iMCU_row(cinfo);
return TRUE;
return JPEG_ROW_COMPLETED;
}
/* Completed the scan */
(*cinfo->inputctl->finish_input_pass) (cinfo);
return JPEG_SCAN_COMPLETED;
}
/*
* Process some data: output from the virtual arrays after reading is done.
* Always emits one fully interleaved MCU row ("iMCU" row).
* Always returns TRUE --- suspension is not possible.
* Decompress and return some data in the multi-pass case.
* Always attempts to emit one fully interleaved MCU row ("iMCU" row).
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
*
* NB: output_buf contains a plane for each component in image.
*/
METHODDEF boolean
decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
METHODDEF(int)
decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
@@ -289,6 +327,15 @@ decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
jpeg_component_info *compptr;
inverse_DCT_method_ptr inverse_DCT;
/* Force some input to be done if we are getting ahead of the input. */
while (cinfo->input_scan_number < cinfo->output_scan_number ||
(cinfo->input_scan_number == cinfo->output_scan_number &&
cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
return JPEG_SUSPENDED;
}
/* OK, output from the virtual arrays. */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Don't bother to IDCT an uninteresting component. */
@@ -297,12 +344,13 @@ decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
/* Align the virtual buffer for this component. */
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[ci],
coef->iMCU_row_num * compptr->v_samp_factor, FALSE);
cinfo->output_iMCU_row * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, FALSE);
/* Count non-dummy DCT block rows in this iMCU row. */
if (coef->iMCU_row_num < last_iMCU_row)
if (cinfo->output_iMCU_row < last_iMCU_row)
block_rows = compptr->v_samp_factor;
else {
/* NB: can't use last_row_height here, since may not be set! */
/* NB: can't use last_row_height here; it is input-side-dependent! */
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (block_rows == 0) block_rows = compptr->v_samp_factor;
}
@@ -316,63 +364,378 @@ decompress_output (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
output_ptr, output_col);
buffer_ptr++;
output_col += compptr->DCT_scaled_size;
output_col += compptr->DCT_h_scaled_size;
}
output_ptr += compptr->DCT_scaled_size;
output_ptr += compptr->DCT_v_scaled_size;
}
}
coef->iMCU_row_num++;
return TRUE;
if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
return JPEG_ROW_COMPLETED;
return JPEG_SCAN_COMPLETED;
}
#endif /* D_MULTISCAN_FILES_SUPPORTED */
#ifdef BLOCK_SMOOTHING_SUPPORTED
/*
* This code applies interblock smoothing as described by section K.8
* of the JPEG standard: the first 5 AC coefficients are estimated from
* the DC values of a DCT block and its 8 neighboring blocks.
* We apply smoothing only for progressive JPEG decoding, and only if
* the coefficients it can estimate are not yet known to full precision.
*/
/* Natural-order array positions of the first 5 zigzag-order coefficients */
#define Q01_POS 1
#define Q10_POS 8
#define Q20_POS 16
#define Q11_POS 9
#define Q02_POS 2
/*
* Determine whether block smoothing is applicable and safe.
* We also latch the current states of the coef_bits[] entries for the
* AC coefficients; otherwise, if the input side of the decompressor
* advances into a new scan, we might think the coefficients are known
* more accurately than they really are.
*/
LOCAL(boolean)
smoothing_ok (j_decompress_ptr cinfo)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
boolean smoothing_useful = FALSE;
int ci, coefi;
jpeg_component_info *compptr;
JQUANT_TBL * qtable;
int * coef_bits;
int * coef_bits_latch;
if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
return FALSE;
/* Allocate latch area if not already done */
if (coef->coef_bits_latch == NULL)
coef->coef_bits_latch = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components *
(SAVED_COEFS * SIZEOF(int)));
coef_bits_latch = coef->coef_bits_latch;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* All components' quantization values must already be latched. */
if ((qtable = compptr->quant_table) == NULL)
return FALSE;
/* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
if (qtable->quantval[0] == 0 ||
qtable->quantval[Q01_POS] == 0 ||
qtable->quantval[Q10_POS] == 0 ||
qtable->quantval[Q20_POS] == 0 ||
qtable->quantval[Q11_POS] == 0 ||
qtable->quantval[Q02_POS] == 0)
return FALSE;
/* DC values must be at least partly known for all components. */
coef_bits = cinfo->coef_bits[ci];
if (coef_bits[0] < 0)
return FALSE;
/* Block smoothing is helpful if some AC coefficients remain inaccurate. */
for (coefi = 1; coefi <= 5; coefi++) {
coef_bits_latch[coefi] = coef_bits[coefi];
if (coef_bits[coefi] != 0)
smoothing_useful = TRUE;
}
coef_bits_latch += SAVED_COEFS;
}
return smoothing_useful;
}
/*
* Variant of decompress_data for use when doing block smoothing.
*/
METHODDEF(int)
decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
JDIMENSION block_num, last_block_column;
int ci, block_row, block_rows, access_rows;
JBLOCKARRAY buffer;
JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
JSAMPARRAY output_ptr;
JDIMENSION output_col;
jpeg_component_info *compptr;
inverse_DCT_method_ptr inverse_DCT;
boolean first_row, last_row;
JBLOCK workspace;
int *coef_bits;
JQUANT_TBL *quanttbl;
INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
int Al, pred;
/* Force some input to be done if we are getting ahead of the input. */
while (cinfo->input_scan_number <= cinfo->output_scan_number &&
! cinfo->inputctl->eoi_reached) {
if (cinfo->input_scan_number == cinfo->output_scan_number) {
/* If input is working on current scan, we ordinarily want it to
* have completed the current row. But if input scan is DC,
* we want it to keep one row ahead so that next block row's DC
* values are up to date.
*/
JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
break;
}
if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
return JPEG_SUSPENDED;
}
/* OK, output from the virtual arrays. */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Don't bother to IDCT an uninteresting component. */
if (! compptr->component_needed)
continue;
/* Count non-dummy DCT block rows in this iMCU row. */
if (cinfo->output_iMCU_row < last_iMCU_row) {
block_rows = compptr->v_samp_factor;
access_rows = block_rows * 2; /* this and next iMCU row */
last_row = FALSE;
} else {
/* NB: can't use last_row_height here; it is input-side-dependent! */
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (block_rows == 0) block_rows = compptr->v_samp_factor;
access_rows = block_rows; /* this iMCU row only */
last_row = TRUE;
}
/* Align the virtual buffer for this component. */
if (cinfo->output_iMCU_row > 0) {
access_rows += compptr->v_samp_factor; /* prior iMCU row too */
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[ci],
(cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
(JDIMENSION) access_rows, FALSE);
buffer += compptr->v_samp_factor; /* point to current iMCU row */
first_row = FALSE;
} else {
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[ci],
(JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
first_row = TRUE;
}
/* Fetch component-dependent info */
coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
quanttbl = compptr->quant_table;
Q00 = quanttbl->quantval[0];
Q01 = quanttbl->quantval[Q01_POS];
Q10 = quanttbl->quantval[Q10_POS];
Q20 = quanttbl->quantval[Q20_POS];
Q11 = quanttbl->quantval[Q11_POS];
Q02 = quanttbl->quantval[Q02_POS];
inverse_DCT = cinfo->idct->inverse_DCT[ci];
output_ptr = output_buf[ci];
/* Loop over all DCT blocks to be processed. */
for (block_row = 0; block_row < block_rows; block_row++) {
buffer_ptr = buffer[block_row];
if (first_row && block_row == 0)
prev_block_row = buffer_ptr;
else
prev_block_row = buffer[block_row-1];
if (last_row && block_row == block_rows-1)
next_block_row = buffer_ptr;
else
next_block_row = buffer[block_row+1];
/* We fetch the surrounding DC values using a sliding-register approach.
* Initialize all nine here so as to do the right thing on narrow pics.
*/
DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
DC7 = DC8 = DC9 = (int) next_block_row[0][0];
output_col = 0;
last_block_column = compptr->width_in_blocks - 1;
for (block_num = 0; block_num <= last_block_column; block_num++) {
/* Fetch current DCT block into workspace so we can modify it. */
jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
/* Update DC values */
if (block_num < last_block_column) {
DC3 = (int) prev_block_row[1][0];
DC6 = (int) buffer_ptr[1][0];
DC9 = (int) next_block_row[1][0];
}
/* Compute coefficient estimates per K.8.
* An estimate is applied only if coefficient is still zero,
* and is not known to be fully accurate.
*/
/* AC01 */
if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
num = 36 * Q00 * (DC4 - DC6);
if (num >= 0) {
pred = (int) (((Q01<<7) + num) / (Q01<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
} else {
pred = (int) (((Q01<<7) - num) / (Q01<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
pred = -pred;
}
workspace[1] = (JCOEF) pred;
}
/* AC10 */
if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
num = 36 * Q00 * (DC2 - DC8);
if (num >= 0) {
pred = (int) (((Q10<<7) + num) / (Q10<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
} else {
pred = (int) (((Q10<<7) - num) / (Q10<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
pred = -pred;
}
workspace[8] = (JCOEF) pred;
}
/* AC20 */
if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
if (num >= 0) {
pred = (int) (((Q20<<7) + num) / (Q20<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
} else {
pred = (int) (((Q20<<7) - num) / (Q20<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
pred = -pred;
}
workspace[16] = (JCOEF) pred;
}
/* AC11 */
if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
if (num >= 0) {
pred = (int) (((Q11<<7) + num) / (Q11<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
} else {
pred = (int) (((Q11<<7) - num) / (Q11<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
pred = -pred;
}
workspace[9] = (JCOEF) pred;
}
/* AC02 */
if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
if (num >= 0) {
pred = (int) (((Q02<<7) + num) / (Q02<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
} else {
pred = (int) (((Q02<<7) - num) / (Q02<<8));
if (Al > 0 && pred >= (1<<Al))
pred = (1<<Al)-1;
pred = -pred;
}
workspace[2] = (JCOEF) pred;
}
/* OK, do the IDCT */
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
output_ptr, output_col);
/* Advance for next column */
DC1 = DC2; DC2 = DC3;
DC4 = DC5; DC5 = DC6;
DC7 = DC8; DC8 = DC9;
buffer_ptr++, prev_block_row++, next_block_row++;
output_col += compptr->DCT_h_scaled_size;
}
output_ptr += compptr->DCT_v_scaled_size;
}
}
if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
return JPEG_ROW_COMPLETED;
return JPEG_SCAN_COMPLETED;
}
#endif /* BLOCK_SMOOTHING_SUPPORTED */
/*
* Initialize coefficient buffer controller.
*/
GLOBAL void
GLOBAL(void)
jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
my_coef_ptr coef;
int ci, i;
jpeg_component_info *compptr;
JBLOCKROW buffer;
coef = (my_coef_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_coef_controller));
cinfo->coef = (struct jpeg_d_coef_controller *) coef;
coef->pub.start_pass = start_pass_coef;
coef->pub.start_input_pass = start_input_pass;
coef->pub.start_output_pass = start_output_pass;
#ifdef BLOCK_SMOOTHING_SUPPORTED
coef->coef_bits_latch = NULL;
#endif
/* Create the coefficient buffer. */
if (need_full_buffer) {
#ifdef D_MULTISCAN_FILES_SUPPORTED
/* Allocate a full-image virtual array for each component, */
/* padded to a multiple of samp_factor DCT blocks in each direction. */
/* Note memmgr implicitly pads the vertical direction. */
/* Note we ask for a pre-zeroed array. */
int ci, access_rows;
jpeg_component_info *compptr;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
access_rows = compptr->v_samp_factor;
#ifdef BLOCK_SMOOTHING_SUPPORTED
/* If block smoothing could be used, need a bigger window */
if (cinfo->progressive_mode)
access_rows *= 3;
#endif
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
(long) compptr->h_samp_factor),
compptr->height_in_blocks,
(JDIMENSION) compptr->v_samp_factor);
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor),
(JDIMENSION) access_rows);
}
coef->pub.consume_data = consume_data;
coef->pub.decompress_data = decompress_data;
coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
#else
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
/* We only need a single-MCU buffer. */
JBLOCKROW buffer;
int i;
buffer = (JBLOCKROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
for (i = 0; i < MAX_BLOCKS_IN_MCU; i++) {
D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
coef->MCU_buffer[i] = buffer + i;
}
coef->whole_image[0] = NULL; /* flag for no virtual arrays */
if (cinfo->lim_Se == 0) /* DC only case: want to bypass later */
FMEMZERO((void FAR *) buffer,
(size_t) (D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)));
coef->pub.consume_data = dummy_consume_data;
coef->pub.decompress_data = decompress_onepass;
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
}
}

189
jdcolor.c
View File

@@ -1,7 +1,8 @@
/*
* jdcolor.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -23,20 +24,28 @@ typedef struct {
int * Cb_b_tab; /* => table for Cb to B conversion */
INT32 * Cr_g_tab; /* => table for Cr to G conversion */
INT32 * Cb_g_tab; /* => table for Cb to G conversion */
/* Private state for RGB->Y conversion */
INT32 * rgb_y_tab; /* => table for RGB to Y conversion */
} my_color_deconverter;
typedef my_color_deconverter * my_cconvert_ptr;
/**************** YCbCr -> RGB conversion: most common case **************/
/**************** RGB -> Y conversion: less common case **************/
/*
* YCbCr is defined per CCIR 601-1, except that Cb and Cr are
* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
* The conversion equations to be implemented are therefore
*
* R = Y + 1.40200 * Cr
* G = Y - 0.34414 * Cb - 0.71414 * Cr
* B = Y + 1.77200 * Cb
*
* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
*
* where Cb and Cr represent the incoming values less CENTERJSAMPLE.
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
*
@@ -61,16 +70,29 @@ typedef my_color_deconverter * my_cconvert_ptr;
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
/*
* Initialize for YCC->RGB colorspace conversion.
/* We allocate one big table for RGB->Y conversion and divide it up into
* three parts, instead of doing three alloc_small requests. This lets us
* use a single table base address, which can be held in a register in the
* inner loops on many machines (more than can hold all three addresses,
* anyway).
*/
METHODDEF void
ycc_rgb_start (j_decompress_ptr cinfo)
#define R_Y_OFF 0 /* offset to R => Y section */
#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
#define TABLE_SIZE (3*(MAXJSAMPLE+1))
/*
* Initialize tables for YCC->RGB colorspace conversion.
*/
LOCAL(void)
build_ycc_rgb_table (j_decompress_ptr cinfo)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
INT32 i, x;
int i;
INT32 x;
SHIFT_TEMPS
cconvert->Cr_r_tab = (int *)
@@ -115,7 +137,7 @@ ycc_rgb_start (j_decompress_ptr cinfo)
* offset required on that side.
*/
METHODDEF void
METHODDEF(void)
ycc_rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
@@ -159,19 +181,111 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
/**************** Cases other than YCbCr -> RGB **************/
/*
* Initialize for RGB->grayscale colorspace conversion.
*/
LOCAL(void)
build_rgb_y_table (j_decompress_ptr cinfo)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
INT32 * rgb_y_tab;
INT32 i;
/* Allocate and fill in the conversion tables. */
cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(TABLE_SIZE * SIZEOF(INT32)));
for (i = 0; i <= MAXJSAMPLE; i++) {
rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i;
rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;
rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
}
}
/*
* Convert RGB to grayscale.
*/
METHODDEF(void)
rgb_gray_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register int r, g, b;
register INT32 * ctab = cconvert->rgb_y_tab;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
r = GETJSAMPLE(inptr0[col]);
g = GETJSAMPLE(inptr1[col]);
b = GETJSAMPLE(inptr2[col]);
/* Y */
outptr[col] = (JSAMPLE)
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
>> SCALEBITS);
}
}
}
/*
* No colorspace change, but conversion from separate-planes
* to interleaved representation.
*/
METHODDEF(void)
rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr[RGB_RED] = inptr0[col];
outptr[RGB_GREEN] = inptr1[col];
outptr[RGB_BLUE] = inptr2[col];
outptr += RGB_PIXELSIZE;
}
}
}
/*
* Color conversion for no colorspace change: just copy the data,
* converting from separate-planes to interleaved representation.
*/
METHODDEF void
METHODDEF(void)
null_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register JSAMPROW inptr, outptr;
register JDIMENSION count;
register int num_components = cinfo->output_components;
register int num_components = cinfo->num_components;
JDIMENSION num_cols = cinfo->output_width;
int ci;
@@ -196,7 +310,7 @@ null_convert (j_decompress_ptr cinfo,
* we just copy the Y (luminance) component and ignore chrominance.
*/
METHODDEF void
METHODDEF(void)
grayscale_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
@@ -206,14 +320,41 @@ grayscale_convert (j_decompress_ptr cinfo,
}
/*
* Convert grayscale to RGB: just duplicate the graylevel three times.
* This is provided to support applications that don't want to cope
* with grayscale as a separate case.
*/
METHODDEF(void)
gray_rgb_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register JSAMPROW inptr, outptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
while (--num_rows >= 0) {
inptr = input_buf[0][input_row++];
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
outptr += RGB_PIXELSIZE;
}
}
}
/*
* Adobe-style YCCK->CMYK conversion.
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
* conversion as above, while passing K (black) unchanged.
* We assume ycc_rgb_start has been called.
* We assume build_ycc_rgb_table has been called.
*/
METHODDEF void
METHODDEF(void)
ycck_cmyk_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
@@ -261,8 +402,8 @@ ycck_cmyk_convert (j_decompress_ptr cinfo,
* Empty method for start_pass.
*/
METHODDEF void
null_method (j_decompress_ptr cinfo)
METHODDEF(void)
start_pass_dcolor (j_decompress_ptr cinfo)
{
/* no work needed */
}
@@ -272,7 +413,7 @@ null_method (j_decompress_ptr cinfo)
* Module initialization routine for output colorspace conversion.
*/
GLOBAL void
GLOBAL(void)
jinit_color_deconverter (j_decompress_ptr cinfo)
{
my_cconvert_ptr cconvert;
@@ -282,8 +423,7 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_deconverter));
cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
/* set start_pass to null method until we find out differently */
cconvert->pub.start_pass = null_method;
cconvert->pub.start_pass = start_pass_dcolor;
/* Make sure num_components agrees with jpeg_color_space */
switch (cinfo->jpeg_color_space) {
@@ -324,6 +464,9 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
/* For color->grayscale conversion, only the Y (0) component is needed */
for (ci = 1; ci < cinfo->num_components; ci++)
cinfo->comp_info[ci].component_needed = FALSE;
} else if (cinfo->jpeg_color_space == JCS_RGB) {
cconvert->pub.color_convert = rgb_gray_convert;
build_rgb_y_table(cinfo);
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
@@ -331,10 +474,12 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
case JCS_RGB:
cinfo->out_color_components = RGB_PIXELSIZE;
if (cinfo->jpeg_color_space == JCS_YCbCr) {
cconvert->pub.start_pass = ycc_rgb_start;
cconvert->pub.color_convert = ycc_rgb_convert;
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
cconvert->pub.color_convert = null_convert;
build_ycc_rgb_table(cinfo);
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
cconvert->pub.color_convert = gray_rgb_convert;
} else if (cinfo->jpeg_color_space == JCS_RGB) {
cconvert->pub.color_convert = rgb_convert;
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
@@ -342,8 +487,8 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
case JCS_CMYK:
cinfo->out_color_components = 4;
if (cinfo->jpeg_color_space == JCS_YCCK) {
cconvert->pub.start_pass = ycc_rgb_start;
cconvert->pub.color_convert = ycck_cmyk_convert;
build_ycc_rgb_table(cinfo);
} else if (cinfo->jpeg_color_space == JCS_CMYK) {
cconvert->pub.color_convert = null_convert;
} else

253
jdct.h
View File

@@ -1,7 +1,7 @@
/*
* jdct.h
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-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.
*
@@ -14,11 +14,16 @@
/*
* A forward DCT routine is given a pointer to a work area of type DCTELEM[];
* the DCT is to be performed in-place in that buffer. Type DCTELEM is int
* for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT
* implementations use an array of type FAST_FLOAT, instead.)
* The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
* A forward DCT routine is given a pointer to an input sample array and
* a pointer to a work area of type DCTELEM[]; the DCT is to be performed
* in-place in that buffer. Type DCTELEM is int for 8-bit samples, INT32
* for 12-bit samples. (NOTE: Floating-point DCT implementations use an
* array of type FAST_FLOAT, instead.)
* The input data is to be fetched from the sample array starting at a
* specified column. (Any row offset needed will be applied to the array
* pointer before it is passed to the FDCT code.)
* Note that the number of samples fetched by the FDCT routine is
* DCT_h_scaled_size * DCT_v_scaled_size.
* The DCT outputs are returned scaled up by a factor of 8; they therefore
* have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
* convention improves accuracy in integer implementations and saves some
@@ -32,8 +37,12 @@ typedef int DCTELEM; /* 16 or 32 bits is fine */
typedef INT32 DCTELEM; /* must have 32 bits */
#endif
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data,
JSAMPARRAY sample_data,
JDIMENSION start_col));
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data,
JSAMPARRAY sample_data,
JDIMENSION start_col));
/*
@@ -44,7 +53,7 @@ typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
* sample array starting at a specified column. (Any row offset needed will
* be applied to the array pointer before it is passed to the IDCT code.)
* Note that the number of samples emitted by the IDCT routine is
* DCT_scaled_size * DCT_scaled_size.
* DCT_h_scaled_size * DCT_v_scaled_size.
*/
/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
@@ -84,36 +93,244 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
#define jpeg_fdct_islow jFDislow
#define jpeg_fdct_ifast jFDifast
#define jpeg_fdct_float jFDfloat
#define jpeg_fdct_7x7 jFD7x7
#define jpeg_fdct_6x6 jFD6x6
#define jpeg_fdct_5x5 jFD5x5
#define jpeg_fdct_4x4 jFD4x4
#define jpeg_fdct_3x3 jFD3x3
#define jpeg_fdct_2x2 jFD2x2
#define jpeg_fdct_1x1 jFD1x1
#define jpeg_fdct_9x9 jFD9x9
#define jpeg_fdct_10x10 jFD10x10
#define jpeg_fdct_11x11 jFD11x11
#define jpeg_fdct_12x12 jFD12x12
#define jpeg_fdct_13x13 jFD13x13
#define jpeg_fdct_14x14 jFD14x14
#define jpeg_fdct_15x15 jFD15x15
#define jpeg_fdct_16x16 jFD16x16
#define jpeg_fdct_16x8 jFD16x8
#define jpeg_fdct_14x7 jFD14x7
#define jpeg_fdct_12x6 jFD12x6
#define jpeg_fdct_10x5 jFD10x5
#define jpeg_fdct_8x4 jFD8x4
#define jpeg_fdct_6x3 jFD6x3
#define jpeg_fdct_4x2 jFD4x2
#define jpeg_fdct_2x1 jFD2x1
#define jpeg_fdct_8x16 jFD8x16
#define jpeg_fdct_7x14 jFD7x14
#define jpeg_fdct_6x12 jFD6x12
#define jpeg_fdct_5x10 jFD5x10
#define jpeg_fdct_4x8 jFD4x8
#define jpeg_fdct_3x6 jFD3x6
#define jpeg_fdct_2x4 jFD2x4
#define jpeg_fdct_1x2 jFD1x2
#define jpeg_idct_islow jRDislow
#define jpeg_idct_ifast jRDifast
#define jpeg_idct_float jRDfloat
#define jpeg_idct_7x7 jRD7x7
#define jpeg_idct_6x6 jRD6x6
#define jpeg_idct_5x5 jRD5x5
#define jpeg_idct_4x4 jRD4x4
#define jpeg_idct_3x3 jRD3x3
#define jpeg_idct_2x2 jRD2x2
#define jpeg_idct_1x1 jRD1x1
#define jpeg_idct_9x9 jRD9x9
#define jpeg_idct_10x10 jRD10x10
#define jpeg_idct_11x11 jRD11x11
#define jpeg_idct_12x12 jRD12x12
#define jpeg_idct_13x13 jRD13x13
#define jpeg_idct_14x14 jRD14x14
#define jpeg_idct_15x15 jRD15x15
#define jpeg_idct_16x16 jRD16x16
#define jpeg_idct_16x8 jRD16x8
#define jpeg_idct_14x7 jRD14x7
#define jpeg_idct_12x6 jRD12x6
#define jpeg_idct_10x5 jRD10x5
#define jpeg_idct_8x4 jRD8x4
#define jpeg_idct_6x3 jRD6x3
#define jpeg_idct_4x2 jRD4x2
#define jpeg_idct_2x1 jRD2x1
#define jpeg_idct_8x16 jRD8x16
#define jpeg_idct_7x14 jRD7x14
#define jpeg_idct_6x12 jRD6x12
#define jpeg_idct_5x10 jRD5x10
#define jpeg_idct_4x8 jRD4x8
#define jpeg_idct_3x6 jRD3x8
#define jpeg_idct_2x4 jRD2x4
#define jpeg_idct_1x2 jRD1x2
#endif /* NEED_SHORT_EXTERNAL_NAMES */
/* Extern declarations for the forward and inverse DCT routines. */
EXTERN void jpeg_fdct_islow JPP((DCTELEM * data));
EXTERN void jpeg_fdct_ifast JPP((DCTELEM * data));
EXTERN void jpeg_fdct_float JPP((FAST_FLOAT * data));
EXTERN(void) jpeg_fdct_islow
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_ifast
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_float
JPP((FAST_FLOAT * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_7x7
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_6x6
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_5x5
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_4x4
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_3x3
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_2x2
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_1x1
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_9x9
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_10x10
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_11x11
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_12x12
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_13x13
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_14x14
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_15x15
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_16x16
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_16x8
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_14x7
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_12x6
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_10x5
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_8x4
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_6x3
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_4x2
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_2x1
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_8x16
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_7x14
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_6x12
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_5x10
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_4x8
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_3x6
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_2x4
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN(void) jpeg_fdct_1x2
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
EXTERN void jpeg_idct_islow
EXTERN(void) jpeg_idct_islow
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_ifast
EXTERN(void) jpeg_idct_ifast
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_float
EXTERN(void) jpeg_idct_float
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_4x4
EXTERN(void) jpeg_idct_7x7
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_2x2
EXTERN(void) jpeg_idct_6x6
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN void jpeg_idct_1x1
EXTERN(void) jpeg_idct_5x5
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_4x4
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_3x3
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_2x2
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_1x1
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_9x9
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_10x10
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_11x11
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_12x12
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_13x13
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_14x14
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_15x15
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_16x16
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_16x8
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_14x7
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_12x6
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_10x5
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_8x4
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_6x3
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_4x2
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_2x1
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_8x16
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_7x14
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_6x12
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_5x10
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_4x8
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_3x6
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_2x4
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
EXTERN(void) jpeg_idct_1x2
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));

View File

@@ -1,14 +1,15 @@
/*
* jddctmgr.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2002-2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains the inverse-DCT management logic.
* This code selects a particular IDCT implementation to be used,
* and it performs related housekeeping chores. No code in this file
* is executed per IDCT step, only during pass setup.
* is executed per IDCT step, only during output pass setup.
*
* Note that the IDCT routines are responsible for performing coefficient
* dequantization as well as the IDCT proper. This module sets up the
@@ -21,30 +22,50 @@
#include "jdct.h" /* Private declarations for DCT subsystem */
/*
* The decompressor input side (jdinput.c) saves away the appropriate
* quantization table for each component at the start of the first scan
* involving that component. (This is necessary in order to correctly
* decode files that reuse Q-table slots.)
* When we are ready to make an output pass, the saved Q-table is converted
* to a multiplier table that will actually be used by the IDCT routine.
* The multiplier table contents are IDCT-method-dependent. To support
* application changes in IDCT method between scans, we can remake the
* multiplier tables if necessary.
* In buffered-image mode, the first output pass may occur before any data
* has been seen for some components, and thus before their Q-tables have
* been saved away. To handle this case, multiplier tables are preset
* to zeroes; the result of the IDCT will be a neutral gray level.
*/
/* Private subobject for this module */
typedef struct {
struct jpeg_inverse_dct pub; /* public fields */
/* Record the IDCT method type actually selected for each component */
J_DCT_METHOD real_method[MAX_COMPONENTS];
/* This array contains the IDCT method code that each multiplier table
* is currently set up for, or -1 if it's not yet set up.
* The actual multiplier tables are pointed to by dct_table in the
* per-component comp_info structures.
*/
int cur_method[MAX_COMPONENTS];
} my_idct_controller;
typedef my_idct_controller * my_idct_ptr;
/* ZIG[i] is the zigzag-order position of the i'th element of a DCT block */
/* read in natural order (left to right, top to bottom). */
static const int ZIG[DCTSIZE2] = {
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
/* Allocated multiplier tables: big enough for any supported variant */
typedef union {
ISLOW_MULT_TYPE islow_array[DCTSIZE2];
#ifdef DCT_IFAST_SUPPORTED
IFAST_MULT_TYPE ifast_array[DCTSIZE2];
#endif
#ifdef DCT_FLOAT_SUPPORTED
FLOAT_MULT_TYPE float_array[DCTSIZE2];
#endif
} multiplier_table;
/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
@@ -60,51 +81,205 @@ static const int ZIG[DCTSIZE2] = {
/*
* Initialize for an input scan.
*
* Verify that all referenced Q-tables are present, and set up
* the multiplier table for each one.
* With a multiple-scan JPEG file, this is called during each input scan,
* NOT during the final output pass where the IDCT is actually done.
* The purpose is to save away the current Q-table contents just in case
* the encoder changes tables between scans. This decoder will dequantize
* any component using the Q-table which was current at the start of the
* first scan using that component.
* Prepare for an output pass.
* Here we select the proper IDCT routine for each component and build
* a matching multiplier table.
*/
METHODDEF void
start_input_pass (j_decompress_ptr cinfo)
METHODDEF(void)
start_pass (j_decompress_ptr cinfo)
{
my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
int ci, qtblno, i;
int ci, i;
jpeg_component_info *compptr;
int method = 0;
inverse_DCT_method_ptr method_ptr = NULL;
JQUANT_TBL * qtbl;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
qtblno = compptr->quant_tbl_no;
/* Make sure specified quantization table is present */
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
qtbl = cinfo->quant_tbl_ptrs[qtblno];
/* Create multiplier table from quant table, unless we already did so. */
if (compptr->dct_table != NULL)
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Select the proper IDCT routine for this component's scaling */
switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) {
#ifdef IDCT_SCALING_SUPPORTED
case ((1 << 8) + 1):
method_ptr = jpeg_idct_1x1;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((2 << 8) + 2):
method_ptr = jpeg_idct_2x2;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((3 << 8) + 3):
method_ptr = jpeg_idct_3x3;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((4 << 8) + 4):
method_ptr = jpeg_idct_4x4;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((5 << 8) + 5):
method_ptr = jpeg_idct_5x5;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((6 << 8) + 6):
method_ptr = jpeg_idct_6x6;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((7 << 8) + 7):
method_ptr = jpeg_idct_7x7;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((9 << 8) + 9):
method_ptr = jpeg_idct_9x9;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((10 << 8) + 10):
method_ptr = jpeg_idct_10x10;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((11 << 8) + 11):
method_ptr = jpeg_idct_11x11;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((12 << 8) + 12):
method_ptr = jpeg_idct_12x12;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((13 << 8) + 13):
method_ptr = jpeg_idct_13x13;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((14 << 8) + 14):
method_ptr = jpeg_idct_14x14;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((15 << 8) + 15):
method_ptr = jpeg_idct_15x15;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((16 << 8) + 16):
method_ptr = jpeg_idct_16x16;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((16 << 8) + 8):
method_ptr = jpeg_idct_16x8;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((14 << 8) + 7):
method_ptr = jpeg_idct_14x7;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((12 << 8) + 6):
method_ptr = jpeg_idct_12x6;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((10 << 8) + 5):
method_ptr = jpeg_idct_10x5;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((8 << 8) + 4):
method_ptr = jpeg_idct_8x4;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((6 << 8) + 3):
method_ptr = jpeg_idct_6x3;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((4 << 8) + 2):
method_ptr = jpeg_idct_4x2;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((2 << 8) + 1):
method_ptr = jpeg_idct_2x1;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((8 << 8) + 16):
method_ptr = jpeg_idct_8x16;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((7 << 8) + 14):
method_ptr = jpeg_idct_7x14;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((6 << 8) + 12):
method_ptr = jpeg_idct_6x12;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((5 << 8) + 10):
method_ptr = jpeg_idct_5x10;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((4 << 8) + 8):
method_ptr = jpeg_idct_4x8;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((3 << 8) + 6):
method_ptr = jpeg_idct_3x6;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((2 << 8) + 4):
method_ptr = jpeg_idct_2x4;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
case ((1 << 8) + 2):
method_ptr = jpeg_idct_1x2;
method = JDCT_ISLOW; /* jidctint uses islow-style table */
break;
#endif
case ((DCTSIZE << 8) + DCTSIZE):
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
method_ptr = jpeg_idct_islow;
method = JDCT_ISLOW;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
method_ptr = jpeg_idct_ifast;
method = JDCT_IFAST;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
method_ptr = jpeg_idct_float;
method = JDCT_FLOAT;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
break;
default:
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size);
break;
}
idct->pub.inverse_DCT[ci] = method_ptr;
/* Create multiplier table from quant table.
* However, we can skip this if the component is uninteresting
* or if we already built the table. Also, if no quant table
* has yet been saved for the component, we leave the
* multiplier table all-zero; we'll be reading zeroes from the
* coefficient controller's buffer anyway.
*/
if (! compptr->component_needed || idct->cur_method[ci] == method)
continue;
switch (idct->real_method[compptr->component_index]) {
qtbl = compptr->quant_table;
if (qtbl == NULL) /* happens if no data yet for component */
continue;
idct->cur_method[ci] = method;
switch (method) {
#ifdef PROVIDE_ISLOW_TABLES
case JDCT_ISLOW:
{
/* For LL&M IDCT method, multipliers are equal to raw quantization
* coefficients, but are stored in natural order as ints.
* coefficients, but are stored as ints to ensure access efficiency.
*/
ISLOW_MULT_TYPE * ismtbl;
compptr->dct_table =
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(ISLOW_MULT_TYPE));
ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
for (i = 0; i < DCTSIZE2; i++) {
ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[ZIG[i]];
ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
}
}
break;
@@ -117,9 +292,9 @@ start_input_pass (j_decompress_ptr cinfo)
* scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* For integer operation, the multiplier table is to be scaled by
* IFAST_SCALE_BITS. The multipliers are stored in natural order.
* IFAST_SCALE_BITS.
*/
IFAST_MULT_TYPE * ifmtbl;
IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
#define CONST_BITS 14
static const INT16 aanscales[DCTSIZE2] = {
/* precomputed values scaled up by 14 bits */
@@ -134,13 +309,9 @@ start_input_pass (j_decompress_ptr cinfo)
};
SHIFT_TEMPS
compptr->dct_table =
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(IFAST_MULT_TYPE));
ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
for (i = 0; i < DCTSIZE2; i++) {
ifmtbl[i] = (IFAST_MULT_TYPE)
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[ZIG[i]],
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
(INT32) aanscales[i]),
CONST_BITS-IFAST_SCALE_BITS);
}
@@ -154,25 +325,21 @@ start_input_pass (j_decompress_ptr cinfo)
* coefficients scaled by scalefactor[row]*scalefactor[col], where
* scalefactor[0] = 1
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
* The multipliers are stored in natural order.
* We apply a further scale factor of 1/8.
*/
FLOAT_MULT_TYPE * fmtbl;
FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
int row, col;
static const double aanscalefactor[DCTSIZE] = {
1.0, 1.387039845, 1.306562965, 1.175875602,
1.0, 0.785694958, 0.541196100, 0.275899379
};
compptr->dct_table =
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
DCTSIZE2 * SIZEOF(FLOAT_MULT_TYPE));
fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
i = 0;
for (row = 0; row < DCTSIZE; row++) {
for (col = 0; col < DCTSIZE; col++) {
fmtbl[i] = (FLOAT_MULT_TYPE)
((double) qtbl->quantval[ZIG[i]] *
aanscalefactor[row] * aanscalefactor[col]);
((double) qtbl->quantval[i] *
aanscalefactor[row] * aanscalefactor[col] * 0.125);
i++;
}
}
@@ -187,37 +354,11 @@ start_input_pass (j_decompress_ptr cinfo)
}
/*
* Prepare for an output pass that will actually perform IDCTs.
*
* start_input_pass should already have been done for all components
* of interest; we need only verify that this is true.
* Note that uninteresting components are not required to have loaded tables.
* This allows the master controller to stop before reading the whole file
* if it has obtained the data for the interesting component(s).
*/
METHODDEF void
start_output_pass (j_decompress_ptr cinfo)
{
jpeg_component_info *compptr;
int ci;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
if (! compptr->component_needed)
continue;
if (compptr->dct_table == NULL)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, compptr->quant_tbl_no);
}
}
/*
* Initialize IDCT manager.
*/
GLOBAL void
GLOBAL(void)
jinit_inverse_dct (j_decompress_ptr cinfo)
{
my_idct_ptr idct;
@@ -228,55 +369,16 @@ jinit_inverse_dct (j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_idct_controller));
cinfo->idct = (struct jpeg_inverse_dct *) idct;
idct->pub.start_input_pass = start_input_pass;
idct->pub.start_output_pass = start_output_pass;
idct->pub.start_pass = start_pass;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
compptr->dct_table = NULL; /* initialize tables to "not prepared" */
switch (compptr->DCT_scaled_size) {
#ifdef IDCT_SCALING_SUPPORTED
case 1:
idct->pub.inverse_DCT[ci] = jpeg_idct_1x1;
idct->real_method[ci] = JDCT_ISLOW; /* jidctred uses islow-style table */
break;
case 2:
idct->pub.inverse_DCT[ci] = jpeg_idct_2x2;
idct->real_method[ci] = JDCT_ISLOW; /* jidctred uses islow-style table */
break;
case 4:
idct->pub.inverse_DCT[ci] = jpeg_idct_4x4;
idct->real_method[ci] = JDCT_ISLOW; /* jidctred uses islow-style table */
break;
#endif
case DCTSIZE:
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
idct->pub.inverse_DCT[ci] = jpeg_idct_islow;
idct->real_method[ci] = JDCT_ISLOW;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
idct->pub.inverse_DCT[ci] = jpeg_idct_ifast;
idct->real_method[ci] = JDCT_IFAST;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
idct->pub.inverse_DCT[ci] = jpeg_idct_float;
idct->real_method[ci] = JDCT_FLOAT;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
break;
default:
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
break;
}
/* Allocate and pre-zero a multiplier table for each component */
compptr->dct_table =
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(multiplier_table));
MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
/* Mark multiplier table not yet set up for any method */
idct->cur_method[ci] = -1;
}
}

1521
jdhuff.c

File diff suppressed because it is too large Load Diff

661
jdinput.c Normal file
View File

@@ -0,0 +1,661 @@
/*
* jdinput.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2002-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains input control logic for the JPEG decompressor.
* These routines are concerned with controlling the decompressor's input
* processing (marker reading and coefficient decoding). The actual input
* reading is done in jdmarker.c, jdhuff.c, and jdarith.c.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Private state */
typedef struct {
struct jpeg_input_controller pub; /* public fields */
int inheaders; /* Nonzero until first SOS is reached */
} my_input_controller;
typedef my_input_controller * my_inputctl_ptr;
/* Forward declarations */
METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
/*
* Routines to calculate various quantities related to the size of the image.
*/
/*
* Compute output image dimensions and related values.
* NOTE: this is exported for possible use by application.
* Hence it mustn't do anything that can't be done twice.
*/
GLOBAL(void)
jpeg_core_output_dimensions (j_decompress_ptr cinfo)
/* Do computations that are needed before master selection phase.
* This function is used for transcoding and full decompression.
*/
{
#ifdef IDCT_SCALING_SUPPORTED
int ci;
jpeg_component_info *compptr;
/* Compute actual output image dimensions and DCT scaling choices. */
if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom) {
/* Provide 1/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 1;
cinfo->min_DCT_v_scaled_size = 1;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 2) {
/* Provide 2/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 2L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 2L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 2;
cinfo->min_DCT_v_scaled_size = 2;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 3) {
/* Provide 3/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 3L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 3L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 3;
cinfo->min_DCT_v_scaled_size = 3;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 4) {
/* Provide 4/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 4L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 4L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 4;
cinfo->min_DCT_v_scaled_size = 4;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 5) {
/* Provide 5/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 5L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 5L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 5;
cinfo->min_DCT_v_scaled_size = 5;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 6) {
/* Provide 6/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 6L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 6L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 6;
cinfo->min_DCT_v_scaled_size = 6;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 7) {
/* Provide 7/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 7L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 7L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 7;
cinfo->min_DCT_v_scaled_size = 7;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 8) {
/* Provide 8/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 8L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 8L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 8;
cinfo->min_DCT_v_scaled_size = 8;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 9) {
/* Provide 9/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 9L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 9L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 9;
cinfo->min_DCT_v_scaled_size = 9;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 10) {
/* Provide 10/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 10L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 10L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 10;
cinfo->min_DCT_v_scaled_size = 10;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 11) {
/* Provide 11/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 11L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 11L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 11;
cinfo->min_DCT_v_scaled_size = 11;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 12) {
/* Provide 12/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 12L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 12L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 12;
cinfo->min_DCT_v_scaled_size = 12;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 13) {
/* Provide 13/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 13L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 13L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 13;
cinfo->min_DCT_v_scaled_size = 13;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 14) {
/* Provide 14/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 14L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 14L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 14;
cinfo->min_DCT_v_scaled_size = 14;
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 15) {
/* Provide 15/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 15L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 15L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 15;
cinfo->min_DCT_v_scaled_size = 15;
} else {
/* Provide 16/block_size scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * 16L, (long) cinfo->block_size);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * 16L, (long) cinfo->block_size);
cinfo->min_DCT_h_scaled_size = 16;
cinfo->min_DCT_v_scaled_size = 16;
}
/* Recompute dimensions of components */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size;
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size;
}
#else /* !IDCT_SCALING_SUPPORTED */
/* Hardwire it to "no scaling" */
cinfo->output_width = cinfo->image_width;
cinfo->output_height = cinfo->image_height;
/* jdinput.c has already initialized DCT_scaled_size,
* and has computed unscaled downsampled_width and downsampled_height.
*/
#endif /* IDCT_SCALING_SUPPORTED */
}
LOCAL(void)
initial_setup (j_decompress_ptr cinfo)
/* Called once, when first SOS marker is reached */
{
int ci;
jpeg_component_info *compptr;
/* Make sure image isn't bigger than I can handle */
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
/* For now, precision must match compiled-in value... */
if (cinfo->data_precision != BITS_IN_JSAMPLE)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Check that number of components won't exceed internal array sizes */
if (cinfo->num_components > MAX_COMPONENTS)
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
MAX_COMPONENTS);
/* Compute maximum sampling factors; check factor validity */
cinfo->max_h_samp_factor = 1;
cinfo->max_v_samp_factor = 1;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
ERREXIT(cinfo, JERR_BAD_SAMPLING);
cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
compptr->h_samp_factor);
cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
compptr->v_samp_factor);
}
/* Derive block_size, natural_order, and lim_Se */
if (cinfo->is_baseline || (cinfo->progressive_mode &&
cinfo->comps_in_scan)) { /* no pseudo SOS marker */
cinfo->block_size = DCTSIZE;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
} else
switch (cinfo->Se) {
case (1*1-1):
cinfo->block_size = 1;
cinfo->natural_order = jpeg_natural_order; /* not needed */
cinfo->lim_Se = cinfo->Se;
break;
case (2*2-1):
cinfo->block_size = 2;
cinfo->natural_order = jpeg_natural_order2;
cinfo->lim_Se = cinfo->Se;
break;
case (3*3-1):
cinfo->block_size = 3;
cinfo->natural_order = jpeg_natural_order3;
cinfo->lim_Se = cinfo->Se;
break;
case (4*4-1):
cinfo->block_size = 4;
cinfo->natural_order = jpeg_natural_order4;
cinfo->lim_Se = cinfo->Se;
break;
case (5*5-1):
cinfo->block_size = 5;
cinfo->natural_order = jpeg_natural_order5;
cinfo->lim_Se = cinfo->Se;
break;
case (6*6-1):
cinfo->block_size = 6;
cinfo->natural_order = jpeg_natural_order6;
cinfo->lim_Se = cinfo->Se;
break;
case (7*7-1):
cinfo->block_size = 7;
cinfo->natural_order = jpeg_natural_order7;
cinfo->lim_Se = cinfo->Se;
break;
case (8*8-1):
cinfo->block_size = 8;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (9*9-1):
cinfo->block_size = 9;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (10*10-1):
cinfo->block_size = 10;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (11*11-1):
cinfo->block_size = 11;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (12*12-1):
cinfo->block_size = 12;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (13*13-1):
cinfo->block_size = 13;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (14*14-1):
cinfo->block_size = 14;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (15*15-1):
cinfo->block_size = 15;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
case (16*16-1):
cinfo->block_size = 16;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
break;
default:
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
break;
}
/* We initialize DCT_scaled_size and min_DCT_scaled_size to block_size.
* In the full decompressor,
* this will be overridden by jpeg_calc_output_dimensions in jdmaster.c;
* but in the transcoder,
* jpeg_calc_output_dimensions is not used, so we must do it here.
*/
cinfo->min_DCT_h_scaled_size = cinfo->block_size;
cinfo->min_DCT_v_scaled_size = cinfo->block_size;
/* Compute dimensions of components */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
compptr->DCT_h_scaled_size = cinfo->block_size;
compptr->DCT_v_scaled_size = cinfo->block_size;
/* Size in DCT blocks */
compptr->width_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
compptr->height_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
/* downsampled_width and downsampled_height will also be overridden by
* jdmaster.c if we are doing full decompression. The transcoder library
* doesn't use these values, but the calling application might.
*/
/* Size in samples */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
(long) cinfo->max_h_samp_factor);
compptr->downsampled_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
(long) cinfo->max_v_samp_factor);
/* Mark component needed, until color conversion says otherwise */
compptr->component_needed = TRUE;
/* Mark no quantization table yet saved for component */
compptr->quant_table = NULL;
}
/* Compute number of fully interleaved MCU rows. */
cinfo->total_iMCU_rows = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
/* Decide whether file contains multiple scans */
if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
cinfo->inputctl->has_multiple_scans = TRUE;
else
cinfo->inputctl->has_multiple_scans = FALSE;
}
LOCAL(void)
per_scan_setup (j_decompress_ptr cinfo)
/* Do computations that are needed before processing a JPEG scan */
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
{
int ci, mcublks, tmp;
jpeg_component_info *compptr;
if (cinfo->comps_in_scan == 1) {
/* Noninterleaved (single-component) scan */
compptr = cinfo->cur_comp_info[0];
/* Overall image size in MCUs */
cinfo->MCUs_per_row = compptr->width_in_blocks;
cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
/* For noninterleaved scan, always one block per MCU */
compptr->MCU_width = 1;
compptr->MCU_height = 1;
compptr->MCU_blocks = 1;
compptr->MCU_sample_width = compptr->DCT_h_scaled_size;
compptr->last_col_width = 1;
/* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row.
*/
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (tmp == 0) tmp = compptr->v_samp_factor;
compptr->last_row_height = tmp;
/* Prepare array describing MCU composition */
cinfo->blocks_in_MCU = 1;
cinfo->MCU_membership[0] = 0;
} else {
/* Interleaved (multi-component) scan */
if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
MAX_COMPS_IN_SCAN);
/* Overall image size in MCUs */
cinfo->MCUs_per_row = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width,
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
cinfo->MCU_rows_in_scan = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
cinfo->blocks_in_MCU = 0;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* Sampling factors give # of blocks of component in each MCU */
compptr->MCU_width = compptr->h_samp_factor;
compptr->MCU_height = compptr->v_samp_factor;
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_h_scaled_size;
/* Figure number of non-dummy blocks in last MCU column & row */
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
if (tmp == 0) tmp = compptr->MCU_width;
compptr->last_col_width = tmp;
tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
if (tmp == 0) tmp = compptr->MCU_height;
compptr->last_row_height = tmp;
/* Prepare array describing MCU composition */
mcublks = compptr->MCU_blocks;
if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
while (mcublks-- > 0) {
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
}
}
}
}
/*
* Save away a copy of the Q-table referenced by each component present
* in the current scan, unless already saved during a prior scan.
*
* In a multiple-scan JPEG file, the encoder could assign different components
* the same Q-table slot number, but change table definitions between scans
* so that each component uses a different Q-table. (The IJG encoder is not
* currently capable of doing this, but other encoders might.) Since we want
* to be able to dequantize all the components at the end of the file, this
* means that we have to save away the table actually used for each component.
* We do this by copying the table at the start of the first scan containing
* the component.
* The JPEG spec prohibits the encoder from changing the contents of a Q-table
* slot between scans of a component using that slot. If the encoder does so
* anyway, this decoder will simply use the Q-table values that were current
* at the start of the first scan for the component.
*
* The decompressor output side looks only at the saved quant tables,
* not at the current Q-table slots.
*/
LOCAL(void)
latch_quant_tables (j_decompress_ptr cinfo)
{
int ci, qtblno;
jpeg_component_info *compptr;
JQUANT_TBL * qtbl;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* No work if we already saved Q-table for this component */
if (compptr->quant_table != NULL)
continue;
/* Make sure specified quantization table is present */
qtblno = compptr->quant_tbl_no;
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
/* OK, save away the quantization table */
qtbl = (JQUANT_TBL *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(JQUANT_TBL));
MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
compptr->quant_table = qtbl;
}
}
/*
* Initialize the input modules to read a scan of compressed data.
* The first call to this is done by jdmaster.c after initializing
* the entire decompressor (during jpeg_start_decompress).
* Subsequent calls come from consume_markers, below.
*/
METHODDEF(void)
start_input_pass (j_decompress_ptr cinfo)
{
per_scan_setup(cinfo);
latch_quant_tables(cinfo);
(*cinfo->entropy->start_pass) (cinfo);
(*cinfo->coef->start_input_pass) (cinfo);
cinfo->inputctl->consume_input = cinfo->coef->consume_data;
}
/*
* Finish up after inputting a compressed-data scan.
* This is called by the coefficient controller after it's read all
* the expected data of the scan.
*/
METHODDEF(void)
finish_input_pass (j_decompress_ptr cinfo)
{
cinfo->inputctl->consume_input = consume_markers;
}
/*
* Read JPEG markers before, between, or after compressed-data scans.
* Change state as necessary when a new scan is reached.
* Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
*
* The consume_input method pointer points either here or to the
* coefficient controller's consume_data routine, depending on whether
* we are reading a compressed data segment or inter-segment markers.
*
* Note: This function should NOT return a pseudo SOS marker (with zero
* component number) to the caller. A pseudo marker received by
* read_markers is processed and then skipped for other markers.
*/
METHODDEF(int)
consume_markers (j_decompress_ptr cinfo)
{
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
int val;
if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
return JPEG_REACHED_EOI;
for (;;) { /* Loop to pass pseudo SOS marker */
val = (*cinfo->marker->read_markers) (cinfo);
switch (val) {
case JPEG_REACHED_SOS: /* Found SOS */
if (inputctl->inheaders) { /* 1st SOS */
if (inputctl->inheaders == 1)
initial_setup(cinfo);
if (cinfo->comps_in_scan == 0) { /* pseudo SOS marker */
inputctl->inheaders = 2;
break;
}
inputctl->inheaders = 0;
/* Note: start_input_pass must be called by jdmaster.c
* before any more input can be consumed. jdapimin.c is
* responsible for enforcing this sequencing.
*/
} else { /* 2nd or later SOS marker */
if (! inputctl->pub.has_multiple_scans)
ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
if (cinfo->comps_in_scan == 0) /* unexpected pseudo SOS marker */
break;
start_input_pass(cinfo);
}
return val;
case JPEG_REACHED_EOI: /* Found EOI */
inputctl->pub.eoi_reached = TRUE;
if (inputctl->inheaders) { /* Tables-only datastream, apparently */
if (cinfo->marker->saw_SOF)
ERREXIT(cinfo, JERR_SOF_NO_SOS);
} else {
/* Prevent infinite loop in coef ctlr's decompress_data routine
* if user set output_scan_number larger than number of scans.
*/
if (cinfo->output_scan_number > cinfo->input_scan_number)
cinfo->output_scan_number = cinfo->input_scan_number;
}
return val;
case JPEG_SUSPENDED:
return val;
default:
return val;
}
}
}
/*
* Reset state to begin a fresh datastream.
*/
METHODDEF(void)
reset_input_controller (j_decompress_ptr cinfo)
{
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
inputctl->pub.consume_input = consume_markers;
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
inputctl->pub.eoi_reached = FALSE;
inputctl->inheaders = 1;
/* Reset other modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->marker->reset_marker_reader) (cinfo);
/* Reset progression state -- would be cleaner if entropy decoder did this */
cinfo->coef_bits = NULL;
}
/*
* Initialize the input controller module.
* This is called only once, when the decompression object is created.
*/
GLOBAL(void)
jinit_input_controller (j_decompress_ptr cinfo)
{
my_inputctl_ptr inputctl;
/* Create subobject in permanent pool */
inputctl = (my_inputctl_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
SIZEOF(my_input_controller));
cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
/* Initialize method pointers */
inputctl->pub.consume_input = consume_markers;
inputctl->pub.reset_input_controller = reset_input_controller;
inputctl->pub.start_input_pass = start_input_pass;
inputctl->pub.finish_input_pass = finish_input_pass;
/* Initialize state: can't use reset_input_controller since we don't
* want to try to reset other modules yet.
*/
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
inputctl->pub.eoi_reached = FALSE;
inputctl->inheaders = 1;
}

View File

@@ -1,13 +1,16 @@
/*
* jdmainct.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-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 contains the main buffer controller for decompression.
* The main buffer lies between the JPEG decompressor proper and the
* post-processor; it holds downsampled data in the JPEG colorspace.
*
* Note that this code is bypassed in raw-data mode, since the application
* supplies the equivalent of the main buffer in that case.
*/
#define JPEG_INTERNALS
@@ -137,36 +140,30 @@ typedef my_main_controller * my_main_ptr;
/* Forward declarations */
METHODDEF void process_data_simple_main
METHODDEF(void) process_data_simple_main
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
METHODDEF void process_data_context_main
METHODDEF(void) process_data_context_main
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
#ifdef D_MULTISCAN_FILES_SUPPORTED
METHODDEF void process_data_input_only
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
#endif
#ifdef QUANT_2PASS_SUPPORTED
METHODDEF void process_data_crank_post
METHODDEF(void) process_data_crank_post
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
#endif
LOCAL void
make_funny_pointers (j_decompress_ptr cinfo)
/* Create the funny pointer lists discussed in the comments above.
* The actual workspace is already allocated (in main->buffer),
* we just have to make the curiously ordered lists.
LOCAL(void)
alloc_funny_pointers (j_decompress_ptr cinfo)
/* Allocate space for the funny pointer lists.
* This is done only once, not once per pass.
*/
{
my_main_ptr main = (my_main_ptr) cinfo->main;
int ci, i, rgroup;
int M = cinfo->min_DCT_scaled_size;
int ci, rgroup;
int M = cinfo->min_DCT_v_scaled_size;
jpeg_component_info *compptr;
JSAMPARRAY buf, xbuf0, xbuf1;
JSAMPARRAY xbuf;
/* Get top-level space for component array pointers.
* We alloc both arrays with one call to save a few cycles.
@@ -178,18 +175,43 @@ make_funny_pointers (j_decompress_ptr cinfo)
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
/* Get space for pointer lists --- M+4 row groups in each list.
* We alloc both pointer lists with one call to save a few cycles.
*/
xbuf0 = (JSAMPARRAY)
xbuf = (JSAMPARRAY)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
xbuf0 += rgroup; /* want one row group at negative offsets */
main->xbuffer[0][ci] = xbuf0;
xbuf1 = xbuf0 + (rgroup * (M + 4));
main->xbuffer[1][ci] = xbuf1;
xbuf += rgroup; /* want one row group at negative offsets */
main->xbuffer[0][ci] = xbuf;
xbuf += rgroup * (M + 4);
main->xbuffer[1][ci] = xbuf;
}
}
LOCAL(void)
make_funny_pointers (j_decompress_ptr cinfo)
/* Create the funny pointer lists discussed in the comments above.
* The actual workspace is already allocated (in main->buffer),
* and the space for the pointer lists is allocated too.
* This routine just fills in the curiously ordered lists.
* This will be repeated at the beginning of each pass.
*/
{
my_main_ptr main = (my_main_ptr) cinfo->main;
int ci, i, rgroup;
int M = cinfo->min_DCT_v_scaled_size;
jpeg_component_info *compptr;
JSAMPARRAY buf, xbuf0, xbuf1;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
xbuf0 = main->xbuffer[0][ci];
xbuf1 = main->xbuffer[1][ci];
/* First copy the workspace pointers as-is */
buf = main->buffer[ci];
for (i = 0; i < rgroup * (M + 2); i++) {
@@ -212,7 +234,7 @@ make_funny_pointers (j_decompress_ptr cinfo)
}
LOCAL void
LOCAL(void)
set_wraparound_pointers (j_decompress_ptr cinfo)
/* Set up the "wraparound" pointers at top and bottom of the pointer lists.
* This changes the pointer list state from top-of-image to the normal state.
@@ -220,14 +242,14 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
{
my_main_ptr main = (my_main_ptr) cinfo->main;
int ci, i, rgroup;
int M = cinfo->min_DCT_scaled_size;
int M = cinfo->min_DCT_v_scaled_size;
jpeg_component_info *compptr;
JSAMPARRAY xbuf0, xbuf1;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
xbuf0 = main->xbuffer[0][ci];
xbuf1 = main->xbuffer[1][ci];
for (i = 0; i < rgroup; i++) {
@@ -240,7 +262,7 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
}
LOCAL void
LOCAL(void)
set_bottom_pointers (j_decompress_ptr cinfo)
/* Change the pointer lists to duplicate the last sample row at the bottom
* of the image. whichptr indicates which xbuffer holds the final iMCU row.
@@ -255,8 +277,8 @@ set_bottom_pointers (j_decompress_ptr cinfo)
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Count sample rows in one iMCU row and in one row group */
iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
iMCUheight = compptr->v_samp_factor * compptr->DCT_v_scaled_size;
rgroup = iMCUheight / cinfo->min_DCT_v_scaled_size;
/* Count nondummy sample rows remaining for this component */
rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
if (rows_left == 0) rows_left = iMCUheight;
@@ -281,19 +303,13 @@ set_bottom_pointers (j_decompress_ptr cinfo)
* Initialize for a processing pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_main_ptr main = (my_main_ptr) cinfo->main;
/* Processing chunks are output rows except in JBUF_CRANK_SOURCE mode. */
main->pub.num_chunks = cinfo->output_height;
switch (pass_mode) {
case JBUF_PASS_THRU:
/* Do nothing if raw-data mode. */
if (cinfo->raw_data_out)
return;
if (cinfo->upsample->need_context_rows) {
main->pub.process_data = process_data_context_main;
make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
@@ -307,14 +323,6 @@ start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
main->buffer_full = FALSE; /* Mark buffer empty */
main->rowgroup_ctr = 0;
break;
#ifdef D_MULTISCAN_FILES_SUPPORTED
case JBUF_CRANK_SOURCE:
/* Reading a multi-scan file, just crank the decompressor */
main->pub.process_data = process_data_input_only;
/* decompressor needs to be called once for each (equivalent) iMCU row */
main->pub.num_chunks = cinfo->total_iMCU_rows;
break;
#endif
#ifdef QUANT_2PASS_SUPPORTED
case JBUF_CRANK_DEST:
/* For last pass of 2-pass quantization, just crank the postprocessor */
@@ -333,7 +341,7 @@ start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
* This handles the simple case where no context is required.
*/
METHODDEF void
METHODDEF(void)
process_data_simple_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)
@@ -349,7 +357,7 @@ process_data_simple_main (j_decompress_ptr cinfo,
}
/* There are always min_DCT_scaled_size row groups in an iMCU row. */
rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
rowgroups_avail = (JDIMENSION) cinfo->min_DCT_v_scaled_size;
/* Note: at the bottom of the image, we may pass extra garbage row groups
* to the postprocessor. The postprocessor has to check for bottom
* of image anyway (at row resolution), so no point in us doing it too.
@@ -373,7 +381,7 @@ process_data_simple_main (j_decompress_ptr cinfo,
* This handles the case where context rows must be provided.
*/
METHODDEF void
METHODDEF(void)
process_data_context_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)
@@ -409,7 +417,7 @@ process_data_context_main (j_decompress_ptr cinfo,
case CTX_PREPARE_FOR_IMCU:
/* Prepare to process first M-1 row groups of this iMCU row */
main->rowgroup_ctr = 0;
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1);
/* Check for bottom of image: if so, tweak pointers to "duplicate"
* the last sample row, and adjust rowgroups_avail to ignore padding rows.
*/
@@ -432,34 +440,13 @@ process_data_context_main (j_decompress_ptr cinfo,
main->buffer_full = FALSE;
/* Still need to process last row group of this iMCU row, */
/* which is saved at index M+1 of the other xbuffer */
main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1);
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2);
main->context_state = CTX_POSTPONED_ROW;
}
}
/*
* Process some data.
* Initial passes in a multiple-scan file: just call the decompressor,
* which will save data in its internal buffer, but return nothing.
*/
#ifdef D_MULTISCAN_FILES_SUPPORTED
METHODDEF void
process_data_input_only (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)
{
if (! (*cinfo->coef->decompress_data) (cinfo, (JSAMPIMAGE) NULL))
return; /* suspension forced, can do nothing more */
*out_row_ctr += 1; /* OK, we did one iMCU row */
}
#endif /* D_MULTISCAN_FILES_SUPPORTED */
/*
* Process some data.
* Final pass of two-pass quantization: just call the postprocessor.
@@ -468,7 +455,7 @@ process_data_input_only (j_decompress_ptr cinfo,
#ifdef QUANT_2PASS_SUPPORTED
METHODDEF void
METHODDEF(void)
process_data_crank_post (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)
@@ -485,7 +472,7 @@ process_data_crank_post (j_decompress_ptr cinfo,
* Initialize main buffer controller.
*/
GLOBAL void
GLOBAL(void)
jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
my_main_ptr main;
@@ -501,31 +488,25 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
if (need_full_buffer) /* shouldn't happen */
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
/* In raw-data mode, we don't need a workspace. This module doesn't
* do anything useful in that mode, except pass calls through to the
* coef controller in CRANK_SOURCE mode (ie, reading a multiscan file).
*/
if (cinfo->raw_data_out)
return;
/* Allocate the workspace.
* ngroups is the number of row groups we need.
*/
if (cinfo->upsample->need_context_rows) {
if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
if (cinfo->min_DCT_v_scaled_size < 2) /* unsupported, see comments above */
ERREXIT(cinfo, JERR_NOTIMPL);
ngroups = cinfo->min_DCT_scaled_size + 2;
alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
ngroups = cinfo->min_DCT_v_scaled_size + 2;
} else {
ngroups = cinfo->min_DCT_scaled_size;
ngroups = cinfo->min_DCT_v_scaled_size;
}
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
main->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * compptr->DCT_scaled_size,
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
(JDIMENSION) (rgroup * ngroups));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
/*
* jdmaster.c
*
* Copyright (C) 1991-1995, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2002-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -18,24 +19,18 @@
/* Private state */
typedef enum {
main_pass, /* read and process a single-scan file */
preread_pass, /* read one scan of a multi-scan file */
output_pass, /* primary processing pass for multi-scan */
post_pass /* optional post-pass for 2-pass quant. */
} D_PASS_TYPE;
typedef struct {
struct jpeg_decomp_master pub; /* public fields */
int pass_number; /* # of passes completed */
boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
D_PASS_TYPE pass_type; /* the type of the current pass */
int pass_number; /* # of passes completed */
int total_passes; /* estimated total # of passes needed */
boolean need_post_pass; /* are we using full two-pass quantization? */
/* Saved references to initialized quantizer modules,
* in case we need to switch modes.
*/
struct jpeg_color_quantizer * quantizer_1pass;
struct jpeg_color_quantizer * quantizer_2pass;
} my_decomp_master;
typedef my_decomp_master * my_master_ptr;
@@ -46,7 +41,7 @@ typedef my_decomp_master * my_master_ptr;
* CRUCIAL: this must match the actual capabilities of jdmerge.c!
*/
LOCAL boolean
LOCAL(boolean)
use_merged_upsample (j_decompress_ptr cinfo)
{
#ifdef UPSAMPLE_MERGING_SUPPORTED
@@ -67,13 +62,15 @@ use_merged_upsample (j_decompress_ptr cinfo)
cinfo->comp_info[2].v_samp_factor != 1)
return FALSE;
/* furthermore, it doesn't work if we've scaled the IDCTs differently */
if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
if (cinfo->comp_info[0].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
cinfo->comp_info[1].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
cinfo->comp_info[2].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
cinfo->comp_info[0].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size ||
cinfo->comp_info[1].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size ||
cinfo->comp_info[2].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size)
return FALSE;
/* ??? also need to test for upsample-time rescaling, when & if supported */
/* by golly, it'll work... */
return TRUE;
return TRUE; /* by golly, it'll work... */
#else
return FALSE;
#endif
@@ -81,88 +78,77 @@ use_merged_upsample (j_decompress_ptr cinfo)
/*
* Support routines that do various essential calculations.
*
* jpeg_calc_output_dimensions is exported for possible use by application.
* Compute output image dimensions and related values.
* NOTE: this is exported for possible use by application.
* Hence it mustn't do anything that can't be done twice.
* Also note that it may be called before the master module is initialized!
*/
GLOBAL void
GLOBAL(void)
jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
/* Do computations that are needed before master selection phase */
/* Do computations that are needed before master selection phase.
* This function is used for full decompression.
*/
{
#ifdef IDCT_SCALING_SUPPORTED
int ci;
jpeg_component_info *compptr;
#endif
/* Compute maximum sampling factors; check factor validity */
cinfo->max_h_samp_factor = 1;
cinfo->max_v_samp_factor = 1;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
ERREXIT(cinfo, JERR_BAD_SAMPLING);
cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
compptr->h_samp_factor);
cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
compptr->v_samp_factor);
}
/* Prevent application from calling me at wrong times */
if (cinfo->global_state != DSTATE_READY)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Compute core output image dimensions and DCT scaling choices. */
jpeg_core_output_dimensions(cinfo);
/* Compute actual output image dimensions and DCT scaling choices. */
#ifdef IDCT_SCALING_SUPPORTED
if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
/* Provide 1/8 scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, 8L);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, 8L);
cinfo->min_DCT_scaled_size = 1;
} else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
/* Provide 1/4 scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, 4L);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, 4L);
cinfo->min_DCT_scaled_size = 2;
} else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
/* Provide 1/2 scaling */
cinfo->output_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, 2L);
cinfo->output_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, 2L);
cinfo->min_DCT_scaled_size = 4;
} else {
/* Provide 1/1 scaling */
cinfo->output_width = cinfo->image_width;
cinfo->output_height = cinfo->image_height;
cinfo->min_DCT_scaled_size = DCTSIZE;
}
/* In selecting the actual DCT scaling for each component, we try to
* scale up the chroma components via IDCT scaling rather than upsampling.
* This saves time if the upsampler gets to use 1:1 scaling.
* Note this code assumes that the supported DCT scalings are powers of 2.
* Note this code adapts subsampling ratios which are powers of 2.
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
int ssize = cinfo->min_DCT_scaled_size;
while (ssize < DCTSIZE &&
(compptr->h_samp_factor * ssize * 2 <=
cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
(compptr->v_samp_factor * ssize * 2 <=
cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
int ssize = 1;
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
compptr->DCT_scaled_size = ssize;
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
ssize = 1;
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
#else /* !IDCT_SCALING_SUPPORTED */
/* Hardwire it to "no scaling" */
cinfo->output_width = cinfo->image_width;
cinfo->output_height = cinfo->image_height;
cinfo->min_DCT_scaled_size = DCTSIZE;
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
/* We don't support IDCT ratios larger than 2. */
if (compptr->DCT_h_scaled_size > compptr->DCT_v_scaled_size * 2)
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
}
/* Recompute downsampled dimensions of components;
* application needs to know these if using raw downsampled data.
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
compptr->DCT_scaled_size = DCTSIZE;
/* Size in samples, after IDCT scaling */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width *
(long) (compptr->h_samp_factor * compptr->DCT_h_scaled_size),
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
compptr->downsampled_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height *
(long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size),
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
}
#endif /* IDCT_SCALING_SUPPORTED */
/* Report number of components in selected colorspace. */
@@ -172,10 +158,8 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
cinfo->out_color_components = 1;
break;
case JCS_RGB:
#if RGB_PIXELSIZE != 3
cinfo->out_color_components = RGB_PIXELSIZE;
break;
#endif /* else share code with YCbCr */
case JCS_YCbCr:
cinfo->out_color_components = 3;
break;
@@ -195,119 +179,6 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
else
cinfo->rec_outbuf_height = 1;
/* Compute various sampling-related dimensions.
* Some of these are of interest to the application if it is dealing with
* "raw" (not upsampled) output, so we do the calculations here.
*/
/* Compute dimensions of components */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Size in DCT blocks */
compptr->width_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
(long) (cinfo->max_h_samp_factor * DCTSIZE));
compptr->height_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
(long) (cinfo->max_v_samp_factor * DCTSIZE));
/* Size in samples, after IDCT scaling */
compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width *
(long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
(long) (cinfo->max_h_samp_factor * DCTSIZE));
compptr->downsampled_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height *
(long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
(long) (cinfo->max_v_samp_factor * DCTSIZE));
/* Mark component needed, until color conversion says otherwise */
compptr->component_needed = TRUE;
}
/* Compute number of fully interleaved MCU rows (number of times that
* main controller will call coefficient controller).
*/
cinfo->total_iMCU_rows = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE));
}
LOCAL void
per_scan_setup (j_decompress_ptr cinfo)
/* Do computations that are needed before processing a JPEG scan */
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
{
int ci, mcublks, tmp;
jpeg_component_info *compptr;
if (cinfo->comps_in_scan == 1) {
/* Noninterleaved (single-component) scan */
compptr = cinfo->cur_comp_info[0];
/* Overall image size in MCUs */
cinfo->MCUs_per_row = compptr->width_in_blocks;
cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
/* For noninterleaved scan, always one block per MCU */
compptr->MCU_width = 1;
compptr->MCU_height = 1;
compptr->MCU_blocks = 1;
compptr->MCU_sample_width = compptr->DCT_scaled_size;
compptr->last_col_width = 1;
/* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row.
*/
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (tmp == 0) tmp = compptr->v_samp_factor;
compptr->last_row_height = tmp;
/* Prepare array describing MCU composition */
cinfo->blocks_in_MCU = 1;
cinfo->MCU_membership[0] = 0;
} else {
/* Interleaved (multi-component) scan */
if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
MAX_COMPS_IN_SCAN);
/* Overall image size in MCUs */
cinfo->MCUs_per_row = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width,
(long) (cinfo->max_h_samp_factor*DCTSIZE));
cinfo->MCU_rows_in_scan = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE));
cinfo->blocks_in_MCU = 0;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* Sampling factors give # of blocks of component in each MCU */
compptr->MCU_width = compptr->h_samp_factor;
compptr->MCU_height = compptr->v_samp_factor;
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
/* Figure number of non-dummy blocks in last MCU column & row */
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
if (tmp == 0) tmp = compptr->MCU_width;
compptr->last_col_width = tmp;
tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
if (tmp == 0) tmp = compptr->MCU_height;
compptr->last_row_height = tmp;
/* Prepare array describing MCU composition */
mcublks = compptr->MCU_blocks;
if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
while (mcublks-- > 0) {
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
}
}
}
}
@@ -354,7 +225,7 @@ per_scan_setup (j_decompress_ptr cinfo)
* enough and used often enough to justify this.
*/
LOCAL void
LOCAL(void)
prepare_range_limit_table (j_decompress_ptr cinfo)
/* Allocate and fill in the sample_range_limit table */
{
@@ -385,17 +256,20 @@ prepare_range_limit_table (j_decompress_ptr cinfo)
/*
* Master selection of decompression modules.
* This is done once at the start of processing an image. We determine
* This is done once at jpeg_start_decompress time. We determine
* which modules will be used and give them appropriate initialization calls.
* We also initialize the decompressor input side to begin consuming data.
*
* Note that this is called only after jpeg_read_header has finished.
* We therefore know what is in the SOF and (first) SOS markers.
* Since jpeg_read_header has finished, we know what is in the SOF
* and (first) SOS markers. We also have all the application parameter
* settings.
*/
LOCAL void
LOCAL(void)
master_selection (j_decompress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
boolean use_c_buffer;
long samplesperrow;
JDIMENSION jd_samplesperrow;
@@ -410,62 +284,56 @@ master_selection (j_decompress_ptr cinfo)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
/* Initialize my private state */
master->pub.eoi_processed = FALSE;
master->pass_number = 0;
master->need_post_pass = FALSE;
if (cinfo->comps_in_scan == cinfo->num_components) {
master->pass_type = main_pass;
master->total_passes = 1;
} else {
#ifdef D_MULTISCAN_FILES_SUPPORTED
master->pass_type = preread_pass;
/* Assume there is a separate scan for each component; */
/* if partially interleaved, we'll increment pass_number appropriately */
master->total_passes = cinfo->num_components + 1;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
}
master->using_merged_upsample = use_merged_upsample(cinfo);
/* There's not a lot of smarts here right now, but it'll get more
* complicated when we have multiple implementations available...
*/
/* Color quantizer selection */
master->quantizer_1pass = NULL;
master->quantizer_2pass = NULL;
/* No mode changes if not using buffered-image mode. */
if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
cinfo->enable_1pass_quant = FALSE;
cinfo->enable_external_quant = FALSE;
cinfo->enable_2pass_quant = FALSE;
}
if (cinfo->quantize_colors) {
if (cinfo->raw_data_out)
ERREXIT(cinfo, JERR_NOTIMPL);
#ifdef QUANT_2PASS_SUPPORTED
/* 2-pass quantizer only works in 3-component color space.
* We use the "2-pass" code in a single pass if a colormap is given.
*/
if (cinfo->out_color_components != 3)
cinfo->two_pass_quantize = FALSE;
else if (cinfo->colormap != NULL)
cinfo->two_pass_quantize = TRUE;
#else
/* Force 1-pass quantize if we don't have 2-pass code compiled. */
cinfo->two_pass_quantize = FALSE;
#endif
if (cinfo->two_pass_quantize) {
#ifdef QUANT_2PASS_SUPPORTED
if (cinfo->colormap == NULL) {
master->need_post_pass = TRUE;
master->total_passes++;
}
jinit_2pass_quantizer(cinfo);
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
/* 2-pass quantizer only works in 3-component color space. */
if (cinfo->out_color_components != 3) {
cinfo->enable_1pass_quant = TRUE;
cinfo->enable_external_quant = FALSE;
cinfo->enable_2pass_quant = FALSE;
cinfo->colormap = NULL;
} else if (cinfo->colormap != NULL) {
cinfo->enable_external_quant = TRUE;
} else if (cinfo->two_pass_quantize) {
cinfo->enable_2pass_quant = TRUE;
} else {
cinfo->enable_1pass_quant = TRUE;
}
if (cinfo->enable_1pass_quant) {
#ifdef QUANT_1PASS_SUPPORTED
jinit_1pass_quantizer(cinfo);
master->quantizer_1pass = cinfo->cquantize;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
}
/* We use the 2-pass code to map to external colormaps. */
if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
#ifdef QUANT_2PASS_SUPPORTED
jinit_2pass_quantizer(cinfo);
master->quantizer_2pass = cinfo->cquantize;
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
}
/* If both quantizers are initialized, the 2-pass one is left active;
* this is necessary for starting with quantization to an external map.
*/
}
/* Post-processing: in particular, color conversion first */
@@ -480,164 +348,172 @@ master_selection (j_decompress_ptr cinfo)
jinit_color_deconverter(cinfo);
jinit_upsampler(cinfo);
}
jinit_d_post_controller(cinfo, master->need_post_pass);
jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
}
/* Inverse DCT */
jinit_inverse_dct(cinfo);
/* Entropy decoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
#ifdef D_ARITH_CODING_SUPPORTED
if (cinfo->arith_code)
jinit_arith_decoder(cinfo);
#else
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
#endif
} else
else {
jinit_huff_decoder(cinfo);
}
jinit_d_coef_controller(cinfo, (master->pass_type == preread_pass));
/* Initialize principal buffer controllers. */
use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
jinit_d_coef_controller(cinfo, use_c_buffer);
if (! cinfo->raw_data_out)
jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
/* Note that main controller is initialized even in raw-data mode. */
/* We can now tell the memory manager to allocate virtual arrays. */
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
/* Initialize input side of decompressor to consume first scan. */
(*cinfo->inputctl->start_input_pass) (cinfo);
#ifdef D_MULTISCAN_FILES_SUPPORTED
/* If jpeg_start_decompress will read the whole file, initialize
* progress monitoring appropriately. The input step is counted
* as one pass.
*/
if (cinfo->progress != NULL && ! cinfo->buffered_image &&
cinfo->inputctl->has_multiple_scans) {
int nscans;
/* Estimate number of scans to set pass_limit. */
if (cinfo->progressive_mode) {
/* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
nscans = 2 + 3 * cinfo->num_components;
} else {
/* For a nonprogressive multiscan file, estimate 1 scan per component. */
nscans = cinfo->num_components;
}
cinfo->progress->pass_counter = 0L;
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
cinfo->progress->completed_passes = 0;
cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
/* Count the input pass as done */
master->pass_number++;
}
#endif /* D_MULTISCAN_FILES_SUPPORTED */
}
/*
* Per-pass setup.
* This is called at the beginning of each pass. We determine which modules
* will be active during this pass and give them appropriate start_pass calls.
* We also set is_last_pass to indicate whether any more passes will be
* required.
* This is called at the beginning of each output pass. We determine which
* modules will be active during this pass and give them appropriate
* start_pass calls. We also set is_dummy_pass to indicate whether this
* is a "real" output pass or a dummy pass for color quantization.
* (In the latter case, jdapistd.c will crank the pass to completion.)
*/
METHODDEF void
prepare_for_pass (j_decompress_ptr cinfo)
METHODDEF(void)
prepare_for_output_pass (j_decompress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
switch (master->pass_type) {
case main_pass:
/* Set up to read and decompress single-scan file in one pass */
per_scan_setup(cinfo);
master->pub.is_last_pass = ! master->need_post_pass;
if (! cinfo->raw_data_out) {
if (! master->using_merged_upsample)
(*cinfo->cconvert->start_pass) (cinfo);
(*cinfo->upsample->start_pass) (cinfo);
if (cinfo->quantize_colors)
(*cinfo->cquantize->start_pass) (cinfo, master->need_post_pass);
(*cinfo->post->start_pass) (cinfo,
(master->need_post_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
}
(*cinfo->idct->start_input_pass) (cinfo);
(*cinfo->idct->start_output_pass) (cinfo);
(*cinfo->entropy->start_pass) (cinfo);
(*cinfo->coef->start_pass) (cinfo, JBUF_PASS_THRU);
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
break;
#ifdef D_MULTISCAN_FILES_SUPPORTED
case preread_pass:
/* Read (another) scan of a multi-scan file */
per_scan_setup(cinfo);
master->pub.is_last_pass = FALSE;
(*cinfo->idct->start_input_pass) (cinfo);
(*cinfo->entropy->start_pass) (cinfo);
(*cinfo->coef->start_pass) (cinfo, JBUF_SAVE_SOURCE);
(*cinfo->main->start_pass) (cinfo, JBUF_CRANK_SOURCE);
break;
case output_pass:
/* All scans read, now do the IDCT and subsequent processing */
master->pub.is_last_pass = ! master->need_post_pass;
if (! cinfo->raw_data_out) {
if (! master->using_merged_upsample)
(*cinfo->cconvert->start_pass) (cinfo);
(*cinfo->upsample->start_pass) (cinfo);
if (cinfo->quantize_colors)
(*cinfo->cquantize->start_pass) (cinfo, master->need_post_pass);
(*cinfo->post->start_pass) (cinfo,
(master->need_post_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
}
(*cinfo->idct->start_output_pass) (cinfo);
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
break;
#endif /* D_MULTISCAN_FILES_SUPPORTED */
if (master->pub.is_dummy_pass) {
#ifdef QUANT_2PASS_SUPPORTED
case post_pass:
/* Final pass of 2-pass quantization */
master->pub.is_last_pass = TRUE;
master->pub.is_dummy_pass = FALSE;
(*cinfo->cquantize->start_pass) (cinfo, FALSE);
(*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
(*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
break;
#endif /* QUANT_2PASS_SUPPORTED */
default:
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif /* QUANT_2PASS_SUPPORTED */
} else {
if (cinfo->quantize_colors && cinfo->colormap == NULL) {
/* Select new quantization method */
if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
cinfo->cquantize = master->quantizer_2pass;
master->pub.is_dummy_pass = TRUE;
} else if (cinfo->enable_1pass_quant) {
cinfo->cquantize = master->quantizer_1pass;
} else {
ERREXIT(cinfo, JERR_MODE_CHANGE);
}
}
(*cinfo->idct->start_pass) (cinfo);
(*cinfo->coef->start_output_pass) (cinfo);
if (! cinfo->raw_data_out) {
if (! master->using_merged_upsample)
(*cinfo->cconvert->start_pass) (cinfo);
(*cinfo->upsample->start_pass) (cinfo);
if (cinfo->quantize_colors)
(*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
(*cinfo->post->start_pass) (cinfo,
(master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
}
}
/* Set up progress monitor's pass info if present */
if (cinfo->progress != NULL) {
cinfo->progress->completed_passes = master->pass_number;
cinfo->progress->total_passes = master->total_passes;
cinfo->progress->total_passes = master->pass_number +
(master->pub.is_dummy_pass ? 2 : 1);
/* In buffered-image mode, we assume one more output pass if EOI not
* yet reached, but no more passes if EOI has been reached.
*/
if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
}
}
}
/*
* Finish up at end of pass.
* In multi-scan mode, we must read next scan header and set the next
* pass_type correctly for prepare_for_pass.
* Finish up at end of an output pass.
*/
METHODDEF void
finish_pass_master (j_decompress_ptr cinfo)
METHODDEF(void)
finish_output_pass (j_decompress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
switch (master->pass_type) {
case main_pass:
case output_pass:
if (cinfo->quantize_colors)
(*cinfo->cquantize->finish_pass) (cinfo);
master->pass_number++;
master->pass_type = post_pass; /* in case need_post_pass is true */
break;
}
#ifdef D_MULTISCAN_FILES_SUPPORTED
case preread_pass:
/* Count one pass done for each component in this scan */
master->pass_number += cinfo->comps_in_scan;
switch ((*cinfo->marker->read_markers) (cinfo)) {
case JPEG_HEADER_OK: /* Found SOS, do another preread pass */
break;
case JPEG_HEADER_TABLES_ONLY: /* Found EOI, no more preread passes */
master->pub.eoi_processed = TRUE;
master->pass_type = output_pass;
break;
case JPEG_SUSPENDED:
ERREXIT(cinfo, JERR_CANT_SUSPEND);
/*
* Switch to a new external colormap between output passes.
*/
GLOBAL(void)
jpeg_new_colormap (j_decompress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
/* Prevent application from calling me at wrong times */
if (cinfo->global_state != DSTATE_BUFIMAGE)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
if (cinfo->quantize_colors && cinfo->enable_external_quant &&
cinfo->colormap != NULL) {
/* Select 2-pass quantizer for external colormap use */
cinfo->cquantize = master->quantizer_2pass;
/* Notify quantizer of colormap change */
(*cinfo->cquantize->new_color_map) (cinfo);
master->pub.is_dummy_pass = FALSE; /* just in case */
} else
ERREXIT(cinfo, JERR_MODE_CHANGE);
}
break;
#endif /* D_MULTISCAN_FILES_SUPPORTED */
#ifdef QUANT_2PASS_SUPPORTED
case post_pass:
(*cinfo->cquantize->finish_pass) (cinfo);
/* there will be no more passes, don't bother to change state */
break;
#endif /* QUANT_2PASS_SUPPORTED */
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
}
}
/*
* Initialize master decompression control.
* This creates my own subrecord and also performs the master selection phase,
* which causes other modules to create their subrecords.
* Initialize master decompression control and select active modules.
* This is performed at the start of jpeg_start_decompress.
*/
GLOBAL void
GLOBAL(void)
jinit_master_decompress (j_decompress_ptr cinfo)
{
my_master_ptr master;
@@ -646,8 +522,10 @@ jinit_master_decompress (j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_decomp_master));
cinfo->master = (struct jpeg_decomp_master *) master;
master->pub.prepare_for_pass = prepare_for_pass;
master->pub.finish_pass = finish_pass_master;
master->pub.prepare_for_output_pass = prepare_for_output_pass;
master->pub.finish_output_pass = finish_output_pass;
master->pub.is_dummy_pass = FALSE;
master_selection(cinfo);
}

View File

@@ -1,7 +1,7 @@
/*
* jdmerge.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-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.
*
@@ -75,24 +75,18 @@ typedef my_upsampler * my_upsample_ptr;
/*
* Initialize for an upsampling pass.
*/
METHODDEF void
start_pass_merged_upsample (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
INT32 i, x;
SHIFT_TEMPS
/* Mark the spare buffer empty */
upsample->spare_full = FALSE;
/* Initialize total-height counter for detecting bottom of image */
upsample->rows_to_go = cinfo->output_height;
/* Initialize the YCC=>RGB conversion tables.
* Initialize tables for YCC->RGB colorspace conversion.
* This is taken directly from jdcolor.c; see that file for more info.
*/
LOCAL(void)
build_ycc_rgb_table (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
int i;
INT32 x;
SHIFT_TEMPS
upsample->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
@@ -124,13 +118,29 @@ start_pass_merged_upsample (j_decompress_ptr cinfo)
}
/*
* Initialize for an upsampling pass.
*/
METHODDEF(void)
start_pass_merged_upsample (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
/* Mark the spare buffer empty */
upsample->spare_full = FALSE;
/* Initialize total-height counter for detecting bottom of image */
upsample->rows_to_go = cinfo->output_height;
}
/*
* Control routine to do upsampling (and color conversion).
*
* The control routine just handles the row buffering considerations.
*/
METHODDEF void
METHODDEF(void)
merged_2v_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
@@ -179,7 +189,7 @@ merged_2v_upsample (j_decompress_ptr cinfo,
}
METHODDEF void
METHODDEF(void)
merged_1v_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
@@ -212,7 +222,7 @@ merged_1v_upsample (j_decompress_ptr cinfo,
* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
*/
METHODDEF void
METHODDEF(void)
h2v1_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
@@ -274,7 +284,7 @@ h2v1_merged_upsample (j_decompress_ptr cinfo,
* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
*/
METHODDEF void
METHODDEF(void)
h2v2_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
@@ -356,7 +366,7 @@ h2v2_merged_upsample (j_decompress_ptr cinfo,
* of this module; no safety checks are made here.
*/
GLOBAL void
GLOBAL(void)
jinit_merged_upsampler (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample;
@@ -383,6 +393,8 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
/* No spare row needed */
upsample->spare_row = NULL;
}
build_ycc_rgb_table(cinfo);
}
#endif /* UPSAMPLE_MERGING_SUPPORTED */

View File

@@ -1,7 +1,7 @@
/*
* jdpostct.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-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.
*
@@ -43,20 +43,20 @@ typedef my_post_controller * my_post_ptr;
/* Forward declarations */
METHODDEF void post_process_1pass
METHODDEF(void) post_process_1pass
JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail));
#ifdef QUANT_2PASS_SUPPORTED
METHODDEF void post_process_prepass
METHODDEF(void) post_process_prepass
JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail));
METHODDEF void post_process_2pass
METHODDEF(void) post_process_2pass
JPP((j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
@@ -69,7 +69,7 @@ METHODDEF void post_process_2pass
* Initialize for a processing pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_post_ptr post = (my_post_ptr) cinfo->post;
@@ -79,6 +79,15 @@ start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
if (cinfo->quantize_colors) {
/* Single-pass processing with color quantization. */
post->pub.post_process_data = post_process_1pass;
/* We could be doing buffered-image output before starting a 2-pass
* color quantization; in that case, jinit_d_post_controller did not
* allocate a strip buffer. Use the virtual-array buffer as workspace.
*/
if (post->buffer == NULL) {
post->buffer = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, post->whole_image,
(JDIMENSION) 0, post->strip_height, TRUE);
}
} else {
/* For single-pass processing without color quantization,
* I have no work to do; just call the upsampler directly.
@@ -113,7 +122,7 @@ start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
* This is used for color precision reduction as well as one-pass quantization.
*/
METHODDEF void
METHODDEF(void)
post_process_1pass (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
@@ -145,7 +154,7 @@ post_process_1pass (j_decompress_ptr cinfo,
* Process some data in the first pass of 2-pass quantization.
*/
METHODDEF void
METHODDEF(void)
post_process_prepass (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
@@ -158,7 +167,8 @@ post_process_prepass (j_decompress_ptr cinfo,
/* Reposition virtual buffer if at start of strip. */
if (post->next_row == 0) {
post->buffer = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, post->whole_image, post->starting_row, TRUE);
((j_common_ptr) cinfo, post->whole_image,
post->starting_row, post->strip_height, TRUE);
}
/* Upsample some data (up to a strip height's worth). */
@@ -188,7 +198,7 @@ post_process_prepass (j_decompress_ptr cinfo,
* Process some data in the second pass of 2-pass quantization.
*/
METHODDEF void
METHODDEF(void)
post_process_2pass (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
@@ -201,7 +211,8 @@ post_process_2pass (j_decompress_ptr cinfo,
/* Reposition virtual buffer if at start of strip. */
if (post->next_row == 0) {
post->buffer = (*cinfo->mem->access_virt_sarray)
((j_common_ptr) cinfo, post->whole_image, post->starting_row, FALSE);
((j_common_ptr) cinfo, post->whole_image,
post->starting_row, post->strip_height, FALSE);
}
/* Determine number of rows to emit. */
@@ -235,7 +246,7 @@ post_process_2pass (j_decompress_ptr cinfo,
* Initialize postprocessing controller.
*/
GLOBAL void
GLOBAL(void)
jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
my_post_ptr post;
@@ -246,6 +257,7 @@ jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
cinfo->post = (struct jpeg_d_post_controller *) post;
post->pub.start_pass = start_pass_dpost;
post->whole_image = NULL; /* flag for no virtual arrays */
post->buffer = NULL; /* flag for no strip buffer */
/* Create the quantization buffer, if needed */
if (cinfo->quantize_colors) {
@@ -256,11 +268,14 @@ jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
if (need_full_buffer) {
/* Two-pass color quantization: need full-image storage. */
/* We round up the number of rows to a multiple of the strip height. */
#ifdef QUANT_2PASS_SUPPORTED
post->whole_image = (*cinfo->mem->request_virt_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
cinfo->output_width * cinfo->out_color_components,
cinfo->output_height, post->strip_height);
(JDIMENSION) jround_up((long) cinfo->output_height,
(long) post->strip_height),
post->strip_height);
#else
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
#endif /* QUANT_2PASS_SUPPORTED */

View File

@@ -1,14 +1,15 @@
/*
* jdsample.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2002-2008 by Guido Vollbeding.
* 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 upsampling routines.
*
* Upsampling input data is counted in "row groups". A row group
* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
* is defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size)
* sample rows of each component. Upsampling will normally produce
* max_v_samp_factor pixel rows from each row group (but this could vary
* if the upsampler is applying a scale factor of its own).
@@ -65,7 +66,7 @@ typedef my_upsampler * my_upsample_ptr;
* Initialize for an upsampling pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_upsample (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
@@ -85,7 +86,7 @@ start_pass_upsample (j_decompress_ptr cinfo)
* color conversion a row at a time.
*/
METHODDEF void
METHODDEF(void)
sep_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
@@ -153,7 +154,7 @@ sep_upsample (j_decompress_ptr cinfo,
* "consumed" until we are done color converting and emitting it.
*/
METHODDEF void
METHODDEF(void)
fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
@@ -166,7 +167,7 @@ fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* These components will not be referenced by color conversion.
*/
METHODDEF void
METHODDEF(void)
noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
@@ -185,7 +186,7 @@ noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* you would be well advised to improve this code.
*/
METHODDEF void
METHODDEF(void)
int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
@@ -229,7 +230,7 @@ int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* It's still a box filter.
*/
METHODDEF void
METHODDEF(void)
h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
@@ -237,11 +238,11 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
register JSAMPROW inptr, outptr;
register JSAMPLE invalue;
JSAMPROW outend;
int inrow;
int outrow;
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
inptr = input_data[inrow];
outptr = output_data[inrow];
for (outrow = 0; outrow < cinfo->max_v_samp_factor; outrow++) {
inptr = input_data[outrow];
outptr = output_data[outrow];
outend = outptr + cinfo->output_width;
while (outptr < outend) {
invalue = *inptr++; /* don't need GETJSAMPLE() here */
@@ -257,7 +258,7 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* It's still a box filter.
*/
METHODDEF void
METHODDEF(void)
h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
@@ -285,123 +286,17 @@ h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
}
/*
* Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
*
* The upsampling algorithm is linear interpolation between pixel centers,
* also known as a "triangle filter". This is a good compromise between
* speed and visual quality. The centers of the output pixels are 1/4 and 3/4
* of the way between input pixel centers.
*
* A note about the "bias" calculations: when rounding fractional values to
* integer, we do not want to always round 0.5 up to the next integer.
* If we did that, we'd introduce a noticeable bias towards larger values.
* Instead, this code is arranged so that 0.5 will be rounded up or down at
* alternate pixel locations (a simple ordered dither pattern).
*/
METHODDEF void
h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
JSAMPARRAY output_data = *output_data_ptr;
register JSAMPROW inptr, outptr;
register int invalue;
register JDIMENSION colctr;
int inrow;
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
inptr = input_data[inrow];
outptr = output_data[inrow];
/* Special case for first column */
invalue = GETJSAMPLE(*inptr++);
*outptr++ = (JSAMPLE) invalue;
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
/* General case: 3/4 * nearer pixel + 1/4 * further pixel */
invalue = GETJSAMPLE(*inptr++) * 3;
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
}
/* Special case for last column */
invalue = GETJSAMPLE(*inptr);
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
*outptr++ = (JSAMPLE) invalue;
}
}
/*
* Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
* Again a triangle filter; see comments for h2v1 case, above.
*
* It is OK for us to reference the adjacent input rows because we demanded
* context from the main buffer controller (see initialization code).
*/
METHODDEF void
h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
JSAMPARRAY output_data = *output_data_ptr;
register JSAMPROW inptr0, inptr1, outptr;
#if BITS_IN_JSAMPLE == 8
register int thiscolsum, lastcolsum, nextcolsum;
#else
register INT32 thiscolsum, lastcolsum, nextcolsum;
#endif
register JDIMENSION colctr;
int inrow, outrow, v;
inrow = outrow = 0;
while (outrow < cinfo->max_v_samp_factor) {
for (v = 0; v < 2; v++) {
/* inptr0 points to nearest input row, inptr1 points to next nearest */
inptr0 = input_data[inrow];
if (v == 0) /* next nearest is row above */
inptr1 = input_data[inrow-1];
else /* next nearest is row below */
inptr1 = input_data[inrow+1];
outptr = output_data[outrow++];
/* Special case for first column */
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
}
/* Special case for last column */
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
}
inrow++;
}
}
/*
* Module initialization routine for upsampling.
*/
GLOBAL void
GLOBAL(void)
jinit_upsampler (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample;
int ci;
jpeg_component_info * compptr;
boolean need_buffer, do_fancy;
boolean need_buffer;
int h_in_group, v_in_group, h_out_group, v_out_group;
upsample = (my_upsample_ptr)
@@ -415,11 +310,6 @@ jinit_upsampler (j_decompress_ptr cinfo)
if (cinfo->CCIR601_sampling) /* this isn't supported */
ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
/* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
* so don't ask for it.
*/
do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
/* Verify we can handle the sampling factors, select per-component methods,
* and create storage as needed.
*/
@@ -428,10 +318,10 @@ jinit_upsampler (j_decompress_ptr cinfo)
/* Compute size of an "input group" after IDCT scaling. This many samples
* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
*/
h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size;
v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
cinfo->min_DCT_scaled_size;
h_in_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
cinfo->min_DCT_h_scaled_size;
v_in_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
cinfo->min_DCT_v_scaled_size;
h_out_group = cinfo->max_h_samp_factor;
v_out_group = cinfo->max_v_samp_factor;
upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
@@ -446,18 +336,11 @@ jinit_upsampler (j_decompress_ptr cinfo)
need_buffer = FALSE;
} else if (h_in_group * 2 == h_out_group &&
v_in_group == v_out_group) {
/* Special cases for 2h1v upsampling */
if (do_fancy && compptr->downsampled_width > 2)
upsample->methods[ci] = h2v1_fancy_upsample;
else
/* Special case for 2h1v upsampling */
upsample->methods[ci] = h2v1_upsample;
} else if (h_in_group * 2 == h_out_group &&
v_in_group * 2 == v_out_group) {
/* Special cases for 2h2v upsampling */
if (do_fancy && compptr->downsampled_width > 2) {
upsample->methods[ci] = h2v2_fancy_upsample;
upsample->pub.need_context_rows = TRUE;
} else
/* Special case for 2h2v upsampling */
upsample->methods[ci] = h2v2_upsample;
} else if ((h_out_group % h_in_group) == 0 &&
(v_out_group % v_in_group) == 0) {

140
jdtrans.c Normal file
View File

@@ -0,0 +1,140 @@
/*
* jdtrans.c
*
* Copyright (C) 1995-1997, Thomas G. Lane.
* Modified 2000-2009 by Guido Vollbeding.
* 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 library routines for transcoding decompression,
* that is, reading raw DCT coefficient arrays from an input JPEG file.
* The routines in jdapimin.c will also be needed by a transcoder.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Forward declarations */
LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
/*
* Read the coefficient arrays from a JPEG file.
* jpeg_read_header must be completed before calling this.
*
* The entire image is read into a set of virtual coefficient-block arrays,
* one per component. The return value is a pointer to the array of
* virtual-array descriptors. These can be manipulated directly via the
* JPEG memory manager, or handed off to jpeg_write_coefficients().
* To release the memory occupied by the virtual arrays, call
* jpeg_finish_decompress() when done with the data.
*
* An alternative usage is to simply obtain access to the coefficient arrays
* during a buffered-image-mode decompression operation. This is allowed
* after any jpeg_finish_output() call. The arrays can be accessed until
* jpeg_finish_decompress() is called. (Note that any call to the library
* may reposition the arrays, so don't rely on access_virt_barray() results
* to stay valid across library calls.)
*
* Returns NULL if suspended. This case need be checked only if
* a suspending data source is used.
*/
GLOBAL(jvirt_barray_ptr *)
jpeg_read_coefficients (j_decompress_ptr cinfo)
{
if (cinfo->global_state == DSTATE_READY) {
/* First call: initialize active modules */
transdecode_master_selection(cinfo);
cinfo->global_state = DSTATE_RDCOEFS;
}
if (cinfo->global_state == DSTATE_RDCOEFS) {
/* Absorb whole file into the coef buffer */
for (;;) {
int retcode;
/* Call progress monitor hook if present */
if (cinfo->progress != NULL)
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
/* Absorb some more input */
retcode = (*cinfo->inputctl->consume_input) (cinfo);
if (retcode == JPEG_SUSPENDED)
return NULL;
if (retcode == JPEG_REACHED_EOI)
break;
/* Advance progress counter if appropriate */
if (cinfo->progress != NULL &&
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
/* startup underestimated number of scans; ratchet up one scan */
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
}
}
}
/* Set state so that jpeg_finish_decompress does the right thing */
cinfo->global_state = DSTATE_STOPPING;
}
/* At this point we should be in state DSTATE_STOPPING if being used
* standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
* to the coefficients during a full buffered-image-mode decompression.
*/
if ((cinfo->global_state == DSTATE_STOPPING ||
cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
return cinfo->coef->coef_arrays;
}
/* Oops, improper usage */
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
return NULL; /* keep compiler happy */
}
/*
* Master selection of decompression modules for transcoding.
* This substitutes for jdmaster.c's initialization of the full decompressor.
*/
LOCAL(void)
transdecode_master_selection (j_decompress_ptr cinfo)
{
/* This is effectively a buffered-image operation. */
cinfo->buffered_image = TRUE;
/* Compute output image dimensions and related values. */
jpeg_core_output_dimensions(cinfo);
/* Entropy decoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code)
jinit_arith_decoder(cinfo);
else {
jinit_huff_decoder(cinfo);
}
/* Always get a full-image coefficient buffer. */
jinit_d_coef_controller(cinfo, TRUE);
/* We can now tell the memory manager to allocate virtual arrays. */
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
/* Initialize input side of decompressor to consume first scan. */
(*cinfo->inputctl->start_input_pass) (cinfo);
/* Initialize progress monitoring. */
if (cinfo->progress != NULL) {
int nscans;
/* Estimate number of scans to set pass_limit. */
if (cinfo->progressive_mode) {
/* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
nscans = 2 + 3 * cinfo->num_components;
} else if (cinfo->inputctl->has_multiple_scans) {
/* For a nonprogressive multiscan file, estimate 1 scan per component. */
nscans = cinfo->num_components;
} else {
nscans = 1;
}
cinfo->progress->pass_counter = 0L;
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
cinfo->progress->completed_passes = 0;
cinfo->progress->total_passes = 1;
}
}

View File

@@ -1,7 +1,7 @@
/*
* jerror.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -10,6 +10,11 @@
* stderr is the right thing to do. Many applications will want to replace
* some or all of these routines.
*
* If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
* you get a Windows-specific hack to display error messages in a dialog box.
* It ain't much, but it beats dropping error messages into the bit bucket,
* which is what happens to output to stderr under most Windows C compilers.
*
* These routines are used by both the compression and decompression code.
*/
@@ -19,6 +24,10 @@
#include "jversion.h"
#include "jerror.h"
#ifdef USE_WINDOWS_MESSAGEBOX
#include <windows.h>
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
@@ -57,7 +66,7 @@ const char * const jpeg_std_message_table[] = {
* or jpeg_destroy) at some point.
*/
METHODDEF void
METHODDEF(void)
error_exit (j_common_ptr cinfo)
{
/* Always display the message */
@@ -74,9 +83,18 @@ error_exit (j_common_ptr cinfo)
* Actual output of an error or trace message.
* Applications may override this method to send JPEG messages somewhere
* other than stderr.
*
* On Windows, printing to stderr is generally completely useless,
* so we provide optional code to produce an error-dialog popup.
* Most Windows applications will still prefer to override this routine,
* but if they don't, it'll do something at least marginally useful.
*
* NOTE: to use the library in an environment that doesn't support the
* C stdio library, you may have to delete the call to fprintf() entirely,
* not just not use this routine.
*/
METHODDEF void
METHODDEF(void)
output_message (j_common_ptr cinfo)
{
char buffer[JMSG_LENGTH_MAX];
@@ -84,8 +102,14 @@ output_message (j_common_ptr cinfo)
/* Create the message */
(*cinfo->err->format_message) (cinfo, buffer);
#ifdef USE_WINDOWS_MESSAGEBOX
/* Display it in a message dialog box */
MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
MB_OK | MB_ICONERROR);
#else
/* Send it to stderr, adding a newline */
fprintf(stderr, "%s\n", buffer);
#endif
}
@@ -100,7 +124,7 @@ output_message (j_common_ptr cinfo)
* or change the policy about which messages to display.
*/
METHODDEF void
METHODDEF(void)
emit_message (j_common_ptr cinfo, int msg_level)
{
struct jpeg_error_mgr * err = cinfo->err;
@@ -129,7 +153,7 @@ emit_message (j_common_ptr cinfo, int msg_level)
* Few applications should need to override this method.
*/
METHODDEF void
METHODDEF(void)
format_message (j_common_ptr cinfo, char * buffer)
{
struct jpeg_error_mgr * err = cinfo->err;
@@ -184,7 +208,7 @@ format_message (j_common_ptr cinfo, char * buffer)
* this method if it has additional error processing state.
*/
METHODDEF void
METHODDEF(void)
reset_error_mgr (j_common_ptr cinfo)
{
cinfo->err->num_warnings = 0;
@@ -203,7 +227,7 @@ reset_error_mgr (j_common_ptr cinfo)
* after which the application may override some of the methods.
*/
GLOBAL struct jpeg_error_mgr *
GLOBAL(struct jpeg_error_mgr *)
jpeg_std_error (struct jpeg_error_mgr * err)
{
err->error_exit = error_exit;

View File

@@ -1,7 +1,8 @@
/*
* jerror.h
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -39,21 +40,33 @@ typedef enum {
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
/* For maintenance convenience, list is alphabetical by message code name */
JMESSAGE(JERR_ARITH_NOTIMPL,
"Sorry, there are legal restrictions on arithmetic coding")
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
JMESSAGE(JERR_BAD_DCTSIZE, "DCT scaled block size %dx%d not supported")
JMESSAGE(JERR_BAD_DROP_SAMPLING,
"Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
JMESSAGE(JERR_BAD_LIB_VERSION,
"Wrong JPEG library version: library is %d, caller expects %d")
JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
JMESSAGE(JERR_BAD_PROGRESSION,
"Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
JMESSAGE(JERR_BAD_PROG_SCRIPT,
"Invalid progressive parameters at scan script entry %d")
JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
JMESSAGE(JERR_BAD_STRUCT_SIZE,
"JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
@@ -62,7 +75,6 @@ JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
JMESSAGE(JERR_DHT_COUNTS, "Bogus DHT counts")
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
@@ -77,9 +89,13 @@ JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
JMESSAGE(JERR_JFIF_MAJOR, "Unsupported JFIF revision number %d.%02d")
JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
"Cannot transcode due to multiple use of quantization table %d")
JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
@@ -122,12 +138,13 @@ JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
JMESSAGE(JTRC_EOI, "End Of Image")
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker, density %dx%d %d")
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
"Warning: thumbnail image size does not match data length %u")
JMESSAGE(JTRC_JFIF_MINOR, "Warning: unknown JFIF revision number %d.%02d")
JMESSAGE(JTRC_JFIF_EXTENSION,
"JFIF extension marker: type 0x%02x, length %u")
JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
JMESSAGE(JTRC_MISC_MARKER, "Skipping marker 0x%02x, length %u")
JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
@@ -142,17 +159,28 @@ JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
JMESSAGE(JTRC_SOI, "Start of Image")
JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
JMESSAGE(JTRC_THUMB_JPEG,
"JFIF extension marker: JPEG-compressed thumbnail image, length %u")
JMESSAGE(JTRC_THUMB_PALETTE,
"JFIF extension marker: palette thumbnail image, length %u")
JMESSAGE(JTRC_THUMB_RGB,
"JFIF extension marker: RGB thumbnail image, length %u")
JMESSAGE(JTRC_UNKNOWN_IDS,
"Unrecognized component IDs %d %d %d, assuming YCbCr")
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
JMESSAGE(JWRN_BOGUS_PROGRESSION,
"Inconsistent progression sequence for component %d coefficient %d")
JMESSAGE(JWRN_EXTRANEOUS_DATA,
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
JMESSAGE(JWRN_MUST_RESYNC,
"Corrupt JPEG data: found marker 0x%02x instead of RST%d")
@@ -203,6 +231,15 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
(cinfo)->err->msg_parm.i[2] = (p3), \
(cinfo)->err->msg_parm.i[3] = (p4), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT6(cinfo,code,p1,p2,p3,p4,p5,p6) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(cinfo)->err->msg_parm.i[2] = (p3), \
(cinfo)->err->msg_parm.i[3] = (p4), \
(cinfo)->err->msg_parm.i[4] = (p5), \
(cinfo)->err->msg_parm.i[5] = (p6), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXITS(cinfo,code,str) \
((cinfo)->err->msg_code = (code), \
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
@@ -247,6 +284,12 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
_mp[4] = (p5); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \

View File

@@ -1,7 +1,8 @@
/*
* jfdctflt.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2003-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -55,27 +56,31 @@
* Perform the forward DCT on one block of samples.
*/
GLOBAL void
jpeg_fdct_float (FAST_FLOAT * data)
GLOBAL(void)
jpeg_fdct_float (FAST_FLOAT * data, JSAMPARRAY sample_data, JDIMENSION start_col)
{
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
FAST_FLOAT *dataptr;
JSAMPROW elemptr;
int ctr;
/* Pass 1: process rows. */
dataptr = data;
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
tmp0 = dataptr[0] + dataptr[7];
tmp7 = dataptr[0] - dataptr[7];
tmp1 = dataptr[1] + dataptr[6];
tmp6 = dataptr[1] - dataptr[6];
tmp2 = dataptr[2] + dataptr[5];
tmp5 = dataptr[2] - dataptr[5];
tmp3 = dataptr[3] + dataptr[4];
tmp4 = dataptr[3] - dataptr[4];
for (ctr = 0; ctr < DCTSIZE; ctr++) {
elemptr = sample_data[ctr] + start_col;
/* Load data into workspace */
tmp0 = (FAST_FLOAT) (GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]));
tmp7 = (FAST_FLOAT) (GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[7]));
tmp1 = (FAST_FLOAT) (GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[6]));
tmp6 = (FAST_FLOAT) (GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[6]));
tmp2 = (FAST_FLOAT) (GETJSAMPLE(elemptr[2]) + GETJSAMPLE(elemptr[5]));
tmp5 = (FAST_FLOAT) (GETJSAMPLE(elemptr[2]) - GETJSAMPLE(elemptr[5]));
tmp3 = (FAST_FLOAT) (GETJSAMPLE(elemptr[3]) + GETJSAMPLE(elemptr[4]));
tmp4 = (FAST_FLOAT) (GETJSAMPLE(elemptr[3]) - GETJSAMPLE(elemptr[4]));
/* Even part */
@@ -84,7 +89,8 @@ jpeg_fdct_float (FAST_FLOAT * data)
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; /* phase 3 */
/* Apply unsigned->signed conversion */
dataptr[0] = tmp10 + tmp11 - 8 * CENTERJSAMPLE; /* phase 3 */
dataptr[4] = tmp10 - tmp11;
z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */

View File

@@ -1,7 +1,8 @@
/*
* jfdctfst.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1996, Thomas G. Lane.
* Modified 2003-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -110,28 +111,32 @@
* Perform the forward DCT on one block of samples.
*/
GLOBAL void
jpeg_fdct_ifast (DCTELEM * data)
GLOBAL(void)
jpeg_fdct_ifast (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
{
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
DCTELEM tmp10, tmp11, tmp12, tmp13;
DCTELEM z1, z2, z3, z4, z5, z11, z13;
DCTELEM *dataptr;
JSAMPROW elemptr;
int ctr;
SHIFT_TEMPS
/* Pass 1: process rows. */
dataptr = data;
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
tmp0 = dataptr[0] + dataptr[7];
tmp7 = dataptr[0] - dataptr[7];
tmp1 = dataptr[1] + dataptr[6];
tmp6 = dataptr[1] - dataptr[6];
tmp2 = dataptr[2] + dataptr[5];
tmp5 = dataptr[2] - dataptr[5];
tmp3 = dataptr[3] + dataptr[4];
tmp4 = dataptr[3] - dataptr[4];
for (ctr = 0; ctr < DCTSIZE; ctr++) {
elemptr = sample_data[ctr] + start_col;
/* Load data into workspace */
tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]);
tmp7 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[7]);
tmp1 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[6]);
tmp6 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[6]);
tmp2 = GETJSAMPLE(elemptr[2]) + GETJSAMPLE(elemptr[5]);
tmp5 = GETJSAMPLE(elemptr[2]) - GETJSAMPLE(elemptr[5]);
tmp3 = GETJSAMPLE(elemptr[3]) + GETJSAMPLE(elemptr[4]);
tmp4 = GETJSAMPLE(elemptr[3]) - GETJSAMPLE(elemptr[4]);
/* Even part */
@@ -140,7 +145,8 @@ jpeg_fdct_ifast (DCTELEM * data)
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
dataptr[0] = tmp10 + tmp11; /* phase 3 */
/* Apply unsigned->signed conversion */
dataptr[0] = tmp10 + tmp11 - 8 * CENTERJSAMPLE; /* phase 3 */
dataptr[4] = tmp10 - tmp11;
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */

4231
jfdctint.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
/*
* jidctflt.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -64,7 +65,7 @@
* Perform dequantization and inverse DCT on one block of coefficients.
*/
GLOBAL void
GLOBAL(void)
jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col)
@@ -76,10 +77,9 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
FLOAT_MULT_TYPE * quantptr;
FAST_FLOAT * wsptr;
JSAMPROW outptr;
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
JSAMPLE *range_limit = cinfo->sample_range_limit;
int ctr;
FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
SHIFT_TEMPS
/* Pass 1: process columns from input, store into work array. */
@@ -96,9 +96,10 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* column DCT calculations can be simplified this way.
*/
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
inptr[DCTSIZE*7]) == 0) {
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */
FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
@@ -151,12 +152,12 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
tmp6 = tmp12 - tmp7; /* phase 2 */
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
tmp4 = tmp10 - tmp5;
wsptr[DCTSIZE*0] = tmp0 + tmp7;
wsptr[DCTSIZE*7] = tmp0 - tmp7;
@@ -164,8 +165,8 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
wsptr[DCTSIZE*6] = tmp1 - tmp6;
wsptr[DCTSIZE*2] = tmp2 + tmp5;
wsptr[DCTSIZE*5] = tmp2 - tmp5;
wsptr[DCTSIZE*4] = tmp3 + tmp4;
wsptr[DCTSIZE*3] = tmp3 - tmp4;
wsptr[DCTSIZE*3] = tmp3 + tmp4;
wsptr[DCTSIZE*4] = tmp3 - tmp4;
inptr++; /* advance pointers to next column */
quantptr++;
@@ -173,7 +174,6 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
}
/* Pass 2: process rows from work array, store into output array. */
/* Note that we must descale the results by a factor of 8 == 2**3. */
wsptr = workspace;
for (ctr = 0; ctr < DCTSIZE; ctr++) {
@@ -186,8 +186,10 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
/* Even part */
tmp10 = wsptr[0] + wsptr[4];
tmp11 = wsptr[0] - wsptr[4];
/* Apply signed->unsigned and prepare float->int conversion */
z5 = wsptr[0] + ((FAST_FLOAT) CENTERJSAMPLE + (FAST_FLOAT) 0.5);
tmp10 = z5 + wsptr[4];
tmp11 = z5 - wsptr[4];
tmp13 = wsptr[2] + wsptr[6];
tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
@@ -208,31 +210,23 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
tmp6 = tmp12 - tmp7;
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
tmp4 = tmp10 - tmp5;
/* Final output stage: scale down by a factor of 8 and range-limit */
/* Final output stage: float->int conversion and range-limit */
outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
& RANGE_MASK];
outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
& RANGE_MASK];
outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
& RANGE_MASK];
outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
& RANGE_MASK];
outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
& RANGE_MASK];
outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
& RANGE_MASK];
outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
& RANGE_MASK];
outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
& RANGE_MASK];
outptr[0] = range_limit[((int) (tmp0 + tmp7)) & RANGE_MASK];
outptr[7] = range_limit[((int) (tmp0 - tmp7)) & RANGE_MASK];
outptr[1] = range_limit[((int) (tmp1 + tmp6)) & RANGE_MASK];
outptr[6] = range_limit[((int) (tmp1 - tmp6)) & RANGE_MASK];
outptr[2] = range_limit[((int) (tmp2 + tmp5)) & RANGE_MASK];
outptr[5] = range_limit[((int) (tmp2 - tmp5)) & RANGE_MASK];
outptr[3] = range_limit[((int) (tmp3 + tmp4)) & RANGE_MASK];
outptr[4] = range_limit[((int) (tmp3 - tmp4)) & RANGE_MASK];
wsptr += DCTSIZE; /* advance pointer to next row */
}

View File

@@ -1,7 +1,7 @@
/*
* jidctfst.c
*
* Copyright (C) 1994, Thomas G. Lane.
* Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -139,9 +139,14 @@
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define ISHIFT_TEMPS DCTELEM ishift_temp;
#if BITS_IN_JSAMPLE == 8
#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
#else
#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
#endif
#define IRIGHT_SHIFT(x,shft) \
((ishift_temp = (x)) < 0 ? \
(ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (32-(shft))) : \
(ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
(ishift_temp >> (shft)))
#else
#define ISHIFT_TEMPS
@@ -159,7 +164,7 @@
* Perform dequantization and inverse DCT on one block of coefficients.
*/
GLOBAL void
GLOBAL(void)
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col)
@@ -192,9 +197,10 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
* column DCT calculations can be simplified this way.
*/
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
inptr[DCTSIZE*7]) == 0) {
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */
int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
@@ -284,8 +290,8 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
*/
#ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
wsptr[7]) == 0) {
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
& RANGE_MASK];

4903
jidctint.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,397 +0,0 @@
/*
* jidctred.c
*
* Copyright (C) 1994, 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 inverse-DCT routines that produce reduced-size output:
* either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
*
* The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
* algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step
* with an 8-to-4 step that produces the four averages of two adjacent outputs
* (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
* These steps were derived by computing the corresponding values at the end
* of the normal LL&M code, then simplifying as much as possible.
*
* 1x1 is trivial: just take the DC coefficient divided by 8.
*
* See jidctint.c for additional comments.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */
#ifdef IDCT_SCALING_SUPPORTED
/*
* This module is specialized to the case DCTSIZE = 8.
*/
#if DCTSIZE != 8
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
#endif
/* Scaling is the same as in jidctint.c. */
#if BITS_IN_JSAMPLE == 8
#define CONST_BITS 13
#define PASS1_BITS 2
#else
#define CONST_BITS 13
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
#endif
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
* causing a lot of useless floating-point operations at run time.
* To get around this we use the following pre-calculated constants.
* If you change CONST_BITS you may want to add appropriate values.
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
*/
#if CONST_BITS == 13
#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */
#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */
#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */
#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */
#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */
#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */
#else
#define FIX_0_211164243 FIX(0.211164243)
#define FIX_0_509795579 FIX(0.509795579)
#define FIX_0_601344887 FIX(0.601344887)
#define FIX_0_720959822 FIX(0.720959822)
#define FIX_0_765366865 FIX(0.765366865)
#define FIX_0_850430095 FIX(0.850430095)
#define FIX_0_899976223 FIX(0.899976223)
#define FIX_1_061594337 FIX(1.061594337)
#define FIX_1_272758580 FIX(1.272758580)
#define FIX_1_451774981 FIX(1.451774981)
#define FIX_1_847759065 FIX(1.847759065)
#define FIX_2_172734803 FIX(2.172734803)
#define FIX_2_562915447 FIX(2.562915447)
#define FIX_3_624509785 FIX(3.624509785)
#endif
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
* For 8-bit samples with the recommended scaling, all the variable
* and constant values involved are no more than 16 bits wide, so a
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
* For 12-bit samples, a full 32-bit multiplication will be needed.
*/
#if BITS_IN_JSAMPLE == 8
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
#else
#define MULTIPLY(var,const) ((var) * (const))
#endif
/* Dequantize a coefficient by multiplying it by the multiplier-table
* entry; produce an int result. In this module, both inputs and result
* are 16 bits or less, so either int or short multiply will work.
*/
#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a reduced-size 4x4 output block.
*/
GLOBAL void
jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col)
{
INT32 tmp0, tmp2, tmp10, tmp12;
INT32 z1, z2, z3, z4;
JCOEFPTR inptr;
ISLOW_MULT_TYPE * quantptr;
int * wsptr;
JSAMPROW outptr;
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
int ctr;
int workspace[DCTSIZE*4]; /* buffers data between passes */
SHIFT_TEMPS
/* Pass 1: process columns from input, store into work array. */
inptr = coef_block;
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
wsptr = workspace;
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
/* Don't bother to process column 4, because second pass won't use it */
if (ctr == DCTSIZE-4)
continue;
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*5] | inptr[DCTSIZE*6] | inptr[DCTSIZE*7]) == 0) {
/* AC terms all zero; we need not examine term 4 for 4x4 output */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
wsptr[DCTSIZE*0] = dcval;
wsptr[DCTSIZE*1] = dcval;
wsptr[DCTSIZE*2] = dcval;
wsptr[DCTSIZE*3] = dcval;
continue;
}
/* Even part */
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
tmp0 <<= (CONST_BITS+1);
z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
tmp10 = tmp0 + tmp2;
tmp12 = tmp0 - tmp2;
/* Odd part */
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
/* Final output stage */
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
}
/* Pass 2: process 4 rows from work array, store into output array. */
wsptr = workspace;
for (ctr = 0; ctr < 4; ctr++) {
outptr = output_buf[ctr] + output_col;
/* It's not clear whether a zero row test is worthwhile here ... */
#ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[5] | wsptr[6] |
wsptr[7]) == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK];
outptr[0] = dcval;
outptr[1] = dcval;
outptr[2] = dcval;
outptr[3] = dcval;
wsptr += DCTSIZE; /* advance pointer to next row */
continue;
}
#endif
/* Even part */
tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
+ MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
tmp10 = tmp0 + tmp2;
tmp12 = tmp0 - tmp2;
/* Odd part */
z1 = (INT32) wsptr[7];
z2 = (INT32) wsptr[5];
z3 = (INT32) wsptr[3];
z4 = (INT32) wsptr[1];
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
/* Final output stage */
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
CONST_BITS+PASS1_BITS+3+1)
& RANGE_MASK];
outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
CONST_BITS+PASS1_BITS+3+1)
& RANGE_MASK];
outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
CONST_BITS+PASS1_BITS+3+1)
& RANGE_MASK];
outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
CONST_BITS+PASS1_BITS+3+1)
& RANGE_MASK];
wsptr += DCTSIZE; /* advance pointer to next row */
}
}
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a reduced-size 2x2 output block.
*/
GLOBAL void
jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col)
{
INT32 tmp0, tmp10, z1;
JCOEFPTR inptr;
ISLOW_MULT_TYPE * quantptr;
int * wsptr;
JSAMPROW outptr;
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
int ctr;
int workspace[DCTSIZE*2]; /* buffers data between passes */
SHIFT_TEMPS
/* Pass 1: process columns from input, store into work array. */
inptr = coef_block;
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
wsptr = workspace;
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
/* Don't bother to process columns 2,4,6 */
if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
continue;
if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*3] |
inptr[DCTSIZE*5] | inptr[DCTSIZE*7]) == 0) {
/* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
wsptr[DCTSIZE*0] = dcval;
wsptr[DCTSIZE*1] = dcval;
continue;
}
/* Even part */
z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
tmp10 = z1 << (CONST_BITS+2);
/* Odd part */
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
/* Final output stage */
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
}
/* Pass 2: process 2 rows from work array, store into output array. */
wsptr = workspace;
for (ctr = 0; ctr < 2; ctr++) {
outptr = output_buf[ctr] + output_col;
/* It's not clear whether a zero row test is worthwhile here ... */
#ifndef NO_ZERO_ROW_TEST
if ((wsptr[1] | wsptr[3] | wsptr[5] | wsptr[7]) == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK];
outptr[0] = dcval;
outptr[1] = dcval;
wsptr += DCTSIZE; /* advance pointer to next row */
continue;
}
#endif
/* Even part */
tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
/* Odd part */
tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
+ MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
+ MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
+ MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
/* Final output stage */
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
CONST_BITS+PASS1_BITS+3+2)
& RANGE_MASK];
outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
CONST_BITS+PASS1_BITS+3+2)
& RANGE_MASK];
wsptr += DCTSIZE; /* advance pointer to next row */
}
}
/*
* Perform dequantization and inverse DCT on one block of coefficients,
* producing a reduced-size 1x1 output block.
*/
GLOBAL void
jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col)
{
int dcval;
ISLOW_MULT_TYPE * quantptr;
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
SHIFT_TEMPS
/* We hardly need an inverse DCT routine for this: just take the
* average pixel value, which is one-eighth of the DC coefficient.
*/
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
dcval = (int) DESCALE((INT32) dcval, 3);
output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
}
#endif /* IDCT_SCALING_SUPPORTED */

View File

@@ -1,7 +1,7 @@
/*
* jmemansi.c
*
* Copyright (C) 1992-1994, Thomas G. Lane.
* 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.
*
@@ -32,13 +32,13 @@ extern void free JPP((void *ptr));
* routines malloc() and free().
*/
GLOBAL void *
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
@@ -52,13 +52,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
* you probably won't be able to process useful-size images in only 64KB.
*/
GLOBAL void FAR *
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
free(object);
@@ -77,7 +77,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
#endif
GLOBAL long
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
@@ -93,7 +93,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
*/
METHODDEF void
METHODDEF(void)
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -106,7 +106,7 @@ read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -119,7 +119,7 @@ write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
{
fclose(info->temp_file);
@@ -137,7 +137,7 @@ close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
* indeed, we can't even find out the actual name of the temp file.
*/
GLOBAL void
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
@@ -154,13 +154,13 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
* cleanup required.
*/
GLOBAL long
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
}
GLOBAL void
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* no work */

View File

@@ -1,7 +1,7 @@
/*
* jmemdos.c
*
* Copyright (C) 1992-1994, Thomas G. Lane.
* Copyright (C) 1992-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -77,6 +77,10 @@ extern char * getenv JPP((const char * name));
#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
@@ -85,7 +89,7 @@ extern char * getenv JPP((const char * name));
/*
* Declarations for assembly-language support routines (see jmemdosa.asm).
*
* The functions are declared "far" as are all pointer arguments;
* 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.
*/
@@ -100,17 +104,17 @@ typedef struct { /* registers for calling EMS driver */
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,
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,
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 *));
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 *));
/*
@@ -120,7 +124,7 @@ EXTERN void far jems_calldriver JPP((EMScontext far *));
static int next_file_num; /* to distinguish among several temp files */
LOCAL void
LOCAL(void)
select_file_name (char * fname)
{
const char * env;
@@ -158,13 +162,13 @@ select_file_name (char * fname)
* routines malloc() and free().
*/
GLOBAL void *
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
@@ -175,13 +179,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
* "Large" objects are allocated in far memory, if possible
*/
GLOBAL void FAR *
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) far_malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
far_free(object);
@@ -200,7 +204,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */
#endif
GLOBAL long
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
@@ -235,7 +239,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
*/
METHODDEF void
METHODDEF(void)
read_file_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -251,7 +255,7 @@ read_file_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
write_file_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -267,7 +271,7 @@ write_file_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
close_file_store (j_common_ptr cinfo, backing_store_ptr info)
{
jdos_close(info->handle.file_handle); /* close the file */
@@ -280,7 +284,7 @@ close_file_store (j_common_ptr cinfo, backing_store_ptr info)
}
LOCAL boolean
LOCAL(boolean)
open_file_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
@@ -325,7 +329,7 @@ typedef struct { /* XMS move specification structure */
#define ODD(X) (((X) & 1L) != 0)
METHODDEF void
METHODDEF(void)
read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -358,7 +362,7 @@ read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -393,7 +397,7 @@ write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
{
XMScontext ctx;
@@ -406,7 +410,7 @@ close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
}
LOCAL boolean
LOCAL(boolean)
open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
@@ -483,7 +487,7 @@ typedef union { /* EMS move specification structure */
#define LOBYTE(W) ((W) & 0xFF)
METHODDEF void
METHODDEF(void)
read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -508,7 +512,7 @@ read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -533,7 +537,7 @@ write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
{
EMScontext ctx;
@@ -546,7 +550,7 @@ close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
}
LOCAL boolean
LOCAL(boolean)
open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
@@ -591,7 +595,7 @@ open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
* Initial opening of a backing-store object.
*/
GLOBAL void
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
@@ -615,14 +619,14 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
* cleanup required.
*/
GLOBAL long
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
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* Microsoft C, at least in v6.00A, will not successfully reclaim freed

289
jmemmac.c Normal file
View File

@@ -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 */
}

265
jmemmgr.c
View File

@@ -1,7 +1,8 @@
/*
* jmemmgr.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -151,10 +152,12 @@ struct jvirt_sarray_control {
JSAMPARRAY mem_buffer; /* => the in-memory buffer */
JDIMENSION rows_in_array; /* total virtual array height */
JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
JDIMENSION unitheight; /* # of rows accessed by access_virt_sarray */
JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */
JDIMENSION rows_in_mem; /* height of memory buffer */
JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
JDIMENSION cur_start_row; /* first logical row # in the buffer */
JDIMENSION first_undef_row; /* row # of first uninitialized row */
boolean pre_zero; /* pre-zero mode requested? */
boolean dirty; /* do current buffer contents need written? */
boolean b_s_open; /* is backing-store data valid? */
jvirt_sarray_ptr next; /* link to next virtual sarray control block */
@@ -165,10 +168,12 @@ struct jvirt_barray_control {
JBLOCKARRAY mem_buffer; /* => the in-memory buffer */
JDIMENSION rows_in_array; /* total virtual array height */
JDIMENSION blocksperrow; /* width of array (and of memory buffer) */
JDIMENSION unitheight; /* # of rows accessed by access_virt_barray */
JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */
JDIMENSION rows_in_mem; /* height of memory buffer */
JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
JDIMENSION cur_start_row; /* first logical row # in the buffer */
JDIMENSION first_undef_row; /* row # of first uninitialized row */
boolean pre_zero; /* pre-zero mode requested? */
boolean dirty; /* do current buffer contents need written? */
boolean b_s_open; /* is backing-store data valid? */
jvirt_barray_ptr next; /* link to next virtual barray control block */
@@ -178,7 +183,7 @@ struct jvirt_barray_control {
#ifdef MEM_STATS /* optional extra stuff for statistics */
LOCAL void
LOCAL(void)
print_mem_stats (j_common_ptr cinfo, int pool_id)
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
@@ -209,7 +214,7 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
#endif /* MEM_STATS */
LOCAL void
LOCAL(void)
out_of_memory (j_common_ptr cinfo, int which)
/* Report an out-of-memory error and stop execution */
/* If we compiled MEM_STATS support, report alloc requests before dying */
@@ -249,7 +254,7 @@ static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
METHODDEF void *
METHODDEF(void *)
alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
/* Allocate a "small" object */
{
@@ -334,7 +339,7 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
* deliberately bunch rows together to ensure a large request size.
*/
METHODDEF void FAR *
METHODDEF(void FAR *)
alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
/* Allocate a "large" object */
{
@@ -387,7 +392,7 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
* a virtual array.
*/
METHODDEF JSAMPARRAY
METHODDEF(JSAMPARRAY)
alloc_sarray (j_common_ptr cinfo, int pool_id,
JDIMENSION samplesperrow, JDIMENSION numrows)
/* Allocate a 2-D sample array */
@@ -435,7 +440,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
* This is essentially the same as the code for sample arrays, above.
*/
METHODDEF JBLOCKARRAY
METHODDEF(JBLOCKARRAY)
alloc_barray (j_common_ptr cinfo, int pool_id,
JDIMENSION blocksperrow, JDIMENSION numrows)
/* Allocate a 2-D coefficient-block array */
@@ -481,21 +486,17 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
/*
* About virtual array management:
*
* To allow machines with limited memory to handle large images, all
* processing in the JPEG system is done a few pixel or block rows at a time.
* The above "normal" array routines are only used to allocate strip buffers
* (as wide as the image, but just a few rows high).
* In some cases multiple passes must be made over the data. In these
* cases the virtual array routines are used. The array is still accessed
* a strip at a time, but the memory manager must save the whole array
* for repeated accesses. The intended implementation is that there is
* a strip buffer in memory (as high as is possible given the desired memory
* limit), plus a backing file that holds the rest of the array.
* (as wide as the image, but just a few rows high). Full-image-sized buffers
* are handled as "virtual" arrays. The array is still accessed a strip at a
* time, but the memory manager must save the whole array for repeated
* accesses. The intended implementation is that there is a strip buffer in
* memory (as high as is possible given the desired memory limit), plus a
* backing file that holds the rest of the array.
*
* The request_virt_array routines are told the total size of the image and
* the unit height, which is the number of rows that will be accessed at once;
* the in-memory buffer should be made a multiple of this height for best
* efficiency.
* the maximum number of rows that will be accessed at once. The in-memory
* buffer must be at least as large as the maxaccess value.
*
* The request routines create control blocks but not the in-memory buffers.
* That is postponed until realize_virt_arrays is called. At that time the
@@ -506,30 +507,23 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
* area accessible (after reading or writing the backing file, if necessary).
* Note that the access routines are told whether the caller intends to modify
* the accessed strip; during a read-only pass this saves having to rewrite
* data to disk.
* data to disk. The access routines are also responsible for pre-zeroing
* any newly accessed rows, if pre-zeroing was requested.
*
* The typical access pattern is one top-to-bottom pass to write the data,
* followed by one or more read-only top-to-bottom passes. However, other
* access patterns may occur while reading. For example, translation of image
* formats that use bottom-to-top scan order will require bottom-to-top read
* passes. The memory manager need not support multiple write passes nor
* funny write orders (meaning that rearranging rows must be handled while
* reading data out of the virtual array, not while putting it in). THIS WILL
* PROBABLY NEED TO CHANGE ... will need multiple write passes for progressive
* JPEG decoding.
*
* In current usage, the access requests are always for nonoverlapping strips;
* that is, successive access start_row numbers always differ by exactly the
* unitheight. This allows fairly simple buffer dump/reload logic if the
* in-memory buffer is made a multiple of the unitheight. The code below
* would work with overlapping access requests, but not very efficiently.
* In current usage, the access requests are usually for nonoverlapping
* strips; that is, successive access start_row numbers differ by exactly
* num_rows = maxaccess. This means we can get good performance with simple
* buffer dump/reload logic, by making the in-memory buffer be a multiple
* of the access height; then there will never be accesses across bufferload
* boundaries. The code will still work with overlapping access requests,
* but it doesn't handle bufferload overlaps very efficiently.
*/
METHODDEF jvirt_sarray_ptr
request_virt_sarray (j_common_ptr cinfo, int pool_id,
METHODDEF(jvirt_sarray_ptr)
request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
JDIMENSION samplesperrow, JDIMENSION numrows,
JDIMENSION unitheight)
JDIMENSION maxaccess)
/* Request a virtual 2-D sample array */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
@@ -539,9 +533,6 @@ request_virt_sarray (j_common_ptr cinfo, int pool_id,
if (pool_id != JPOOL_IMAGE)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
/* Round array size up to a multiple of unitheight */
numrows = (JDIMENSION) jround_up((long) numrows, (long) unitheight);
/* get control block */
result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
SIZEOF(struct jvirt_sarray_control));
@@ -549,7 +540,8 @@ request_virt_sarray (j_common_ptr cinfo, int pool_id,
result->mem_buffer = NULL; /* marks array not yet realized */
result->rows_in_array = numrows;
result->samplesperrow = samplesperrow;
result->unitheight = unitheight;
result->maxaccess = maxaccess;
result->pre_zero = pre_zero;
result->b_s_open = FALSE; /* no associated backing-store object */
result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
mem->virt_sarray_list = result;
@@ -558,10 +550,10 @@ request_virt_sarray (j_common_ptr cinfo, int pool_id,
}
METHODDEF jvirt_barray_ptr
request_virt_barray (j_common_ptr cinfo, int pool_id,
METHODDEF(jvirt_barray_ptr)
request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
JDIMENSION blocksperrow, JDIMENSION numrows,
JDIMENSION unitheight)
JDIMENSION maxaccess)
/* Request a virtual 2-D coefficient-block array */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
@@ -571,9 +563,6 @@ request_virt_barray (j_common_ptr cinfo, int pool_id,
if (pool_id != JPOOL_IMAGE)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
/* Round array size up to a multiple of unitheight */
numrows = (JDIMENSION) jround_up((long) numrows, (long) unitheight);
/* get control block */
result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
SIZEOF(struct jvirt_barray_control));
@@ -581,7 +570,8 @@ request_virt_barray (j_common_ptr cinfo, int pool_id,
result->mem_buffer = NULL; /* marks array not yet realized */
result->rows_in_array = numrows;
result->blocksperrow = blocksperrow;
result->unitheight = unitheight;
result->maxaccess = maxaccess;
result->pre_zero = pre_zero;
result->b_s_open = FALSE; /* no associated backing-store object */
result->next = mem->virt_barray_list; /* add to list of virtual arrays */
mem->virt_barray_list = result;
@@ -590,25 +580,25 @@ request_virt_barray (j_common_ptr cinfo, int pool_id,
}
METHODDEF void
METHODDEF(void)
realize_virt_arrays (j_common_ptr cinfo)
/* Allocate the in-memory buffers for any unrealized virtual arrays */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
long space_per_unitheight, maximum_space, avail_mem;
long unitheights, max_unitheights;
long space_per_minheight, maximum_space, avail_mem;
long minheights, max_minheights;
jvirt_sarray_ptr sptr;
jvirt_barray_ptr bptr;
/* Compute the minimum space needed (unitheight rows in each buffer)
/* Compute the minimum space needed (maxaccess rows in each buffer)
* and the maximum space needed (full image height in each buffer).
* These may be of use to the system-dependent jpeg_mem_available routine.
*/
space_per_unitheight = 0;
space_per_minheight = 0;
maximum_space = 0;
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
if (sptr->mem_buffer == NULL) { /* if not realized yet */
space_per_unitheight += (long) sptr->unitheight *
space_per_minheight += (long) sptr->maxaccess *
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
maximum_space += (long) sptr->rows_in_array *
(long) sptr->samplesperrow * SIZEOF(JSAMPLE);
@@ -616,46 +606,46 @@ realize_virt_arrays (j_common_ptr cinfo)
}
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
if (bptr->mem_buffer == NULL) { /* if not realized yet */
space_per_unitheight += (long) bptr->unitheight *
space_per_minheight += (long) bptr->maxaccess *
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
maximum_space += (long) bptr->rows_in_array *
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
}
}
if (space_per_unitheight <= 0)
if (space_per_minheight <= 0)
return; /* no unrealized arrays, no work */
/* Determine amount of memory to actually use; this is system-dependent. */
avail_mem = jpeg_mem_available(cinfo, space_per_unitheight, maximum_space,
avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
mem->total_space_allocated);
/* If the maximum space needed is available, make all the buffers full
* height; otherwise parcel it out with the same number of unitheights
* height; otherwise parcel it out with the same number of minheights
* in each buffer.
*/
if (avail_mem >= maximum_space)
max_unitheights = 1000000000L;
max_minheights = 1000000000L;
else {
max_unitheights = avail_mem / space_per_unitheight;
max_minheights = avail_mem / space_per_minheight;
/* If there doesn't seem to be enough space, try to get the minimum
* anyway. This allows a "stub" implementation of jpeg_mem_available().
*/
if (max_unitheights <= 0)
max_unitheights = 1;
if (max_minheights <= 0)
max_minheights = 1;
}
/* Allocate the in-memory buffers and initialize backing store as needed. */
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
if (sptr->mem_buffer == NULL) { /* if not realized yet */
unitheights = ((long) sptr->rows_in_array - 1L) / sptr->unitheight + 1L;
if (unitheights <= max_unitheights) {
minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
if (minheights <= max_minheights) {
/* This buffer fits in memory */
sptr->rows_in_mem = sptr->rows_in_array;
} else {
/* It doesn't fit in memory, create backing store. */
sptr->rows_in_mem = (JDIMENSION) (max_unitheights * sptr->unitheight);
sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
jpeg_open_backing_store(cinfo, & sptr->b_s_info,
(long) sptr->rows_in_array *
(long) sptr->samplesperrow *
@@ -666,19 +656,20 @@ realize_virt_arrays (j_common_ptr cinfo)
sptr->samplesperrow, sptr->rows_in_mem);
sptr->rowsperchunk = mem->last_rowsperchunk;
sptr->cur_start_row = 0;
sptr->first_undef_row = 0;
sptr->dirty = FALSE;
}
}
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
if (bptr->mem_buffer == NULL) { /* if not realized yet */
unitheights = ((long) bptr->rows_in_array - 1L) / bptr->unitheight + 1L;
if (unitheights <= max_unitheights) {
minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
if (minheights <= max_minheights) {
/* This buffer fits in memory */
bptr->rows_in_mem = bptr->rows_in_array;
} else {
/* It doesn't fit in memory, create backing store. */
bptr->rows_in_mem = (JDIMENSION) (max_unitheights * bptr->unitheight);
bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
jpeg_open_backing_store(cinfo, & bptr->b_s_info,
(long) bptr->rows_in_array *
(long) bptr->blocksperrow *
@@ -689,17 +680,18 @@ realize_virt_arrays (j_common_ptr cinfo)
bptr->blocksperrow, bptr->rows_in_mem);
bptr->rowsperchunk = mem->last_rowsperchunk;
bptr->cur_start_row = 0;
bptr->first_undef_row = 0;
bptr->dirty = FALSE;
}
}
}
LOCAL void
LOCAL(void)
do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
/* Do backing store read or write of a virtual sample array */
{
long bytesperrow, file_offset, byte_count, rows, i;
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
file_offset = ptr->cur_start_row * bytesperrow;
@@ -707,9 +699,11 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
/* One chunk, but check for short chunk at end of buffer */
rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
/* Transfer no more than is currently defined */
thisrow = (long) ptr->cur_start_row + i;
rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
/* Transfer no more than fits in file */
rows = MIN(rows, (long) ptr->rows_in_array -
((long) ptr->cur_start_row + i));
rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
if (rows <= 0) /* this chunk might be past end of file! */
break;
byte_count = rows * bytesperrow;
@@ -726,11 +720,11 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
}
LOCAL void
LOCAL(void)
do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
/* Do backing store read or write of a virtual coefficient-block array */
{
long bytesperrow, file_offset, byte_count, rows, i;
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
file_offset = ptr->cur_start_row * bytesperrow;
@@ -738,9 +732,11 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
/* One chunk, but check for short chunk at end of buffer */
rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
/* Transfer no more than is currently defined */
thisrow = (long) ptr->cur_start_row + i;
rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
/* Transfer no more than fits in file */
rows = MIN(rows, (long) ptr->rows_in_array -
((long) ptr->cur_start_row + i));
rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
if (rows <= 0) /* this chunk might be past end of file! */
break;
byte_count = rows * bytesperrow;
@@ -757,20 +753,25 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
}
METHODDEF JSAMPARRAY
METHODDEF(JSAMPARRAY)
access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
JDIMENSION start_row, boolean writable)
JDIMENSION start_row, JDIMENSION num_rows,
boolean writable)
/* Access the part of a virtual sample array starting at start_row */
/* and extending for ptr->unitheight rows. writable is true if */
/* and extending for num_rows rows. writable is true if */
/* caller intends to modify the accessed area. */
{
JDIMENSION end_row = start_row + num_rows;
JDIMENSION undef_row;
/* debugging check */
if (start_row >= ptr->rows_in_array || ptr->mem_buffer == NULL)
if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
ptr->mem_buffer == NULL)
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
@@ -791,19 +792,43 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
/* use long arithmetic here to avoid overflow & unsigned problems */
long ltemp;
ltemp = (long) start_row + (long) ptr->unitheight -
(long) ptr->rows_in_mem;
ltemp = (long) end_row - (long) ptr->rows_in_mem;
if (ltemp < 0)
ltemp = 0; /* don't fall off front end of file */
ptr->cur_start_row = (JDIMENSION) ltemp;
}
/* If reading, read in the selected part of the array.
* If we are writing, we need not pre-read the selected portion,
* since the access sequence constraints ensure it would be garbage.
/* Read in the selected part of the array.
* During the initial write pass, we will do no actual read
* because the selected part is all undefined.
*/
if (! writable) {
do_sarray_io(cinfo, ptr, FALSE);
}
/* Ensure the accessed part of the array is defined; prezero if needed.
* To improve locality of access, we only prezero the part of the array
* that the caller is about to access, not the entire in-memory array.
*/
if (ptr->first_undef_row < end_row) {
if (ptr->first_undef_row < start_row) {
if (writable) /* writer skipped over a section of array */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
undef_row = start_row; /* but reader is allowed to read ahead */
} else {
undef_row = ptr->first_undef_row;
}
if (writable)
ptr->first_undef_row = end_row;
if (ptr->pre_zero) {
size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
end_row -= ptr->cur_start_row;
while (undef_row < end_row) {
FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
undef_row++;
}
} else {
if (! writable) /* reader looking at undefined data */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
}
}
/* Flag the buffer dirty if caller will write in it */
if (writable)
@@ -813,20 +838,25 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
}
METHODDEF JBLOCKARRAY
METHODDEF(JBLOCKARRAY)
access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
JDIMENSION start_row, boolean writable)
JDIMENSION start_row, JDIMENSION num_rows,
boolean writable)
/* Access the part of a virtual block array starting at start_row */
/* and extending for ptr->unitheight rows. writable is true if */
/* and extending for num_rows rows. writable is true if */
/* caller intends to modify the accessed area. */
{
JDIMENSION end_row = start_row + num_rows;
JDIMENSION undef_row;
/* debugging check */
if (start_row >= ptr->rows_in_array || ptr->mem_buffer == NULL)
if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
ptr->mem_buffer == NULL)
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
@@ -847,19 +877,43 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
/* use long arithmetic here to avoid overflow & unsigned problems */
long ltemp;
ltemp = (long) start_row + (long) ptr->unitheight -
(long) ptr->rows_in_mem;
ltemp = (long) end_row - (long) ptr->rows_in_mem;
if (ltemp < 0)
ltemp = 0; /* don't fall off front end of file */
ptr->cur_start_row = (JDIMENSION) ltemp;
}
/* If reading, read in the selected part of the array.
* If we are writing, we need not pre-read the selected portion,
* since the access sequence constraints ensure it would be garbage.
/* Read in the selected part of the array.
* During the initial write pass, we will do no actual read
* because the selected part is all undefined.
*/
if (! writable) {
do_barray_io(cinfo, ptr, FALSE);
}
/* Ensure the accessed part of the array is defined; prezero if needed.
* To improve locality of access, we only prezero the part of the array
* that the caller is about to access, not the entire in-memory array.
*/
if (ptr->first_undef_row < end_row) {
if (ptr->first_undef_row < start_row) {
if (writable) /* writer skipped over a section of array */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
undef_row = start_row; /* but reader is allowed to read ahead */
} else {
undef_row = ptr->first_undef_row;
}
if (writable)
ptr->first_undef_row = end_row;
if (ptr->pre_zero) {
size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
end_row -= ptr->cur_start_row;
while (undef_row < end_row) {
FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
undef_row++;
}
} else {
if (! writable) /* reader looking at undefined data */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
}
}
/* Flag the buffer dirty if caller will write in it */
if (writable)
@@ -873,7 +927,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
* Release all objects belonging to a specified pool.
*/
METHODDEF void
METHODDEF(void)
free_pool (j_common_ptr cinfo, int pool_id)
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
@@ -945,7 +999,7 @@ free_pool (j_common_ptr cinfo, int pool_id)
* Note that this cannot be called unless cinfo->mem is non-NULL.
*/
METHODDEF void
METHODDEF(void)
self_destruct (j_common_ptr cinfo)
{
int pool;
@@ -971,7 +1025,7 @@ self_destruct (j_common_ptr cinfo)
* When this is called, only the error manager pointer is valid in cinfo!
*/
GLOBAL void
GLOBAL(void)
jinit_memory_mgr (j_common_ptr cinfo)
{
my_mem_ptr mem;
@@ -1023,6 +1077,9 @@ jinit_memory_mgr (j_common_ptr cinfo)
mem->pub.free_pool = free_pool;
mem->pub.self_destruct = self_destruct;
/* Make MAX_ALLOC_CHUNK accessible to other modules */
mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
/* Initialize working state */
mem->pub.max_memory_to_use = max_to_use;

View File

@@ -1,7 +1,7 @@
/*
* jmemname.c
*
* Copyright (C) 1992-1994, Thomas G. Lane.
* Copyright (C) 1992-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -30,9 +30,14 @@ extern void free JPP((void *ptr));
#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
/*
@@ -86,7 +91,7 @@ extern int errno;
#endif
LOCAL void
LOCAL(void)
select_file_name (char * fname)
{
FILE * tfile;
@@ -117,7 +122,7 @@ select_file_name (char * fname)
#define TEMP_FILE_NAME "%sJPG%dXXXXXX"
#endif
LOCAL void
LOCAL(void)
select_file_name (char * fname)
{
next_file_num++; /* advance counter */
@@ -134,13 +139,13 @@ select_file_name (char * fname)
* routines malloc() and free().
*/
GLOBAL void *
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
@@ -154,13 +159,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
* you probably won't be able to process useful-size images in only 64KB.
*/
GLOBAL void FAR *
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
free(object);
@@ -179,7 +184,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
#endif
GLOBAL long
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
@@ -195,7 +200,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
*/
METHODDEF void
METHODDEF(void)
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -208,7 +213,7 @@ read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
void FAR * buffer_address,
long file_offset, long byte_count)
@@ -221,7 +226,7 @@ write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
}
METHODDEF void
METHODDEF(void)
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
{
fclose(info->temp_file); /* close the file */
@@ -238,7 +243,7 @@ close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
* Initial opening of a backing-store object.
*/
GLOBAL void
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
@@ -257,14 +262,14 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
* cleanup required.
*/
GLOBAL long
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
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* no work */

View File

@@ -1,7 +1,7 @@
/*
* jmemnobs.c
*
* Copyright (C) 1992-1994, Thomas G. Lane.
* 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.
*
@@ -31,13 +31,13 @@ extern void free JPP((void *ptr));
* routines malloc() and free().
*/
GLOBAL void *
GLOBAL(void *)
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
{
return (void *) malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
{
free(object);
@@ -51,13 +51,13 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
* you probably won't be able to process useful-size images in only 64KB.
*/
GLOBAL void FAR *
GLOBAL(void FAR *)
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
{
return (void FAR *) malloc(sizeofobject);
}
GLOBAL void
GLOBAL(void)
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
{
free(object);
@@ -69,7 +69,7 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
* Here we always say, "we got all you want bud!"
*/
GLOBAL long
GLOBAL(long)
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
long max_bytes_needed, long already_allocated)
{
@@ -83,7 +83,7 @@ jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
* this should never be called and we can just error out.
*/
GLOBAL void
GLOBAL(void)
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
long total_bytes_needed)
{
@@ -96,13 +96,13 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
* cleanup required. Here, there isn't any.
*/
GLOBAL long
GLOBAL(long)
jpeg_mem_init (j_common_ptr cinfo)
{
return 0; /* just set max_memory_to_use to 0 */
}
GLOBAL void
GLOBAL(void)
jpeg_mem_term (j_common_ptr cinfo)
{
/* no work */

View File

@@ -1,7 +1,7 @@
/*
* jmemsys.h
*
* Copyright (C) 1992-1994, Thomas G. Lane.
* Copyright (C) 1992-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -14,7 +14,8 @@
* in the IJG distribution. You may need to modify it if you write a
* custom memory manager. If system-dependent changes are needed in
* this file, the best method is to #ifdef them based on a configuration
* symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR.
* symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
* and USE_MAC_MEMMGR.
*/
@@ -43,8 +44,8 @@
* On an 80x86 machine using small-data memory model, these manage near heap.
*/
EXTERN void * jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object,
EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
size_t sizeofobject));
/*
@@ -56,8 +57,9 @@ EXTERN void jpeg_free_small JPP((j_common_ptr cinfo, void * object,
* in case a different allocation strategy is desirable for large chunks.
*/
EXTERN void FAR * jpeg_get_large JPP((j_common_ptr cinfo,size_t sizeofobject));
EXTERN void jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
size_t sizeofobject));
EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
size_t sizeofobject));
/*
@@ -98,7 +100,7 @@ EXTERN void jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
* Conversely, zero may be returned to always use the minimum amount of memory.
*/
EXTERN long jpeg_mem_available JPP((j_common_ptr cinfo,
EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
long min_bytes_needed,
long max_bytes_needed,
long already_allocated));
@@ -113,6 +115,7 @@ EXTERN long jpeg_mem_available JPP((j_common_ptr cinfo,
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
typedef unsigned short XMSH; /* type of extended-memory handles */
@@ -126,6 +129,11 @@ typedef union {
#endif /* USE_MSDOS_MEMMGR */
#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
#include <Files.h>
#endif /* USE_MAC_MEMMGR */
typedef struct backing_store_struct * backing_store_ptr;
typedef struct backing_store_struct {
@@ -146,13 +154,21 @@ typedef struct backing_store_struct {
/* For the MS-DOS manager (jmemdos.c), we need: */
handle_union handle; /* reference to backing-store storage object */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
#else
#ifdef USE_MAC_MEMMGR
/* For the Mac manager (jmemmac.c), we need: */
short temp_file; /* file reference number to temp file */
FSSpec tempSpec; /* the FSSpec for the temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
#else
/* For a typical implementation with temp files, we need: */
FILE * temp_file; /* stdio reference to temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
#endif
#endif
} backing_store_info;
/*
* Initial opening of a backing-store object. This must fill in the
* read/write/close pointers in the object. The read/write routines
@@ -161,7 +177,7 @@ typedef struct backing_store_struct {
* just take an error exit.)
*/
EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo,
EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
backing_store_ptr info,
long total_bytes_needed));
@@ -178,5 +194,5 @@ EXTERN void jpeg_open_backing_store JPP((j_common_ptr cinfo,
* all opened backing-store objects have been closed.
*/
EXTERN long jpeg_mem_init JPP((j_common_ptr cinfo));
EXTERN void jpeg_mem_term JPP((j_common_ptr cinfo));
EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));

View File

@@ -1,7 +1,8 @@
/*
* jmorecfg.h
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -158,8 +159,14 @@ typedef short INT16;
/* INT32 must hold at least signed 32-bit values. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */
#ifndef _BASETSD_H /* MinGW is slightly different */
#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */
typedef long INT32;
#endif
#endif
#endif
#endif
/* Datatype used for image dimensions. The JPEG standard only supports
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
@@ -173,16 +180,34 @@ typedef unsigned int JDIMENSION;
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
/* These defines are used in all function definitions and extern declarations.
* You could modify them if you need to change function linkage conventions.
/* These macros are used in all function definitions and extern declarations.
* You could modify them if you need to change function linkage conventions;
* in particular, you'll need to do that to make the library a Windows DLL.
* Another application is to make all functions global for use with debuggers
* or code profilers that require it.
*/
#define METHODDEF static /* a function called through method pointers */
#define LOCAL static /* a function used only in its module */
#define GLOBAL /* a function referenced thru EXTERNs */
#define EXTERN extern /* a reference to a GLOBAL function */
/* a function called through method pointers: */
#define METHODDEF(type) static type
/* a function used only in its module: */
#define LOCAL(type) static type
/* a function referenced thru EXTERNs: */
#define GLOBAL(type) type
/* a reference to a GLOBAL function: */
#define EXTERN(type) extern type
/* This macro is used to declare a "method", that is, a function pointer.
* We want to supply prototype parameters if the compiler can cope.
* Note that the arglist parameter must be parenthesized!
* Again, you can customize this if you need special linkage keywords.
*/
#ifdef HAVE_PROTOTYPES
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
#else
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
#endif
/* Here is the pseudo-keyword for declaring pointers that must be "far"
@@ -191,11 +216,13 @@ typedef unsigned int JDIMENSION;
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
*/
#ifndef FAR
#ifdef NEED_FAR_POINTERS
#define FAR far
#else
#define FAR
#endif
#endif
/*
@@ -238,8 +265,6 @@ typedef int boolean;
* (You may HAVE to do that if your compiler doesn't like null source files.)
*/
/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
/* Capability options common to encoder and decoder: */
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
@@ -248,22 +273,29 @@ typedef int boolean;
/* Encoder capability options: */
#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#undef C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? (NYI) */
#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
/* Note: if you selected 12-bit data precision, it is dangerous to turn off
* ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
* precision, so jchuff.c normally uses entropy optimization to compute
* usable tables for higher precision. If you don't want to do optimization,
* you'll have to supply different default Huffman tables.
* The exact same statements apply for progressive JPEG: the default tables
* don't work for progressive mode. (This may get fixed, however.)
*/
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
/* Decoder capability options: */
#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
@@ -280,9 +312,7 @@ typedef int boolean;
* the offsets will also change the order in which colormap data is organized.
* RESTRICTIONS:
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
* 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
* useful if you are using JPEG color spaces other than YCbCr or grayscale.
* 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* is not 3 (they don't understand about dummy color components!). So you
* can't use color quantization if you change that value.
*/

194
jpegint.h
View File

@@ -1,7 +1,8 @@
/*
* jpegint.h
*
* Copyright (C) 1991-1995, Thomas G. Lane.
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -15,23 +16,28 @@
typedef enum { /* Operating modes for buffer controllers */
JBUF_PASS_THRU, /* Plain stripwise operation */
JBUF_CRANK_SOURCE, /* Run source subobject, no output expected */
/* Remaining modes require a full-image buffer to have been created */
JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
} J_BUF_MODE;
/* Values of global_state field */
/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
#define CSTATE_START 100 /* after create_compress */
#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */
#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */
#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */
#define DSTATE_START 200 /* after create_decompress */
#define DSTATE_INHEADER 201 /* read_header initialized but not done */
#define DSTATE_READY 202 /* read_header done, found image */
#define DSTATE_SCANNING 203 /* start_decompress done, read_scanlines OK */
#define DSTATE_RAW_OK 204 /* start_decompress done, read_raw_data OK */
#define DSTATE_STOPPING 205 /* done reading data, looking for EOI */
#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */
#define DSTATE_READY 202 /* found SOS, ready for start_decompress */
#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/
#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */
#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */
#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */
#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */
#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */
#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */
#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */
/* Declarations for compression modules */
@@ -94,14 +100,16 @@ struct jpeg_downsampler {
};
/* Forward DCT (also controls coefficient quantization) */
struct jpeg_forward_dct {
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
/* perhaps this should be an array??? */
JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
jpeg_component_info * compptr,
typedef JMETHOD(void, forward_DCT_ptr,
(j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks));
struct jpeg_forward_dct {
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
/* It is useful to allow each component to have a separate FDCT method. */
forward_DCT_ptr forward_DCT[MAX_COMPONENTS];
};
/* Entropy encoding */
@@ -113,15 +121,16 @@ struct jpeg_entropy_encoder {
/* Marker writing */
struct jpeg_marker_writer {
/* write_any_marker is exported for use by applications */
/* Probably only COM and APPn markers should be written */
JMETHOD(void, write_any_marker, (j_compress_ptr cinfo, int marker,
const JOCTET *dataptr, unsigned int datalen));
JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
/* These routines are exported to allow insertion of extra markers */
/* Probably only COM and APPn markers should be written this way */
JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
unsigned int datalen));
JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
};
@@ -129,12 +138,23 @@ struct jpeg_marker_writer {
/* Master control module */
struct jpeg_decomp_master {
JMETHOD(void, prepare_for_pass, (j_decompress_ptr cinfo));
JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
/* State variables made visible to other modules */
boolean is_last_pass; /* True during last pass */
boolean eoi_processed; /* True if EOI marker already read */
boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
};
/* Input control module */
struct jpeg_input_controller {
JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
/* State variables made visible to other modules */
boolean has_multiple_scans; /* True if file has multiple scans */
boolean eoi_reached; /* True when EOI has been consumed */
};
/* Main buffer control (downsampled-data buffer) */
@@ -143,17 +163,17 @@ struct jpeg_d_main_controller {
JMETHOD(void, process_data, (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail));
/* During input-only passes, output_buf and out_rows_avail are ignored.
* out_row_ctr is incremented towards the limit num_chunks.
*/
JDIMENSION num_chunks; /* number of chunks to be processed in pass */
};
/* Coefficient buffer control */
struct jpeg_d_coef_controller {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
JMETHOD(boolean, decompress_data, (j_decompress_ptr cinfo,
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
JSAMPIMAGE output_buf));
/* Pointer to array of coefficient virtual arrays, or NULL if none */
jvirt_barray_ptr *coef_arrays;
};
/* Decompression postprocessing (color quantization buffer control) */
@@ -172,16 +192,12 @@ struct jpeg_d_post_controller {
struct jpeg_marker_reader {
JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
/* Read markers until SOS or EOI.
* Returns same codes as are defined for jpeg_read_header,
* but HEADER_OK and HEADER_TABLES_ONLY merely indicate which marker type
* stopped the scan --- further validation is needed to declare file OK.
* Returns same codes as are defined for jpeg_consume_input:
* JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
*/
JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
/* Read a restart marker --- exported for use by entropy decoder only */
jpeg_marker_parser_method read_restart_marker;
/* Application-overridable marker processing methods */
jpeg_marker_parser_method process_COM;
jpeg_marker_parser_method process_APPn[16];
/* State of marker reader --- nominally internal, but applications
* supplying COM or APPn handlers might like to know the state.
@@ -206,8 +222,7 @@ typedef JMETHOD(void, inverse_DCT_method_ptr,
JSAMPARRAY output_buf, JDIMENSION output_col));
struct jpeg_inverse_dct {
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
/* It is useful to allow each component to have a separate IDCT method. */
inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
};
@@ -241,6 +256,7 @@ struct jpeg_color_quantizer {
JSAMPARRAY input_buf, JSAMPARRAY output_buf,
int num_rows));
JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
};
@@ -277,7 +293,8 @@ struct jpeg_color_quantizer {
/* Short forms of external names for systems with brain-damaged linkers. */
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jinit_master_compress jICMaster
#define jinit_compress_master jICompress
#define jinit_c_master_control jICMaster
#define jinit_c_main_controller jICMainC
#define jinit_c_prep_controller jICPrepC
#define jinit_c_coef_controller jICCoefC
@@ -285,13 +302,16 @@ struct jpeg_color_quantizer {
#define jinit_downsampler jIDownsampler
#define jinit_forward_dct jIFDCT
#define jinit_huff_encoder jIHEncoder
#define jinit_arith_encoder jIAEncoder
#define jinit_marker_writer jIMWriter
#define jinit_master_decompress jIDMaster
#define jinit_d_main_controller jIDMainC
#define jinit_d_coef_controller jIDCoefC
#define jinit_d_post_controller jIDPostC
#define jinit_input_controller jIInCtlr
#define jinit_marker_reader jIMReader
#define jinit_huff_decoder jIHDecoder
#define jinit_arith_decoder jIADecoder
#define jinit_inverse_dct jIIDCT
#define jinit_upsampler jIUpsampler
#define jinit_color_deconverter jIDColor
@@ -301,54 +321,100 @@ struct jpeg_color_quantizer {
#define jinit_memory_mgr jIMemMgr
#define jdiv_round_up jDivRound
#define jround_up jRound
#define jzero_far jZeroFar
#define jcopy_sample_rows jCopySamples
#define jcopy_block_row jCopyBlocks
#define jzero_far jZeroFar
#define jpeg_zigzag_order jZIGTable
#define jpeg_natural_order jZAGTable
#define jpeg_natural_order7 jZAG7Table
#define jpeg_natural_order6 jZAG6Table
#define jpeg_natural_order5 jZAG5Table
#define jpeg_natural_order4 jZAG4Table
#define jpeg_natural_order3 jZAG3Table
#define jpeg_natural_order2 jZAG2Table
#define jpeg_aritab jAriTab
#endif /* NEED_SHORT_EXTERNAL_NAMES */
/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
* and coefficient-block arrays. This won't work on 80x86 because the arrays
* are FAR and we're assuming a small-pointer memory model. However, some
* DOS compilers provide far-pointer versions of memcpy() and memset() even
* in the small-model libraries. These will be used if USE_FMEM is defined.
* Otherwise, the routines in jutils.c do it the hard way.
*/
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */
#define FMEMZERO(target,size) MEMZERO(target,size)
#else /* 80x86 case */
#ifdef USE_FMEM
#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
#else
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
#define FMEMZERO(target,size) jzero_far(target, size)
#endif
#endif
/* Compression module initialization routines */
EXTERN void jinit_master_compress JPP((j_compress_ptr cinfo));
EXTERN void jinit_c_main_controller JPP((j_compress_ptr cinfo,
EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
boolean transcode_only));
EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
boolean need_full_buffer));
EXTERN void jinit_c_prep_controller JPP((j_compress_ptr cinfo,
EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
boolean need_full_buffer));
EXTERN void jinit_c_coef_controller JPP((j_compress_ptr cinfo,
EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
boolean need_full_buffer));
EXTERN void jinit_color_converter JPP((j_compress_ptr cinfo));
EXTERN void jinit_downsampler JPP((j_compress_ptr cinfo));
EXTERN void jinit_forward_dct JPP((j_compress_ptr cinfo));
EXTERN void jinit_huff_encoder JPP((j_compress_ptr cinfo));
EXTERN void jinit_marker_writer JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_arith_encoder JPP((j_compress_ptr cinfo));
EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
/* Decompression module initialization routines */
EXTERN void jinit_master_decompress JPP((j_decompress_ptr cinfo));
EXTERN void jinit_d_main_controller JPP((j_decompress_ptr cinfo,
EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
boolean need_full_buffer));
EXTERN void jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
boolean need_full_buffer));
EXTERN void jinit_d_post_controller JPP((j_decompress_ptr cinfo,
EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
boolean need_full_buffer));
EXTERN void jinit_marker_reader JPP((j_decompress_ptr cinfo));
EXTERN void jinit_huff_decoder JPP((j_decompress_ptr cinfo));
EXTERN void jinit_inverse_dct JPP((j_decompress_ptr cinfo));
EXTERN void jinit_upsampler JPP((j_decompress_ptr cinfo));
EXTERN void jinit_color_deconverter JPP((j_decompress_ptr cinfo));
EXTERN void jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
EXTERN void jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
EXTERN void jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_arith_decoder JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
/* Memory manager initialization */
EXTERN void jinit_memory_mgr JPP((j_common_ptr cinfo));
EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
/* Utility routines in jutils.c */
EXTERN long jdiv_round_up JPP((long a, long b));
EXTERN long jround_up JPP((long a, long b));
EXTERN void jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
EXTERN(long) jdiv_round_up JPP((long a, long b));
EXTERN(long) jround_up JPP((long a, long b));
EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
JSAMPARRAY output_array, int dest_row,
int num_rows, JDIMENSION num_cols));
EXTERN void jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
JDIMENSION num_blocks));
EXTERN void jzero_far JPP((void FAR * target, size_t bytestozero));
/* Constant tables in jutils.c */
#if 0 /* This table is not actually needed in v6a */
extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
#endif
extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
extern const int jpeg_natural_order7[]; /* zz to natural order for 7x7 block */
extern const int jpeg_natural_order6[]; /* zz to natural order for 6x6 block */
extern const int jpeg_natural_order5[]; /* zz to natural order for 5x5 block */
extern const int jpeg_natural_order4[]; /* zz to natural order for 4x4 block */
extern const int jpeg_natural_order3[]; /* zz to natural order for 3x3 block */
extern const int jpeg_natural_order2[]; /* zz to natural order for 2x2 block */
/* Arithmetic coding probability estimation tables in jaricom.c */
extern const INT32 jpeg_aritab[];
/* Suppress undefined-structure complaints if necessary. */

429
jpeglib.h
View File

@@ -1,7 +1,8 @@
/*
* jpeglib.h
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2002-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -26,11 +27,19 @@
#include "jmorecfg.h" /* seldom changed options */
/* Version ID for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
#ifdef __cplusplus
#ifndef DONT_USE_EXTERN_C
extern "C" {
#endif
#endif
/* Version IDs for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 80".
*/
#define JPEG_LIB_VERSION 51 /* Version 5a */
#define JPEG_LIB_VERSION 80 /* Compatibility version 8.0 */
#define JPEG_LIB_VERSION_MAJOR 8
#define JPEG_LIB_VERSION_MINOR 4
/* Various constants determining the sizes of things.
@@ -38,25 +47,23 @@
* if you want to be compatible.
*/
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
#define DCTSIZE 8 /* The basic DCT block is 8x8 coefficients */
#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */
#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
#define MAX_BLOCKS_IN_MCU 10 /* JPEG limit on # of blocks in an MCU */
/* This macro is used to declare a "method", that is, a function pointer.
* We want to supply prototype parameters if the compiler can cope.
* Note that the arglist parameter must be parenthesized!
/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
* the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
* If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
* to handle it. We even let you do this from the jconfig.h file. However,
* we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
* sometimes emits noncompliant files doesn't mean you should too.
*/
#ifdef HAVE_PROTOTYPES
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
#else
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */
#ifndef D_MAX_BLOCKS_IN_MCU
#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */
#endif
@@ -83,8 +90,9 @@ typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */
/* DCT coefficient quantization tables. */
typedef struct {
/* This field directly represents the contents of a JPEG DQT marker.
* Note: the values are always given in zigzag order.
/* This array gives the coefficient quantizers in natural array order
* (not the zigzag order in which they are stored in a JPEG DQT marker).
* CAUTION: IJG versions prior to v6a kept this array in zigzag order.
*/
UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
/* This field is used only during compression. It's initialized FALSE when
@@ -126,6 +134,7 @@ typedef struct {
/* These values may vary between scans. */
/* For compression, they must be supplied by parameter setup; */
/* for decompression, they are read from the SOS marker. */
/* The decompressor output side may not use these variables. */
int dc_tbl_no; /* DC entropy table selector (0..3) */
int ac_tbl_no; /* AC entropy table selector (0..3) */
@@ -138,18 +147,18 @@ typedef struct {
*/
JDIMENSION width_in_blocks;
JDIMENSION height_in_blocks;
/* Size of a DCT block in samples. Always DCTSIZE for compression.
* For decompression this is the size of the output from one DCT block,
* reflecting any scaling we choose to apply during the IDCT step.
* Values of 1,2,4,8 are likely to be supported. Note that different
* components may receive different IDCT scalings.
/* Size of a DCT block in samples,
* reflecting any scaling we choose to apply during the DCT step.
* Values from 1 to 16 are supported.
* Note that different components may receive different DCT scalings.
*/
int DCT_scaled_size;
int DCT_h_scaled_size;
int DCT_v_scaled_size;
/* The downsampled dimensions are the component's actual, unpadded number
* of samples at the main buffer (preprocessing/compression interface), thus
* downsampled_width = ceil(image_width * Hi/Hmax)
* and similarly for height. For decompression, IDCT scaling is included, so
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
* of samples at the main buffer (preprocessing/compression interface);
* DCT scaling is included, so
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_h_scaled_size/DCTSIZE)
* and similarly for height.
*/
JDIMENSION downsampled_width; /* actual width in samples */
JDIMENSION downsampled_height; /* actual height in samples */
@@ -159,19 +168,48 @@ typedef struct {
*/
boolean component_needed; /* do we need the value of this component? */
/* These values are computed before starting a scan of the component: */
/* These values are computed before starting a scan of the component. */
/* The decompressor output side may not use these variables. */
int MCU_width; /* number of blocks per MCU, horizontally */
int MCU_height; /* number of blocks per MCU, vertically */
int MCU_blocks; /* MCU_width * MCU_height */
int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */
int MCU_sample_width; /* MCU width in samples: MCU_width * DCT_h_scaled_size */
int last_col_width; /* # of non-dummy blocks across in last MCU */
int last_row_height; /* # of non-dummy blocks down in last MCU */
/* Saved quantization table for component; NULL if none yet saved.
* See jdinput.c comments about the need for this information.
* This field is currently used only for decompression.
*/
JQUANT_TBL * quant_table;
/* Private per-component storage for DCT or IDCT subsystem. */
void * dct_table;
} jpeg_component_info;
/* The script for encoding a multiple-scan file is an array of these: */
typedef struct {
int comps_in_scan; /* number of components encoded in this scan */
int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
int Ss, Se; /* progressive JPEG spectral selection parms */
int Ah, Al; /* progressive JPEG successive approx. parms */
} jpeg_scan_info;
/* The decompressor can save APPn and COM markers in a list of these: */
typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
struct jpeg_marker_struct {
jpeg_saved_marker_ptr next; /* next in list, or NULL */
UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
unsigned int original_length; /* # bytes of data in the file */
unsigned int data_length; /* # bytes of data saved at data[] */
JOCTET FAR * data; /* the data contained in the marker */
/* the marker length word is not counted in data_length or original_length */
};
/* Known color spaces. */
typedef enum {
@@ -213,8 +251,9 @@ typedef enum {
struct jpeg_error_mgr * err; /* Error handler module */\
struct jpeg_memory_mgr * mem; /* Memory manager module */\
struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
boolean is_decompressor; /* so common code can tell which is which */\
int global_state /* for checking call sequence validity */
void * client_data; /* Available for use by application */\
boolean is_decompressor; /* So common code can tell which is which */\
int global_state /* For checking call sequence validity */
/* Routines that are to be used by both halves of the library are declared
* to receive a pointer to this structure. There are no actual instances of
@@ -261,6 +300,17 @@ struct jpeg_compress_struct {
* helper routines to simplify changing parameters.
*/
unsigned int scale_num, scale_denom; /* fraction by which to scale image */
JDIMENSION jpeg_width; /* scaled JPEG image width */
JDIMENSION jpeg_height; /* scaled JPEG image height */
/* Dimensions of actual JPEG image that will be written to file,
* derived from input dimensions by scaling factors above.
* These fields are computed by jpeg_start_compress().
* You can also use jpeg_calc_jpeg_dimensions() to determine these values
* in advance of calling jpeg_start_compress().
*/
int data_precision; /* bits of precision in image data */
int num_components; /* # of color components in JPEG image */
@@ -270,7 +320,10 @@ struct jpeg_compress_struct {
/* comp_info[i] describes component that appears i'th in SOF */
JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
/* ptrs to coefficient quantization tables, or NULL if not defined */
int q_scale_factor[NUM_QUANT_TBLS];
/* ptrs to coefficient quantization tables, or NULL if not defined,
* and corresponding scale factors (percentage, initialized 100).
*/
JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
@@ -280,11 +333,18 @@ struct jpeg_compress_struct {
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
int num_scans; /* # of entries in scan_info array */
const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
/* The default value of scan_info is NULL, which causes a single-scan
* sequential JPEG file to be emitted. To create a multi-scan file,
* set num_scans and scan_info to point to an array of scan definitions.
*/
boolean raw_data_in; /* TRUE=caller supplies downsampled data */
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
boolean interleave; /* TRUE=interleaved output, FALSE=not */
boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
J_DCT_METHOD dct_method; /* DCT algorithm selector */
@@ -299,6 +359,8 @@ struct jpeg_compress_struct {
/* Parameters controlling emission of special markers. */
boolean write_JFIF_header; /* should a JFIF marker be written? */
UINT8 JFIF_major_version; /* What to write for the JFIF version number */
UINT8 JFIF_minor_version;
/* These three values are not used by the JPEG code, merely copied */
/* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
/* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
@@ -322,9 +384,13 @@ struct jpeg_compress_struct {
/*
* These fields are computed during compression startup
*/
boolean progressive_mode; /* TRUE if scan script uses progressive mode */
int max_h_samp_factor; /* largest h_samp_factor */
int max_v_samp_factor; /* largest v_samp_factor */
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
/* The coefficient controller receives data in units of MCU rows as defined
* for fully interleaved scans (whether the JPEG file is interleaved or not).
@@ -344,10 +410,16 @@ struct jpeg_compress_struct {
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
int blocks_in_MCU; /* # of DCT blocks per MCU */
int MCU_membership[MAX_BLOCKS_IN_MCU];
int MCU_membership[C_MAX_BLOCKS_IN_MCU];
/* MCU_membership[i] is index in cur_comp_info of component owning */
/* i'th block in an MCU */
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
int block_size; /* the basic DCT block size: 1..16 */
const int * natural_order; /* natural-order position array */
int lim_Se; /* min( Se, DCTSIZE2-1 ) */
/*
* Links to compression subobjects (methods and private variables of modules)
*/
@@ -360,6 +432,8 @@ struct jpeg_compress_struct {
struct jpeg_downsampler * downsample;
struct jpeg_forward_dct * fdct;
struct jpeg_entropy_encoder * entropy;
jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
int script_space_size;
};
@@ -390,16 +464,22 @@ struct jpeg_decompress_struct {
double output_gamma; /* image gamma wanted in output */
boolean buffered_image; /* TRUE=multiple output passes */
boolean raw_data_out; /* TRUE=downsampled data wanted */
J_DCT_METHOD dct_method; /* IDCT algorithm selector */
boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
boolean quantize_colors; /* TRUE=colormapped output wanted */
/* the following are ignored if not quantize_colors: */
boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
J_DITHER_MODE dither_mode; /* type of color dithering to use */
int desired_number_of_colors; /* max number of colors to use */
J_DCT_METHOD dct_method; /* DCT algorithm selector */
boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
int desired_number_of_colors; /* max # colors to use in created colormap */
/* these are significant only in buffered-image mode: */
boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
boolean enable_external_quant;/* enable future use of external colormap */
boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
/* Description of actual output image that will be returned to application.
* These fields are computed by jpeg_start_decompress().
@@ -423,21 +503,47 @@ struct jpeg_decompress_struct {
/* When quantizing colors, the output colormap is described by these fields.
* The application can supply a colormap by setting colormap non-NULL before
* calling jpeg_start_decompress; otherwise a colormap is created during
* jpeg_start_decompress.
* jpeg_start_decompress or jpeg_start_output.
* The map has out_color_components rows and actual_number_of_colors columns.
*/
int actual_number_of_colors; /* number of entries in use */
JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
/* State variable: index of next scaled scanline to be read from
* jpeg_read_scanlines(). Application may use this to control its
* processing loop, e.g., "while (output_scanline < output_height)".
/* State variables: these variables indicate the progress of decompression.
* The application may examine these but must not modify them.
*/
/* Row index of next scanline to be read from jpeg_read_scanlines().
* Application may use this to control its processing loop, e.g.,
* "while (output_scanline < output_height)".
*/
JDIMENSION output_scanline; /* 0 .. output_height-1 */
/* Current input scan number and number of iMCU rows completed in scan.
* These indicate the progress of the decompressor input side.
*/
int input_scan_number; /* Number of SOS markers seen so far */
JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */
/* The "output scan number" is the notional scan being displayed by the
* output side. The decompressor will not allow output scan/row number
* to get ahead of input scan/row, but it can fall arbitrarily far behind.
*/
int output_scan_number; /* Nominal scan number being displayed */
JDIMENSION output_iMCU_row; /* Number of iMCU rows read */
/* Current progression status. coef_bits[c][i] indicates the precision
* with which component c's DCT coefficient i (in zigzag order) is known.
* It is -1 when no data has yet been received, otherwise it is the point
* transform (shift) value for the most recent scan of the coefficient
* (thus, 0 at completion of the progression).
* This pointer is NULL when reading a non-progressive file.
*/
int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */
/* Internal JPEG parameters --- the application usually need not look at
* these fields.
* these fields. Note that the decompressor output side may not use
* any parameters that can change between scans.
*/
/* Quantization and Huffman tables are carried forward across input
@@ -460,19 +566,23 @@ struct jpeg_decompress_struct {
jpeg_component_info * comp_info;
/* comp_info[i] describes component that appears i'th in SOF */
boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
/* These fields record data obtained from optional markers recognized by
* the JPEG library.
*/
boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
/* Data copied from JFIF marker: */
/* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
UINT8 JFIF_major_version; /* JFIF version number */
UINT8 JFIF_minor_version;
UINT8 density_unit; /* JFIF code for pixel size units */
UINT16 X_density; /* Horizontal pixel density */
UINT16 Y_density; /* Vertical pixel density */
@@ -481,6 +591,12 @@ struct jpeg_decompress_struct {
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
/* Aside from the specific data retained from APPn markers known to the
* library, the uninterpreted contents of any or all APPn and COM markers
* can be saved in a list for examination by the application.
*/
jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
/* Remaining fields are known throughout decompressor, but generally
* should not be touched by a surrounding application.
*/
@@ -491,13 +607,16 @@ struct jpeg_decompress_struct {
int max_h_samp_factor; /* largest h_samp_factor */
int max_v_samp_factor; /* largest v_samp_factor */
int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be output by coef ctlr */
/* The coefficient controller outputs data in units of MCU rows as defined
* for fully interleaved scans (whether the JPEG file is interleaved or not).
* There are v_samp_factor * DCT_scaled_size sample rows of each component
* in an "iMCU" (interleaved MCU) row.
JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
/* The coefficient controller's input and output progress is measured in
* units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
* in fully interleaved JPEG scans, but are used whether the scan is
* interleaved or not. We define an iMCU row as v_samp_factor DCT block
* rows of each component. Therefore, the IDCT output contains
* v_samp_factor*DCT_v_scaled_size sample rows of a component per iMCU row.
*/
JSAMPLE * sample_range_limit; /* table for fast range-limiting */
@@ -505,6 +624,7 @@ struct jpeg_decompress_struct {
/*
* These fields are valid during any one scan.
* They describe the components and MCUs actually appearing in the scan.
* Note that the decompressor output side must not use these fields.
*/
int comps_in_scan; /* # of JPEG components in this scan */
jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
@@ -514,10 +634,18 @@ struct jpeg_decompress_struct {
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
int blocks_in_MCU; /* # of DCT blocks per MCU */
int MCU_membership[MAX_BLOCKS_IN_MCU];
int MCU_membership[D_MAX_BLOCKS_IN_MCU];
/* MCU_membership[i] is index in cur_comp_info of component owning */
/* i'th block in an MCU */
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
/* These fields are derived from Se of first SOS marker.
*/
int block_size; /* the basic DCT block size: 1..16 */
const int * natural_order; /* natural-order position array for entropy decode */
int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */
/* This field is shared between entropy decoder and marker parser.
* It is either zero or the code of a JPEG marker that has been
* read from the data source, but has not yet been processed.
@@ -531,6 +659,7 @@ struct jpeg_decompress_struct {
struct jpeg_d_main_controller * main;
struct jpeg_d_coef_controller * coef;
struct jpeg_d_post_controller * post;
struct jpeg_input_controller * inputctl;
struct jpeg_marker_reader * marker;
struct jpeg_entropy_decoder * entropy;
struct jpeg_inverse_dct * idct;
@@ -639,7 +768,7 @@ struct jpeg_source_mgr {
JMETHOD(void, init_source, (j_decompress_ptr cinfo));
JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo));
JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
JMETHOD(void, term_source, (j_decompress_ptr cinfo));
};
@@ -677,22 +806,26 @@ struct jpeg_memory_mgr {
JDIMENSION numrows));
JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
int pool_id,
boolean pre_zero,
JDIMENSION samplesperrow,
JDIMENSION numrows,
JDIMENSION unitheight));
JDIMENSION maxaccess));
JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
int pool_id,
boolean pre_zero,
JDIMENSION blocksperrow,
JDIMENSION numrows,
JDIMENSION unitheight));
JDIMENSION maxaccess));
JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
jvirt_sarray_ptr ptr,
JDIMENSION start_row,
JDIMENSION num_rows,
boolean writable));
JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
jvirt_barray_ptr ptr,
JDIMENSION start_row,
JDIMENSION num_rows,
boolean writable));
JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
JMETHOD(void, self_destruct, (j_common_ptr cinfo));
@@ -703,6 +836,9 @@ struct jpeg_memory_mgr {
* after creating the JPEG object.
*/
long max_memory_to_use;
/* Maximum allocation request accepted by alloc_large. */
long max_alloc_chunk;
};
@@ -733,35 +869,53 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jpeg_std_error jStdError
#define jpeg_create_compress jCreaCompress
#define jpeg_create_decompress jCreaDecompress
#define jpeg_CreateCompress jCreaCompress
#define jpeg_CreateDecompress jCreaDecompress
#define jpeg_destroy_compress jDestCompress
#define jpeg_destroy_decompress jDestDecompress
#define jpeg_stdio_dest jStdDest
#define jpeg_stdio_src jStdSrc
#define jpeg_mem_dest jMemDest
#define jpeg_mem_src jMemSrc
#define jpeg_set_defaults jSetDefaults
#define jpeg_set_colorspace jSetColorspace
#define jpeg_default_colorspace jDefColorspace
#define jpeg_set_quality jSetQuality
#define jpeg_set_linear_quality jSetLQuality
#define jpeg_default_qtables jDefQTables
#define jpeg_add_quant_table jAddQuantTable
#define jpeg_quality_scaling jQualityScaling
#define jpeg_simple_progression jSimProgress
#define jpeg_suppress_tables jSuppressTables
#define jpeg_alloc_quant_table jAlcQTable
#define jpeg_alloc_huff_table jAlcHTable
#define jpeg_start_compress jStrtCompress
#define jpeg_write_scanlines jWrtScanlines
#define jpeg_finish_compress jFinCompress
#define jpeg_calc_jpeg_dimensions jCjpegDimensions
#define jpeg_write_raw_data jWrtRawData
#define jpeg_write_marker jWrtMarker
#define jpeg_write_m_header jWrtMHeader
#define jpeg_write_m_byte jWrtMByte
#define jpeg_write_tables jWrtTables
#define jpeg_read_header jReadHeader
#define jpeg_start_decompress jStrtDecompress
#define jpeg_read_scanlines jReadScanlines
#define jpeg_finish_decompress jFinDecompress
#define jpeg_read_raw_data jReadRawData
#define jpeg_has_multiple_scans jHasMultScn
#define jpeg_start_output jStrtOutput
#define jpeg_finish_output jFinOutput
#define jpeg_input_complete jInComplete
#define jpeg_new_colormap jNewCMap
#define jpeg_consume_input jConsumeInput
#define jpeg_core_output_dimensions jCoreDimensions
#define jpeg_calc_output_dimensions jCalcDimensions
#define jpeg_save_markers jSaveMarkers
#define jpeg_set_marker_processor jSetMarker
#define jpeg_read_coefficients jReadCoefs
#define jpeg_write_coefficients jWrtCoefs
#define jpeg_copy_critical_parameters jCopyCrit
#define jpeg_abort_compress jAbrtCompress
#define jpeg_abort_decompress jAbrtDecompress
#define jpeg_abort jAbort
@@ -771,68 +925,103 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
/* Default error-management setup */
EXTERN struct jpeg_error_mgr *jpeg_std_error JPP((struct jpeg_error_mgr *err));
EXTERN(struct jpeg_error_mgr *) jpeg_std_error
JPP((struct jpeg_error_mgr * err));
/* Initialization and destruction of JPEG compression objects */
/* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx */
EXTERN void jpeg_create_compress JPP((j_compress_ptr cinfo));
EXTERN void jpeg_create_decompress JPP((j_decompress_ptr cinfo));
EXTERN void jpeg_destroy_compress JPP((j_compress_ptr cinfo));
EXTERN void jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
/* Initialization of JPEG compression objects.
* jpeg_create_compress() and jpeg_create_decompress() are the exported
* names that applications should call. These expand to calls on
* jpeg_CreateCompress and jpeg_CreateDecompress with additional information
* passed for version mismatch checking.
* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
*/
#define jpeg_create_compress(cinfo) \
jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
(size_t) sizeof(struct jpeg_compress_struct))
#define jpeg_create_decompress(cinfo) \
jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
(size_t) sizeof(struct jpeg_decompress_struct))
EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
int version, size_t structsize));
EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
int version, size_t structsize));
/* Destruction of JPEG compression objects */
EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
/* Standard data source and destination managers: stdio streams. */
/* Caller is responsible for opening the file before and closing after. */
EXTERN void jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
EXTERN void jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
/* Data source and destination managers: memory buffers. */
EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo,
unsigned char ** outbuffer,
unsigned long * outsize));
EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,
unsigned char * inbuffer,
unsigned long insize));
/* Default parameter setup for compression */
EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
/* Compression parameter setup aids */
EXTERN void jpeg_set_colorspace JPP((j_compress_ptr cinfo,
EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
J_COLOR_SPACE colorspace));
EXTERN void jpeg_default_colorspace JPP((j_compress_ptr cinfo));
EXTERN void jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
boolean force_baseline));
EXTERN void jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
int scale_factor,
boolean force_baseline));
EXTERN void jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo,
boolean force_baseline));
EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table,
int scale_factor,
boolean force_baseline));
EXTERN int jpeg_quality_scaling JPP((int quality));
EXTERN void jpeg_suppress_tables JPP((j_compress_ptr cinfo,
EXTERN(int) jpeg_quality_scaling JPP((int quality));
EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
boolean suppress));
EXTERN JQUANT_TBL * jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
EXTERN JHUFF_TBL * jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
/* Main entry points for compression */
EXTERN void jpeg_start_compress JPP((j_compress_ptr cinfo,
EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
boolean write_all_tables));
EXTERN JDIMENSION jpeg_write_scanlines JPP((j_compress_ptr cinfo,
EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
JSAMPARRAY scanlines,
JDIMENSION num_lines));
EXTERN void jpeg_finish_compress JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
/* Precalculate JPEG dimensions for current compression parameters. */
EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo));
/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
EXTERN JDIMENSION jpeg_write_raw_data JPP((j_compress_ptr cinfo,
EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
JSAMPIMAGE data,
JDIMENSION num_lines));
/* Write a special marker. See libjpeg.doc concerning safe usage. */
EXTERN void jpeg_write_marker JPP((j_compress_ptr cinfo, int marker,
/* Write a special marker. See libjpeg.txt concerning safe usage. */
EXTERN(void) jpeg_write_marker
JPP((j_compress_ptr cinfo, int marker,
const JOCTET * dataptr, unsigned int datalen));
/* Same, but piecemeal. */
EXTERN(void) jpeg_write_m_header
JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
EXTERN(void) jpeg_write_m_byte
JPP((j_compress_ptr cinfo, int val));
/* Alternate compression function: just write an abbreviated table file */
EXTERN void jpeg_write_tables JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
/* Decompression startup: read start of JPEG datastream to see what's there */
EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo,
EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
boolean require_image));
/* Return value is one of: */
#define JPEG_HEADER_OK 0 /* Found valid image datastream */
#define JPEG_HEADER_TABLES_ONLY 1 /* Found valid table-specs-only datastream */
#define JPEG_SUSPENDED 2 /* Had to suspend before end of headers */
#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
#define JPEG_HEADER_OK 1 /* Found valid image datastream */
#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
/* If you pass require_image = TRUE (normal case), you need not check for
* a TABLES_ONLY return code; an abbreviated file will cause an error exit.
* JPEG_SUSPENDED is only possible if you use a data source module that can
@@ -840,42 +1029,71 @@ EXTERN int jpeg_read_header JPP((j_decompress_ptr cinfo,
*/
/* Main entry points for decompression */
EXTERN void jpeg_start_decompress JPP((j_decompress_ptr cinfo));
EXTERN JDIMENSION jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
JSAMPARRAY scanlines,
JDIMENSION max_lines));
EXTERN boolean jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
EXTERN JDIMENSION jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
JSAMPIMAGE data,
JDIMENSION max_lines));
/* Additional entry points for buffered-image mode. */
EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
int scan_number));
EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
/* Return value is one of: */
/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
#define JPEG_REACHED_SOS 1 /* Reached start of new scan */
#define JPEG_REACHED_EOI 2 /* Reached end of image */
#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */
#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
/* Precalculate output dimensions for current decompression parameters. */
EXTERN void jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo));
EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
/* Control saving of COM and APPn markers into marker_list. */
EXTERN(void) jpeg_save_markers
JPP((j_decompress_ptr cinfo, int marker_code,
unsigned int length_limit));
/* Install a special processing method for COM or APPn markers. */
EXTERN void jpeg_set_marker_processor JPP((j_decompress_ptr cinfo,
int marker_code,
EXTERN(void) jpeg_set_marker_processor
JPP((j_decompress_ptr cinfo, int marker_code,
jpeg_marker_parser_method routine));
/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
jvirt_barray_ptr * coef_arrays));
EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
j_compress_ptr dstinfo));
/* If you choose to abort compression or decompression before completing
* jpeg_finish_(de)compress, then you need to clean up to release memory,
* temporary files, etc. You can just call jpeg_destroy_(de)compress
* if you're done with the JPEG object, but if you want to clean it up and
* reuse it, call this:
*/
EXTERN void jpeg_abort_compress JPP((j_compress_ptr cinfo));
EXTERN void jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
/* Generic versions of jpeg_abort and jpeg_destroy that work on either
* flavor of JPEG object. These may be more convenient in some places.
*/
EXTERN void jpeg_abort JPP((j_common_ptr cinfo));
EXTERN void jpeg_destroy JPP((j_common_ptr cinfo));
EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
/* Default restart-marker-resync procedure for use by data source modules */
EXTERN boolean jpeg_resync_to_restart JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
int desired));
/* These marker codes are exported since applications and data source modules
@@ -910,6 +1128,7 @@ struct jpeg_decomp_master { long dummy; };
struct jpeg_d_main_controller { long dummy; };
struct jpeg_d_coef_controller { long dummy; };
struct jpeg_d_post_controller { long dummy; };
struct jpeg_input_controller { long dummy; };
struct jpeg_marker_reader { long dummy; };
struct jpeg_entropy_decoder { long dummy; };
struct jpeg_inverse_dct { long dummy; };
@@ -932,4 +1151,10 @@ struct jpeg_color_quantizer { long dummy; };
#include "jerror.h" /* fetch error codes too */
#endif
#ifdef __cplusplus
#ifndef DONT_USE_EXTERN_C
}
#endif
#endif
#endif /* JPEGLIB_H */

285
jpegtran.1 Normal file
View File

@@ -0,0 +1,285 @@
.TH JPEGTRAN 1 "28 December 2009"
.SH NAME
jpegtran \- lossless transformation of JPEG files
.SH SYNOPSIS
.B jpegtran
[
.I options
]
[
.I filename
]
.LP
.SH DESCRIPTION
.LP
.B jpegtran
performs various useful transformations of JPEG files.
It can translate the coded representation from one variant of JPEG to another,
for example from baseline JPEG to progressive JPEG or vice versa. It can also
perform some rearrangements of the image data, for example turning an image
from landscape to portrait format by rotation.
.PP
.B jpegtran
works by rearranging the compressed data (DCT coefficients), without
ever fully decoding the image. Therefore, its transformations are lossless:
there is no image degradation at all, which would not be true if you used
.B djpeg
followed by
.B cjpeg
to accomplish the same conversion. But by the same token,
.B jpegtran
cannot perform lossy operations such as changing the image quality.
.PP
.B jpegtran
reads the named JPEG/JFIF file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output.
.SH OPTIONS
All switch names may be abbreviated; for example,
.B \-optimize
may be written
.B \-opt
or
.BR \-o .
Upper and lower case are equivalent.
British spellings are also accepted (e.g.,
.BR \-optimise ),
though for brevity these are not mentioned below.
.PP
To specify the coded JPEG representation used in the output file,
.B jpegtran
accepts a subset of the switches recognized by
.BR cjpeg :
.TP
.B \-optimize
Perform optimization of entropy encoding parameters.
.TP
.B \-progressive
Create progressive JPEG file.
.TP
.BI \-restart " N"
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
attached to the number.
.TP
.B \-arithmetic
Use arithmetic coding.
.TP
.BI \-scans " file"
Use the scan script given in the specified text file.
.PP
See
.BR cjpeg (1)
for more details about these switches.
If you specify none of these switches, you get a plain baseline-JPEG output
file. The quality setting and so forth are determined by the input file.
.PP
The image can be losslessly transformed by giving one of these switches:
.TP
.B \-flip horizontal
Mirror image horizontally (left-right).
.TP
.B \-flip vertical
Mirror image vertically (top-bottom).
.TP
.B \-rotate 90
Rotate image 90 degrees clockwise.
.TP
.B \-rotate 180
Rotate image 180 degrees.
.TP
.B \-rotate 270
Rotate image 270 degrees clockwise (or 90 ccw).
.TP
.B \-transpose
Transpose image (across UL-to-LR axis).
.TP
.B \-transverse
Transverse transpose (across UR-to-LL axis).
.IP
The transpose transformation has no restrictions regarding image dimensions.
The other transformations operate rather oddly if the image dimensions are not
a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
transform complete blocks of DCT coefficient data in the desired way.
.IP
.BR jpegtran 's
default behavior when transforming an odd-size image is designed
to preserve exact reversibility and mathematical consistency of the
transformation set. As stated, transpose is able to flip the entire image
area. Horizontal mirroring leaves any partial iMCU column at the right edge
untouched, but is able to flip all rows of the image. Similarly, vertical
mirroring leaves any partial iMCU row at the bottom edge untouched, but is
able to flip all columns. The other transforms can be built up as sequences
of transpose and flip operations; for consistency, their actions on edge
pixels are defined to be the same as the end result of the corresponding
transpose-and-flip sequence.
.IP
For practical use, you may prefer to discard any untransformable edge pixels
rather than having a strange-looking strip along the right and/or bottom edges
of a transformed image. To do this, add the
.B \-trim
switch:
.TP
.B \-trim
Drop non-transformable edge blocks.
.IP
Obviously, a transformation with
.B \-trim
is not reversible, so strictly speaking
.B jpegtran
with this switch is not lossless. Also, the expected mathematical
equivalences between the transformations no longer hold. For example,
.B \-rot 270 -trim
trims only the bottom edge, but
.B \-rot 90 -trim
followed by
.B \-rot 180 -trim
trims both edges.
.IP
If you are only interested in perfect transformation, add the
.B \-perfect
switch:
.TP
.B \-perfect
Fails with an error if the transformation is not perfect.
.IP
For example you may want to do
.IP
.B (jpegtran \-rot 90 -perfect
.I foo.jpg
.B || djpeg
.I foo.jpg
.B | pnmflip \-r90 | cjpeg)
.IP
to do a perfect rotation if available or an approximated one if not.
.PP
We also offer a lossless-crop option, which discards data outside a given
image region but losslessly preserves what is inside. Like the rotate and
flip transforms, lossless crop is restricted by the current JPEG format: the
upper left corner of the selected region must fall on an iMCU boundary. If
this does not hold for the given crop parameters, we silently move the upper
left corner up and/or left to make it so, simultaneously increasing the region
dimensions to keep the lower right crop corner unchanged. (Thus, the output
image covers at least the requested region, but may cover more.)
The image can be losslessly cropped by giving the switch:
.TP
.B \-crop WxH+X+Y
Crop to a rectangular subarea of width W, height H starting at point X,Y.
.PP
Other not-strictly-lossless transformation switches are:
.TP
.B \-grayscale
Force grayscale output.
.IP
This option discards the chrominance channels if the input image is YCbCr
(ie, a standard color JPEG), resulting in a grayscale JPEG file. The
luminance channel is preserved exactly, so this is a better method of reducing
to grayscale than decompression, conversion, and recompression. This switch
is particularly handy for fixing a monochrome picture that was mistakenly
encoded as a color JPEG. (In such a case, the space savings from getting rid
of the near-empty chroma channels won't be large; but the decoding time for
a grayscale JPEG is substantially less than that for a color JPEG.)
.TP
.BI \-scale " M/N"
Scale the output image by a factor M/N.
.IP
Currently supported scale factors are M/N with all M from 1 to 16, where N is
the source DCT size, which is 8 for baseline JPEG. If the /N part is omitted,
then M specifies the DCT scaled size to be applied on the given input. For
baseline JPEG this is equivalent to M/8 scaling, since the source DCT size
for baseline JPEG is 8.
.B Caution:
An implementation of the JPEG SmartScale extension is required for this
feature. SmartScale enabled JPEG is not yet widely implemented, so many
decoders will be unable to view a SmartScale extended JPEG file at all.
.PP
.B jpegtran
also recognizes these switches that control what to do with "extra" markers,
such as comment blocks:
.TP
.B \-copy none
Copy no extra markers from source file. This setting suppresses all
comments and other excess baggage present in the source file.
.TP
.B \-copy comments
Copy only comment markers. This setting copies comments from the source file,
but discards any other inessential (for image display) data.
.TP
.B \-copy all
Copy all extra markers. This setting preserves miscellaneous markers
found in the source file, such as JFIF thumbnails, Exif data, and Photoshop
settings. In some files these extra markers can be sizable.
.IP
The default behavior is
.BR "\-copy comments" .
(Note: in IJG releases v6 and v6a,
.B jpegtran
always did the equivalent of
.BR "\-copy none" .)
.PP
Additional switches recognized by jpegtran are:
.TP
.BI \-maxmemory " N"
Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example,
.B \-max 4m
selects 4000000 bytes. If more space is needed, temporary files will be used.
.TP
.BI \-outfile " name"
Send output image to the named file, not to standard output.
.TP
.B \-verbose
Enable debug printout. More
.BR \-v 's
give more output. Also, version information is printed at startup.
.TP
.B \-debug
Same as
.BR \-verbose .
.SH EXAMPLES
.LP
This example converts a baseline JPEG file to progressive form:
.IP
.B jpegtran \-progressive
.I foo.jpg
.B >
.I fooprog.jpg
.PP
This example rotates an image 90 degrees clockwise, discarding any
unrotatable edge pixels:
.IP
.B jpegtran \-rot 90 -trim
.I foo.jpg
.B >
.I foo90.jpg
.SH ENVIRONMENT
.TP
.B JPEGMEM
If this environment variable is set, its value is the default memory limit.
The value is specified as described for the
.B \-maxmemory
switch.
.B JPEGMEM
overrides the default value specified when the program was compiled, and
itself is overridden by an explicit
.BR \-maxmemory .
.SH SEE ALSO
.BR cjpeg (1),
.BR djpeg (1),
.BR rdjpgcom (1),
.BR wrjpgcom (1)
.br
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
.SH AUTHOR
Independent JPEG Group
.SH BUGS
The transform options can't transform odd-size images perfectly. Use
.B \-trim
or
.B \-perfect
if you don't like the results.
.PP
The entire image is read into memory and then written out again, even in
cases where this isn't really necessary. Expect swapping on large images,
especially when using the more complex transform options.

560
jpegtran.c Normal file
View File

@@ -0,0 +1,560 @@
/*
* jpegtran.c
*
* Copyright (C) 1995-2011, Thomas G. Lane, Guido Vollbeding.
* 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, and partly to djpeg.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 char * scaleoption; /* -scale 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
fprintf(stderr, "Switches for modifying the image:\n");
#if TRANSFORMS_SUPPORTED
fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\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, " -perfect Fail if there is non-transformable edge blocks\n");
fprintf(stderr, " -rotate [90|180|270] Rotate image (degrees clockwise)\n");
#endif
fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n");
#if TRANSFORMS_SUPPORTED
fprintf(stderr, " -transpose Transpose image\n");
fprintf(stderr, " -transverse Transverse transpose image\n");
fprintf(stderr, " -trim Drop non-transformable edge blocks\n");
#endif
fprintf(stderr, "Switches for advanced users:\n");
#ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif
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_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, 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;
boolean simple_progressive;
char * scansarg = NULL; /* saves -scans parm if any */
/* Set up default JPEG parameters. */
simple_progressive = FALSE;
outfilename = NULL;
scaleoption = NULL;
copyoption = JCOPYOPT_DEFAULT;
transformoption.transform = JXFORM_NONE;
transformoption.perfect = FALSE;
transformoption.trim = FALSE;
transformoption.force_grayscale = FALSE;
transformoption.crop = 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", 2)) {
/* 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, "crop", 2)) {
/* Perform lossless cropping. */
#if TRANSFORMS_SUPPORTED
if (++argn >= argc) /* advance to next argument */
usage();
if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) {
fprintf(stderr, "%s: bogus -crop argument '%s'\n",
progname, argv[argn]);
exit(EXIT_FAILURE);
}
#else
select_transform(JXFORM_NONE); /* force an error */
#endif
} else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
/* Enable debug printouts. */
/* On first -d, print version identification */
static 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, "perfect", 2)) {
/* Fail if there is any partial edge MCUs that the transform can't
* handle. */
transformoption.perfect = TRUE;
} else if (keymatch(arg, "progressive", 2)) {
/* 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, "scale", 4)) {
/* Scale the output image by a fraction M/N. */
if (++argn >= argc) /* advance to next argument */
usage();
scaleoption = argv[argn];
/* We must postpone processing until decompression startup. */
} 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;
/* We assume all-in-memory processing and can therefore use only a
* single file pointer for sequential input and output operation.
*/
FILE * fp;
/* 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 ((fp = fopen(argv[file_index], READ_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s for reading\n", progname, argv[file_index]);
exit(EXIT_FAILURE);
}
} else {
/* default input file is stdin */
fp = read_stdin();
}
#ifdef PROGRESS_REPORT
start_progress_monitor((j_common_ptr) &dstinfo, &progress);
#endif
/* Specify data source for decompression */
jpeg_stdio_src(&srcinfo, fp);
/* Enable saving of extra markers that we want to copy */
jcopy_markers_setup(&srcinfo, copyoption);
/* Read file header */
(void) jpeg_read_header(&srcinfo, TRUE);
/* Adjust default decompression parameters */
if (scaleoption != NULL)
if (sscanf(scaleoption, "%d/%d",
&srcinfo.scale_num, &srcinfo.scale_denom) < 1)
usage();
/* 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
/* Fail right away if -perfect is given and transformation is not perfect.
*/
if (!jtransform_request_workspace(&srcinfo, &transformoption)) {
fprintf(stderr, "%s: transformation is not perfect\n", progname);
exit(EXIT_FAILURE);
}
#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
/* Close input file, if we opened it.
* Note: we assume that jpeg_read_coefficients consumed all input
* until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
* only consume more while (! cinfo->inputctl->eoi_reached).
* We cannot call jpeg_finish_decompress here since we still need the
* virtual arrays allocated from the source object for processing.
*/
if (fp != stdin)
fclose(fp);
/* Open the output file. */
if (outfilename != NULL) {
if ((fp = fopen(outfilename, WRITE_BINARY)) == NULL) {
fprintf(stderr, "%s: can't open %s for writing\n", progname, outfilename);
exit(EXIT_FAILURE);
}
} else {
/* default output file is stdout */
fp = write_stdout();
}
/* 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, fp);
/* 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 output file, if we opened it */
if (fp != stdout)
fclose(fp);
#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 */
}

412
jquant1.c
View File

@@ -1,7 +1,8 @@
/*
* jquant1.c
*
* Copyright (C) 1991-1995, Thomas G. Lane.
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -142,11 +143,18 @@ typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
typedef struct {
struct jpeg_color_quantizer pub; /* public fields */
/* Initially allocated colormap is saved here */
JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
int sv_actual; /* number of entries in use */
JSAMPARRAY colorindex; /* Precomputed mapping for speed */
/* colorindex[i][j] = index of color closest to pixel value j in component i,
* premultiplied as described above. Since colormap indexes must fit into
* JSAMPLEs, the entries of this array will too.
*/
boolean is_padded; /* is the colorindex padded for odither? */
int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
/* Variables for ordered dithering */
int row_index; /* cur row's vertical index in dither matrix */
@@ -161,9 +169,9 @@ typedef my_cquantizer * my_cquantize_ptr;
/*
* Policy-making subroutines for create_colormap: these routines determine
* the colormap to be used. The rest of the module only assumes that the
* colormap is orthogonal.
* Policy-making subroutines for create_colormap and create_colorindex.
* These routines determine the colormap to be used. The rest of the module
* only assumes that the colormap is orthogonal.
*
* * select_ncolors decides how to divvy up the available colors
* among the components.
@@ -175,7 +183,7 @@ typedef my_cquantizer * my_cquantize_ptr;
*/
LOCAL int
LOCAL(int)
select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
/* Determine allocation of desired colors to components, */
/* and fill in Ncolors[] array to indicate choice. */
@@ -234,7 +242,7 @@ select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
}
LOCAL int
LOCAL(int)
output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
/* Return j'th output value, where j will range from 0 to maxj */
/* The output values must fall in 0..MAXJSAMPLE in increasing order */
@@ -248,7 +256,7 @@ output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
}
LOCAL int
LOCAL(int)
largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
/* Return largest input value that should map to j'th output value */
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
@@ -258,12 +266,134 @@ largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
}
/*
* Create the colormap.
*/
LOCAL(void)
create_colormap (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
JSAMPARRAY colormap; /* Created colormap */
int total_colors; /* Number of distinct output colors */
int i,j,k, nci, blksize, blkdist, ptr, val;
/* Select number of colors for each component */
total_colors = select_ncolors(cinfo, cquantize->Ncolors);
/* Report selected color counts */
if (cinfo->out_color_components == 3)
TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
total_colors, cquantize->Ncolors[0],
cquantize->Ncolors[1], cquantize->Ncolors[2]);
else
TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
/* Allocate and fill in the colormap. */
/* The colors are ordered in the map in standard row-major order, */
/* i.e. rightmost (highest-indexed) color changes most rapidly. */
colormap = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
/* blksize is number of adjacent repeated entries for a component */
/* blkdist is distance between groups of identical entries for a component */
blkdist = total_colors;
for (i = 0; i < cinfo->out_color_components; i++) {
/* fill in colormap entries for i'th color component */
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
blksize = blkdist / nci;
for (j = 0; j < nci; j++) {
/* Compute j'th output value (out of nci) for component */
val = output_value(cinfo, i, j, nci-1);
/* Fill in all colormap entries that have this value of this component */
for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
/* fill in blksize entries beginning at ptr */
for (k = 0; k < blksize; k++)
colormap[i][ptr+k] = (JSAMPLE) val;
}
}
blkdist = blksize; /* blksize of this color is blkdist of next */
}
/* Save the colormap in private storage,
* where it will survive color quantization mode changes.
*/
cquantize->sv_colormap = colormap;
cquantize->sv_actual = total_colors;
}
/*
* Create the color index table.
*/
LOCAL(void)
create_colorindex (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
JSAMPROW indexptr;
int i,j,k, nci, blksize, val, pad;
/* For ordered dither, we pad the color index tables by MAXJSAMPLE in
* each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
* This is not necessary in the other dithering modes. However, we
* flag whether it was done in case user changes dithering mode.
*/
if (cinfo->dither_mode == JDITHER_ORDERED) {
pad = MAXJSAMPLE*2;
cquantize->is_padded = TRUE;
} else {
pad = 0;
cquantize->is_padded = FALSE;
}
cquantize->colorindex = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (MAXJSAMPLE+1 + pad),
(JDIMENSION) cinfo->out_color_components);
/* blksize is number of adjacent repeated entries for a component */
blksize = cquantize->sv_actual;
for (i = 0; i < cinfo->out_color_components; i++) {
/* fill in colorindex entries for i'th color component */
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
blksize = blksize / nci;
/* adjust colorindex pointers to provide padding at negative indexes. */
if (pad)
cquantize->colorindex[i] += MAXJSAMPLE;
/* in loop, val = index of current output value, */
/* and k = largest j that maps to current val */
indexptr = cquantize->colorindex[i];
val = 0;
k = largest_input_value(cinfo, i, 0, nci-1);
for (j = 0; j <= MAXJSAMPLE; j++) {
while (j > k) /* advance val if past boundary */
k = largest_input_value(cinfo, i, ++val, nci-1);
/* premultiply so that no multiplication needed in main processing */
indexptr[j] = (JSAMPLE) (val * blksize);
}
/* Pad at both ends if necessary */
if (pad)
for (j = 1; j <= MAXJSAMPLE; j++) {
indexptr[-j] = indexptr[0];
indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
}
}
}
/*
* Create an ordered-dither array for a component having ncolors
* distinct output values.
*/
LOCAL ODITHER_MATRIX_PTR
LOCAL(ODITHER_MATRIX_PTR)
make_odither_array (j_decompress_ptr cinfo, int ncolors)
{
ODITHER_MATRIX_PTR odither;
@@ -294,106 +424,23 @@ make_odither_array (j_decompress_ptr cinfo, int ncolors)
/*
* Create the colormap and color index table.
* Also creates the ordered-dither tables, if required.
* Create the ordered-dither tables.
* Components having the same number of representative colors may
* share a dither table.
*/
LOCAL void
create_colormap (j_decompress_ptr cinfo)
LOCAL(void)
create_odither_tables (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
JSAMPARRAY colormap; /* Created colormap */
JSAMPROW indexptr;
int total_colors; /* Number of distinct output colors */
int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
ODITHER_MATRIX_PTR odither;
int i,j,k, nci, blksize, blkdist, ptr, val, pad;
/* Select number of colors for each component */
total_colors = select_ncolors(cinfo, Ncolors);
/* Report selected color counts */
if (cinfo->out_color_components == 3)
TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
total_colors, Ncolors[0], Ncolors[1], Ncolors[2]);
else
TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
/* For ordered dither, we pad the color index tables by MAXJSAMPLE in
* each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
* This is not necessary in the other dithering modes.
*/
pad = (cinfo->dither_mode == JDITHER_ORDERED) ? MAXJSAMPLE*2 : 0;
/* Allocate and fill in the colormap and color index. */
/* The colors are ordered in the map in standard row-major order, */
/* i.e. rightmost (highest-indexed) color changes most rapidly. */
colormap = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
cquantize->colorindex = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (MAXJSAMPLE+1 + pad),
(JDIMENSION) cinfo->out_color_components);
/* blksize is number of adjacent repeated entries for a component */
/* blkdist is distance between groups of identical entries for a component */
blkdist = total_colors;
int i, j, nci;
for (i = 0; i < cinfo->out_color_components; i++) {
/* fill in colormap entries for i'th color component */
nci = Ncolors[i]; /* # of distinct values for this color */
blksize = blkdist / nci;
for (j = 0; j < nci; j++) {
/* Compute j'th output value (out of nci) for component */
val = output_value(cinfo, i, j, nci-1);
/* Fill in all colormap entries that have this value of this component */
for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
/* fill in blksize entries beginning at ptr */
for (k = 0; k < blksize; k++)
colormap[i][ptr+k] = (JSAMPLE) val;
}
}
blkdist = blksize; /* blksize of this color is blkdist of next */
/* adjust colorindex pointers to provide padding at negative indexes. */
if (pad)
cquantize->colorindex[i] += MAXJSAMPLE;
/* fill in colorindex entries for i'th color component */
/* in loop, val = index of current output value, */
/* and k = largest j that maps to current val */
indexptr = cquantize->colorindex[i];
val = 0;
k = largest_input_value(cinfo, i, 0, nci-1);
for (j = 0; j <= MAXJSAMPLE; j++) {
while (j > k) /* advance val if past boundary */
k = largest_input_value(cinfo, i, ++val, nci-1);
/* premultiply so that no multiplication needed in main processing */
indexptr[j] = (JSAMPLE) (val * blksize);
}
/* Pad at both ends if necessary */
if (pad)
for (j = 1; j <= MAXJSAMPLE; j++) {
indexptr[-j] = indexptr[0];
indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
}
}
/* Make the colormap available to the application. */
cinfo->colormap = colormap;
cinfo->actual_number_of_colors = total_colors;
if (cinfo->dither_mode == JDITHER_ORDERED) {
/* Allocate and fill in the ordered-dither tables. Components having
* the same number of representative colors may share a dither table.
*/
for (i = 0; i < cinfo->out_color_components; i++) {
nci = Ncolors[i]; /* # of distinct values for this color */
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
odither = NULL; /* search for matching prior component */
for (j = 0; j < i; j++) {
if (nci == Ncolors[j]) {
if (nci == cquantize->Ncolors[j]) {
odither = cquantize->odither[j];
break;
}
@@ -403,14 +450,13 @@ create_colormap (j_decompress_ptr cinfo)
cquantize->odither[i] = odither;
}
}
}
/*
* Map some rows of pixels to the output colormapped representation.
*/
METHODDEF void
METHODDEF(void)
color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows)
/* General case, no dithering */
@@ -438,7 +484,7 @@ color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
}
METHODDEF void
METHODDEF(void)
color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows)
/* Fast path for out_color_components==3, no dithering */
@@ -466,7 +512,7 @@ color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
}
METHODDEF void
METHODDEF(void)
quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows)
/* General case, with ordered dithering */
@@ -485,7 +531,7 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
for (row = 0; row < num_rows; row++) {
/* Initialize output values to 0 so can process components separately */
jzero_far((void FAR *) output_buf[row],
FMEMZERO((void FAR *) output_buf[row],
(size_t) (width * SIZEOF(JSAMPLE)));
row_index = cquantize->row_index;
for (ci = 0; ci < nc; ci++) {
@@ -516,7 +562,7 @@ quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
}
METHODDEF void
METHODDEF(void)
quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows)
/* Fast path for out_color_components==3, with ordered dithering */
@@ -561,7 +607,7 @@ quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
}
METHODDEF void
METHODDEF(void)
quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows)
/* General case, with Floyd-Steinberg dithering */
@@ -590,7 +636,7 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
for (row = 0; row < num_rows; row++) {
/* Initialize output values to 0 so can process components separately */
jzero_far((void FAR *) output_buf[row],
FMEMZERO((void FAR *) output_buf[row],
(size_t) (width * SIZEOF(JSAMPLE)));
for (ci = 0; ci < nc; ci++) {
input_ptr = input_buf[row] + ci;
@@ -609,7 +655,7 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
errorptr = cquantize->fserrors[ci]; /* => entry before first column */
}
colorindex_ci = cquantize->colorindex[ci];
colormap_ci = cinfo->colormap[ci];
colormap_ci = cquantize->sv_colormap[ci];
/* Preset error values: no error propagated to first pixel from left */
cur = 0;
/* and no error propagated to row below yet */
@@ -670,51 +716,38 @@ quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
/*
* Initialize for one-pass color quantization.
* Allocate workspace for Floyd-Steinberg errors.
*/
METHODDEF void
start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
LOCAL(void)
alloc_fs_workspace (j_decompress_ptr cinfo)
{
/* no work in 1-pass case */
}
/*
* Finish up at the end of the pass.
*/
METHODDEF void
finish_pass_1_quant (j_decompress_ptr cinfo)
{
/* no work in 1-pass case */
}
/*
* Module initialization routine for 1-pass color quantization.
*/
GLOBAL void
jinit_1pass_quantizer (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize;
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
size_t arraysize;
int i;
cquantize = (my_cquantize_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_cquantizer));
cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
cquantize->pub.start_pass = start_pass_1_quant;
cquantize->pub.finish_pass = finish_pass_1_quant;
arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
for (i = 0; i < cinfo->out_color_components; i++) {
cquantize->fserrors[i] = (FSERRPTR)
(*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
}
}
/* Make sure my internal arrays won't overflow */
if (cinfo->out_color_components > MAX_Q_COMPS)
ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
/* Make sure colormap indexes can be represented by JSAMPLEs */
if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
/*
* Initialize for one-pass color quantization.
*/
METHODDEF(void)
start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
size_t arraysize;
int i;
/* Install my colormap. */
cinfo->colormap = cquantize->sv_colormap;
cinfo->actual_number_of_colors = cquantize->sv_actual;
/* Initialize for desired dithering mode. */
switch (cinfo->dither_mode) {
@@ -730,28 +763,95 @@ jinit_1pass_quantizer (j_decompress_ptr cinfo)
else
cquantize->pub.color_quantize = quantize_ord_dither;
cquantize->row_index = 0; /* initialize state for ordered dither */
/* If user changed to ordered dither from another mode,
* we must recreate the color index table with padding.
* This will cost extra space, but probably isn't very likely.
*/
if (! cquantize->is_padded)
create_colorindex(cinfo);
/* Create ordered-dither tables if we didn't already. */
if (cquantize->odither[0] == NULL)
create_odither_tables(cinfo);
break;
case JDITHER_FS:
cquantize->pub.color_quantize = quantize_fs_dither;
cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
/* Allocate Floyd-Steinberg workspace if necessary. */
/* We do this now since it is FAR storage and may affect the memory */
/* manager's space calculations. */
arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
for (i = 0; i < cinfo->out_color_components; i++) {
cquantize->fserrors[i] = (FSERRPTR) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
/* Allocate Floyd-Steinberg workspace if didn't already. */
if (cquantize->fserrors[0] == NULL)
alloc_fs_workspace(cinfo);
/* Initialize the propagated errors to zero. */
jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
}
arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
for (i = 0; i < cinfo->out_color_components; i++)
FMEMZERO((void FAR *) cquantize->fserrors[i], arraysize);
break;
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
}
/* Create the colormap. */
/*
* Finish up at the end of the pass.
*/
METHODDEF(void)
finish_pass_1_quant (j_decompress_ptr cinfo)
{
/* no work in 1-pass case */
}
/*
* Switch to a new external colormap between output passes.
* Shouldn't get to this module!
*/
METHODDEF(void)
new_color_map_1_quant (j_decompress_ptr cinfo)
{
ERREXIT(cinfo, JERR_MODE_CHANGE);
}
/*
* Module initialization routine for 1-pass color quantization.
*/
GLOBAL(void)
jinit_1pass_quantizer (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize;
cquantize = (my_cquantize_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_cquantizer));
cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
cquantize->pub.start_pass = start_pass_1_quant;
cquantize->pub.finish_pass = finish_pass_1_quant;
cquantize->pub.new_color_map = new_color_map_1_quant;
cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */
/* Make sure my internal arrays won't overflow */
if (cinfo->out_color_components > MAX_Q_COMPS)
ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
/* Make sure colormap indexes can be represented by JSAMPLEs */
if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
/* Create the colormap and color index table. */
create_colormap(cinfo);
create_colorindex(cinfo);
/* Allocate Floyd-Steinberg workspace now if requested.
* We do this now since it is FAR storage and may affect the memory
* manager's space calculations. If the user changes to FS dither
* mode in a later pass, we will allocate the space then, and will
* possibly overrun the max_memory_to_use setting.
*/
if (cinfo->dither_mode == JDITHER_FS)
alloc_fs_workspace(cinfo);
}
#endif /* QUANT_1PASS_SUPPORTED */

170
jquant2.c
View File

@@ -1,7 +1,8 @@
/*
* jquant2.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -193,9 +194,15 @@ typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
typedef struct {
struct jpeg_color_quantizer pub; /* public fields */
/* Space for the eventually created colormap is stashed here */
JSAMPARRAY sv_colormap; /* colormap allocated at init time */
int desired; /* desired # of colors = size of colormap */
/* Variables for accumulating image statistics */
hist3d histogram; /* pointer to the histogram */
boolean needs_zeroed; /* TRUE if next pass must zero histogram */
/* Variables for Floyd-Steinberg dithering */
FSERRPTR fserrors; /* accumulated errors */
boolean on_odd_row; /* flag to remember which row we are on */
@@ -214,7 +221,7 @@ typedef my_cquantizer * my_cquantize_ptr;
* NULL pointer).
*/
METHODDEF void
METHODDEF(void)
prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
JSAMPARRAY output_buf, int num_rows)
{
@@ -263,7 +270,7 @@ typedef struct {
typedef box * boxptr;
LOCAL boxptr
LOCAL(boxptr)
find_biggest_color_pop (boxptr boxlist, int numboxes)
/* Find the splittable box with the largest color population */
/* Returns NULL if no splittable boxes remain */
@@ -283,7 +290,7 @@ find_biggest_color_pop (boxptr boxlist, int numboxes)
}
LOCAL boxptr
LOCAL(boxptr)
find_biggest_volume (boxptr boxlist, int numboxes)
/* Find the splittable box with the largest (scaled) volume */
/* Returns NULL if no splittable boxes remain */
@@ -303,7 +310,7 @@ find_biggest_volume (boxptr boxlist, int numboxes)
}
LOCAL void
LOCAL(void)
update_box (j_decompress_ptr cinfo, boxptr boxp)
/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
/* and recompute its volume and population */
@@ -414,7 +421,7 @@ update_box (j_decompress_ptr cinfo, boxptr boxp)
}
LOCAL int
LOCAL(int)
median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
int desired_colors)
/* Repeatedly select and split the largest box until we have enough boxes */
@@ -489,7 +496,7 @@ median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
}
LOCAL void
LOCAL(void)
compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
/* Compute representative color for a box, put it in colormap[icolor] */
{
@@ -529,18 +536,17 @@ compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
}
LOCAL void
select_colors (j_decompress_ptr cinfo)
LOCAL(void)
select_colors (j_decompress_ptr cinfo, int desired_colors)
/* Master routine for color selection */
{
boxptr boxlist;
int numboxes;
int desired = cinfo->desired_number_of_colors;
int i;
/* Allocate workspace for box list */
boxlist = (boxptr) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, desired * SIZEOF(box));
((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
/* Initialize one box containing whole space */
numboxes = 1;
boxlist[0].c0min = 0;
@@ -552,7 +558,7 @@ select_colors (j_decompress_ptr cinfo)
/* Shrink it to actually-used volume and set its statistics */
update_box(cinfo, & boxlist[0]);
/* Perform median-cut to produce final box list */
numboxes = median_cut(cinfo, boxlist, numboxes, desired);
numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
/* Compute the representative color for each box, fill colormap */
for (i = 0; i < numboxes; i++)
compute_color(cinfo, & boxlist[i], i);
@@ -637,7 +643,7 @@ select_colors (j_decompress_ptr cinfo)
* inner-loop variables.
*/
LOCAL int
LOCAL(int)
find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
JSAMPLE colorlist[])
/* Locate the colormap entries close enough to an update box to be candidates
@@ -766,7 +772,7 @@ find_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
}
LOCAL void
LOCAL(void)
find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
/* Find the closest colormap entry for each cell in the update box,
@@ -846,7 +852,7 @@ find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
}
LOCAL void
LOCAL(void)
fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
/* Fill the inverse-colormap entries in the update box that contains */
/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */
@@ -906,7 +912,7 @@ fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
* Map some rows of pixels to the output colormapped representation.
*/
METHODDEF void
METHODDEF(void)
pass2_no_dither (j_decompress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
/* This version performs no dithering */
@@ -940,7 +946,7 @@ pass2_no_dither (j_decompress_ptr cinfo,
}
METHODDEF void
METHODDEF(void)
pass2_fs_dither (j_decompress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
/* This version performs Floyd-Steinberg dithering */
@@ -1099,7 +1105,7 @@ pass2_fs_dither (j_decompress_ptr cinfo,
* to Aaron Giles for this idea.
*/
LOCAL void
LOCAL(void)
init_error_limit (j_decompress_ptr cinfo)
/* Allocate and fill in the error_limiter table */
{
@@ -1134,15 +1140,20 @@ init_error_limit (j_decompress_ptr cinfo)
* Finish up at the end of each pass.
*/
METHODDEF void
METHODDEF(void)
finish_pass1 (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
/* Select the representative colors and fill in cinfo->colormap */
select_colors(cinfo);
cinfo->colormap = cquantize->sv_colormap;
select_colors(cinfo, cquantize->desired);
/* Force next pass to zero the color index table */
cquantize->needs_zeroed = TRUE;
}
METHODDEF void
METHODDEF(void)
finish_pass2 (j_decompress_ptr cinfo)
{
/* no work */
@@ -1153,17 +1164,23 @@ finish_pass2 (j_decompress_ptr cinfo)
* Initialize for each processing pass.
*/
METHODDEF void
METHODDEF(void)
start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
hist3d histogram = cquantize->histogram;
int i;
/* Only F-S dithering or no dithering is supported. */
/* If user asks for ordered dither, give him F-S. */
if (cinfo->dither_mode != JDITHER_NONE)
cinfo->dither_mode = JDITHER_FS;
if (is_pre_scan) {
/* Set up method pointers */
cquantize->pub.color_quantize = prescan_quantize;
cquantize->pub.finish_pass = finish_pass1;
cquantize->needs_zeroed = TRUE; /* Always zero histogram */
} else {
/* Set up method pointers */
if (cinfo->dither_mode == JDITHER_FS)
@@ -1171,12 +1188,52 @@ start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
else
cquantize->pub.color_quantize = pass2_no_dither;
cquantize->pub.finish_pass = finish_pass2;
/* Make sure color count is acceptable */
i = cinfo->actual_number_of_colors;
if (i < 1)
ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
if (i > MAXNUMCOLORS)
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
if (cinfo->dither_mode == JDITHER_FS) {
size_t arraysize = (size_t) ((cinfo->output_width + 2) *
(3 * SIZEOF(FSERROR)));
/* Allocate Floyd-Steinberg workspace if we didn't already. */
if (cquantize->fserrors == NULL)
cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
/* Initialize the propagated errors to zero. */
FMEMZERO((void FAR *) cquantize->fserrors, arraysize);
/* Make the error-limit table if we didn't already. */
if (cquantize->error_limiter == NULL)
init_error_limit(cinfo);
cquantize->on_odd_row = FALSE;
}
/* Zero the histogram or inverse color map */
}
/* Zero the histogram or inverse color map, if necessary */
if (cquantize->needs_zeroed) {
for (i = 0; i < HIST_C0_ELEMS; i++) {
jzero_far((void FAR *) histogram[i],
FMEMZERO((void FAR *) histogram[i],
HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
}
cquantize->needs_zeroed = FALSE;
}
}
/*
* Switch to a new external colormap between output passes.
*/
METHODDEF(void)
new_color_map_2_quant (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
/* Reset the inverse color map */
cquantize->needs_zeroed = TRUE;
}
@@ -1184,7 +1241,7 @@ start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
* Module initialization routine for 2-pass color quantization.
*/
GLOBAL void
GLOBAL(void)
jinit_2pass_quantizer (j_decompress_ptr cinfo)
{
my_cquantize_ptr cquantize;
@@ -1195,26 +1252,14 @@ jinit_2pass_quantizer (j_decompress_ptr cinfo)
SIZEOF(my_cquantizer));
cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
cquantize->pub.start_pass = start_pass_2_quant;
cquantize->pub.new_color_map = new_color_map_2_quant;
cquantize->fserrors = NULL; /* flag optional arrays not allocated */
cquantize->error_limiter = NULL;
/* Make sure jdmaster didn't give me a case I can't handle */
if (cinfo->out_color_components != 3)
ERREXIT(cinfo, JERR_NOTIMPL);
/* Only F-S dithering or no dithering is supported. */
/* If user asks for ordered dither, give him F-S. */
if (cinfo->dither_mode != JDITHER_NONE)
cinfo->dither_mode = JDITHER_FS;
/* Make sure color count is acceptable */
i = (cinfo->colormap != NULL) ? cinfo->actual_number_of_colors
: cinfo->desired_number_of_colors;
/* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
if (i < 8)
ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
/* Make sure colormap indexes can be represented by JSAMPLEs */
if (i > MAXNUMCOLORS)
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
/* Allocate the histogram/inverse colormap storage */
cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
@@ -1223,29 +1268,42 @@ jinit_2pass_quantizer (j_decompress_ptr cinfo)
((j_common_ptr) cinfo, JPOOL_IMAGE,
HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
}
cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
/* Allocate storage for the completed colormap,
* unless it has been supplied by the application.
/* Allocate storage for the completed colormap, if required.
* We do this now since it is FAR storage and may affect
* the memory manager's space calculations.
*/
if (cinfo->colormap == NULL) {
cinfo->colormap = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) cinfo->desired_number_of_colors, (JDIMENSION) 3);
}
if (cinfo->enable_2pass_quant) {
/* Make sure color count is acceptable */
int desired = cinfo->desired_number_of_colors;
/* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
if (desired < 8)
ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
/* Make sure colormap indexes can be represented by JSAMPLEs */
if (desired > MAXNUMCOLORS)
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
cquantize->desired = desired;
} else
cquantize->sv_colormap = NULL;
/* Allocate Floyd-Steinberg workspace if necessary. */
/* This isn't needed until pass 2, but again it is FAR storage. */
/* Only F-S dithering or no dithering is supported. */
/* If user asks for ordered dither, give him F-S. */
if (cinfo->dither_mode != JDITHER_NONE)
cinfo->dither_mode = JDITHER_FS;
/* Allocate Floyd-Steinberg workspace if necessary.
* This isn't really needed until pass 2, but again it is FAR storage.
* Although we will cope with a later change in dither_mode,
* we do not promise to honor max_memory_to_use if dither_mode changes.
*/
if (cinfo->dither_mode == JDITHER_FS) {
size_t arraysize = (size_t) ((cinfo->output_width + 2) *
(3 * SIZEOF(FSERROR)));
cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
/* Initialize the propagated errors to zero. */
jzero_far((void FAR *) cquantize->fserrors, arraysize);
cquantize->on_odd_row = FALSE;
((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
/* Might as well create the error-limiting table too. */
init_error_limit(cinfo);
}
}

152
jutils.c
View File

@@ -1,12 +1,13 @@
/*
* jutils.c
*
* Copyright (C) 1991-1994, Thomas G. Lane.
* Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2009-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains miscellaneous utility routines needed for both
* compression and decompression.
* This file contains tables and miscellaneous utility routines needed
* for both compression and decompression.
* Note we prefix all global names with "j" to minimize conflicts with
* a surrounding application.
*/
@@ -16,11 +17,110 @@
#include "jpeglib.h"
/*
* jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
* of a DCT block read in natural order (left to right, top to bottom).
*/
#if 0 /* This table is not actually needed in v6a */
const int jpeg_zigzag_order[DCTSIZE2] = {
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
#endif
/*
* jpeg_natural_order[i] is the natural-order position of the i'th element
* of zigzag order.
*
* When reading corrupted data, the Huffman decoders could attempt
* to reference an entry beyond the end of this array (if the decoded
* zero run length reaches past the end of the block). To prevent
* wild stores without adding an inner-loop test, we put some extra
* "63"s after the real entries. This will cause the extra coefficient
* to be stored in location 63 of the block, not somewhere random.
* The worst case would be a run-length of 15, which means we need 16
* fake entries.
*/
const int jpeg_natural_order[DCTSIZE2+16] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
const int jpeg_natural_order7[7*7+16] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 14, 21, 28, 35,
42, 49, 50, 43, 36, 29, 22, 30,
37, 44, 51, 52, 45, 38, 46, 53,
54,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
const int jpeg_natural_order6[6*6+16] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 41, 34, 27,
20, 13, 21, 28, 35, 42, 43, 36,
29, 37, 44, 45,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
const int jpeg_natural_order5[5*5+16] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 12,
19, 26, 33, 34, 27, 20, 28, 35,
36,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
const int jpeg_natural_order4[4*4+16] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 25, 18, 11, 19, 26, 27,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
const int jpeg_natural_order3[3*3+16] = {
0, 1, 8, 16, 9, 2, 10, 17,
18,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
const int jpeg_natural_order2[2*2+16] = {
0, 1, 8, 9,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
/*
* Arithmetic utilities
*/
GLOBAL long
GLOBAL(long)
jdiv_round_up (long a, long b)
/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
/* Assumes a >= 0, b > 0 */
@@ -29,7 +129,7 @@ jdiv_round_up (long a, long b)
}
GLOBAL long
GLOBAL(long)
jround_up (long a, long b)
/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
/* Assumes a >= 0, b > 0 */
@@ -48,18 +148,32 @@ jround_up (long a, long b)
* is not all that great, because these routines aren't very heavily used.)
*/
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */
#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
#define FMEMZERO(target,size) MEMZERO(target,size)
#else /* 80x86 case, define if we can */
#ifdef USE_FMEM
#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
#else
/* This function is for use by the FMEMZERO macro defined in jpegint.h.
* Do not call this function directly, use the FMEMZERO macro instead.
*/
GLOBAL(void)
jzero_far (void FAR * target, size_t bytestozero)
/* Zero out a chunk of FAR memory. */
/* This might be sample-array data, block-array data, or alloc_large data. */
{
register char FAR * ptr = (char FAR *) target;
register size_t count;
for (count = bytestozero; count > 0; count--) {
*ptr++ = 0;
}
}
#endif
#endif
GLOBAL void
GLOBAL(void)
jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
JSAMPARRAY output_array, int dest_row,
int num_rows, JDIMENSION num_cols)
@@ -93,7 +207,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
}
GLOBAL void
GLOBAL(void)
jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
JDIMENSION num_blocks)
/* Copy a row of coefficient blocks from one place to another. */
@@ -111,21 +225,3 @@ jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
}
#endif
}
GLOBAL void
jzero_far (void FAR * target, size_t bytestozero)
/* Zero out a chunk of FAR memory. */
/* This might be sample-array data, block-array data, or alloc_medium data. */
{
#ifdef FMEMZERO
FMEMZERO(target, bytestozero);
#else
register char FAR * ptr = (char FAR *) target;
register size_t count;
for (count = bytestozero; count > 0; count--) {
*ptr++ = 0;
}
#endif
}

View File

@@ -1,7 +1,7 @@
/*
* jversion.h
*
* Copyright (C) 1991-1995, Thomas G. Lane.
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@@ -9,6 +9,6 @@
*/
#define JVERSION "5b 15-Mar-95"
#define JVERSION "8d 15-Jan-2012"
#define JCOPYRIGHT "Copyright (C) 1995, Thomas G. Lane"
#define JCOPYRIGHT "Copyright (C) 2012, Thomas G. Lane, Guido Vollbeding"

4
libjpeg.map Normal file
View File

@@ -0,0 +1,4 @@
LIBJPEG_8.0 {
global:
*;
};

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More