- Switched to IJG code for reading JPEG images. I have included a stripped-

down version of the library with the ZDoom source. (It actually uses less
  space than zlib now.) Unix users probably ought to use the system-supplied
  libjpeg instead. I modified Makefile.linux to hopefully do that. I'm sure
  Jim or someone will correct me if it doesn't actually work.


SVN r293 (trunk)
This commit is contained in:
Randy Heit 2006-08-16 18:08:39 +00:00
parent 21869a6c08
commit ed12bdc0f4
42 changed files with 11261 additions and 623 deletions

View file

@ -16,7 +16,7 @@ ifdef GC
endif endif
CFLAGS += -MMD -DHAVE_FILELENGTH -D__forceinline=inline -Izlib -IFLAC `sdl-config --cflags` CFLAGS += -MMD -DHAVE_FILELENGTH -D__forceinline=inline -Izlib -IFLAC `sdl-config --cflags`
CFLAGS += -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DNEED_STRUPR CFLAGS += -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DNEED_STRUPR
LDFLAGS += -lFLAC++ -lFLAC -lz -lfmod `sdl-config --libs` LDFLAGS += -lFLAC++ -lFLAC -lz -ljpeg -lfmod `sdl-config --libs`
NASMFLAGS += -f elf -DM_TARGET_LINUX NASMFLAGS += -f elf -DM_TARGET_LINUX
SRCDIRS = src/ $(addprefix src/,g_doom/ g_heretic/ g_hexen/ g_raven/ g_shared/ g_strife/ oplsynth/ sound/ sdl/) SRCDIRS = src/ $(addprefix src/,g_doom/ g_heretic/ g_hexen/ g_raven/ g_shared/ g_strife/ oplsynth/ sound/ sdl/)

View file

@ -27,6 +27,7 @@ basetools: ccdv.exe
$(MAKE) -C tools/xlatcc $(MAKE) -C tools/xlatcc
$(MAKE) -C wadsrc -f Makefile.mgw $(MAKE) -C wadsrc -f Makefile.mgw
$(MAKE) -C flac -f Makefile.mgw $(MAKE) -C flac -f Makefile.mgw
$(MAKE) -C jpeg-6b -f Makefile.mgw
cleanexe: cleanexe:
@$(MAKE) -C . -f Makefile.mingw clean @$(MAKE) -C . -f Makefile.mingw clean
@ -41,6 +42,7 @@ clean:
@$(MAKE) -C . -f Makefile.mingw clean @$(MAKE) -C . -f Makefile.mingw clean
@$(MAKE) -C zlib -f Makefile.mgw clean @$(MAKE) -C zlib -f Makefile.mgw clean
@$(MAKE) -C flac -f Makefile.mgw clean @$(MAKE) -C flac -f Makefile.mgw clean
@$(MAKE) -C jpeg-6b -f Makefile.mgw clean
ifeq (msys,$(OSTYPE)) ifeq (msys,$(OSTYPE))
rm -f ccdv.exe rm -f ccdv.exe
else else

View file

@ -25,8 +25,8 @@ RELEASEOBJDIR ?= releaseobj
CCDV = @ccdv CCDV = @ccdv
RE2C = tools/re2c/re2c RE2C = tools/re2c/re2c
CPPFLAGS = -DWIN32 -D_WIN32 -D_WINDOWS -DHAVE_STRUPR -DHAVE_FILELENGTH -DI_DO_NOT_LIKE_BIG_DOWNLOADS -D__forceinline=inline -MMD -Izlib -IFLAC -Isrc -Isrc/win32 -Isrc/g_doom -Isrc/g_heretic -I src/g_hexen -Isrc/g_raven -Isrc/g_strife -Isrc/g_shared -Isrc/oplsynth -Isrc/sound CPPFLAGS = -DWIN32 -D_WIN32 -D_WINDOWS -DHAVE_STRUPR -DHAVE_FILELENGTH -DI_DO_NOT_LIKE_BIG_DOWNLOADS -D__forceinline=inline -MMD -Izlib -IFLAC -Ijpeg-6b -Isrc -Isrc/win32 -Isrc/g_doom -Isrc/g_heretic -I src/g_hexen -Isrc/g_raven -Isrc/g_strife -Isrc/g_shared -Isrc/oplsynth -Isrc/sound
LDFLAGS += flac/libflac.a zlib/libz.a -lfmod -lwsock32 -lwinmm -lddraw -ldsound -ldxguid -ldinput8 -lole32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lsetupapi -lws2_32 -Wl,--subsystem,windows LDFLAGS += flac/libflac.a zlib/libz.a jpeg-6b/libjpeg.a -lfmod -lwsock32 -lwinmm -lddraw -ldsound -ldxguid -ldinput8 -lole32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lsetupapi -lws2_32 -Wl,--subsystem,windows
ifdef FMODDIR ifdef FMODDIR
CPPFLAGS += -I$(FMODDIR)/api/inc CPPFLAGS += -I$(FMODDIR)/api/inc

View file

@ -1,3 +1,10 @@
August 16, 2006
- Switched to IJG code for reading JPEG images. I have included a stripped-
down version of the library with the ZDoom source. (It actually uses less
space than zlib now.) Unix users probably ought to use the system-supplied
libjpeg instead. I modified Makefile.linux to hopefully do that. I'm sure
Jim or someone will correct me if it doesn't actually work.
August 14, 2006 August 14, 2006
- Added JPEG texture support, courtesy of Ken's Picture Library. I will - Added JPEG texture support, courtesy of Ken's Picture Library. I will
probably switch to the IJG library once I pare it down. (Ken's code is 18K probably switch to the IJG library once I pare it down. (Ken's code is 18K

63
jpeg-6b/Makefile.mgw Normal file
View file

@ -0,0 +1,63 @@
# Makefile for libjpeg, derived from zlib/Makefile.mgw.
STATICLIB = libjpeg.a
CCDV = @../ccdv
CC = gcc
CFLAGS = $(LOC) -O2 -Wall -fomit-frame-pointer
AS = $(CC)
ASFLAGS = $(LOC) -Wall
LD = $(CC)
LDFLAGS = $(LOC) -s
AR = ar
ARFLAGS = rcs
OBJS = jcomapi.o jdapimin.o jdapistd.o jdatasrc.o jdcoefct.o jdcolor.o \
jddctmgr.o jdhuff.o jdinput.o jdmainct.o jdmarker.o jdmaster.o \
jdmerge.o jdphuff.o jdpostct.o jdsample.o jerror.o jidctint.o \
jmemmgr.o jutils.o
all: $(STATICLIB)
.c.o:
$(CCDV) $(CC) $(CFLAGS) -c -o $@ $<
$(STATICLIB): $(OBJS)
$(CCDV) $(AR) $(ARFLAGS) $@ $(OBJS)
.PHONY: clean
clean:
ifeq (msys,$(OSTYPE))
rm -f $(STATICLIB)
rm -f *.o
else
-del /q /f $(STATICLIB) 2>nul
-del /q /f *.o 2>nul
endif
jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h

385
jpeg-6b/README Normal file
View file

@ -0,0 +1,385 @@
The Independent JPEG Group's JPEG software
==========================================
README for release 6b of 27-Mar-1998
====================================
This distribution contains the sixth public release of the Independent JPEG
Group's free JPEG software. You are welcome to redistribute this software and
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
Serious users of this software (particularly those incorporating it into
larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
our electronic mailing list. Mailing list members are notified of updates
and have a chance to participate in technical discussions, etc.
This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
Group.
IJG is not affiliated with the official ISO JPEG standards committee.
DOCUMENTATION ROADMAP
=====================
This file contains the following sections:
OVERVIEW General description of JPEG and the IJG software.
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
REFERENCES Where to learn more about JPEG.
ARCHIVE LOCATIONS Where to find newer versions of this software.
RELATED SOFTWARE Other stuff you should get.
FILE FORMAT WARS Software *not* to get.
TO DO Plans for future IJG releases.
Other documentation files in the distribution are:
User documentation:
install.doc How to configure and install the IJG software.
usage.doc Usage instructions for cjpeg, djpeg, jpegtran,
rdjpgcom, and wrjpgcom.
*.1 Unix-style man pages for programs (same info as usage.doc).
wizard.doc Advanced usage instructions for JPEG wizards only.
change.log Version-to-version change highlights.
Programmer and internal documentation:
libjpeg.doc How to use the JPEG library in your own programs.
example.c Sample code for calling the JPEG library.
structure.doc Overview of the JPEG library's internal structure.
filelist.doc Road map of IJG files.
coderules.doc Coding style rules --- please read if you contribute code.
Please read at least the files install.doc and usage.doc. Useful information
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
If you want to understand how the JPEG code works, we suggest reading one or
more of the REFERENCES, then looking at the documentation files (in roughly
the order listed) before diving into the code.
OVERVIEW
========
This package contains C software to implement JPEG image compression and
decompression. JPEG (pronounced "jay-peg") is a standardized compression
method for full-color and gray-scale images. JPEG is intended for compressing
"real-world" scenes; line drawings, cartoons and other non-realistic images
are not its strong suit. JPEG is lossy, meaning that the output image is not
exactly identical to the input image. Hence you must not use JPEG if you
have to have identical output bits. However, on typical photographic images,
very good compression levels can be obtained with no visible change, and
remarkably high compression levels are possible if you can tolerate a
low-quality image. For more details, see the references, or just experiment
with various compression settings.
This software implements JPEG baseline, extended-sequential, and progressive
compression processes. Provision is made for supporting all variants of these
processes, although some uncommon parameter settings aren't implemented yet.
For legal reasons, we are not distributing code for the arithmetic-coding
variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting
the hierarchical or lossless processes defined in the standard.
We provide a set of library routines for reading and writing JPEG image files,
plus two sample applications "cjpeg" and "djpeg", which use the library to
perform conversion between JPEG and some other popular image file formats.
The library is intended to be reused in other applications.
In order to support file conversion and viewing software, we have included
considerable functionality beyond the bare JPEG coding/decoding capability;
for example, the color quantization modules are not strictly part of JPEG
decoding, but they are essential for output to colormapped file formats or
colormapped displays. These extra functions can be compiled out of the
library if not required for a particular application. We have also included
"jpegtran", a utility for lossless transcoding between different JPEG
processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
inserting and extracting textual comments in JFIF files.
The emphasis in designing this software has been on achieving portability and
flexibility, while also making it fast enough to be useful. In particular,
the software is not intended to be read as a tutorial on JPEG. (See the
REFERENCES section for introductory material.) Rather, it is intended to
be reliable, portable, industrial-strength code. We do not claim to have
achieved that goal in every aspect of the software, but we strive for it.
We welcome the use of this software as a component of commercial products.
No royalty is required, but we do ask for an acknowledgement in product
documentation, as described under LEGAL ISSUES.
LEGAL ISSUES
============
In plain English:
1. We don't promise that this software works. (But if you find any bugs,
please let us know!)
2. You can use this software for whatever you want. You don't have to pay us.
3. You may not pretend that you wrote this software. If you use it in a
program, you must acknowledge somewhere in your documentation that
you've used the IJG code.
In legalese:
The authors make NO WARRANTY or representation, either express or implied,
with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you,
its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-1998, Thomas G. Lane.
All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this
software (or portions thereof) for any purpose, without fee, subject to these
conditions:
(1) If any part of the source code for this software is distributed, then this
README file must be included, with this copyright and no-warranty notice
unaltered; and any additions, deletions, or changes to the original files
must be clearly indicated in accompanying documentation.
(2) If only executable code is distributed, then the accompanying
documentation must state that "this software is based in part on the work of
the Independent JPEG Group".
(3) Permission for use of this software is granted only if the user accepts
full responsibility for any undesirable consequences; the authors accept
NO LIABILITY for damages of any kind.
These conditions apply to any software derived from or based on the IJG code,
not just to the unmodified library. If you use our work, you ought to
acknowledge us.
Permission is NOT granted for the use of any IJG author's name or company name
in advertising or publicity relating to this software or products derived from
it. This software may be referred to only as "the Independent JPEG Group's
software".
We specifically permit and encourage the use of this software as the basis of
commercial products, provided that all warranty or liability claims are
assumed by the product vendor.
ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
ansi2knr.c is NOT covered by the above copyright and conditions, but instead
by the usual distribution terms of the Free Software Foundation; principally,
that you must include source code if you redistribute it. (See the file
ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
of any program generated from the IJG code, this does not limit you more than
the foregoing paragraphs do.
The Unix configuration script "configure" was produced with GNU Autoconf.
It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub,
ltconfig, ltmain.sh). Another support script, install-sh, is copyright
by M.I.T. but is also freely distributable.
It appears that the arithmetic coding option of the JPEG spec is covered by
patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
legally be used without obtaining one or more licenses. For this reason,
support for arithmetic coding has been removed from the free JPEG software.
(Since arithmetic coding provides only a marginal gain over the unpatented
Huffman mode, it is unlikely that very many implementations will support it.)
So far as we are aware, there are no patent restrictions on the remaining
code.
The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent, GIF reading support has
been removed altogether, and the GIF writer has been simplified to produce
"uncompressed GIFs". This technique does not use the LZW algorithm; the
resulting GIF files are larger than usual, but are readable by all standard
GIF decoders.
We are required to state that
"The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of
CompuServe Incorporated."
REFERENCES
==========
We highly recommend reading one or more of these references before trying to
understand the innards of the JPEG software.
The best short technical introduction to the JPEG compression algorithm is
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
(Adjacent articles in that issue discuss MPEG motion picture compression,
applications of JPEG, and related topics.) If you don't have the CACM issue
handy, a PostScript file containing a revised version of Wallace's article is
available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
omits the sample images that appeared in CACM, but it includes corrections
and some added material. Note: the Wallace article is copyright ACM and IEEE,
and it may not be used for commercial purposes.
A somewhat less technical, more leisurely introduction to JPEG can be found in
"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
good explanations and example C code for a multitude of compression methods
including JPEG. It is an excellent source if you are comfortable reading C
code but don't know much about data compression in general. The book's JPEG
sample code is far from industrial-strength, but when you are ready to look
at a full implementation, you've got one here...
The best full description of JPEG is the textbook "JPEG Still Image Data
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
The book includes the complete text of the ISO JPEG standards (DIS 10918-1
and draft DIS 10918-2). This is by far the most complete exposition of JPEG
in existence, and we highly recommend it.
The JPEG standard itself is not available electronically; you must order a
paper copy through ISO or ITU. (Unless you feel a need to own a certified
official copy, we recommend buying the Pennebaker and Mitchell book instead;
it's much cheaper and includes a great deal of useful explanatory material.)
In the USA, copies of the standard may be ordered from ANSI Sales at (212)
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
doesn't take credit card orders, but Global does.) It's not cheap: as of
1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
shipping/handling. The standard is divided into two parts, Part 1 being the
actual specification, while Part 2 covers compliance testing methods. Part 1
is titled "Digital Compression and Coding of Continuous-tone Still Images,
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
Continuous-tone Still Images, Part 2: Compliance testing" and has document
numbers ISO/IEC IS 10918-2, ITU-T T.83.
Some extensions to the original JPEG standard are defined in JPEG Part 3,
a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG
currently does not support any Part 3 extensions.
The JPEG standard does not specify all details of an interchangeable file
format. For the omitted details we follow the "JFIF" conventions, revision
1.02. A copy of the JFIF spec is available from:
Literature Department
C-Cube Microsystems, Inc.
1778 McCarthy Blvd.
Milpitas, CA 95035
phone (408) 944-6300, fax (408) 944-6314
A PostScript version of this document is available by FTP at
ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text
version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
the figures.
The TIFF 6.0 file format specification can be obtained by FTP from
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or
from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision
of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
uses our library to implement TIFF/JPEG per the Note. libtiff is available
from ftp://ftp.sgi.com/graphics/tiff/.
ARCHIVE LOCATIONS
=================
The "official" archive site for this software is ftp.uu.net (Internet
address 192.48.96.9). The most recent released version can always be found
there in directory graphics/jpeg. This particular version will be archived
as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have
direct Internet access, UUNET's archives are also available via UUCP; contact
help@uunet.uu.net for information on retrieving files that way.
Numerous Internet sites maintain copies of the UUNET files. However, only
ftp.uu.net is guaranteed to have the latest official version.
You can also obtain this software in DOS-compatible "zip" archive format from
the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net
release.
The JPEG FAQ (Frequently Asked Questions) article is a useful source of
general information about JPEG. It is updated constantly and therefore is
not included in this distribution. The FAQ is posted every two weeks to
Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
and other news.answers archive sites, including the official news.answers
archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
with body
send usenet/news.answers/jpeg-faq/part1
send usenet/news.answers/jpeg-faq/part2
RELATED SOFTWARE
================
Numerous viewing and image manipulation programs now support JPEG. (Quite a
few of them use this library to do so.) The JPEG FAQ described above lists
some of the more popular free and shareware viewers, and tells where to
obtain them on Internet.
If you are on a Unix machine, we highly recommend Jef Poskanzer's free
PBMPLUS software, which provides many useful operations on PPM-format image
files. In particular, it can convert PPM images to and from a wide range of
other formats, thus making cjpeg/djpeg considerably more useful. The latest
version is distributed by the NetPBM group, and is available from numerous
sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
you are likely to have difficulty making it work on any non-Unix machine.
A different free JPEG implementation, written by the PVRG group at Stanford,
is available from ftp://havefun.stanford.edu/pub/jpeg/. This program
is designed for research and experimentation rather than production use;
it is slower, harder to use, and less portable than the IJG code, but it
is easier to read and modify. Also, the PVRG code supports lossless JPEG,
which we do not. (On the other hand, it doesn't do progressive JPEG.)
FILE FORMAT WARS
================
Some JPEG programs produce files that are not compatible with our library.
The root of the problem is that the ISO JPEG committee failed to specify a
concrete file format. Some vendors "filled in the blanks" on their own,
creating proprietary formats that no one else could read. (For example, none
of the early commercial JPEG implementations for the Macintosh were able to
exchange compressed files.)
The file format we have adopted is called JFIF (see REFERENCES). This format
has been agreed to by a number of major commercial JPEG vendors, and it has
become the de facto standard. JFIF is a minimal or "low end" representation.
We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
Technical Note #2) for "high end" applications that need to record a lot of
additional data about an image. TIFF/JPEG is fairly new and not yet widely
supported, unfortunately.
The upcoming JPEG Part 3 standard defines a file format called SPIFF.
SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
be able to read the most common variant of SPIFF. SPIFF has some technical
advantages over JFIF, but its major claim to fame is simply that it is an
official standard rather than an informal one. At this point it is unclear
whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
standard. IJG intends to support SPIFF once the standard is frozen, but we
have not decided whether it should become our default output format or not.
(In any case, our decoder will remain capable of reading JFIF indefinitely.)
Various proprietary file formats incorporating JPEG compression also exist.
We have little or no sympathy for the existence of these formats. Indeed,
one of the original reasons for developing this free software was to help
force convergence on common, open format standards for JPEG files. Don't
use a proprietary file format!
TO DO
=====
The major thrust for v7 will probably be improvement of visual quality.
The current method for scaling the quantization tables is known not to be
very good at low Q values. We also intend to investigate block boundary
smoothing, "poor man's variable quantization", and other means of improving
quality-vs-file-size performance without sacrificing compatibility.
In future versions, we are considering supporting some of the upcoming JPEG
Part 3 extensions --- principally, variable quantization and the SPIFF file
format.
As always, speeding things up is of great interest.
Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.

106
jpeg-6b/jcomapi.c Normal file
View file

@ -0,0 +1,106 @@
/*
* jcomapi.c
*
* 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.
*
* This file contains application interface routines that are used for both
* compression and decompression.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/*
* Abort processing of a JPEG compression or decompression operation,
* but don't destroy the object itself.
*
* For this, we merely clean up all the nonpermanent memory pools.
* Note that temp files (virtual arrays) are not allowed to belong to
* the permanent pool, so we will be able to close all temp files here.
* Closing a data source or destination, if necessary, is the application's
* responsibility.
*/
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.
*/
for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
(*cinfo->mem->free_pool) (cinfo, pool);
}
/* Reset overall state for possible reuse of object */
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;
}
}
/*
* Destruction of a JPEG object.
*
* Everything gets deallocated except the master jpeg_compress_struct itself
* and the error manager struct. Both of these are supplied by the application
* and must be freed, if necessary, by the application. (Often they are on
* the stack and so don't need to be freed anyway.)
* Closing a data source or destination, if necessary, is the application's
* responsibility.
*/
GLOBAL(void)
jpeg_destroy (j_common_ptr cinfo)
{
/* We need only tell the memory manager to release everything. */
/* NB: mem pointer is NULL if memory mgr failed to initialize. */
if (cinfo->mem != NULL)
(*cinfo->mem->self_destruct) (cinfo);
cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */
cinfo->global_state = 0; /* mark it destroyed */
}
/*
* Convenience routines for allocating quantization and Huffman tables.
* (Would jutils.c be a more reasonable place to put these?)
*/
GLOBAL(JQUANT_TBL *)
jpeg_alloc_quant_table (j_common_ptr cinfo)
{
JQUANT_TBL *tbl;
tbl = (JQUANT_TBL *)
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
tbl->sent_table = FALSE; /* make sure this is false in any new table */
return tbl;
}
GLOBAL(JHUFF_TBL *)
jpeg_alloc_huff_table (j_common_ptr cinfo)
{
JHUFF_TBL *tbl;
tbl = (JHUFF_TBL *)
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
tbl->sent_table = FALSE; /* make sure this is false in any new table */
return tbl;
}

26
jpeg-6b/jconfig.h Normal file
View file

@ -0,0 +1,26 @@
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
/* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES
#define HAVE_UNSIGNED_CHAR
#define HAVE_UNSIGNED_SHORT
/* #define void char */
/* #define const */
#undef CHAR_IS_UNSIGNED
#define HAVE_STDDEF_H
#define HAVE_STDLIB_H
#undef NEED_BSD_STRINGS
#undef NEED_SYS_TYPES_H
/* 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 */

343
jpeg-6b/jdapimin.c Normal file
View file

@ -0,0 +1,343 @@
/*
* jdapimin.c
*
* 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.
*
* 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
#include "jinclude.h"
#include "jpeglib.h"
/*
* Initialization of a JPEG decompression object.
* The error manager must already be set up (in case memory manager fails).
*/
GLOBAL(void)
jpeg_CreateDecompress (j_decompress_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_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;
/* 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->src = 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;
}
/* Initialize marker processor so application can override methods
* for COM, APPn markers before calling jpeg_read_header.
*/
cinfo->marker_list = NULL;
jinit_marker_reader(cinfo);
/* And initialize the overall input controller. */
jinit_input_controller(cinfo);
/* OK, I'm ready */
cinfo->global_state = DSTATE_START;
}
/*
* Destruction of a JPEG decompression object
*/
GLOBAL(void)
jpeg_destroy_decompress (j_decompress_ptr cinfo)
{
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
}
/*
* 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 */
}
/*
* Set default decompression parameters.
*/
LOCAL(void)
default_decompress_parms (j_decompress_ptr cinfo)
{
/* Guess the input colorspace, and set output colorspace accordingly. */
/* (Wish JPEG committee had provided a real way to specify this...) */
/* Note application may override our guesses. */
switch (cinfo->num_components) {
case 1:
cinfo->jpeg_color_space = JCS_GRAYSCALE;
cinfo->out_color_space = JCS_GRAYSCALE;
break;
case 3:
if (cinfo->saw_JFIF_marker) {
cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
} else if (cinfo->saw_Adobe_marker) {
switch (cinfo->Adobe_transform) {
case 0:
cinfo->jpeg_color_space = JCS_RGB;
break;
case 1:
cinfo->jpeg_color_space = JCS_YCbCr;
break;
default:
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
break;
}
} else {
/* Saw no special markers, try to guess from the component IDs */
int cid0 = cinfo->comp_info[0].component_id;
int cid1 = cinfo->comp_info[1].component_id;
int cid2 = cinfo->comp_info[2].component_id;
if (cid0 == 1 && cid1 == 2 && cid2 == 3)
cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
else {
TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
}
}
/* Always guess RGB is proper output colorspace. */
cinfo->out_color_space = JCS_RGB;
break;
case 4:
if (cinfo->saw_Adobe_marker) {
switch (cinfo->Adobe_transform) {
case 0:
cinfo->jpeg_color_space = JCS_CMYK;
break;
case 2:
cinfo->jpeg_color_space = JCS_YCCK;
break;
default:
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
break;
}
} else {
/* No special markers, assume straight CMYK. */
cinfo->jpeg_color_space = JCS_CMYK;
}
cinfo->out_color_space = JCS_CMYK;
break;
default:
cinfo->jpeg_color_space = JCS_UNKNOWN;
cinfo->out_color_space = JCS_UNKNOWN;
break;
}
/* Set defaults for other decompression parameters. */
cinfo->scale_num = 1; /* 1:1 scaling */
cinfo->scale_denom = 1;
cinfo->output_gamma = 1.0;
cinfo->dct_method = JDCT_DEFAULT;
cinfo->do_fancy_upsampling = TRUE;
cinfo->do_block_smoothing = TRUE;
}
/*
* Decompression startup: read start of JPEG datastream to see what's there.
* Need only initialize JPEG object and supply a data source before calling.
*
* This routine will read as far as the first SOS marker (ie, actual start of
* compressed data), and will save all tables and parameters in the JPEG
* object. It will also initialize the decompression parameters to default
* values, and finally return JPEG_HEADER_OK. On return, the application may
* adjust the decompression parameters and then call jpeg_start_decompress.
* (Or, if the application only wanted to determine the image parameters,
* the data need not be decompressed. In that case, call jpeg_abort or
* jpeg_destroy to release any temporary space.)
* If an abbreviated (tables only) datastream is presented, the routine will
* return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
* re-use the JPEG object to read the abbreviated image datastream(s).
* It is unnecessary (but OK) to call jpeg_abort in this case.
* The JPEG_SUSPENDED return code only occurs if the data source module
* requests suspension of the decompressor. In this case the application
* should load more source data and then re-call jpeg_read_header to resume
* 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)
jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
{
int retcode;
if (cinfo->global_state != DSTATE_START &&
cinfo->global_state != DSTATE_INHEADER)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
retcode = jpeg_consume_input(cinfo);
switch (retcode) {
case JPEG_REACHED_SOS:
retcode = JPEG_HEADER_OK;
break;
case JPEG_REACHED_EOI:
if (require_image) /* Complain if application wanted an image */
ERREXIT(cinfo, JERR_NO_IMAGE);
/* 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).
*/
jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
retcode = JPEG_HEADER_TABLES_ONLY;
break;
case JPEG_SUSPENDED:
/* no work */
break;
}
return retcode;
}
/*
* 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.
*
* 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(int)
jpeg_consume_input (j_decompress_ptr cinfo)
{
int retcode = JPEG_SUSPENDED;
/* 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;
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_BUFPOST:
case DSTATE_STOPPING:
retcode = (*cinfo->inputctl->consume_input) (cinfo);
break;
default:
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
}
return retcode;
}
/*
* Finish JPEG decompression.
*
* This will normally just verify the file trailer and release temp storage.
*
* Returns FALSE if suspended. The return value need be inspected only if
* a suspending data source is used.
*/
GLOBAL(boolean)
jpeg_finish_decompress (j_decompress_ptr cinfo)
{
if (cinfo->global_state == DSTATE_SCANNING) {
/* Terminate final pass of non-buffered mode */
if (cinfo->output_scanline < cinfo->output_height)
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
(*cinfo->master->finish_output_pass) (cinfo);
cinfo->global_state = DSTATE_STOPPING;
} else if (cinfo->global_state != DSTATE_STOPPING) {
/* STOPPING = repeat call after a suspension, anything else is error */
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
}
/* 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);
/* We can use jpeg_abort to release memory and reset global_state */
jpeg_abort((j_common_ptr) cinfo);
return TRUE;
}

144
jpeg-6b/jdapistd.c Normal file
View file

@ -0,0 +1,144 @@
/*
* 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);
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;
}
/* Ready for application to drive output pass through
* jpeg_read_scanlines or jpeg_read_raw_data.
*/
cinfo->global_state = 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;
}

212
jpeg-6b/jdatasrc.c Normal file
View file

@ -0,0 +1,212 @@
/*
* jdatasrc.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 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.
* 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.
*/
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
#include "jinclude.h"
#include "jpeglib.h"
#include "jerror.h"
/* Expanded data source object for stdio input */
typedef struct {
struct jpeg_source_mgr pub; /* public fields */
FILE * infile; /* source stream */
JOCTET * buffer; /* start of buffer */
boolean start_of_file; /* have we gotten any data yet? */
} my_source_mgr;
typedef my_source_mgr * my_src_ptr;
#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
/*
* Initialize source --- called by jpeg_read_header
* before any data is actually read.
*/
METHODDEF(void)
init_source (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
/* We reset the empty-input-file flag for each image,
* but we don't clear the input buffer.
* This is correct behavior for reading a series of images from one source.
*/
src->start_of_file = TRUE;
}
/*
* Fill the input buffer --- called whenever buffer is emptied.
*
* In typical applications, this should read fresh data into the buffer
* (ignoring the current state of next_input_byte & bytes_in_buffer),
* reset the pointer & count to the start of the buffer, and return TRUE
* indicating that the buffer has been reloaded. It is not necessary to
* fill the buffer entirely, only to obtain at least one more byte.
*
* There is no such thing as an EOF return. If the end of the file has been
* reached, the routine has a choice of ERREXIT() or inserting fake data into
* the buffer. In most cases, generating a warning message and inserting a
* fake EOI marker is the best course of action --- this will allow the
* decompressor to output however much of the image is there. However,
* the resulting error message is misleading if the real problem is an empty
* input file, so we handle that case specially.
*
* In applications that need to be able to suspend compression due to input
* not being available yet, a FALSE return indicates that no more data can be
* obtained right now, but more may be forthcoming later. In this situation,
* the decompressor will return to its caller (with an indication of the
* number of scanlines it has read, if any). The application should resume
* decompression after it has loaded more data into the input buffer. Note
* that there are substantial restrictions on the use of suspension --- see
* the documentation.
*
* When suspending, the decompressor will back up to a convenient restart point
* (typically the start of the current MCU). next_input_byte & bytes_in_buffer
* indicate where the restart point will be if the current call returns FALSE.
* Data beyond this point must be rescanned after resumption, so move it to
* the front of the buffer rather than discarding it.
*/
METHODDEF(boolean)
fill_input_buffer (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
size_t nbytes;
nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
if (nbytes <= 0) {
if (src->start_of_file) /* Treat empty input file as fatal error */
ERREXIT(cinfo, JERR_INPUT_EMPTY);
WARNMS(cinfo, JWRN_JPEG_EOF);
/* Insert a fake EOI marker */
src->buffer[0] = (JOCTET) 0xFF;
src->buffer[1] = (JOCTET) JPEG_EOI;
nbytes = 2;
}
src->pub.next_input_byte = src->buffer;
src->pub.bytes_in_buffer = nbytes;
src->start_of_file = FALSE;
return TRUE;
}
/*
* Skip data --- used to skip over a potentially large amount of
* uninteresting data (such as an APPn marker).
*
* Writers of suspendable-input applications must note that skip_input_data
* is not granted the right to give a suspension return. If the skip extends
* beyond the data currently in the buffer, the buffer can be marked empty so
* that the next read will cause a fill_input_buffer call that can suspend.
* Arranging for additional bytes to be discarded before reloading the input
* buffer is the application writer's problem.
*/
METHODDEF(void)
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
my_src_ptr src = (my_src_ptr) 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);
/* 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;
}
}
/*
* An additional method that can be provided by data source modules is the
* resync_to_restart method for error recovery in the presence of RST markers.
* For the moment, this source module just uses the default resync method
* provided by the JPEG library. That method assumes that no backtracking
* is possible.
*/
/*
* Terminate source --- called by jpeg_finish_decompress
* after all data has been read. Often a no-op.
*
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
* application must deal with any cleanup that should happen even
* for error exit.
*/
METHODDEF(void)
term_source (j_decompress_ptr cinfo)
{
/* no work necessary here */
}
/*
* Prepare for input from a stdio stream.
* The caller must have already opened the stream, and is responsible
* for closing it after finishing decompression.
*/
GLOBAL(void)
jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
{
my_src_ptr src;
/* The source object and input buffer are made permanent so that a series
* of JPEG images can be read from the same file by calling jpeg_stdio_src
* only before the first one. (If we discarded the buffer at the end of
* one image, we'd likely lose the start of the next one.)
* This makes it unsafe to use this manager and a different source
* manager serially with the same JPEG object. Caveat programmer.
*/
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(my_source_mgr));
src = (my_src_ptr) cinfo->src;
src->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
INPUT_BUF_SIZE * SIZEOF(JOCTET));
}
src = (my_src_ptr) cinfo->src;
src->pub.init_source = init_source;
src->pub.fill_input_buffer = fill_input_buffer;
src->pub.skip_input_data = skip_input_data;
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->pub.term_source = term_source;
src->infile = infile;
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
src->pub.next_input_byte = NULL; /* until buffer loaded */
}

409
jpeg-6b/jdcoefct.c Normal file
View file

@ -0,0 +1,409 @@
/*
* jdcoefct.c
*
* 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.
*
* 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"
/* Private buffer controller object */
typedef struct {
struct jpeg_d_coef_controller pub; /* public fields */
/* 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 */
/* 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; it is used only by the input side.
*/
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
} my_coef_controller;
typedef my_coef_controller * my_coef_ptr;
/* Forward declarations */
METHODDEF(int) decompress_onepass
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#ifdef D_MULTISCAN_FILES_SUPPORTED
METHODDEF(int) decompress_data
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
#endif
LOCAL(void)
start_iMCU_row (j_decompress_ptr cinfo)
/* Reset within-iMCU-row counters for a new row (input side) */
{
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 (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_vert_offset = 0;
}
/*
* Initialize for an input processing pass.
*/
METHODDEF(void)
start_input_pass (j_decompress_ptr cinfo)
{
cinfo->input_iMCU_row = 0;
start_iMCU_row(cinfo);
}
/*
* Initialize for an output processing pass.
*/
METHODDEF(void)
start_output_pass (j_decompress_ptr cinfo)
{
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 */
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
int blkn, ci, xindex, yindex, yoffset, useful_width;
JSAMPARRAY output_ptr;
JDIMENSION start_col, output_col;
jpeg_component_info *compptr;
inverse_DCT_method_ptr inverse_DCT;
/* 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;
MCU_col_num++) {
/* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
MEMZERO((void *) 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 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
* incremented past them!). Note the inner loop relies on having
* allocated the MCU_buffer[] blocks sequentially.
*/
blkn = 0; /* index of current DCT block within MCU */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* Don't bother to IDCT an uninteresting component. */
if (! compptr->component_needed) {
blkn += compptr->MCU_blocks;
continue;
}
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[compptr->component_index] +
yoffset * compptr->DCT_scaled_size;
start_col = MCU_col_num * compptr->MCU_sample_width;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (cinfo->input_iMCU_row < last_iMCU_row ||
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;
}
}
blkn += compptr->MCU_width;
output_ptr += compptr->DCT_scaled_size;
}
}
}
/* Completed an MCU row, but perhaps not an iMCU row */
coef->MCU_ctr = 0;
}
/* Completed the iMCU row, advance counters for next one */
cinfo->output_iMCU_row++;
if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
start_iMCU_row(cinfo);
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
/*
* 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(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 start_col;
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
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],
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;
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;
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
coef->MCU_buffer[blkn++] = buffer_ptr++;
}
}
}
/* Try to fetch the MCU. */
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 JPEG_SUSPENDED;
}
}
/* Completed an MCU row, but perhaps not an iMCU row */
coef->MCU_ctr = 0;
}
/* Completed the iMCU row, advance counters for next one */
if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
start_iMCU_row(cinfo);
return JPEG_ROW_COMPLETED;
}
/* Completed the scan */
(*cinfo->inputctl->finish_input_pass) (cinfo);
return JPEG_SCAN_COMPLETED;
}
/*
* 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(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;
JDIMENSION block_num;
int ci, block_row, block_rows;
JBLOCKARRAY buffer;
JBLOCKROW buffer_ptr;
JSAMPARRAY output_ptr;
JDIMENSION output_col;
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. */
if (! compptr->component_needed)
continue;
/* Align the virtual buffer for this component. */
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[ci],
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 (cinfo->output_iMCU_row < last_iMCU_row)
block_rows = compptr->v_samp_factor;
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;
}
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];
output_col = 0;
for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
output_ptr, output_col);
buffer_ptr++;
output_col += compptr->DCT_scaled_size;
}
output_ptr += compptr->DCT_scaled_size;
}
}
if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
return JPEG_ROW_COMPLETED;
return JPEG_SCAN_COMPLETED;
}
#endif /* D_MULTISCAN_FILES_SUPPORTED */
/*
* Initialize coefficient buffer controller.
*/
GLOBAL(void)
jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
my_coef_ptr coef;
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_input_pass = start_input_pass;
coef->pub.start_output_pass = start_output_pass;
/* 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 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;
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
(long) compptr->h_samp_factor),
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor),
(JDIMENSION) 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_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,
D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
coef->MCU_buffer[i] = buffer + i;
}
coef->pub.consume_data = dummy_consume_data;
coef->pub.decompress_data = decompress_onepass;
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
}
}

393
jpeg-6b/jdcolor.c Normal file
View file

@ -0,0 +1,393 @@
/*
* jdcolor.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 output colorspace conversion routines.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Private subobject */
typedef struct {
struct jpeg_color_deconverter pub; /* public fields */
/* Private state for YCC->RGB conversion */
int * Cr_r_tab; /* => table for Cr to R conversion */
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 */
} my_color_deconverter;
typedef my_color_deconverter * my_cconvert_ptr;
/**************** YCbCr -> RGB conversion: most 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
* where Cb and Cr represent the incoming values less CENTERJSAMPLE.
* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
*
* To avoid floating-point arithmetic, we represent the fractional constants
* as integers scaled up by 2^16 (about 4 digits precision); we have to divide
* the products by 2^16, with appropriate rounding, to get the correct answer.
* Notice that Y, being an integral input, does not contribute any fraction
* so it need not participate in the rounding.
*
* For even more speed, we avoid doing any multiplications in the inner loop
* by precalculating the constants times Cb and Cr for all possible values.
* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
* for 12-bit samples it is still acceptable. It's not very reasonable for
* 16-bit samples, but if you want lossless storage you shouldn't be changing
* colorspace anyway.
* The Cr=>R and Cb=>B values can be rounded to integers in advance; the
* values for the G calculation are left scaled up, since we must add them
* together before rounding.
*/
#define SCALEBITS 16 /* speediest right-shift on some machines */
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
/*
* 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;
int i;
INT32 x;
SHIFT_TEMPS
cconvert->Cr_r_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
cconvert->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
cconvert->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 1.40200 * x */
cconvert->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
/* Cb=>B value is nearest int to 1.77200 * x */
cconvert->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
/* Cr=>G value is scaled-up -0.71414 * x */
cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
/* Cb=>G value is scaled-up -0.34414 * x */
/* We also add in ONE_HALF so that need not do it in inner loop */
cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
}
}
/*
* Convert some rows of samples to the output colorspace.
*
* Note that we change from noninterleaved, one-plane-per-component format
* to interleaved-pixel format. The output buffer is therefore three times
* as wide as the input buffer.
* A starting row offset is provided only for the input buffer. The caller
* can easily adjust the passed output_buf value to accommodate any row
* offset required on that side.
*/
METHODDEF(void)
ycc_rgb_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 y, cb, cr;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
/* copy these pointers into registers if possible */
register JSAMPLE * range_limit = cinfo->sample_range_limit;
register int * Crrtab = cconvert->Cr_r_tab;
register int * Cbbtab = cconvert->Cb_b_tab;
register INT32 * Crgtab = cconvert->Cr_g_tab;
register INT32 * Cbgtab = cconvert->Cb_g_tab;
SHIFT_TEMPS
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++) {
y = GETJSAMPLE(inptr0[col]);
cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]);
/* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
outptr[RGB_GREEN] = range_limit[y +
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
outptr += RGB_PIXELSIZE;
}
}
}
/**************** Cases other than YCbCr -> RGB **************/
/*
* Color conversion for no colorspace change: just copy the data,
* converting from separate-planes to interleaved representation.
*/
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->num_components;
JDIMENSION num_cols = cinfo->output_width;
int ci;
while (--num_rows >= 0) {
for (ci = 0; ci < num_components; ci++) {
inptr = input_buf[ci][input_row];
outptr = output_buf[0] + ci;
for (count = num_cols; count > 0; count--) {
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
outptr += num_components;
}
}
input_row++;
output_buf++;
}
}
/*
* Color conversion for grayscale: just copy the data.
* This also works for YCbCr -> grayscale conversion, in which
* we just copy the Y (luminance) component and ignore chrominance.
*/
METHODDEF(void)
grayscale_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
num_rows, cinfo->output_width);
}
/*
* 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 build_ycc_rgb_table has been called.
*/
METHODDEF(void)
ycck_cmyk_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 y, cb, cr;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2, inptr3;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
/* copy these pointers into registers if possible */
register JSAMPLE * range_limit = cinfo->sample_range_limit;
register int * Crrtab = cconvert->Cr_r_tab;
register int * Cbbtab = cconvert->Cb_b_tab;
register INT32 * Crgtab = cconvert->Cr_g_tab;
register INT32 * Cbgtab = cconvert->Cb_g_tab;
SHIFT_TEMPS
while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
inptr3 = input_buf[3][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
y = GETJSAMPLE(inptr0[col]);
cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]);
/* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS)))];
outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
/* K passes through unchanged */
outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
outptr += 4;
}
}
}
/*
* Empty method for start_pass.
*/
METHODDEF(void)
start_pass_dcolor (j_decompress_ptr cinfo)
{
/* no work needed */
}
/*
* Module initialization routine for output colorspace conversion.
*/
GLOBAL(void)
jinit_color_deconverter (j_decompress_ptr cinfo)
{
my_cconvert_ptr cconvert;
int ci;
cconvert = (my_cconvert_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_color_deconverter));
cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
cconvert->pub.start_pass = start_pass_dcolor;
/* Make sure num_components agrees with jpeg_color_space */
switch (cinfo->jpeg_color_space) {
case JCS_GRAYSCALE:
if (cinfo->num_components != 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
break;
case JCS_RGB:
case JCS_YCbCr:
if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
break;
case JCS_CMYK:
case JCS_YCCK:
if (cinfo->num_components != 4)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
break;
default: /* JCS_UNKNOWN can be anything */
if (cinfo->num_components < 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
break;
}
/* Set out_color_components and conversion method based on requested space.
* Also clear the component_needed flags for any unused components,
* so that earlier pipeline stages can avoid useless computation.
*/
switch (cinfo->out_color_space) {
case JCS_GRAYSCALE:
cinfo->out_color_components = 1;
if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
cinfo->jpeg_color_space == JCS_YCbCr) {
cconvert->pub.color_convert = grayscale_convert;
/* 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
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
case JCS_RGB:
cinfo->out_color_components = RGB_PIXELSIZE;
if (cinfo->jpeg_color_space == JCS_YCbCr) {
cconvert->pub.color_convert = ycc_rgb_convert;
build_ycc_rgb_table(cinfo);
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
cconvert->pub.color_convert = gray_rgb_convert;
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
cconvert->pub.color_convert = null_convert;
} else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
case JCS_CMYK:
cinfo->out_color_components = 4;
if (cinfo->jpeg_color_space == JCS_YCCK) {
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
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
default:
/* Permit null conversion to same output space */
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
cinfo->out_color_components = cinfo->num_components;
cconvert->pub.color_convert = null_convert;
} else /* unsupported non-null conversion */
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
}
cinfo->output_components = cinfo->out_color_components;
}

164
jpeg-6b/jdct.h Normal file
View file

@ -0,0 +1,164 @@
/*
* jdct.h
*
* 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 include file contains common declarations for the forward and
* inverse DCT modules. These declarations are private to the DCT managers
* (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
* The individual DCT algorithms are kept in separate files to ease
* machine-dependent tuning (e.g., assembly coding).
*/
/*
* 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).
* 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
* work in floating-point ones.
* Quantization of the output coefficients is done by jcdctmgr.c.
*/
#if BITS_IN_JSAMPLE == 8
typedef int DCTELEM; /* 16 or 32 bits is fine */
#else
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));
/*
* An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
* to an output sample array. The routine must dequantize the input data as
* well as perform the IDCT; for dequantization, it uses the multiplier table
* pointed to by compptr->dct_table. The output data is to be placed into 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 IDCT code.)
* Note that the number of samples emitted by the IDCT routine is
* DCT_scaled_size * DCT_scaled_size.
*/
/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
/*
* Each IDCT routine has its own ideas about the best dct_table element type.
*/
typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
#if BITS_IN_JSAMPLE == 8
typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */
#else
typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */
#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */
#endif
typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
/*
* Each IDCT routine is responsible for range-limiting its results and
* converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
* be quite far out of range if the input data is corrupt, so a bulletproof
* range-limiting step is required. We use a mask-and-table-lookup method
* to do the combined operations quickly. See the comments with
* prepare_range_limit_table (in jdmaster.c) for more info.
*/
#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE)
#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
/* Short forms of external names for systems with brain-damaged linkers. */
/* 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_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
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
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
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));
/*
* Macros for handling fixed-point arithmetic; these are used by many
* but not all of the DCT/IDCT modules.
*
* All values are expected to be of type INT32.
* Fractional constants are scaled left by CONST_BITS bits.
* CONST_BITS is defined within each module using these macros,
* and may differ from one module to the next.
*/
#define ONE ((INT32) 1)
#define CONST_SCALE (ONE << CONST_BITS)
/* Convert a positive real constant to an integer scaled by CONST_SCALE.
* Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
* thus causing a lot of useless floating-point operations at run time.
*/
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
/* Descale and correctly round an INT32 value that's scaled by N bits.
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
* the fudge factor is correct for either sign of X.
*/
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
* This macro is used only when the two inputs will actually be no more than
* 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
* full 32x32 multiply. This provides a useful speedup on many machines.
* Unfortunately there is no way to specify a 16x16->32 multiply portably
* in C, but some C compilers will do the right thing if you provide the
* correct combination of casts.
*/
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const)))
#endif
#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const)))
#endif
#ifndef MULTIPLY16C16 /* default definition */
#define MULTIPLY16C16(var,const) ((var) * (const))
#endif
/* Same except both inputs are variables. */
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2)))
#endif
#ifndef MULTIPLY16V16 /* default definition */
#define MULTIPLY16V16(var1,var2) ((var1) * (var2))
#endif

172
jpeg-6b/jddctmgr.c Normal file
View file

@ -0,0 +1,172 @@
/*
* jddctmgr.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 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 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
* dequantization multiplier table needed by the IDCT routine.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#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 */
/* 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;
/* Allocated multiplier tables: big enough for any supported variant */
typedef union {
ISLOW_MULT_TYPE islow_array[DCTSIZE2];
} multiplier_table;
/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
* so be sure to compile that code if either ISLOW or SCALING is requested.
*/
#ifdef DCT_ISLOW_SUPPORTED
#define PROVIDE_ISLOW_TABLES
#endif
/*
* Prepare for an output pass.
* Here we select the proper IDCT routine for each component and build
* a matching multiplier table.
*/
METHODDEF(void)
start_pass (j_decompress_ptr cinfo)
{
my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
int ci, i;
jpeg_component_info *compptr;
int method = 0;
inverse_DCT_method_ptr method_ptr = NULL;
JQUANT_TBL * qtbl;
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_scaled_size) {
case DCTSIZE:
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
method_ptr = jpeg_idct_islow;
method = JDCT_ISLOW;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
break;
default:
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_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;
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 as ints to ensure access efficiency.
*/
ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
for (i = 0; i < DCTSIZE2; i++) {
ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
}
}
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
}
}
/*
* Initialize IDCT manager.
*/
GLOBAL(void)
jinit_inverse_dct (j_decompress_ptr cinfo)
{
my_idct_ptr idct;
int ci;
jpeg_component_info *compptr;
idct = (my_idct_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_idct_controller));
cinfo->idct = (struct jpeg_inverse_dct *) idct;
idct->pub.start_pass = start_pass;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* 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;
}
}

651
jpeg-6b/jdhuff.c Normal file
View file

@ -0,0 +1,651 @@
/*
* jdhuff.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 Huffman entropy decoding routines.
*
* Much of the complexity here has to do with supporting input suspension.
* If the data source module demands suspension, we want to be able to back
* up to the start of the current MCU. To do this, we copy state variables
* into local working storage, and update them back to the permanent
* storage only upon successful completion of an MCU.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jdhuff.h" /* Declarations shared with jdphuff.c */
/*
* Expanded entropy decoder object for Huffman decoding.
*
* The savable_state subrecord contains fields that change within an MCU,
* but must not be updated permanently until we complete the MCU.
*/
typedef struct {
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
} savable_state;
/* This macro is to work around compilers with missing or broken
* structure assignment. You'll need to fix this code if you have
* such a compiler and you change MAX_COMPS_IN_SCAN.
*/
#ifndef NO_STRUCT_ASSIGN
#define ASSIGN_STATE(dest,src) ((dest) = (src))
#else
#if MAX_COMPS_IN_SCAN == 4
#define ASSIGN_STATE(dest,src) \
((dest).last_dc_val[0] = (src).last_dc_val[0], \
(dest).last_dc_val[1] = (src).last_dc_val[1], \
(dest).last_dc_val[2] = (src).last_dc_val[2], \
(dest).last_dc_val[3] = (src).last_dc_val[3])
#endif
#endif
typedef struct {
struct jpeg_entropy_decoder pub; /* public fields */
/* These fields are loaded into local variables at start of each MCU.
* In case of suspension, we exit WITHOUT updating them.
*/
bitread_perm_state bitstate; /* Bit buffer at start of MCU */
savable_state saved; /* Other state at start of MCU */
/* These fields are NOT loaded into local working state. */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
/* Pointers to derived tables (these workspaces have image lifespan) */
d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
/* Precalculated info set up by start_pass for use in decode_mcu: */
/* Pointers to derived tables to be used for each block within an MCU */
d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
/* Whether we care about the DC and AC coefficient values for each block */
boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
} huff_entropy_decoder;
typedef huff_entropy_decoder * huff_entropy_ptr;
/*
* Initialize for a Huffman-compressed scan.
*/
METHODDEF(void)
start_pass_huff_decoder (j_decompress_ptr cinfo)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int ci, blkn, dctbl, actbl;
jpeg_component_info * compptr;
/* 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 because
* there are some baseline files out there with all zeroes in these bytes.
*/
if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
cinfo->Ah != 0 || cinfo->Al != 0)
WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no;
actbl = compptr->ac_tbl_no;
/* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */
jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
& entropy->dc_derived_tbls[dctbl]);
jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
& entropy->ac_derived_tbls[actbl]);
/* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 0;
}
/* Precalculate decoding info for each block in an MCU of this scan */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Precalculate which table to use for each block */
entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
/* Decide whether we really care about the coefficient values */
if (compptr->component_needed) {
entropy->dc_needed[blkn] = TRUE;
/* we don't need the ACs if producing a 1/8th-size image */
entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
} else {
entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
}
}
/* Initialize bitread state variables */
entropy->bitstate.bits_left = 0;
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
entropy->pub.insufficient_data = FALSE;
/* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
}
/*
* Compute the derived values for a Huffman table.
* This routine also performs some validation checks on the table.
*
* Note this is also used by jdphuff.c.
*/
GLOBAL(void)
jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
d_derived_tbl ** pdtbl)
{
JHUFF_TBL *htbl;
d_derived_tbl *dtbl;
int p, i, l, si, numsymbols;
int lookbits, ctr;
char huffsize[257];
unsigned int huffcode[257];
unsigned int code;
/* Note that huffsize[] and huffcode[] are filled in code-length order,
* paralleling the order of the symbols themselves in htbl->huffval[].
*/
/* Find the input Huffman table */
if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
htbl =
isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
if (htbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
/* Allocate a workspace if we haven't already done so. */
if (*pdtbl == NULL)
*pdtbl = (d_derived_tbl *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(d_derived_tbl));
dtbl = *pdtbl;
dtbl->pub = htbl; /* fill in back link */
/* Figure C.1: make table of Huffman code length for each symbol */
p = 0;
for (l = 1; l <= 16; l++) {
i = (int) htbl->bits[l];
if (i < 0 || p + i > 256) /* protect against table overrun */
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
while (i--)
huffsize[p++] = (char) l;
}
huffsize[p] = 0;
numsymbols = p;
/* Figure C.2: generate the codes themselves */
/* We also validate that the counts represent a legal Huffman code tree. */
code = 0;
si = huffsize[0];
p = 0;
while (huffsize[p]) {
while (((int) huffsize[p]) == si) {
huffcode[p++] = code;
code++;
}
/* code is now 1 more than the last code used for codelength si; but
* it must still fit in si bits, since no code is allowed to be all ones.
*/
if (((INT32) code) >= (((INT32) 1) << si))
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
code <<= 1;
si++;
}
/* Figure F.15: generate decoding tables for bit-sequential decoding */
p = 0;
for (l = 1; l <= 16; l++) {
if (htbl->bits[l]) {
/* valoffset[l] = huffval[] index of 1st symbol of code length l,
* minus the minimum code of length l
*/
dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
p += htbl->bits[l];
dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
} else {
dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
}
}
dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
/* Compute lookahead tables to speed up decoding.
* First we set all the table entries to 0, indicating "too long";
* then we iterate through the Huffman codes that are short enough and
* fill in all the entries that correspond to bit sequences starting
* with that code.
*/
MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
p = 0;
for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
/* l = current code's length, p = its index in huffcode[] & huffval[]. */
/* Generate left-justified code followed by all possible bit sequences */
lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
dtbl->look_nbits[lookbits] = l;
dtbl->look_sym[lookbits] = htbl->huffval[p];
lookbits++;
}
}
}
/* Validate symbols as being reasonable.
* For AC tables, we make no check, but accept all byte values 0..255.
* For DC tables, we require the symbols to be in range 0..15.
* (Tighter bounds could be applied depending on the data depth and mode,
* but this is sufficient to ensure safe decoding.)
*/
if (isDC) {
for (i = 0; i < numsymbols; i++) {
int sym = htbl->huffval[i];
if (sym < 0 || sym > 15)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
}
}
}
/*
* Out-of-line code for bit fetching (shared with jdphuff.c).
* See jdhuff.h for info about usage.
* Note: current values of get_buffer and bits_left are passed as parameters,
* but are returned in the corresponding fields of the state struct.
*
* On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
* of get_buffer to be used. (On machines with wider words, an even larger
* buffer could be used.) However, on some machines 32-bit shifts are
* quite slow and take time proportional to the number of places shifted.
* (This is true with most PC compilers, for instance.) In this case it may
* be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the
* average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
*/
#ifdef SLOW_SHIFT_32
#define MIN_GET_BITS 15 /* minimum allowable value */
#else
#define MIN_GET_BITS (BIT_BUF_SIZE-7)
#endif
GLOBAL(boolean)
jpeg_fill_bit_buffer (bitread_working_state * state,
register bit_buf_type get_buffer, register int bits_left,
int nbits)
/* Load up the bit buffer to a depth of at least nbits */
{
/* Copy heavily used state fields into locals (hopefully registers) */
register const JOCTET * next_input_byte = state->next_input_byte;
register size_t bytes_in_buffer = state->bytes_in_buffer;
j_decompress_ptr cinfo = state->cinfo;
/* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
/* (It is assumed that no request will be for more than that many bits.) */
/* We fail to do so only if we hit a marker or are forced to suspend. */
if (cinfo->unread_marker == 0) { /* cannot advance past a marker */
while (bits_left < MIN_GET_BITS) {
register int c;
/* Attempt to read a byte */
if (bytes_in_buffer == 0) {
if (! (*cinfo->src->fill_input_buffer) (cinfo))
return FALSE;
next_input_byte = cinfo->src->next_input_byte;
bytes_in_buffer = cinfo->src->bytes_in_buffer;
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
/* If it's 0xFF, check and discard stuffed zero byte */
if (c == 0xFF) {
/* Loop here to discard any padding FF's on terminating marker,
* so that we can save a valid unread_marker value. NOTE: we will
* accept multiple FF's followed by a 0 as meaning a single FF data
* byte. This data pattern is not valid according to the standard.
*/
do {
if (bytes_in_buffer == 0) {
if (! (*cinfo->src->fill_input_buffer) (cinfo))
return FALSE;
next_input_byte = cinfo->src->next_input_byte;
bytes_in_buffer = cinfo->src->bytes_in_buffer;
}
bytes_in_buffer--;
c = GETJOCTET(*next_input_byte++);
} while (c == 0xFF);
if (c == 0) {
/* Found FF/00, which represents an FF data byte */
c = 0xFF;
} else {
/* Oops, it's actually a marker indicating end of compressed data.
* Save the marker code for later use.
* Fine point: it might appear that we should save the marker into
* bitread working state, not straight into permanent state. But
* once we have hit a marker, we cannot need to suspend within the
* current MCU, because we will read no more bytes from the data
* source. So it is OK to update permanent state right away.
*/
cinfo->unread_marker = c;
/* See if we need to insert some fake zero bits. */
goto no_more_bytes;
}
}
/* OK, load c into get_buffer */
get_buffer = (get_buffer << 8) | c;
bits_left += 8;
} /* end while */
} else {
no_more_bytes:
/* We get here if we've read the marker that terminates the compressed
* data segment. There should be enough bits in the buffer register
* to satisfy the request; if so, no problem.
*/
if (nbits > bits_left) {
/* Uh-oh. Report corrupted data to user and stuff zeroes into
* the data stream, so that we can produce some kind of image.
* We use a nonvolatile flag to ensure that only one warning message
* appears per data segment.
*/
if (! cinfo->entropy->insufficient_data) {
WARNMS(cinfo, JWRN_HIT_MARKER);
cinfo->entropy->insufficient_data = TRUE;
}
/* Fill the buffer with zero bits */
get_buffer <<= MIN_GET_BITS - bits_left;
bits_left = MIN_GET_BITS;
}
}
/* Unload the local registers */
state->next_input_byte = next_input_byte;
state->bytes_in_buffer = bytes_in_buffer;
state->get_buffer = get_buffer;
state->bits_left = bits_left;
return TRUE;
}
/*
* Out-of-line code for Huffman code decoding.
* See jdhuff.h for info about usage.
*/
GLOBAL(int)
jpeg_huff_decode (bitread_working_state * state,
register bit_buf_type get_buffer, register int bits_left,
d_derived_tbl * htbl, int min_bits)
{
register int l = min_bits;
register INT32 code;
/* HUFF_DECODE has determined that the code is at least min_bits */
/* bits long, so fetch that many bits in one swoop. */
CHECK_BIT_BUFFER(*state, l, return -1);
code = GET_BITS(l);
/* Collect the rest of the Huffman code one bit at a time. */
/* This is per Figure F.16 in the JPEG spec. */
while (code > htbl->maxcode[l]) {
code <<= 1;
CHECK_BIT_BUFFER(*state, 1, return -1);
code |= GET_BITS(1);
l++;
}
/* Unload the local registers */
state->get_buffer = get_buffer;
state->bits_left = bits_left;
/* With garbage input we may reach the sentinel value l = 17. */
if (l > 16) {
WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
return 0; /* fake a zero as the safest result */
}
return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
}
/*
* Figure F.12: extend sign bit.
* On some machines, a shift and add will be faster than a table lookup.
*/
#ifdef AVOID_TABLES
#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
#else
#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
static const int extend_test[16] = /* entry n is 2**(n-1) */
{ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
{ 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
#endif /* AVOID_TABLES */
/*
* Check for a restart marker & resynchronize decoder.
* Returns FALSE if must suspend.
*/
LOCAL(boolean)
process_restart (j_decompress_ptr cinfo)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int ci;
/* Throw away any unused bits remaining in bit buffer; */
/* include any full bytes in next_marker's count of discarded bytes */
cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
entropy->bitstate.bits_left = 0;
/* Advance past the RSTn marker */
if (! (*cinfo->marker->read_restart_marker) (cinfo))
return FALSE;
/* Re-initialize DC predictions to 0 */
for (ci = 0; ci < cinfo->comps_in_scan; ci++)
entropy->saved.last_dc_val[ci] = 0;
/* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
/* Reset out-of-data flag, unless read_restart_marker left us smack up
* against a marker. In that case we will end up treating the next data
* segment as empty, and we can avoid producing bogus output pixels by
* leaving the flag set.
*/
if (cinfo->unread_marker == 0)
entropy->pub.insufficient_data = FALSE;
return TRUE;
}
/*
* Decode and return one MCU's worth of Huffman-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 HAS BEEN ZEROED BY THE CALLER.
* (Wholesale zeroing is usually a little faster than retail...)
*
* Returns FALSE if data source requested suspension. In that case no
* changes have been made to permanent state. (Exception: some output
* coefficients may already have been assigned. This is harmless for
* this module, since we'll just re-assign them on the next call.)
*/
METHODDEF(boolean)
decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int blkn;
BITREAD_STATE_VARS;
savable_state state;
/* Process restart marker if needed; may have to suspend */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
if (! process_restart(cinfo))
return FALSE;
}
/* If we've run out of data, just leave the MCU set to zeroes.
* This way, we return uniform gray for the remainder of the segment.
*/
if (! entropy->pub.insufficient_data) {
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
JBLOCKROW block = MCU_data[blkn];
d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
register int s, k, r;
/* Decode a single block's worth of coefficients */
/* Section F.2.2.1: decode the DC coefficient difference */
HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
if (s) {
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
}
if (entropy->dc_needed[blkn]) {
/* Convert DC difference to actual value, update last_dc_val */
int ci = cinfo->MCU_membership[blkn];
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
/* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
(*block)[0] = (JCOEF) s;
}
if (entropy->ac_needed[blkn]) {
/* Section F.2.2.2: decode the AC coefficients */
/* Since zeroes are skipped, output area must be cleared beforehand */
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
/* Output coefficient in natural (dezigzagged) order.
* Note: the extra entries in jpeg_natural_order[] will save us
* if k >= DCTSIZE2, which could happen if the data is corrupted.
*/
(*block)[jpeg_natural_order[k]] = (JCOEF) s;
} else {
if (r != 15)
break;
k += 15;
}
}
} else {
/* Section F.2.2.2: decode the AC coefficients */
/* In this path we just discard the values */
for (k = 1; k < DCTSIZE2; k++) {
HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
DROP_BITS(s);
} else {
if (r != 15)
break;
k += 15;
}
}
}
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
return TRUE;
}
/*
* Module initialization routine for Huffman entropy decoding.
*/
GLOBAL(void)
jinit_huff_decoder (j_decompress_ptr cinfo)
{
huff_entropy_ptr entropy;
int i;
entropy = (huff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(huff_entropy_decoder));
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
entropy->pub.start_pass = start_pass_huff_decoder;
entropy->pub.decode_mcu = decode_mcu;
/* Mark tables unallocated */
for (i = 0; i < NUM_HUFF_TBLS; i++) {
entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
}
}

194
jpeg-6b/jdhuff.h Normal file
View file

@ -0,0 +1,194 @@
/*
* jdhuff.h
*
* 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 declarations for Huffman entropy decoding routines
* that are shared between the sequential decoder (jdhuff.c) and the
* progressive decoder (jdphuff.c). No other modules need to see these.
*/
/* Short forms of external names for systems with brain-damaged linkers. */
/* Derived data constructed for each Huffman table */
#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
typedef struct {
/* Basic tables: (element [0] of each array is unused) */
INT32 maxcode[18]; /* largest code of length k (-1 if none) */
/* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
INT32 valoffset[17]; /* huffval[] offset for codes of length k */
/* valoffset[k] = huffval[] index of 1st symbol of code length k, less
* the smallest code of length k; so given a code of length k, the
* corresponding symbol is huffval[code + valoffset[k]]
*/
/* Link to public Huffman table (needed only in jpeg_huff_decode) */
JHUFF_TBL *pub;
/* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
* the input data stream. If the next Huffman code is no more
* than HUFF_LOOKAHEAD bits long, we can obtain its length and
* the corresponding symbol directly from these tables.
*/
int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
} d_derived_tbl;
/* Expand a Huffman table definition into the derived format */
EXTERN(void) jpeg_make_d_derived_tbl
JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
d_derived_tbl ** pdtbl));
/*
* Fetching the next N bits from the input stream is a time-critical operation
* for the Huffman decoders. We implement it with a combination of inline
* macros and out-of-line subroutines. Note that N (the number of bits
* demanded at one time) never exceeds 15 for JPEG use.
*
* We read source bytes into get_buffer and dole out bits as needed.
* If get_buffer already contains enough bits, they are fetched in-line
* by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough
* bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
* as full as possible (not just to the number of bits needed; this
* prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
* Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
* On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
* at least the requested number of bits --- dummy zeroes are inserted if
* necessary.
*/
typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
#define BIT_BUF_SIZE 32 /* size of buffer in bits */
/* If long is > 32 bits on your machine, and shifting/masking longs is
* reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
* appropriately should be a win. Unfortunately we can't define the size
* with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
* because not all machines measure sizeof in 8-bit bytes.
*/
typedef struct { /* Bitreading state saved across MCUs */
bit_buf_type get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */
} bitread_perm_state;
typedef struct { /* Bitreading working state within an MCU */
/* Current data source location */
/* We need a copy, rather than munging the original, in case of suspension */
const JOCTET * next_input_byte; /* => next byte to read from source */
size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
/* Bit input buffer --- note these values are kept in register variables,
* not in this struct, inside the inner loops.
*/
bit_buf_type get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */
/* Pointer needed by jpeg_fill_bit_buffer. */
j_decompress_ptr cinfo; /* back link to decompress master record */
} bitread_working_state;
/* Macros to declare and load/save bitread local variables. */
#define BITREAD_STATE_VARS \
register bit_buf_type get_buffer; \
register int bits_left; \
bitread_working_state br_state
#define BITREAD_LOAD_STATE(cinfop,permstate) \
br_state.cinfo = cinfop; \
br_state.next_input_byte = cinfop->src->next_input_byte; \
br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
get_buffer = permstate.get_buffer; \
bits_left = permstate.bits_left;
#define BITREAD_SAVE_STATE(cinfop,permstate) \
cinfop->src->next_input_byte = br_state.next_input_byte; \
cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
permstate.get_buffer = get_buffer; \
permstate.bits_left = bits_left
/*
* These macros provide the in-line portion of bit fetching.
* Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
* before using GET_BITS, PEEK_BITS, or DROP_BITS.
* The variables get_buffer and bits_left are assumed to be locals,
* but the state struct might not be (jpeg_huff_decode needs this).
* CHECK_BIT_BUFFER(state,n,action);
* Ensure there are N bits in get_buffer; if suspend, take action.
* val = GET_BITS(n);
* Fetch next N bits.
* val = PEEK_BITS(n);
* Fetch next N bits without removing them from the buffer.
* DROP_BITS(n);
* Discard next N bits.
* The value N should be a simple variable, not an expression, because it
* is evaluated multiple times.
*/
#define CHECK_BIT_BUFFER(state,nbits,action) \
{ if (bits_left < (nbits)) { \
if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \
{ action; } \
get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
#define GET_BITS(nbits) \
(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
#define PEEK_BITS(nbits) \
(((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1))
#define DROP_BITS(nbits) \
(bits_left -= (nbits))
/* Load up the bit buffer to a depth of at least nbits */
EXTERN(boolean) jpeg_fill_bit_buffer
JPP((bitread_working_state * state, register bit_buf_type get_buffer,
register int bits_left, int nbits));
/*
* Code for extracting next Huffman-coded symbol from input bit stream.
* Again, this is time-critical and we make the main paths be macros.
*
* We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
* without looping. Usually, more than 95% of the Huffman codes will be 8
* or fewer bits long. The few overlength codes are handled with a loop,
* which need not be inline code.
*
* Notes about the HUFF_DECODE macro:
* 1. Near the end of the data segment, we may fail to get enough bits
* for a lookahead. In that case, we do it the hard way.
* 2. If the lookahead table contains no entry, the next code must be
* more than HUFF_LOOKAHEAD bits long.
* 3. jpeg_huff_decode returns -1 if forced to suspend.
*/
#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
{ register int nb, look; \
if (bits_left < HUFF_LOOKAHEAD) { \
if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
get_buffer = state.get_buffer; bits_left = state.bits_left; \
if (bits_left < HUFF_LOOKAHEAD) { \
nb = 1; goto slowlabel; \
} \
} \
look = PEEK_BITS(HUFF_LOOKAHEAD); \
if ((nb = htbl->look_nbits[look]) != 0) { \
DROP_BITS(nb); \
result = htbl->look_sym[look]; \
} else { \
nb = HUFF_LOOKAHEAD+1; \
slowlabel: \
if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
{ failaction; } \
get_buffer = state.get_buffer; bits_left = state.bits_left; \
} \
}
/* Out-of-line case for Huffman code fetching */
EXTERN(int) jpeg_huff_decode
JPP((bitread_working_state * state, register bit_buf_type get_buffer,
register int bits_left, d_derived_tbl * htbl, int min_bits));

381
jpeg-6b/jdinput.c Normal file
View file

@ -0,0 +1,381 @@
/*
* jdinput.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 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 jdphuff.c.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Private state */
typedef struct {
struct jpeg_input_controller pub; /* public fields */
boolean inheaders; /* TRUE 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.
*/
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);
}
/* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
* In the full decompressor, this will be overridden by jdmaster.c;
* but in the transcoder, jdmaster.c is not used, so we must do it here.
*/
cinfo->min_DCT_scaled_size = DCTSIZE;
/* Compute dimensions of components */
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
compptr->DCT_scaled_size = DCTSIZE;
/* 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));
/* 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*DCTSIZE));
/* 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_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 > 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.
*/
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;
val = (*cinfo->marker->read_markers) (cinfo);
switch (val) {
case JPEG_REACHED_SOS: /* Found SOS */
if (inputctl->inheaders) { /* 1st SOS */
initial_setup(cinfo);
inputctl->inheaders = FALSE;
/* 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! */
start_input_pass(cinfo);
}
break;
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;
}
break;
case JPEG_SUSPENDED:
break;
}
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 = TRUE;
/* 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 = TRUE;
}

480
jpeg-6b/jdmainct.c Normal file
View file

@ -0,0 +1,480 @@
/*
* jdmainct.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 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
#include "jinclude.h"
#include "jpeglib.h"
/*
* In the current system design, the main buffer need never be a full-image
* buffer; any full-height buffers will be found inside the coefficient or
* postprocessing controllers. Nonetheless, the main controller is not
* trivial. Its responsibility is to provide context rows for upsampling/
* rescaling, and doing this in an efficient fashion is a bit tricky.
*
* Postprocessor input data is counted in "row groups". A row group
* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
* sample rows of each component. (We require DCT_scaled_size values to be
* chosen such that these numbers are integers. In practice DCT_scaled_size
* values will likely be powers of two, so we actually have the stronger
* condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
* Upsampling will typically produce max_v_samp_factor pixel rows from each
* row group (times any additional scale factor that the upsampler is
* applying).
*
* The coefficient controller will deliver data to us one iMCU row at a time;
* each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or
* exactly min_DCT_scaled_size row groups. (This amount of data corresponds
* to one row of MCUs when the image is fully interleaved.) Note that the
* number of sample rows varies across components, but the number of row
* groups does not. Some garbage sample rows may be included in the last iMCU
* row at the bottom of the image.
*
* Depending on the vertical scaling algorithm used, the upsampler may need
* access to the sample row(s) above and below its current input row group.
* The upsampler is required to set need_context_rows TRUE at global selection
* time if so. When need_context_rows is FALSE, this controller can simply
* obtain one iMCU row at a time from the coefficient controller and dole it
* out as row groups to the postprocessor.
*
* When need_context_rows is TRUE, this controller guarantees that the buffer
* passed to postprocessing contains at least one row group's worth of samples
* above and below the row group(s) being processed. Note that the context
* rows "above" the first passed row group appear at negative row offsets in
* the passed buffer. At the top and bottom of the image, the required
* context rows are manufactured by duplicating the first or last real sample
* row; this avoids having special cases in the upsampling inner loops.
*
* The amount of context is fixed at one row group just because that's a
* convenient number for this controller to work with. The existing
* upsamplers really only need one sample row of context. An upsampler
* supporting arbitrary output rescaling might wish for more than one row
* group of context when shrinking the image; tough, we don't handle that.
* (This is justified by the assumption that downsizing will be handled mostly
* by adjusting the DCT_scaled_size values, so that the actual scale factor at
* the upsample step needn't be much less than one.)
*
* To provide the desired context, we have to retain the last two row groups
* of one iMCU row while reading in the next iMCU row. (The last row group
* can't be processed until we have another row group for its below-context,
* and so we have to save the next-to-last group too for its above-context.)
* We could do this most simply by copying data around in our buffer, but
* that'd be very slow. We can avoid copying any data by creating a rather
* strange pointer structure. Here's how it works. We allocate a workspace
* consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
* of row groups per iMCU row). We create two sets of redundant pointers to
* the workspace. Labeling the physical row groups 0 to M+1, the synthesized
* pointer lists look like this:
* M+1 M-1
* master pointer --> 0 master pointer --> 0
* 1 1
* ... ...
* M-3 M-3
* M-2 M
* M-1 M+1
* M M-2
* M+1 M-1
* 0 0
* We read alternate iMCU rows using each master pointer; thus the last two
* row groups of the previous iMCU row remain un-overwritten in the workspace.
* The pointer lists are set up so that the required context rows appear to
* be adjacent to the proper places when we pass the pointer lists to the
* upsampler.
*
* The above pictures describe the normal state of the pointer lists.
* At top and bottom of the image, we diddle the pointer lists to duplicate
* the first or last sample row as necessary (this is cheaper than copying
* sample rows around).
*
* This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that
* situation each iMCU row provides only one row group so the buffering logic
* must be different (eg, we must read two iMCU rows before we can emit the
* first row group). For now, we simply do not support providing context
* rows when min_DCT_scaled_size is 1. That combination seems unlikely to
* be worth providing --- if someone wants a 1/8th-size preview, they probably
* want it quick and dirty, so a context-free upsampler is sufficient.
*/
/* Private buffer controller object */
typedef struct {
struct jpeg_d_main_controller pub; /* public fields */
/* Pointer to allocated workspace (M or M+2 row groups). */
JSAMPARRAY buffer[MAX_COMPONENTS];
boolean buffer_full; /* Have we gotten an iMCU row from decoder? */
JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */
/* Remaining fields are only used in the context case. */
/* These are the master pointers to the funny-order pointer lists. */
JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */
int whichptr; /* indicates which pointer set is now in use */
int context_state; /* process_data state machine status */
JDIMENSION rowgroups_avail; /* row groups available to postprocessor */
JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */
} my_main_controller;
typedef my_main_controller * my_main_ptr;
/* context_state values: */
#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */
#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */
#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */
/* Forward declarations */
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
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
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 mymain = (my_main_ptr) cinfo->main;
int ci, rgroup;
int M = cinfo->min_DCT_scaled_size;
jpeg_component_info *compptr;
JSAMPARRAY xbuf;
/* Get top-level space for component array pointers.
* We alloc both arrays with one call to save a few cycles.
*/
mymain->xbuffer[0] = (JSAMPIMAGE)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
mymain->xbuffer[1] = mymain->xbuffer[0] + cinfo->num_components;
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 */
/* 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.
*/
xbuf = (JSAMPARRAY)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
xbuf += rgroup; /* want one row group at negative offsets */
mymain->xbuffer[0][ci] = xbuf;
xbuf += rgroup * (M + 4);
mymain->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 mymain = (my_main_ptr) cinfo->main;
int ci, i, rgroup;
int M = cinfo->min_DCT_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_scaled_size) /
cinfo->min_DCT_scaled_size; /* height of a row group of component */
xbuf0 = mymain->xbuffer[0][ci];
xbuf1 = mymain->xbuffer[1][ci];
/* First copy the workspace pointers as-is */
buf = mymain->buffer[ci];
for (i = 0; i < rgroup * (M + 2); i++) {
xbuf0[i] = xbuf1[i] = buf[i];
}
/* In the second list, put the last four row groups in swapped order */
for (i = 0; i < rgroup * 2; i++) {
xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
}
/* The wraparound pointers at top and bottom will be filled later
* (see set_wraparound_pointers, below). Initially we want the "above"
* pointers to duplicate the first actual data line. This only needs
* to happen in xbuffer[0].
*/
for (i = 0; i < rgroup; i++) {
xbuf0[i - rgroup] = xbuf0[0];
}
}
}
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.
*/
{
my_main_ptr mymain = (my_main_ptr) cinfo->main;
int ci, i, rgroup;
int M = cinfo->min_DCT_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 */
xbuf0 = mymain->xbuffer[0][ci];
xbuf1 = mymain->xbuffer[1][ci];
for (i = 0; i < rgroup; i++) {
xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
xbuf0[rgroup*(M+2) + i] = xbuf0[i];
xbuf1[rgroup*(M+2) + i] = xbuf1[i];
}
}
}
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.
* Also sets rowgroups_avail to indicate number of nondummy row groups in row.
*/
{
my_main_ptr mymain = (my_main_ptr) cinfo->main;
int ci, i, rgroup, iMCUheight, rows_left;
jpeg_component_info *compptr;
JSAMPARRAY xbuf;
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;
/* Count nondummy sample rows remaining for this component */
rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
if (rows_left == 0) rows_left = iMCUheight;
/* Count nondummy row groups. Should get same answer for each component,
* so we need only do it once.
*/
if (ci == 0) {
mymain->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
}
/* Duplicate the last real sample row rgroup*2 times; this pads out the
* last partial rowgroup and ensures at least one full rowgroup of context.
*/
xbuf = mymain->xbuffer[mymain->whichptr][ci];
for (i = 0; i < rgroup * 2; i++) {
xbuf[rows_left + i] = xbuf[rows_left-1];
}
}
}
/*
* Initialize for a processing pass.
*/
METHODDEF(void)
start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_main_ptr mymain = (my_main_ptr) cinfo->main;
switch (pass_mode) {
case JBUF_PASS_THRU:
if (cinfo->upsample->need_context_rows) {
mymain->pub.process_data = process_data_context_main;
make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
mymain->whichptr = 0; /* Read first iMCU row into xbuffer[0] */
mymain->context_state = CTX_PREPARE_FOR_IMCU;
mymain->iMCU_row_ctr = 0;
} else {
/* Simple case with no context needed */
mymain->pub.process_data = process_data_simple_main;
}
mymain->buffer_full = FALSE; /* Mark buffer empty */
mymain->rowgroup_ctr = 0;
break;
default:
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
break;
}
}
/*
* Process some data.
* This handles the simple case where no context is required.
*/
METHODDEF(void)
process_data_simple_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)
{
my_main_ptr mymain = (my_main_ptr) cinfo->main;
JDIMENSION rowgroups_avail;
/* Read input data if we haven't filled the main buffer yet */
if (! mymain->buffer_full) {
if (! (*cinfo->coef->decompress_data) (cinfo, mymain->buffer))
return; /* suspension forced, can do nothing more */
mymain->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
}
/* There are always min_DCT_scaled_size row groups in an iMCU row. */
rowgroups_avail = (JDIMENSION) cinfo->min_DCT_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.
*/
/* Feed the postprocessor */
(*cinfo->post->post_process_data) (cinfo, mymain->buffer,
&mymain->rowgroup_ctr, rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail);
/* Has postprocessor consumed all the data yet? If so, mark buffer empty */
if (mymain->rowgroup_ctr >= rowgroups_avail) {
mymain->buffer_full = FALSE;
mymain->rowgroup_ctr = 0;
}
}
/*
* Process some data.
* This handles the case where context rows must be provided.
*/
METHODDEF(void)
process_data_context_main (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail)
{
my_main_ptr mymain = (my_main_ptr) cinfo->main;
/* Read input data if we haven't filled the main buffer yet */
if (! mymain->buffer_full) {
if (! (*cinfo->coef->decompress_data) (cinfo,
mymain->xbuffer[mymain->whichptr]))
return; /* suspension forced, can do nothing more */
mymain->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
mymain->iMCU_row_ctr++; /* count rows received */
}
/* Postprocessor typically will not swallow all the input data it is handed
* in one call (due to filling the output buffer first). Must be prepared
* to exit and restart. This switch lets us keep track of how far we got.
* Note that each case falls through to the next on successful completion.
*/
switch (mymain->context_state) {
case CTX_POSTPONED_ROW:
/* Call postprocessor using previously set pointers for postponed row */
(*cinfo->post->post_process_data) (cinfo, mymain->xbuffer[mymain->whichptr],
&mymain->rowgroup_ctr, mymain->rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail);
if (mymain->rowgroup_ctr < mymain->rowgroups_avail)
return; /* Need to suspend */
mymain->context_state = CTX_PREPARE_FOR_IMCU;
if (*out_row_ctr >= out_rows_avail)
return; /* Postprocessor exactly filled output buf */
/*FALLTHROUGH*/
case CTX_PREPARE_FOR_IMCU:
/* Prepare to process first M-1 row groups of this iMCU row */
mymain->rowgroup_ctr = 0;
mymain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_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.
*/
if (mymain->iMCU_row_ctr == cinfo->total_iMCU_rows)
set_bottom_pointers(cinfo);
mymain->context_state = CTX_PROCESS_IMCU;
/*FALLTHROUGH*/
case CTX_PROCESS_IMCU:
/* Call postprocessor using previously set pointers */
(*cinfo->post->post_process_data) (cinfo, mymain->xbuffer[mymain->whichptr],
&mymain->rowgroup_ctr, mymain->rowgroups_avail,
output_buf, out_row_ctr, out_rows_avail);
if (mymain->rowgroup_ctr < mymain->rowgroups_avail)
return; /* Need to suspend */
/* After the first iMCU, change wraparound pointers to normal state */
if (mymain->iMCU_row_ctr == 1)
set_wraparound_pointers(cinfo);
/* Prepare to load new iMCU row using other xbuffer list */
mymain->whichptr ^= 1; /* 0=>1 or 1=>0 */
mymain->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 */
mymain->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
mymain->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
mymain->context_state = CTX_POSTPONED_ROW;
}
}
/*
* Initialize main buffer controller.
*/
GLOBAL(void)
jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
my_main_ptr mymain;
int ci, rgroup, ngroups;
jpeg_component_info *compptr;
mymain = (my_main_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_main_controller));
cinfo->main = (struct jpeg_d_main_controller *) mymain;
mymain->pub.start_pass = start_pass_main;
if (need_full_buffer) /* shouldn't happen */
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
/* 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 */
ERREXIT(cinfo, JERR_NOTIMPL);
alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
ngroups = cinfo->min_DCT_scaled_size + 2;
} else {
ngroups = cinfo->min_DCT_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 */
mymain->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * compptr->DCT_scaled_size,
(JDIMENSION) (rgroup * ngroups));
}
}

1307
jpeg-6b/jdmarker.c Normal file

File diff suppressed because it is too large Load diff

366
jpeg-6b/jdmaster.c Normal file
View file

@ -0,0 +1,366 @@
/*
* jdmaster.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 master control logic for the JPEG decompressor.
* 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.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Private state */
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 */
/* 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;
/*
* Determine whether merged upsample/color conversion should be used.
* CRUCIAL: this must match the actual capabilities of jdmerge.c!
*/
LOCAL(boolean)
use_merged_upsample (j_decompress_ptr cinfo)
{
#ifdef UPSAMPLE_MERGING_SUPPORTED
/* Merging is the equivalent of plain box-filter upsampling */
if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
return FALSE;
/* jdmerge.c only supports YCC=>RGB color conversion */
if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
cinfo->out_color_space != JCS_RGB ||
cinfo->out_color_components != RGB_PIXELSIZE)
return FALSE;
/* and it only handles 2h1v or 2h2v sampling ratios */
if (cinfo->comp_info[0].h_samp_factor != 2 ||
cinfo->comp_info[1].h_samp_factor != 1 ||
cinfo->comp_info[2].h_samp_factor != 1 ||
cinfo->comp_info[0].v_samp_factor > 2 ||
cinfo->comp_info[1].v_samp_factor != 1 ||
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)
return FALSE;
/* ??? also need to test for upsample-time rescaling, when & if supported */
return TRUE; /* by golly, it'll work... */
#else
return FALSE;
#endif
}
/*
* 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)
jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
/* Do computations that are needed before master selection phase */
{
/* Prevent application from calling me at wrong times */
if (cinfo->global_state != DSTATE_READY)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* 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 to DCTSIZE,
* and has computed unscaled downsampled_width and downsampled_height.
*/
/* Report number of components in selected colorspace. */
/* Probably this should be in the color conversion module... */
switch (cinfo->out_color_space) {
case JCS_GRAYSCALE:
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;
case JCS_CMYK:
case JCS_YCCK:
cinfo->out_color_components = 4;
break;
default: /* else must be same colorspace as in file */
cinfo->out_color_components = cinfo->num_components;
break;
}
cinfo->output_components = cinfo->out_color_components;
/* See if upsampler will want to emit more than one row at a time */
if (use_merged_upsample(cinfo))
cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
else
cinfo->rec_outbuf_height = 1;
}
/*
* Several decompression processes need to range-limit values to the range
* 0..MAXJSAMPLE; the input value may fall somewhat outside this range
* due to noise introduced by quantization, roundoff error, etc. These
* processes are inner loops and need to be as fast as possible. On most
* machines, particularly CPUs with pipelines or instruction prefetch,
* a (subscript-check-less) C table lookup
* x = sample_range_limit[x];
* is faster than explicit tests
* if (x < 0) x = 0;
* else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
* These processes all use a common table prepared by the routine below.
*
* For most steps we can mathematically guarantee that the initial value
* of x is within MAXJSAMPLE+1 of the legal range, so a table running from
* -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial
* limiting step (just after the IDCT), a wildly out-of-range value is
* possible if the input data is corrupt. To avoid any chance of indexing
* off the end of memory and getting a bad-pointer trap, we perform the
* post-IDCT limiting thus:
* x = range_limit[x & MASK];
* where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
* samples. Under normal circumstances this is more than enough range and
* a correct output will be generated; with bogus input data the mask will
* cause wraparound, and we will safely generate a bogus-but-in-range output.
* For the post-IDCT step, we want to convert the data from signed to unsigned
* representation by adding CENTERJSAMPLE at the same time that we limit it.
* So the post-IDCT limiting table ends up looking like this:
* CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
* MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
* 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
* 0,1,...,CENTERJSAMPLE-1
* Negative inputs select values from the upper half of the table after
* masking.
*
* We can save some space by overlapping the start of the post-IDCT table
* with the simpler range limiting table. The post-IDCT table begins at
* sample_range_limit + CENTERJSAMPLE.
*
* Note that the table is allocated in near data space on PCs; it's small
* enough and used often enough to justify this.
*/
LOCAL(void)
prepare_range_limit_table (j_decompress_ptr cinfo)
/* Allocate and fill in the sample_range_limit table */
{
JSAMPLE * table;
int i;
table = (JSAMPLE *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */
cinfo->sample_range_limit = table;
/* First segment of "simple" table: limit[x] = 0 for x < 0 */
MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
/* Main part of "simple" table: limit[x] = x */
for (i = 0; i <= MAXJSAMPLE; i++)
table[i] = (JSAMPLE) i;
table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */
/* End of simple table, rest of first half of post-IDCT table */
for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
table[i] = MAXJSAMPLE;
/* Second half of post-IDCT table */
MEMZERO(table + (2 * (MAXJSAMPLE+1)),
(2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
}
/*
* Master selection of decompression modules.
* 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.
*
* 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)
master_selection (j_decompress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
boolean use_c_buffer;
long samplesperrow;
JDIMENSION jd_samplesperrow;
/* Initialize dimensions and other stuff */
jpeg_calc_output_dimensions(cinfo);
prepare_range_limit_table(cinfo);
/* Width of an output scanline must be representable as JDIMENSION. */
samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
jd_samplesperrow = (JDIMENSION) samplesperrow;
if ((long) jd_samplesperrow != samplesperrow)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
/* Initialize my private state */
master->pass_number = 0;
master->using_merged_upsample = use_merged_upsample(cinfo);
/* Color quantizer selection */
master->quantizer_1pass = NULL;
master->quantizer_2pass = NULL;
/* Post-processing: in particular, color conversion first */
if (master->using_merged_upsample) {
#ifdef UPSAMPLE_MERGING_SUPPORTED
jinit_merged_upsampler(cinfo); /* does color conversion too */
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
jinit_color_deconverter(cinfo);
jinit_upsampler(cinfo);
}
jinit_d_post_controller(cinfo, 0);
/* Inverse DCT */
jinit_inverse_dct(cinfo);
/* Entropy decoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) {
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
} else {
if (cinfo->progressive_mode) {
#ifdef D_PROGRESSIVE_SUPPORTED
jinit_phuff_decoder(cinfo);
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else
jinit_huff_decoder(cinfo);
}
/* Initialize principal buffer controllers. */
use_c_buffer = cinfo->inputctl->has_multiple_scans;
jinit_d_coef_controller(cinfo, use_c_buffer);
jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
/* 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->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 = 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 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_output_pass (j_decompress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
(*cinfo->idct->start_pass) (cinfo);
(*cinfo->coef->start_output_pass) (cinfo);
if (! master->using_merged_upsample)
(*cinfo->cconvert->start_pass) (cinfo);
(*cinfo->upsample->start_pass) (cinfo);
(*cinfo->post->start_pass) (cinfo, 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->pass_number + 1;
}
}
/*
* Finish up at end of an output pass.
*/
METHODDEF(void)
finish_output_pass (j_decompress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
master->pass_number++;
}
/*
* Initialize master decompression control and select active modules.
* This is performed at the start of jpeg_start_decompress.
*/
GLOBAL(void)
jinit_master_decompress (j_decompress_ptr cinfo)
{
my_master_ptr master;
master = (my_master_ptr)
(*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_output_pass = prepare_for_output_pass;
master->pub.finish_output_pass = finish_output_pass;
master_selection(cinfo);
}

400
jpeg-6b/jdmerge.c Normal file
View file

@ -0,0 +1,400 @@
/*
* jdmerge.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 code for merged upsampling/color conversion.
*
* This file combines functions from jdsample.c and jdcolor.c;
* read those files first to understand what's going on.
*
* When the chroma components are to be upsampled by simple replication
* (ie, box filtering), we can save some work in color conversion by
* calculating all the output pixels corresponding to a pair of chroma
* samples at one time. In the conversion equations
* R = Y + K1 * Cr
* G = Y + K2 * Cb + K3 * Cr
* B = Y + K4 * Cb
* only the Y term varies among the group of pixels corresponding to a pair
* of chroma samples, so the rest of the terms can be calculated just once.
* At typical sampling ratios, this eliminates half or three-quarters of the
* multiplications needed for color conversion.
*
* This file currently provides implementations for the following cases:
* YCbCr => RGB color conversion only.
* Sampling ratios of 2h1v or 2h2v.
* No scaling needed at upsample time.
* Corner-aligned (non-CCIR601) sampling alignment.
* Other special cases could be added, but in most applications these are
* the only common cases. (For uncommon cases we fall back on the more
* general code in jdsample.c and jdcolor.c.)
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#ifdef UPSAMPLE_MERGING_SUPPORTED
/* Private subobject */
typedef struct {
struct jpeg_upsampler pub; /* public fields */
/* Pointer to routine to do actual upsampling/conversion of one row group */
JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf));
/* Private state for YCC->RGB conversion */
int * Cr_r_tab; /* => table for Cr to R conversion */
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 */
/* For 2:1 vertical sampling, we produce two output rows at a time.
* We need a "spare" row buffer to hold the second output row if the
* application provides just a one-row buffer; we also use the spare
* to discard the dummy last row if the image height is odd.
*/
JSAMPROW spare_row;
boolean spare_full; /* T if spare buffer is occupied */
JDIMENSION out_row_width; /* samples per output row */
JDIMENSION rows_to_go; /* counts rows remaining in image */
} my_upsampler;
typedef my_upsampler * my_upsample_ptr;
#define SCALEBITS 16 /* speediest right-shift on some machines */
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
/*
* 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));
upsample->Cb_b_tab = (int *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(int));
upsample->Cr_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
upsample->Cb_g_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(MAXJSAMPLE+1) * SIZEOF(INT32));
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
/* Cr=>R value is nearest int to 1.40200 * x */
upsample->Cr_r_tab[i] = (int)
RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
/* Cb=>B value is nearest int to 1.77200 * x */
upsample->Cb_b_tab[i] = (int)
RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
/* Cr=>G value is scaled-up -0.71414 * x */
upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
/* Cb=>G value is scaled-up -0.34414 * x */
/* We also add in ONE_HALF so that need not do it in inner loop */
upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
}
}
/*
* 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)
merged_2v_upsample (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)
/* 2:1 vertical sampling case: may need a spare row. */
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
JSAMPROW work_ptrs[2];
JDIMENSION num_rows; /* number of rows returned to caller */
if (upsample->spare_full) {
/* If we have a spare row saved from a previous cycle, just return it. */
jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
1, upsample->out_row_width);
num_rows = 1;
upsample->spare_full = FALSE;
} else {
/* Figure number of rows to return to caller. */
num_rows = 2;
/* Not more than the distance to the end of the image. */
if (num_rows > upsample->rows_to_go)
num_rows = upsample->rows_to_go;
/* And not more than what the client can accept: */
out_rows_avail -= *out_row_ctr;
if (num_rows > out_rows_avail)
num_rows = out_rows_avail;
/* Create output pointer array for upsampler. */
work_ptrs[0] = output_buf[*out_row_ctr];
if (num_rows > 1) {
work_ptrs[1] = output_buf[*out_row_ctr + 1];
} else {
work_ptrs[1] = upsample->spare_row;
upsample->spare_full = TRUE;
}
/* Now do the upsampling. */
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
}
/* Adjust counts */
*out_row_ctr += num_rows;
upsample->rows_to_go -= num_rows;
/* When the buffer is emptied, declare this input row group consumed */
if (! upsample->spare_full)
(*in_row_group_ctr)++;
}
METHODDEF(void)
merged_1v_upsample (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)
/* 1:1 vertical sampling case: much easier, never need a spare row. */
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
/* Just do the upsampling. */
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
output_buf + *out_row_ctr);
/* Adjust counts */
(*out_row_ctr)++;
(*in_row_group_ctr)++;
}
/*
* These are the routines invoked by the control routines to do
* the actual upsampling/conversion. One row group is processed per call.
*
* Note: since we may be writing directly into application-supplied buffers,
* we have to be honest about the output width; we can't assume the buffer
* has been rounded up to an even width.
*/
/*
* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
*/
METHODDEF(void)
h2v1_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
register int y, cred, cgreen, cblue;
int cb, cr;
register JSAMPROW outptr;
JSAMPROW inptr0, inptr1, inptr2;
JDIMENSION col;
/* copy these pointers into registers if possible */
register JSAMPLE * range_limit = cinfo->sample_range_limit;
int * Crrtab = upsample->Cr_r_tab;
int * Cbbtab = upsample->Cb_b_tab;
INT32 * Crgtab = upsample->Cr_g_tab;
INT32 * Cbgtab = upsample->Cb_g_tab;
SHIFT_TEMPS
inptr0 = input_buf[0][in_row_group_ctr];
inptr1 = input_buf[1][in_row_group_ctr];
inptr2 = input_buf[2][in_row_group_ctr];
outptr = output_buf[0];
/* Loop for each pair of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cred = Crrtab[cr];
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 2 Y values and emit 2 pixels */
y = GETJSAMPLE(*inptr0++);
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
outptr += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr0++);
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
outptr += RGB_PIXELSIZE;
}
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cred = Crrtab[cr];
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr0);
outptr[RGB_RED] = range_limit[y + cred];
outptr[RGB_GREEN] = range_limit[y + cgreen];
outptr[RGB_BLUE] = range_limit[y + cblue];
}
}
/*
* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
*/
METHODDEF(void)
h2v2_merged_upsample (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
JSAMPARRAY output_buf)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
register int y, cred, cgreen, cblue;
int cb, cr;
register JSAMPROW outptr0, outptr1;
JSAMPROW inptr00, inptr01, inptr1, inptr2;
JDIMENSION col;
/* copy these pointers into registers if possible */
register JSAMPLE * range_limit = cinfo->sample_range_limit;
int * Crrtab = upsample->Cr_r_tab;
int * Cbbtab = upsample->Cb_b_tab;
INT32 * Crgtab = upsample->Cr_g_tab;
INT32 * Cbgtab = upsample->Cb_g_tab;
SHIFT_TEMPS
inptr00 = input_buf[0][in_row_group_ctr*2];
inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
inptr1 = input_buf[1][in_row_group_ctr];
inptr2 = input_buf[2][in_row_group_ctr];
outptr0 = output_buf[0];
outptr1 = output_buf[1];
/* Loop for each group of output pixels */
for (col = cinfo->output_width >> 1; col > 0; col--) {
/* Do the chroma part of the calculation */
cb = GETJSAMPLE(*inptr1++);
cr = GETJSAMPLE(*inptr2++);
cred = Crrtab[cr];
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
/* Fetch 4 Y values and emit 4 pixels */
y = GETJSAMPLE(*inptr00++);
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr00++);
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
outptr0 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
outptr1 += RGB_PIXELSIZE;
y = GETJSAMPLE(*inptr01++);
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
outptr1 += RGB_PIXELSIZE;
}
/* If image width is odd, do the last output column separately */
if (cinfo->output_width & 1) {
cb = GETJSAMPLE(*inptr1);
cr = GETJSAMPLE(*inptr2);
cred = Crrtab[cr];
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
cblue = Cbbtab[cb];
y = GETJSAMPLE(*inptr00);
outptr0[RGB_RED] = range_limit[y + cred];
outptr0[RGB_GREEN] = range_limit[y + cgreen];
outptr0[RGB_BLUE] = range_limit[y + cblue];
y = GETJSAMPLE(*inptr01);
outptr1[RGB_RED] = range_limit[y + cred];
outptr1[RGB_GREEN] = range_limit[y + cgreen];
outptr1[RGB_BLUE] = range_limit[y + cblue];
}
}
/*
* Module initialization routine for merged upsampling/color conversion.
*
* NB: this is called under the conditions determined by use_merged_upsample()
* in jdmaster.c. That routine MUST correspond to the actual capabilities
* of this module; no safety checks are made here.
*/
GLOBAL(void)
jinit_merged_upsampler (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample;
upsample = (my_upsample_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_upsampler));
cinfo->upsample = (struct jpeg_upsampler *) upsample;
upsample->pub.start_pass = start_pass_merged_upsample;
upsample->pub.need_context_rows = FALSE;
upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
if (cinfo->max_v_samp_factor == 2) {
upsample->pub.upsample = merged_2v_upsample;
upsample->upmethod = h2v2_merged_upsample;
/* Allocate a spare row buffer */
upsample->spare_row = (JSAMPROW)
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
} else {
upsample->pub.upsample = merged_1v_upsample;
upsample->upmethod = h2v1_merged_upsample;
/* No spare row needed */
upsample->spare_row = NULL;
}
build_ycc_rgb_table(cinfo);
}
#endif /* UPSAMPLE_MERGING_SUPPORTED */

668
jpeg-6b/jdphuff.c Normal file
View file

@ -0,0 +1,668 @@
/*
* jdphuff.c
*
* Copyright (C) 1995-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains Huffman entropy decoding routines for progressive JPEG.
*
* Much of the complexity here has to do with supporting input suspension.
* If the data source module demands suspension, we want to be able to back
* up to the start of the current MCU. To do this, we copy state variables
* into local working storage, and update them back to the permanent
* storage only upon successful completion of an MCU.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jdhuff.h" /* Declarations shared with jdhuff.c */
#ifdef D_PROGRESSIVE_SUPPORTED
/*
* Expanded entropy decoder object for progressive Huffman decoding.
*
* The savable_state subrecord contains fields that change within an MCU,
* but must not be updated permanently until we complete the MCU.
*/
typedef struct {
unsigned int EOBRUN; /* remaining EOBs in EOBRUN */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
} savable_state;
/* This macro is to work around compilers with missing or broken
* structure assignment. You'll need to fix this code if you have
* such a compiler and you change MAX_COMPS_IN_SCAN.
*/
#ifndef NO_STRUCT_ASSIGN
#define ASSIGN_STATE(dest,src) ((dest) = (src))
#else
#if MAX_COMPS_IN_SCAN == 4
#define ASSIGN_STATE(dest,src) \
((dest).EOBRUN = (src).EOBRUN, \
(dest).last_dc_val[0] = (src).last_dc_val[0], \
(dest).last_dc_val[1] = (src).last_dc_val[1], \
(dest).last_dc_val[2] = (src).last_dc_val[2], \
(dest).last_dc_val[3] = (src).last_dc_val[3])
#endif
#endif
typedef struct {
struct jpeg_entropy_decoder pub; /* public fields */
/* These fields are loaded into local variables at start of each MCU.
* In case of suspension, we exit WITHOUT updating them.
*/
bitread_perm_state bitstate; /* Bit buffer at start of MCU */
savable_state saved; /* Other state at start of MCU */
/* These fields are NOT loaded into local working state. */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
/* Pointers to derived tables (these workspaces have image lifespan) */
d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
} phuff_entropy_decoder;
typedef phuff_entropy_decoder * phuff_entropy_ptr;
/* Forward declarations */
METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
/*
* Initialize for a Huffman-compressed scan.
*/
METHODDEF(void)
start_pass_phuff_decoder (j_decompress_ptr cinfo)
{
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
boolean is_DC_band, bad;
int ci, coefi, tbl;
int *coef_bit_ptr;
jpeg_component_info * compptr;
is_DC_band = (cinfo->Ss == 0);
/* Validate scan parameters */
bad = FALSE;
if (is_DC_band) {
if (cinfo->Se != 0)
bad = TRUE;
} else {
/* need not check Ss/Se < 0 since they came from unsigned bytes */
if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
bad = TRUE;
/* AC scans may have only one component */
if (cinfo->comps_in_scan != 1)
bad = TRUE;
}
if (cinfo->Ah != 0) {
/* Successive approximation refinement scan: must have Al = Ah-1. */
if (cinfo->Al != cinfo->Ah-1)
bad = TRUE;
}
if (cinfo->Al > 13) /* need not check for < 0 */
bad = TRUE;
/* Arguably the maximum Al value should be less than 13 for 8-bit precision,
* but the spec doesn't say so, and we try to be liberal about what we
* accept. Note: large Al values could result in out-of-range DC
* coefficients during early scans, leading to bizarre displays due to
* overflows in the IDCT math. But we won't crash.
*/
if (bad)
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
/* 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 cindex = cinfo->cur_comp_info[ci]->component_index;
coef_bit_ptr = & cinfo->coef_bits[cindex][0];
if (!is_DC_band && 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 (is_DC_band)
entropy->pub.decode_mcu = decode_mcu_DC_first;
else
entropy->pub.decode_mcu = decode_mcu_AC_first;
} else {
if (is_DC_band)
entropy->pub.decode_mcu = decode_mcu_DC_refine;
else
entropy->pub.decode_mcu = decode_mcu_AC_refine;
}
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* Make sure requested tables are present, and compute derived tables.
* We may build same derived table more than once, but it's not expensive.
*/
if (is_DC_band) {
if (cinfo->Ah == 0) { /* DC refinement needs no table */
tbl = compptr->dc_tbl_no;
jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
& entropy->derived_tbls[tbl]);
}
} else {
tbl = compptr->ac_tbl_no;
jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
& entropy->derived_tbls[tbl]);
/* remember the single active table */
entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
}
/* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 0;
}
/* Initialize bitread state variables */
entropy->bitstate.bits_left = 0;
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
entropy->pub.insufficient_data = FALSE;
/* Initialize private state variables */
entropy->saved.EOBRUN = 0;
/* Initialize restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
}
/*
* Figure F.12: extend sign bit.
* On some machines, a shift and add will be faster than a table lookup.
*/
#ifdef AVOID_TABLES
#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
#else
#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
static const int extend_test[16] = /* entry n is 2**(n-1) */
{ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
{ 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
#endif /* AVOID_TABLES */
/*
* Check for a restart marker & resynchronize decoder.
* Returns FALSE if must suspend.
*/
LOCAL(boolean)
process_restart (j_decompress_ptr cinfo)
{
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
int ci;
/* Throw away any unused bits remaining in bit buffer; */
/* include any full bytes in next_marker's count of discarded bytes */
cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
entropy->bitstate.bits_left = 0;
/* Advance past the RSTn marker */
if (! (*cinfo->marker->read_restart_marker) (cinfo))
return FALSE;
/* Re-initialize DC predictions to 0 */
for (ci = 0; ci < cinfo->comps_in_scan; ci++)
entropy->saved.last_dc_val[ci] = 0;
/* Re-init EOB run count, too */
entropy->saved.EOBRUN = 0;
/* Reset restart counter */
entropy->restarts_to_go = cinfo->restart_interval;
/* Reset out-of-data flag, unless read_restart_marker left us smack up
* against a marker. In that case we will end up treating the next data
* segment as empty, and we can avoid producing bogus output pixels by
* leaving the flag set.
*/
if (cinfo->unread_marker == 0)
entropy->pub.insufficient_data = FALSE;
return TRUE;
}
/*
* Huffman MCU decoding.
* Each of these routines decodes and returns one MCU's worth of
* Huffman-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.
*
* We return FALSE if data source requested suspension. In that case no
* changes have been made to permanent state. (Exception: some output
* coefficients may already have been assigned. This is harmless for
* spectral selection, since we'll just re-assign them on the next call.
* Successive approximation AC refinement has to be more careful, however.)
*/
/*
* 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)
{
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
int Al = cinfo->Al;
register int s, r;
int blkn, ci;
JBLOCKROW block;
BITREAD_STATE_VARS;
savable_state state;
d_derived_tbl * tbl;
jpeg_component_info * compptr;
/* Process restart marker if needed; may have to suspend */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
if (! process_restart(cinfo))
return FALSE;
}
/* If we've run out of data, just leave the MCU set to zeroes.
* This way, we return uniform gray for the remainder of the segment.
*/
if (! entropy->pub.insufficient_data) {
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(state, entropy->saved);
/* 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];
tbl = entropy->derived_tbls[compptr->dc_tbl_no];
/* Decode a single block's worth of coefficients */
/* Section F.2.2.1: decode the DC coefficient difference */
HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
if (s) {
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
}
/* Convert DC difference to actual value, update last_dc_val */
s += state.last_dc_val[ci];
state.last_dc_val[ci] = s;
/* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
(*block)[0] = (JCOEF) (s << Al);
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
ASSIGN_STATE(entropy->saved, state);
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
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)
{
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
int Se = cinfo->Se;
int Al = cinfo->Al;
register int s, k, r;
unsigned int EOBRUN;
JBLOCKROW block;
BITREAD_STATE_VARS;
d_derived_tbl * tbl;
/* Process restart marker if needed; may have to suspend */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
if (! process_restart(cinfo))
return FALSE;
}
/* If we've run out of data, just leave the MCU set to zeroes.
* This way, we return uniform gray for the remainder of the segment.
*/
if (! entropy->pub.insufficient_data) {
/* Load up working state.
* We can avoid loading/saving bitread state if in an EOB run.
*/
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
/* There is always only one block per MCU */
if (EOBRUN > 0) /* if it's a band of zeroes... */
EOBRUN--; /* ...process it now (we do nothing) */
else {
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
block = MCU_data[0];
tbl = entropy->ac_derived_tbl;
for (k = cinfo->Ss; k <= Se; k++) {
HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
r = s >> 4;
s &= 15;
if (s) {
k += r;
CHECK_BIT_BUFFER(br_state, s, return FALSE);
r = GET_BITS(s);
s = HUFF_EXTEND(r, s);
/* Scale and output coefficient in natural (dezigzagged) order */
(*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
} else {
if (r == 15) { /* ZRL */
k += 15; /* skip 15 zeroes in band */
} else { /* EOBr, run length is 2^r + appended bits */
EOBRUN = 1 << r;
if (r) { /* EOBr, r > 0 */
CHECK_BIT_BUFFER(br_state, r, return FALSE);
r = GET_BITS(r);
EOBRUN += r;
}
EOBRUN--; /* this band is processed at this moment */
break; /* force end-of-band */
}
}
}
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
}
/* Completed MCU, so update state */
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
return TRUE;
}
/*
* MCU decoding for DC successive approximation refinement scan.
* Note: we assume such scans can be multi-component, although the spec
* is not very clear on the point.
*/
METHODDEF(boolean)
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
int blkn;
JBLOCKROW block;
BITREAD_STATE_VARS;
/* Process restart marker if needed; may have to suspend */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
if (! process_restart(cinfo))
return FALSE;
}
/* Not worth the cycles to check insufficient_data here,
* since we will not change the data anyway if we read zeroes.
*/
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
/* Encoded data is simply the next bit of the two's-complement DC value */
CHECK_BIT_BUFFER(br_state, 1, return FALSE);
if (GET_BITS(1))
(*block)[0] |= p1;
/* Note: since we use |=, repeating the assignment later is safe */
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
return TRUE;
}
/*
* MCU decoding for AC successive approximation refinement scan.
*/
METHODDEF(boolean)
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
{
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
int Se = cinfo->Se;
int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
register int s, k, r;
unsigned int EOBRUN;
JBLOCKROW block;
JCOEFPTR thiscoef;
BITREAD_STATE_VARS;
d_derived_tbl * tbl;
int num_newnz;
int newnz_pos[DCTSIZE2];
/* Process restart marker if needed; may have to suspend */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0)
if (! process_restart(cinfo))
return FALSE;
}
/* If we've run out of data, don't modify the MCU.
*/
if (! entropy->pub.insufficient_data) {
/* Load up working state */
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
/* There is always only one block per MCU */
block = MCU_data[0];
tbl = entropy->ac_derived_tbl;
/* If we are forced to suspend, we must undo the assignments to any newly
* nonzero coefficients in the block, because otherwise we'd get confused
* next time about which coefficients were already nonzero.
* But we need not undo addition of bits to already-nonzero coefficients;
* instead, we can test the current bit to see if we already did it.
*/
num_newnz = 0;
/* initialize coefficient loop counter to start of band */
k = cinfo->Ss;
if (EOBRUN == 0) {
for (; k <= Se; k++) {
HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
r = s >> 4;
s &= 15;
if (s) {
if (s != 1) /* size of new coef should always be 1 */
WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1))
s = p1; /* newly nonzero coef is positive */
else
s = m1; /* newly nonzero coef is negative */
} else {
if (r != 15) {
EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */
if (r) {
CHECK_BIT_BUFFER(br_state, r, goto undoit);
r = GET_BITS(r);
EOBRUN += r;
}
break; /* rest of block is handled by EOB logic */
}
/* note s = 0 for processing ZRL */
}
/* Advance over already-nonzero coefs and r still-zero coefs,
* appending correction bits to the nonzeroes. A correction bit is 1
* if the absolute value of the coefficient must be increased.
*/
do {
thiscoef = *block + jpeg_natural_order[k];
if (*thiscoef != 0) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1)) {
if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
if (*thiscoef >= 0)
*thiscoef += p1;
else
*thiscoef += m1;
}
}
} else {
if (--r < 0)
break; /* reached target zero coefficient */
}
k++;
} while (k <= Se);
if (s) {
int pos = jpeg_natural_order[k];
/* Output newly nonzero coefficient */
(*block)[pos] = (JCOEF) s;
/* Remember its position in case we have to suspend */
newnz_pos[num_newnz++] = pos;
}
}
}
if (EOBRUN > 0) {
/* Scan any remaining coefficient positions after the end-of-band
* (the last newly nonzero coefficient, if any). Append a correction
* bit to each already-nonzero coefficient. A correction bit is 1
* if the absolute value of the coefficient must be increased.
*/
for (; k <= Se; k++) {
thiscoef = *block + jpeg_natural_order[k];
if (*thiscoef != 0) {
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
if (GET_BITS(1)) {
if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
if (*thiscoef >= 0)
*thiscoef += p1;
else
*thiscoef += m1;
}
}
}
}
/* Count one block completed in EOB run */
EOBRUN--;
}
/* Completed MCU, so update state */
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
}
/* Account for restart interval (no-op if not using restarts) */
entropy->restarts_to_go--;
return TRUE;
undoit:
/* Re-zero any output coefficients that we made newly nonzero */
while (num_newnz > 0)
(*block)[newnz_pos[--num_newnz]] = 0;
return FALSE;
}
/*
* Module initialization routine for progressive Huffman entropy decoding.
*/
GLOBAL(void)
jinit_phuff_decoder (j_decompress_ptr cinfo)
{
phuff_entropy_ptr entropy;
int *coef_bit_ptr;
int ci, i;
entropy = (phuff_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(phuff_entropy_decoder));
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
entropy->pub.start_pass = start_pass_phuff_decoder;
/* Mark derived tables unallocated */
for (i = 0; i < NUM_HUFF_TBLS; i++) {
entropy->derived_tbls[i] = NULL;
}
/* Create progression status table */
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;
}
#endif /* D_PROGRESSIVE_SUPPORTED */

70
jpeg-6b/jdpostct.c Normal file
View file

@ -0,0 +1,70 @@
/*
* jdpostct.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 the decompression postprocessing controller.
* This controller manages the upsampling, color conversion, and color
* quantization/reduction steps; specifically, it controls the buffering
* between upsample/color conversion and color quantization/reduction.
*
* If no color quantization/reduction is required, then this module has no
* work to do, and it just hands off to the upsample/color conversion code.
* An integrated upsample/convert/quantize process would replace this module
* entirely.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Private buffer controller object */
typedef struct {
struct jpeg_d_post_controller pub; /* public fields */
} my_post_controller;
typedef my_post_controller * my_post_ptr;
/*
* Initialize for a processing pass.
*/
METHODDEF(void)
start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
{
my_post_ptr post = (my_post_ptr) cinfo->post;
switch (pass_mode) {
case JBUF_PASS_THRU:
/* For single-pass processing without color quantization,
* I have no work to do; just call the upsampler directly.
*/
post->pub.post_process_data = cinfo->upsample->upsample;
break;
default:
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
break;
}
}
/*
* Initialize postprocessing controller.
*/
GLOBAL(void)
jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
{
my_post_ptr post;
post = (my_post_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_post_controller));
cinfo->post = (struct jpeg_d_post_controller *) post;
post->pub.start_pass = start_pass_dpost;
}

478
jpeg-6b/jdsample.c Normal file
View file

@ -0,0 +1,478 @@
/*
* jdsample.c
*
* 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.
*
* 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)
* 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).
*
* An excellent reference for image resampling is
* Digital Image Warping, George Wolberg, 1990.
* Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Pointer to routine to upsample a single component */
typedef JMETHOD(void, upsample1_ptr,
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
/* Private subobject */
typedef struct {
struct jpeg_upsampler pub; /* public fields */
/* Color conversion buffer. When using separate upsampling and color
* conversion steps, this buffer holds one upsampled row group until it
* has been color converted and output.
* Note: we do not allocate any storage for component(s) which are full-size,
* ie do not need rescaling. The corresponding entry of color_buf[] is
* simply set to point to the input data array, thereby avoiding copying.
*/
JSAMPARRAY color_buf[MAX_COMPONENTS];
/* Per-component upsampling method pointers */
upsample1_ptr methods[MAX_COMPONENTS];
int next_row_out; /* counts rows emitted from color_buf */
JDIMENSION rows_to_go; /* counts rows remaining in image */
/* Height of an input row group for each component. */
int rowgroup_height[MAX_COMPONENTS];
/* These arrays save pixel expansion factors so that int_expand need not
* recompute them each time. They are unused for other upsampling methods.
*/
UINT8 h_expand[MAX_COMPONENTS];
UINT8 v_expand[MAX_COMPONENTS];
} my_upsampler;
typedef my_upsampler * my_upsample_ptr;
/*
* Initialize for an upsampling pass.
*/
METHODDEF(void)
start_pass_upsample (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
/* Mark the conversion buffer empty */
upsample->next_row_out = cinfo->max_v_samp_factor;
/* Initialize total-height counter for detecting bottom of image */
upsample->rows_to_go = cinfo->output_height;
}
/*
* Control routine to do upsampling (and color conversion).
*
* In this version we upsample each component independently.
* We upsample one row group into the conversion buffer, then apply
* color conversion a row at a time.
*/
METHODDEF(void)
sep_upsample (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)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
int ci;
jpeg_component_info * compptr;
JDIMENSION num_rows;
/* Fill the conversion buffer, if it's empty */
if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* Invoke per-component upsample method. Notice we pass a POINTER
* to color_buf[ci], so that fullsize_upsample can change it.
*/
(*upsample->methods[ci]) (cinfo, compptr,
input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
upsample->color_buf + ci);
}
upsample->next_row_out = 0;
}
/* Color-convert and emit rows */
/* How many we have in the buffer: */
num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
/* Not more than the distance to the end of the image. Need this test
* in case the image height is not a multiple of max_v_samp_factor:
*/
if (num_rows > upsample->rows_to_go)
num_rows = upsample->rows_to_go;
/* And not more than what the client can accept: */
out_rows_avail -= *out_row_ctr;
if (num_rows > out_rows_avail)
num_rows = out_rows_avail;
(*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
(JDIMENSION) upsample->next_row_out,
output_buf + *out_row_ctr,
(int) num_rows);
/* Adjust counts */
*out_row_ctr += num_rows;
upsample->rows_to_go -= num_rows;
upsample->next_row_out += num_rows;
/* When the buffer is emptied, declare this input row group consumed */
if (upsample->next_row_out >= cinfo->max_v_samp_factor)
(*in_row_group_ctr)++;
}
/*
* These are the routines invoked by sep_upsample to upsample pixel values
* of a single component. One row group is processed per call.
*/
/*
* For full-size components, we just make color_buf[ci] point at the
* input buffer, and thus avoid copying any data. Note that this is
* safe only because sep_upsample doesn't declare the input row group
* "consumed" until we are done color converting and emitting it.
*/
METHODDEF(void)
fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
*output_data_ptr = input_data;
}
/*
* This is a no-op version used for "uninteresting" components.
* These components will not be referenced by color conversion.
*/
METHODDEF(void)
noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
*output_data_ptr = NULL; /* safety check */
}
/*
* This version handles any integral sampling ratios.
* This is not used for typical JPEG files, so it need not be fast.
* Nor, for that matter, is it particularly accurate: the algorithm is
* simple replication of the input pixel onto the corresponding output
* pixels. The hi-falutin sampling literature refers to this as a
* "box filter". A box filter tends to introduce visible artifacts,
* so if you are actually going to use 3:1 or 4:1 sampling ratios
* you would be well advised to improve this code.
*/
METHODDEF(void)
int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
{
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
JSAMPARRAY output_data = *output_data_ptr;
register JSAMPROW inptr, outptr;
register JSAMPLE invalue;
register int h;
JSAMPROW outend;
int h_expand, v_expand;
int inrow, outrow;
h_expand = upsample->h_expand[compptr->component_index];
v_expand = upsample->v_expand[compptr->component_index];
inrow = outrow = 0;
while (outrow < cinfo->max_v_samp_factor) {
/* Generate one output row with proper horizontal expansion */
inptr = input_data[inrow];
outptr = output_data[outrow];
outend = outptr + cinfo->output_width;
while (outptr < outend) {
invalue = *inptr++; /* don't need GETJSAMPLE() here */
for (h = h_expand; h > 0; h--) {
*outptr++ = invalue;
}
}
/* Generate any additional output rows by duplicating the first one */
if (v_expand > 1) {
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
v_expand-1, cinfo->output_width);
}
inrow++;
outrow += v_expand;
}
}
/*
* Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
* It's still a box filter.
*/
METHODDEF(void)
h2v1_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 JSAMPLE invalue;
JSAMPROW outend;
int inrow;
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
inptr = input_data[inrow];
outptr = output_data[inrow];
outend = outptr + cinfo->output_width;
while (outptr < outend) {
invalue = *inptr++; /* don't need GETJSAMPLE() here */
*outptr++ = invalue;
*outptr++ = invalue;
}
}
}
/*
* Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
* It's still a box filter.
*/
METHODDEF(void)
h2v2_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 JSAMPLE invalue;
JSAMPROW outend;
int inrow, outrow;
inrow = outrow = 0;
while (outrow < cinfo->max_v_samp_factor) {
inptr = input_data[inrow];
outptr = output_data[outrow];
outend = outptr + cinfo->output_width;
while (outptr < outend) {
invalue = *inptr++; /* don't need GETJSAMPLE() here */
*outptr++ = invalue;
*outptr++ = invalue;
}
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
1, cinfo->output_width);
inrow++;
outrow += 2;
}
}
/*
* 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)
jinit_upsampler (j_decompress_ptr cinfo)
{
my_upsample_ptr upsample;
int ci;
jpeg_component_info * compptr;
boolean need_buffer, do_fancy;
int h_in_group, v_in_group, h_out_group, v_out_group;
upsample = (my_upsample_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(my_upsampler));
cinfo->upsample = (struct jpeg_upsampler *) upsample;
upsample->pub.start_pass = start_pass_upsample;
upsample->pub.upsample = sep_upsample;
upsample->pub.need_context_rows = FALSE; /* until we find out differently */
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.
*/
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
/* 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_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 */
need_buffer = TRUE;
if (! compptr->component_needed) {
/* Don't bother to upsample an uninteresting component. */
upsample->methods[ci] = noop_upsample;
need_buffer = FALSE;
} else if (h_in_group == h_out_group && v_in_group == v_out_group) {
/* Fullsize components can be processed without any work. */
upsample->methods[ci] = fullsize_upsample;
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
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
upsample->methods[ci] = h2v2_upsample;
} else if ((h_out_group % h_in_group) == 0 &&
(v_out_group % v_in_group) == 0) {
/* Generic integral-factors upsampling method */
upsample->methods[ci] = int_upsample;
upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
} else
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
if (need_buffer) {
upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) jround_up((long) cinfo->output_width,
(long) cinfo->max_h_samp_factor),
(JDIMENSION) cinfo->max_v_samp_factor);
}
}
}

261
jpeg-6b/jerror.c Normal file
View file

@ -0,0 +1,261 @@
/*
* jerror.c
*
* 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.
*
* This file contains simple error-reporting and trace-message routines.
* These are suitable for Unix-like systems and others where writing to
* stderr is the right thing to do. 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.
*/
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
#include <stdio.h>
#include <stdlib.h>
#include "jinclude.h"
#include "jpeglib.h"
#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
/*
* Create the message string table.
* We do this from the master message list in jerror.h by re-reading
* jerror.h with a suitable definition for macro JMESSAGE.
* The message table is made an external symbol just in case any applications
* want to refer to it directly.
*/
#define JMESSAGE(code,string) string ,
const char * const jpeg_std_message_table[] = {
#include "jerror.h"
NULL
};
/*
* Error exit handler: must not return to caller.
*
* Applications may override this if they want to get control back after
* an error. Typically one would longjmp somewhere instead of exiting.
* The setjmp buffer can be made a private field within an expanded error
* handler object. Note that the info needed to generate an error message
* is stored in the error object, so you can generate the message now or
* later, at your convenience.
* You should make sure that the JPEG object is cleaned up (with jpeg_abort
* or jpeg_destroy) at some point.
*/
METHODDEF(void)
error_exit (j_common_ptr cinfo)
{
/* Always display the message */
(*cinfo->err->output_message) (cinfo);
/* Let the memory manager delete any temp files before we die */
jpeg_destroy(cinfo);
exit(EXIT_FAILURE);
}
/*
* 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)
output_message (j_common_ptr cinfo)
{
char buffer[JMSG_LENGTH_MAX];
/* 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
}
/*
* Decide whether to emit a trace or warning message.
* msg_level is one of:
* -1: recoverable corrupt-data warning, may want to abort.
* 0: important advisory messages (always display to user).
* 1: first level of tracing detail.
* 2,3,...: successively more detailed tracing messages.
* An application might override this method if it wanted to abort on warnings
* or change the policy about which messages to display.
*/
METHODDEF(void)
emit_message (j_common_ptr cinfo, int msg_level)
{
struct jpeg_error_mgr * err = cinfo->err;
if (msg_level < 0) {
/* It's a warning message. Since corrupt files may generate many warnings,
* the policy implemented here is to show only the first warning,
* unless trace_level >= 3.
*/
if (err->num_warnings == 0 || err->trace_level >= 3)
(*err->output_message) (cinfo);
/* Always count warnings in num_warnings. */
err->num_warnings++;
} else {
/* It's a trace message. Show it if trace_level >= msg_level. */
if (err->trace_level >= msg_level)
(*err->output_message) (cinfo);
}
}
/*
* Format a message string for the most recent JPEG error or message.
* The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
* characters. Note that no '\n' character is added to the string.
* Few applications should need to override this method.
*/
METHODDEF(void)
format_message (j_common_ptr cinfo, char * buffer)
{
struct jpeg_error_mgr * err = cinfo->err;
int msg_code = err->msg_code;
const char * msgtext = NULL;
const char * msgptr;
char ch;
boolean isstring;
/* Look up message string in proper table */
if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
msgtext = err->jpeg_message_table[msg_code];
} else if (err->addon_message_table != NULL &&
msg_code >= err->first_addon_message &&
msg_code <= err->last_addon_message) {
msgtext = err->addon_message_table[msg_code - err->first_addon_message];
}
/* Defend against bogus message number */
if (msgtext == NULL) {
err->msg_parm.i[0] = msg_code;
msgtext = err->jpeg_message_table[0];
}
/* Check for string parameter, as indicated by %s in the message text */
isstring = FALSE;
msgptr = msgtext;
while ((ch = *msgptr++) != '\0') {
if (ch == '%') {
if (*msgptr == 's') isstring = TRUE;
break;
}
}
/* Format the message into the passed buffer */
#if _MSC_VER >= 1400
if (isstring)
sprintf_s(buffer, JMSG_LENGTH_MAX, msgtext, err->msg_parm.s);
else
sprintf_s(buffer, JMSG_LENGTH_MAX, msgtext,
err->msg_parm.i[0], err->msg_parm.i[1],
err->msg_parm.i[2], err->msg_parm.i[3],
err->msg_parm.i[4], err->msg_parm.i[5],
err->msg_parm.i[6], err->msg_parm.i[7]);
#else
if (isstring)
sprintf(buffer, msgtext, err->msg_parm.s);
else
sprintf(buffer, msgtext,
err->msg_parm.i[0], err->msg_parm.i[1],
err->msg_parm.i[2], err->msg_parm.i[3],
err->msg_parm.i[4], err->msg_parm.i[5],
err->msg_parm.i[6], err->msg_parm.i[7]);
#endif
}
/*
* Reset error state variables at start of a new image.
* This is called during compression startup to reset trace/error
* processing to default state, without losing any application-specific
* method pointers. An application might possibly want to override
* this method if it has additional error processing state.
*/
METHODDEF(void)
reset_error_mgr (j_common_ptr cinfo)
{
cinfo->err->num_warnings = 0;
/* trace_level is not reset since it is an application-supplied parameter */
cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
}
/*
* Fill in the standard error-handling methods in a jpeg_error_mgr object.
* Typical call is:
* struct jpeg_compress_struct cinfo;
* struct jpeg_error_mgr err;
*
* cinfo.err = jpeg_std_error(&err);
* after which the application may override some of the methods.
*/
GLOBAL(struct jpeg_error_mgr *)
jpeg_std_error (struct jpeg_error_mgr * err)
{
err->error_exit = error_exit;
err->emit_message = emit_message;
err->output_message = output_message;
err->format_message = format_message;
err->reset_error_mgr = reset_error_mgr;
err->trace_level = 0; /* default = no tracing */
err->num_warnings = 0; /* no warnings emitted yet */
err->msg_code = 0; /* may be useful as a flag for "no error" */
/* Initialize message table pointers */
err->jpeg_message_table = jpeg_std_message_table;
err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
err->addon_message_table = NULL;
err->first_addon_message = 0; /* for safety */
err->last_addon_message = 0;
return err;
}

290
jpeg-6b/jerror.h Normal file
View file

@ -0,0 +1,290 @@
/*
* jerror.h
*
* 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.
*
* This file defines the error and message codes for the JPEG library.
* Edit this file to add new codes, or to translate the message strings to
* some other language.
* A set of error-reporting macros are defined too. Some applications using
* the JPEG library may wish to include this file to get the error codes
* and/or the macros.
*/
/*
* To define the enum list of message codes, include this file without
* defining macro JMESSAGE. To create a message string table, include it
* again with a suitable JMESSAGE definition (see jerror.c for an example).
*/
#ifndef JMESSAGE
#ifndef JERROR_H
/* First time through, define the enum list */
#define JMAKE_ENUM_LIST
#else
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
#define JMESSAGE(code,string)
#endif /* JERROR_H */
#endif /* JMESSAGE */
#ifdef JMAKE_ENUM_LIST
typedef enum {
#define JMESSAGE(code,string) code ,
#endif /* JMAKE_ENUM_LIST */
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_BUFFER_MODE, "Bogus buffer control mode")
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
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")
JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
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_INDEX, "Bogus DHT index %d")
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
JMESSAGE(JERR_FILE_READ, "Input file read error")
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
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_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_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")
JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
JMESSAGE(JERR_QUANT_COMPONENTS,
"Cannot quantize more than %d color components")
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
JMESSAGE(JERR_TFILE_WRITE,
"Write failed on temporary file --- out of disk space?")
JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
JMESSAGE(JMSG_VERSION, JVERSION)
JMESSAGE(JTRC_16BIT_TABLES,
"Caution: quantization tables are too coarse for baseline JPEG")
JMESSAGE(JTRC_ADOBE,
"Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
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: version %d.%02d, density %dx%d %d")
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
"Warning: thumbnail image size does not match data length %u")
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, "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")
JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
JMESSAGE(JTRC_RST, "RST%d")
JMESSAGE(JTRC_SMOOTH_NOTIMPL,
"Smoothing not supported with nonstandard sampling ratios")
JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
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_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")
JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
#ifdef JMAKE_ENUM_LIST
JMSG_LASTMSGCODE
} J_MESSAGE_CODE;
#undef JMAKE_ENUM_LIST
#endif /* JMAKE_ENUM_LIST */
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
#undef JMESSAGE
#ifndef JERROR_H
#define JERROR_H
/* Macros to simplify using the error and trace message stuff */
/* The first parameter is either type of cinfo pointer */
/* Fatal errors (print message and exit) */
#define ERREXIT(cinfo,code) \
((cinfo)->err->msg_code = (code), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT1(cinfo,code,p1) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT2(cinfo,code,p1,p2) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT3(cinfo,code,p1,p2,p3) \
((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->error_exit) ((j_common_ptr) (cinfo)))
#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
((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->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), \
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
#define MAKESTMT(stuff) do { stuff } while (0)
/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
#define WARNMS(cinfo,code) \
((cinfo)->err->msg_code = (code), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
#define WARNMS1(cinfo,code,p1) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
#define WARNMS2(cinfo,code,p1,p2) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
/* Informational/debugging messages */
#define TRACEMS(cinfo,lvl,code) \
((cinfo)->err->msg_code = (code), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#define TRACEMS1(cinfo,lvl,code,p1) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#define TRACEMS2(cinfo,lvl,code,p1,p2) \
((cinfo)->err->msg_code = (code), \
(cinfo)->err->msg_parm.i[0] = (p1), \
(cinfo)->err->msg_parm.i[1] = (p2), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
_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); \
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
(cinfo)->err->msg_code = (code); \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
#define TRACEMSS(cinfo,lvl,code,str) \
((cinfo)->err->msg_code = (code), \
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
#endif /* JERROR_H */

389
jpeg-6b/jidctint.c Normal file
View file

@ -0,0 +1,389 @@
/*
* jidctint.c
*
* 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.
*
* This file contains a slow-but-accurate integer implementation of the
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
* must also perform dequantization of the input coefficients.
*
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
* on each row (or vice versa, but it's more convenient to emit a row at
* a time). Direct algorithms are also available, but they are much more
* complex and seem not to be any faster when reduced to code.
*
* This implementation is based on an algorithm described in
* C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
* Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
* Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
* The primary algorithm described there uses 11 multiplies and 29 adds.
* We use their alternate method with 12 multiplies and 32 adds.
* The advantage of this method is that no data path contains more than one
* multiplication; this allows a very simple and accurate implementation in
* scaled fixed-point arithmetic, with a minimal number of shifts.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */
#ifdef DCT_ISLOW_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
/*
* The poop on this scaling stuff is as follows:
*
* Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
* larger than the true IDCT outputs. The final outputs are therefore
* a factor of N larger than desired; since N=8 this can be cured by
* a simple right shift at the end of the algorithm. The advantage of
* this arrangement is that we save two multiplications per 1-D IDCT,
* because the y0 and y4 inputs need not be divided by sqrt(N).
*
* We have to do addition and subtraction of the integer inputs, which
* is no problem, and multiplication by fractional constants, which is
* a problem to do in integer arithmetic. We multiply all the constants
* by CONST_SCALE and convert them to integer constants (thus retaining
* CONST_BITS bits of precision in the constants). After doing a
* multiplication we have to divide the product by CONST_SCALE, with proper
* rounding, to produce the correct output. This division can be done
* cheaply as a right shift of CONST_BITS bits. We postpone shifting
* as long as possible so that partial sums can be added together with
* full fractional precision.
*
* The outputs of the first pass are scaled up by PASS1_BITS bits so that
* they are represented to better-than-integral precision. These outputs
* require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
* with the recommended scaling. (To scale up 12-bit sample data further, an
* intermediate INT32 array would be needed.)
*
* To avoid overflow of the 32-bit intermediate results in pass 2, we must
* have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
* shows that the values given below are the most effective.
*/
#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_298631336 ((INT32) 2446) /* FIX(0.298631336) */
#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
#else
#define FIX_0_298631336 FIX(0.298631336)
#define FIX_0_390180644 FIX(0.390180644)
#define FIX_0_541196100 FIX(0.541196100)
#define FIX_0_765366865 FIX(0.765366865)
#define FIX_0_899976223 FIX(0.899976223)
#define FIX_1_175875602 FIX(1.175875602)
#define FIX_1_501321110 FIX(1.501321110)
#define FIX_1_847759065 FIX(1.847759065)
#define FIX_1_961570560 FIX(1.961570560)
#define FIX_2_053119869 FIX(2.053119869)
#define FIX_2_562915447 FIX(2.562915447)
#define FIX_3_072711026 FIX(3.072711026)
#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.
*/
GLOBAL(void)
jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col)
{
INT32 tmp0, tmp1, tmp2, tmp3;
INT32 tmp10, tmp11, tmp12, tmp13;
INT32 z1, z2, z3, z4, z5;
JCOEFPTR inptr;
ISLOW_MULT_TYPE * quantptr;
int * wsptr;
JSAMPROW outptr;
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
int ctr;
int workspace[DCTSIZE2]; /* buffers data between passes */
SHIFT_TEMPS
/* Pass 1: process columns from input, store into work array. */
/* Note results are scaled up by sqrt(8) compared to a true IDCT; */
/* furthermore, we scale the results by 2**PASS1_BITS. */
inptr = coef_block;
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
wsptr = workspace;
for (ctr = DCTSIZE; ctr > 0; ctr--) {
/* Due to quantization, we will usually find that many of the input
* coefficients are zero, especially the AC terms. We can exploit this
* by short-circuiting the IDCT calculation for any column in which all
* the AC terms are zero. In that case each output is equal to the
* DC coefficient (with scale factor as needed).
* With typical images and quantization tables, half or more of the
* column DCT calculations can be simplified this way.
*/
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
wsptr[DCTSIZE*0] = dcval;
wsptr[DCTSIZE*1] = dcval;
wsptr[DCTSIZE*2] = dcval;
wsptr[DCTSIZE*3] = dcval;
wsptr[DCTSIZE*4] = dcval;
wsptr[DCTSIZE*5] = dcval;
wsptr[DCTSIZE*6] = dcval;
wsptr[DCTSIZE*7] = dcval;
inptr++; /* advance pointers to next column */
quantptr++;
wsptr++;
continue;
}
/* Even part: reverse the even part of the forward DCT. */
/* The rotator is sqrt(2)*c(-6). */
z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
tmp0 = (z2 + z3) << CONST_BITS;
tmp1 = (z2 - z3) << CONST_BITS;
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
/* Odd part per figure 8; the matrix is unitary and hence its
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
*/
tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
z1 = tmp0 + tmp3;
z2 = tmp1 + tmp2;
z3 = tmp0 + tmp2;
z4 = tmp1 + tmp3;
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z3 += z5;
z4 += z5;
tmp0 += z1 + z3;
tmp1 += z2 + z4;
tmp2 += z2 + z3;
tmp3 += z1 + z4;
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
inptr++; /* advance pointers to next column */
quantptr++;
wsptr++;
}
/* 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, */
/* and also undo the PASS1_BITS scaling. */
wsptr = workspace;
for (ctr = 0; ctr < DCTSIZE; ctr++) {
outptr = output_buf[ctr] + output_col;
/* Rows of zeroes can be exploited in the same way as we did with columns.
* However, the column calculation has created many nonzero AC terms, so
* the simplification applies less often (typically 5% to 10% of the time).
* On machines with very fast multiplication, it's possible that the
* test takes more time than it's worth. In that case this section
* may be commented out.
*/
#ifndef NO_ZERO_ROW_TEST
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
/* AC terms all zero */
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
& RANGE_MASK];
outptr[0] = dcval;
outptr[1] = dcval;
outptr[2] = dcval;
outptr[3] = dcval;
outptr[4] = dcval;
outptr[5] = dcval;
outptr[6] = dcval;
outptr[7] = dcval;
wsptr += DCTSIZE; /* advance pointer to next row */
continue;
}
#endif
/* Even part: reverse the even part of the forward DCT. */
/* The rotator is sqrt(2)*c(-6). */
z2 = (INT32) wsptr[2];
z3 = (INT32) wsptr[6];
z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
tmp10 = tmp0 + tmp3;
tmp13 = tmp0 - tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp1 - tmp2;
/* Odd part per figure 8; the matrix is unitary and hence its
* transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
*/
tmp0 = (INT32) wsptr[7];
tmp1 = (INT32) wsptr[5];
tmp2 = (INT32) wsptr[3];
tmp3 = (INT32) wsptr[1];
z1 = tmp0 + tmp3;
z2 = tmp1 + tmp2;
z3 = tmp0 + tmp2;
z4 = tmp1 + tmp3;
z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
z3 += z5;
z4 += z5;
tmp0 += z1 + z3;
tmp1 += z2 + z4;
tmp2 += z2 + z3;
tmp3 += z1 + z4;
/* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
CONST_BITS+PASS1_BITS+3)
& RANGE_MASK];
wsptr += DCTSIZE; /* advance pointer to next row */
}
}
#endif /* DCT_ISLOW_SUPPORTED */

91
jpeg-6b/jinclude.h Normal file
View file

@ -0,0 +1,91 @@
/*
* jinclude.h
*
* Copyright (C) 1991-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 exists to provide a single place to fix any problems with
* including the wrong system include files. (Common problems are taken
* care of by the standard jconfig symbols, but on really weird systems
* you may have to edit this file.)
*
* NOTE: this file is NOT intended to be included by applications using the
* JPEG library. Most applications need only include jpeglib.h.
*/
/* Include auto-config file to find out which system include files we need. */
#include "jconfig.h" /* auto configuration options */
#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
/*
* We need the NULL macro and size_t typedef.
* On an ANSI-conforming system it is sufficient to include <stddef.h>.
* Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
* pull in <sys/types.h> as well.
* Note that the core JPEG library does not require <stdio.h>;
* only the default error handler and data source/destination modules do.
* But we must pull it in because of the references to FILE in jpeglib.h.
* You can remove those references if you want to compile without <stdio.h>.
*/
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef NEED_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <stdio.h>
/*
* We need memory copying and zeroing functions, plus strncpy().
* ANSI and System V implementations declare these in <string.h>.
* BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
* Some systems may declare memset and memcpy in <memory.h>.
*
* NOTE: we assume the size parameters to these functions are of type size_t.
* Change the casts in these macros if not!
*/
#ifdef NEED_BSD_STRINGS
#include <strings.h>
#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
#else /* not BSD, assume ANSI/SysV string lib */
#include <string.h>
#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
#endif
/*
* In ANSI C, and indeed any rational implementation, size_t is also the
* type returned by sizeof(). However, it seems there are some irrational
* implementations out there, in which sizeof() returns an int even though
* size_t is defined as long or unsigned long. To ensure consistent results
* we always use this SIZEOF() macro in place of using sizeof() directly.
*/
#define SIZEOF(object) ((size_t) sizeof(object))
/*
* The modules that use fread() and fwrite() always invoke them through
* these macros. On some systems you may need to twiddle the argument casts.
* CAUTION: argument order is different from underlying functions!
*/
#define JFREAD(file,buf,sizeofbuf) \
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
#define JFWRITE(file,buf,sizeofbuf) \
((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))

652
jpeg-6b/jmemmgr.c Normal file
View file

@ -0,0 +1,652 @@
/*
* jmemmgr.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 the JPEG system-independent memory management
* routines. This code is usable across a wide variety of machines; most
* of the system dependencies have been isolated in a separate file.
* The major functions provided here are:
* * pool-based allocation and freeing of memory;
* * policy decisions about how to divide available memory among the
* virtual arrays;
* * control logic for swapping virtual arrays between main memory and
* backing storage.
* The separate system-dependent file provides the actual backing-storage
* access code, and it contains the policy decision about how much total
* main memory to use.
* This file is system-dependent in the sense that some of its functions
* are unnecessary in some systems. For example, if there is enough virtual
* memory so that backing storage will never be used, much of the virtual
* array control logic could be removed. (Of course, if you have that much
* memory then you shouldn't care about a little bit of unused code...)
*/
#define JPEG_INTERNALS
#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */
#include "jinclude.h"
#include "jpeglib.h"
/*
* Some important notes:
* The allocation routines provided here must never return NULL.
* They should exit to error_exit if unsuccessful.
*
* It's not a good idea to try to merge the sarray and barray routines,
* even though they are textually almost the same, because samples are
* usually stored as bytes while coefficients are shorts or ints. Thus,
* in machines where byte pointers have a different representation from
* word pointers, the resulting machine code could not be the same.
*/
/*
* Many machines require storage alignment: longs must start on 4-byte
* boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc()
* always returns pointers that are multiples of the worst-case alignment
* requirement, and we had better do so too.
* There isn't any really portable way to determine the worst-case alignment
* requirement. This module assumes that the alignment requirement is
* multiples of sizeof(ALIGN_TYPE).
* By default, we define ALIGN_TYPE as double. This is necessary on some
* workstations (where doubles really do need 8-byte alignment) and will work
* fine on nearly everything. If your machine has lesser alignment needs,
* you can save a few bytes by making ALIGN_TYPE smaller.
* The only place I know of where this will NOT work is certain Macintosh
* 680x0 compilers that define double as a 10-byte IEEE extended float.
* Doing 10-byte alignment is counterproductive because longwords won't be
* aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have
* such a compiler.
*/
#ifndef ALIGN_TYPE /* so can override from jconfig.h */
#define ALIGN_TYPE double
#endif
/*
* We allocate objects from "pools", where each pool is gotten with a single
* request to jpeg_get_small() or jpeg_get_large(). There is no per-object
* overhead within a pool, except for alignment padding. Each pool has a
* header with a link to the next pool of the same class.
* Small and large pool headers are identical except that the latter's
* link pointer must be FAR on 80x86 machines.
* Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
* field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
* of the alignment requirement of ALIGN_TYPE.
*/
typedef union small_pool_struct * small_pool_ptr;
typedef union small_pool_struct {
struct {
small_pool_ptr next; /* next in list of pools */
size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_left; /* bytes still available in this pool */
} hdr;
ALIGN_TYPE dummy; /* included in union to ensure alignment */
} small_pool_hdr;
typedef union large_pool_struct * large_pool_ptr;
typedef union large_pool_struct {
struct {
large_pool_ptr next; /* next in list of pools */
size_t bytes_used; /* how many bytes already used within pool */
size_t bytes_left; /* bytes still available in this pool */
} hdr;
ALIGN_TYPE dummy; /* included in union to ensure alignment */
} large_pool_hdr;
/*
* Here is the full definition of a memory manager object.
*/
typedef struct {
struct jpeg_memory_mgr pub; /* public fields */
/* Each pool identifier (lifetime class) names a linked list of pools. */
small_pool_ptr small_list[JPOOL_NUMPOOLS];
large_pool_ptr large_list[JPOOL_NUMPOOLS];
/* Since we only have one lifetime class of virtual arrays, only one
* linked list is necessary (for each datatype). Note that the virtual
* array control blocks being linked together are actually stored somewhere
* in the small-pool list.
*/
jvirt_barray_ptr virt_barray_list;
/* alloc_sarray and alloc_barray set this value for use by virtual
* array routines.
*/
JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */
} my_memory_mgr;
typedef my_memory_mgr * my_mem_ptr;
/*
* The control blocks for virtual arrays.
* Note that these blocks are allocated in the "small" pool area.
* System-dependent info for the associated backing store (if any) is hidden
* inside the backing_store_info struct.
*/
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 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? */
jvirt_barray_ptr next; /* link to next virtual barray control block */
};
LOCAL(void)
out_of_memory (j_common_ptr cinfo, int which)
/* Report an out-of-memory error and stop execution */
{
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
}
/*
* Allocation of "small" objects.
*
* For these, we use pooled storage. When a new pool must be created,
* we try to get enough space for the current request plus a "slop" factor,
* where the slop will be the amount of leftover space in the new pool.
* The speed vs. space tradeoff is largely determined by the slop values.
* A different slop value is provided for each pool class (lifetime),
* and we also distinguish the first pool of a class from later ones.
* NOTE: the values given work fairly well on both 16- and 32-bit-int
* machines, but may be too small if longs are 64 bits or more.
*/
static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
{
1600, /* first PERMANENT pool */
16000 /* first IMAGE pool */
};
static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
{
0, /* additional PERMANENT pools */
5000 /* additional IMAGE pools */
};
#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
METHODDEF(void *)
alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
/* Allocate a "small" object */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
small_pool_ptr hdr_ptr, prev_hdr_ptr;
char * data_ptr;
size_t odd_bytes, min_request, slop;
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
if (odd_bytes > 0)
sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
/* See if space is available in any existing pool */
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
prev_hdr_ptr = NULL;
hdr_ptr = mem->small_list[pool_id];
while (hdr_ptr != NULL) {
if (hdr_ptr->hdr.bytes_left >= sizeofobject)
break; /* found pool with enough space */
prev_hdr_ptr = hdr_ptr;
hdr_ptr = hdr_ptr->hdr.next;
}
/* Time to make a new pool? */
if (hdr_ptr == NULL) {
/* min_request is what we need now, slop is what will be leftover */
min_request = sizeofobject + SIZEOF(small_pool_hdr);
if (prev_hdr_ptr == NULL) /* first pool in class? */
slop = first_pool_slop[pool_id];
else
slop = extra_pool_slop[pool_id];
/* Try to get space, if fail reduce slop and try again */
for (;;) {
hdr_ptr = (small_pool_ptr) malloc(min_request + slop);
if (hdr_ptr != NULL)
break;
slop /= 2;
if (slop < MIN_SLOP) /* give up when it gets real small */
out_of_memory(cinfo, 2); /* jpeg_get_small failed */
}
/* Success, initialize the new pool header and add to end of list */
hdr_ptr->hdr.next = NULL;
hdr_ptr->hdr.bytes_used = 0;
hdr_ptr->hdr.bytes_left = sizeofobject + slop;
if (prev_hdr_ptr == NULL) /* first pool in class? */
mem->small_list[pool_id] = hdr_ptr;
else
prev_hdr_ptr->hdr.next = hdr_ptr;
}
/* OK, allocate the object from the current pool */
data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
hdr_ptr->hdr.bytes_used += sizeofobject;
hdr_ptr->hdr.bytes_left -= sizeofobject;
return (void *) data_ptr;
}
/*
* Allocation of "large" objects.
*
* The external semantics of these are the same as "small" objects,
* except that FAR pointers are used on 80x86. However the pool
* management heuristics are quite different. We assume that each
* request is large enough that it may as well be passed directly to
* jpeg_get_large; the pool management just links everything together
* so that we can free it all on demand.
* Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
* structures. The routines that create these structures (see below)
* deliberately bunch rows together to ensure a large request size.
*/
METHODDEF(void *)
alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
/* Allocate a "large" object */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
large_pool_ptr hdr_ptr;
size_t odd_bytes;
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
if (odd_bytes > 0)
sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
/* Always make a new pool */
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
hdr_ptr = (large_pool_ptr) malloc(sizeofobject + SIZEOF(large_pool_hdr));
if (hdr_ptr == NULL)
out_of_memory(cinfo, 4); /* jpeg_get_large failed */
/* Success, initialize the new pool header and add to list */
hdr_ptr->hdr.next = mem->large_list[pool_id];
/* We maintain space counts in each pool header for statistical purposes,
* even though they are not needed for allocation.
*/
hdr_ptr->hdr.bytes_used = sizeofobject;
hdr_ptr->hdr.bytes_left = 0;
mem->large_list[pool_id] = hdr_ptr;
return (void *) (hdr_ptr + 1); /* point to first data byte in pool */
}
/*
* Creation of 2-D sample arrays.
* The pointers are in near heap, the samples themselves in FAR heap.
*
* To minimize allocation overhead and to allow I/O of large contiguous
* blocks, we allocate the sample rows in groups of as many rows as possible
* without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
* NB: the virtual array control routines, later in this file, know about
* this chunking of rows. The rowsperchunk value is left in the mem manager
* object so that it can be saved away if this sarray is the workspace for
* a virtual array.
*/
METHODDEF(JSAMPARRAY)
alloc_sarray (j_common_ptr cinfo, int pool_id,
JDIMENSION samplesperrow, JDIMENSION numrows)
/* Allocate a 2-D sample array */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
JSAMPARRAY result;
JSAMPROW workspace;
JDIMENSION i;
/* Calculate max # of rows allowed in one allocation chunk */
mem->last_rowsperchunk = numrows;
/* Get space for row pointers (small object) */
result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
(size_t) (numrows * SIZEOF(JSAMPROW)));
/* Get the rows themselves (large objects) */
workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
(size_t) ((size_t) numrows * (size_t) samplesperrow
* SIZEOF(JSAMPLE)));
for (i = 0; i < numrows; i++) {
result[i] = workspace;
workspace += samplesperrow;
}
return result;
}
/*
* Creation of 2-D coefficient-block arrays.
* This is essentially the same as the code for sample arrays, above.
*/
METHODDEF(JBLOCKARRAY)
alloc_barray (j_common_ptr cinfo, int pool_id,
JDIMENSION blocksperrow, JDIMENSION numrows)
/* Allocate a 2-D coefficient-block array */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
JBLOCKARRAY result;
JBLOCKROW workspace;
JDIMENSION i;
/* Calculate max # of rows allowed in one allocation chunk */
mem->last_rowsperchunk = numrows;
/* Get space for row pointers (small object) */
result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
(size_t) (numrows * SIZEOF(JBLOCKROW)));
/* Get the rows themselves (large objects) */
workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
(size_t) ((size_t) numrows * (size_t) blocksperrow
* SIZEOF(JBLOCK)));
for (i = 0; i < numrows; i++) {
result[i] = workspace;
workspace += blocksperrow;
}
return result;
}
/*
* About virtual array management:
*
* The above "normal" array routines are only used to allocate strip buffers
* (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 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
* total amount of space needed is known (approximately, anyway), so free
* memory can be divided up fairly.
*
* The access_virt_array routines are responsible for making a specific strip
* area accessible (after reading or writing the backing file, if necessary).
* Note that the access routines are told whether the caller intends to modify
* the accessed strip; during a read-only pass this saves having to rewrite
* data to disk. The access routines are also responsible for pre-zeroing
* any newly accessed rows, if pre-zeroing was requested.
*
* 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_barray_ptr)
request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
JDIMENSION blocksperrow, JDIMENSION numrows,
JDIMENSION maxaccess)
/* Request a virtual 2-D coefficient-block array */
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
jvirt_barray_ptr result;
/* Only IMAGE-lifetime virtual arrays are currently supported */
if (pool_id != JPOOL_IMAGE)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
/* get control block */
result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
SIZEOF(struct jvirt_barray_control));
result->mem_buffer = NULL; /* marks array not yet realized */
result->rows_in_array = numrows;
result->blocksperrow = blocksperrow;
result->maxaccess = maxaccess;
result->pre_zero = pre_zero;
result->next = mem->virt_barray_list; /* add to list of virtual arrays */
mem->virt_barray_list = result;
return result;
}
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_minheight;
long minheights;
jvirt_barray_ptr bptr;
/* 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_minheight = 0;
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
if (bptr->mem_buffer == NULL) { /* if not realized yet */
space_per_minheight += (long) bptr->maxaccess *
(long) bptr->blocksperrow * SIZEOF(JBLOCK);
}
}
if (space_per_minheight <= 0)
return; /* no unrealized arrays, no work */
/* Allocate the in-memory buffers and initialize backing store as needed. */
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
if (bptr->mem_buffer == NULL) { /* if not realized yet */
minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
bptr->rows_in_mem = bptr->rows_in_array;
bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
bptr->blocksperrow, bptr->rows_in_mem);
bptr->rowsperchunk = mem->last_rowsperchunk;
bptr->cur_start_row = 0;
bptr->first_undef_row = 0;
bptr->dirty = FALSE;
}
}
}
METHODDEF(JBLOCKARRAY)
access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
JDIMENSION start_row, JDIMENSION num_rows,
boolean writable)
/* Access the part of a virtual block array starting at start_row */
/* 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 (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 || end_row > ptr->cur_start_row+ptr->rows_in_mem)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* 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) {
MEMZERO((void *) 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)
ptr->dirty = TRUE;
/* Return address of proper part of the buffer */
return ptr->mem_buffer + (start_row - ptr->cur_start_row);
}
/*
* Release all objects belonging to a specified pool.
*/
METHODDEF(void)
free_pool (j_common_ptr cinfo, int pool_id)
{
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
small_pool_ptr shdr_ptr;
large_pool_ptr lhdr_ptr;
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
/* Release large objects */
lhdr_ptr = mem->large_list[pool_id];
mem->large_list[pool_id] = NULL;
while (lhdr_ptr != NULL) {
large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
free(lhdr_ptr);
lhdr_ptr = next_lhdr_ptr;
}
/* Release small objects */
shdr_ptr = mem->small_list[pool_id];
mem->small_list[pool_id] = NULL;
while (shdr_ptr != NULL) {
small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
free(shdr_ptr);
shdr_ptr = next_shdr_ptr;
}
}
/*
* Close up shop entirely.
* Note that this cannot be called unless cinfo->mem is non-NULL.
*/
METHODDEF(void)
self_destruct (j_common_ptr cinfo)
{
int pool;
/* Close all backing store, release all memory.
* Releasing pools in reverse order might help avoid fragmentation
* with some (brain-damaged) malloc libraries.
*/
for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
free_pool(cinfo, pool);
}
/* Release the memory manager control block too. */
free(cinfo->mem);
cinfo->mem = NULL; /* ensures I will be called only once */
}
/*
* Memory manager initialization.
* When this is called, only the error manager pointer is valid in cinfo!
*/
GLOBAL(void)
jinit_memory_mgr (j_common_ptr cinfo)
{
my_mem_ptr mem;
int pool;
cinfo->mem = NULL; /* for safety if init fails */
/* Check for configuration errors.
* SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
* doesn't reflect any real hardware alignment requirement.
* The test is a little tricky: for X>0, X and X-1 have no one-bits
* in common if and only if X is a power of 2, ie has only one one-bit.
* Some compilers may give an "unreachable code" warning here; ignore it.
*/
if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
/* Attempt to allocate memory manager's control block */
mem = (my_mem_ptr) malloc(SIZEOF(my_memory_mgr));
if (mem == NULL) {
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
}
/* OK, fill in the method pointers */
mem->pub.alloc_small = alloc_small;
mem->pub.alloc_large = alloc_large;
mem->pub.alloc_sarray = alloc_sarray;
mem->pub.alloc_barray = alloc_barray;
mem->pub.request_virt_barray = request_virt_barray;
mem->pub.realize_virt_arrays = realize_virt_arrays;
mem->pub.access_virt_barray = access_virt_barray;
mem->pub.free_pool = free_pool;
mem->pub.self_destruct = self_destruct;
/* Initialize working state */
for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
mem->small_list[pool] = NULL;
mem->large_list[pool] = NULL;
}
mem->virt_barray_list = NULL;
/* Declare ourselves open for business */
cinfo->mem = & mem->pub;
}

330
jpeg-6b/jmorecfg.h Normal file
View file

@ -0,0 +1,330 @@
/*
* jmorecfg.h
*
* 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 additional configuration options that customize the
* JPEG software for special applications or support machine-dependent
* optimizations. Most users will not need to touch this file.
*/
/*
* Define BITS_IN_JSAMPLE as either
* 8 for 8-bit sample values (the usual setting)
* 12 for 12-bit sample values
* Only 8 and 12 are legal data precisions for lossy JPEG according to the
* JPEG standard, and the IJG code does not support anything else!
* We do not support run-time selection of data precision, sorry.
*/
#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
/*
* Maximum number of components (color channels) allowed in JPEG image.
* To meet the letter of the JPEG spec, set this to 255. However, darn
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
* really short on memory. (Each allowed component costs a hundred or so
* bytes of storage, whether actually used in an image or not.)
*/
#define MAX_COMPONENTS 10 /* maximum number of image components */
/*
* Basic data types.
* You may need to change these if you have a machine with unusual data
* type sizes; for example, "char" not 8 bits, "short" not 16 bits,
* or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
* but it had better be at least 16.
*/
/* Representation of a single sample (pixel element value).
* We frequently allocate large arrays of these, so it's important to keep
* them small. But if you have memory to burn and access to char or short
* arrays is very slow on your hardware, you might want to change these.
*/
#if BITS_IN_JSAMPLE == 8
/* JSAMPLE should be the smallest type that will hold the values 0..255.
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
*/
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char JSAMPLE;
#define GETJSAMPLE(value) ((int) (value))
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JSAMPLE;
#ifdef CHAR_IS_UNSIGNED
#define GETJSAMPLE(value) ((int) (value))
#else
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */
#endif /* HAVE_UNSIGNED_CHAR */
#define MAXJSAMPLE 255
#define CENTERJSAMPLE 128
#endif /* BITS_IN_JSAMPLE == 8 */
#if BITS_IN_JSAMPLE == 12
/* JSAMPLE should be the smallest type that will hold the values 0..4095.
* On nearly all machines "short" will do nicely.
*/
typedef short JSAMPLE;
#define GETJSAMPLE(value) ((int) (value))
#define MAXJSAMPLE 4095
#define CENTERJSAMPLE 2048
#endif /* BITS_IN_JSAMPLE == 12 */
/* Representation of a DCT frequency coefficient.
* This should be a signed value of at least 16 bits; "short" is usually OK.
* Again, we allocate large arrays of these, but you can change to int
* if you have memory to burn and "short" is really slow.
*/
typedef short JCOEF;
/* Compressed datastreams are represented as arrays of JOCTET.
* These must be EXACTLY 8 bits wide, at least once they are written to
* external storage. Note that when using the stdio data source/destination
* managers, this is also the data type passed to fread/fwrite.
*/
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char JOCTET;
#define GETJOCTET(value) (value)
#else /* not HAVE_UNSIGNED_CHAR */
typedef char JOCTET;
#ifdef CHAR_IS_UNSIGNED
#define GETJOCTET(value) (value)
#else
#define GETJOCTET(value) ((value) & 0xFF)
#endif /* CHAR_IS_UNSIGNED */
#endif /* HAVE_UNSIGNED_CHAR */
/* These typedefs are used for various table entries and so forth.
* They must be at least as wide as specified; but making them too big
* won't cost a huge amount of memory, so we don't provide special
* extraction code like we did for JSAMPLE. (In other words, these
* typedefs live at a different point on the speed/space tradeoff curve.)
*/
/* UINT8 must hold at least the values 0..255. */
#ifdef HAVE_UNSIGNED_CHAR
typedef unsigned char UINT8;
#else /* not HAVE_UNSIGNED_CHAR */
#ifdef CHAR_IS_UNSIGNED
typedef char UINT8;
#else /* not CHAR_IS_UNSIGNED */
typedef short UINT8;
#endif /* CHAR_IS_UNSIGNED */
#endif /* HAVE_UNSIGNED_CHAR */
/* UINT16 must hold at least the values 0..65535. */
#ifdef HAVE_UNSIGNED_SHORT
typedef unsigned short UINT16;
#else /* not HAVE_UNSIGNED_SHORT */
typedef unsigned int UINT16;
#endif /* HAVE_UNSIGNED_SHORT */
/* INT16 must hold at least the values -32768..32767. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
typedef short INT16;
#endif
/* INT32 must hold at least signed 32-bit values. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
typedef long INT32;
#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
* "unsigned int" is sufficient on all machines. However, if you need to
* handle larger images and you don't mind deviating from the spec, you
* can change this datatype.
*/
typedef unsigned int JDIMENSION;
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
/* 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.
*/
/* 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
/*
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
* in standard header files. Or you may have conflicts with application-
* specific header files that you want to include together with these files.
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
*/
#ifndef HAVE_BOOLEAN
typedef int boolean;
#endif
#ifndef FALSE /* in case these macros already exist */
#define FALSE 0 /* values of boolean */
#endif
#ifndef TRUE
#define TRUE 1
#endif
/*
* The remaining options affect code selection within the JPEG library,
* but they don't need to be visible to most applications using the library.
* To minimize application namespace pollution, the symbols won't be
* defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
*/
#ifdef JPEG_INTERNALS
#define JPEG_INTERNAL_OPTIONS
#endif
#ifdef JPEG_INTERNAL_OPTIONS
/*
* These defines indicate whether to include various optional functions.
* Undefining some of these symbols will produce a smaller but less capable
* library. Note that you can leave certain source files out of the
* compilation/linking process if you've #undef'd the corresponding symbols.
* (You may HAVE to do that if your compiler doesn't like null source files.)
*/
/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
/* Capability options common to encoder and decoder: */
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
/* Decoder capability options: */
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
/* more capability options later, no doubt */
/*
* Ordering of RGB data in scanlines passed to or from the application.
* If your application wants to deal with data in the order B,G,R, just
* change these macros. You can also deal with formats such as R,G,B,X
* (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
* 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
* is not 3 (they don't understand about dummy color components!). So you
* can't use color quantization if you change that value.
*/
#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
#define RGB_GREEN 1 /* Offset of Green */
#define RGB_BLUE 2 /* Offset of Blue */
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
/* Definitions for speed-related optimizations. */
/* If your compiler supports inline functions, define INLINE
* as the inline keyword; otherwise define it as empty.
*/
#ifndef INLINE
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
#define INLINE __inline__
#endif
#ifdef _MSC_VER
#define INLINE __inline
#endif
#ifndef INLINE
#define INLINE /* default is to define it as empty */
#endif
#endif
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
*/
#ifndef MULTIPLIER
#define MULTIPLIER int /* type for fastest integer multiply */
#endif
/* FAST_FLOAT should be either float or double, whichever is done faster
* by your compiler. (Note that this type is only used in the floating point
* DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
* Typically, float is faster in ANSI C compilers, while double is faster in
* pre-ANSI compilers (because they insist on converting to double anyway).
* The code below therefore chooses float if we have ANSI-style prototypes.
*/
#ifndef FAST_FLOAT
#ifdef HAVE_PROTOTYPES
#define FAST_FLOAT float
#else
#define FAST_FLOAT double
#endif
#endif
#endif /* JPEG_INTERNAL_OPTIONS */

284
jpeg-6b/jpeg-6b.vcproj Normal file
View file

@ -0,0 +1,284 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="jpeg-6b"
ProjectGUID="{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}"
RootNamespace="jpeg6b"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
EnableIntrinsicFunctions="true"
OmitFramePointers="true"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CallingConvention="1"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\jcomapi.c"
>
</File>
<File
RelativePath=".\jdapimin.c"
>
</File>
<File
RelativePath=".\jdapistd.c"
>
</File>
<File
RelativePath=".\jdatasrc.c"
>
</File>
<File
RelativePath=".\jdcoefct.c"
>
</File>
<File
RelativePath=".\jdcolor.c"
>
</File>
<File
RelativePath=".\jddctmgr.c"
>
</File>
<File
RelativePath=".\jdhuff.c"
>
</File>
<File
RelativePath=".\jdinput.c"
>
</File>
<File
RelativePath=".\jdmainct.c"
>
</File>
<File
RelativePath=".\jdmarker.c"
>
</File>
<File
RelativePath=".\jdmaster.c"
>
</File>
<File
RelativePath=".\jdmerge.c"
>
</File>
<File
RelativePath=".\jdphuff.c"
>
</File>
<File
RelativePath=".\jdpostct.c"
>
</File>
<File
RelativePath=".\jdsample.c"
>
</File>
<File
RelativePath=".\jerror.c"
>
</File>
<File
RelativePath=".\jidctint.c"
>
</File>
<File
RelativePath=".\jmemmgr.c"
>
</File>
<File
RelativePath=".\jutils.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\jconfig.h"
>
</File>
<File
RelativePath=".\jdct.h"
>
</File>
<File
RelativePath=".\jdhuff.h"
>
</File>
<File
RelativePath=".\jerror.h"
>
</File>
<File
RelativePath=".\jinclude.h"
>
</File>
<File
RelativePath=".\jmorecfg.h"
>
</File>
<File
RelativePath=".\jpegint.h"
>
</File>
<File
RelativePath=".\jpeglib.h"
>
</File>
<File
RelativePath=".\jversion.h"
>
</File>
</Filter>
<File
RelativePath=".\readme-zdoom.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

261
jpeg-6b/jpegint.h Normal file
View file

@ -0,0 +1,261 @@
/*
* jpegint.h
*
* 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 provides common declarations for the various JPEG modules.
* These declarations are considered internal to the JPEG library; most
* applications using the library shouldn't need to include this file.
*/
/* Declarations for both compression & decompression */
typedef enum { /* Operating modes for buffer controllers */
JBUF_PASS_THRU, /* Plain stripwise operation */
/* 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 (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 /* 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 decompression modules */
/* Master control module */
struct jpeg_decomp_master {
JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
};
/* 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) */
struct jpeg_d_main_controller {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
JMETHOD(void, process_data, (j_decompress_ptr cinfo,
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail));
};
/* Coefficient buffer control */
struct jpeg_d_coef_controller {
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) */
struct jpeg_d_post_controller {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
JMETHOD(void, post_process_data, (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));
};
/* Marker reading & parsing */
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_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;
/* State of marker reader --- nominally internal, but applications
* supplying COM or APPn handlers might like to know the state.
*/
boolean saw_SOI; /* found SOI? */
boolean saw_SOF; /* found SOF? */
int next_restart_num; /* next restart number expected (0-7) */
unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
};
/* Entropy decoding */
struct jpeg_entropy_decoder {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
JBLOCKROW *MCU_data));
/* This is here to share code between baseline and progressive decoders; */
/* other modules probably should not use it */
boolean insufficient_data; /* set TRUE after emitting warning */
};
/* Inverse DCT (also performs dequantization) */
typedef JMETHOD(void, inverse_DCT_method_ptr,
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col));
struct jpeg_inverse_dct {
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];
};
/* Upsampling (note that upsampler must also call color converter) */
struct jpeg_upsampler {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
JMETHOD(void, upsample, (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));
boolean need_context_rows; /* TRUE if need rows above & below */
};
/* Colorspace conversion */
struct jpeg_color_deconverter {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows));
};
/* Color quantization or color precision reduction */
struct jpeg_color_quantizer {
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
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));
};
/* Miscellaneous useful macros */
#undef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#undef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
/* We assume that right shift corresponds to signed division by 2 with
* rounding towards minus infinity. This is correct for typical "arithmetic
* shift" instructions that shift in copies of the sign bit. But some
* C compilers implement >> with an unsigned shift. For these machines you
* must define RIGHT_SHIFT_IS_UNSIGNED.
* RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
* It is only applied with constant shift counts. SHIFT_TEMPS must be
* included in the variables of any routine using RIGHT_SHIFT.
*/
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define SHIFT_TEMPS INT32 shift_temp;
#define RIGHT_SHIFT(x,shft) \
((shift_temp = (x)) < 0 ? \
(shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
(shift_temp >> (shft)))
#else
#define SHIFT_TEMPS
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
#endif
/* Compression module initialization routines */
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,
boolean need_full_buffer));
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_phuff_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,
boolean need_full_buffer));
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,
boolean need_full_buffer));
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_phuff_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));
/* Utility routines in jutils.c */
static INLINE 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 */
{
return (a + b - 1L) / b;
}
static INLINE 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 */
{
a += b - 1L;
return a - (a % 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));
/* 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 */

941
jpeg-6b/jpeglib.h Normal file
View file

@ -0,0 +1,941 @@
/*
* jpeglib.h
*
* 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.
*
* This file defines the application interface for the JPEG library.
* Most applications using the library need only include this file,
* and perhaps jerror.h if they want to know the exact error codes.
*/
#ifndef JPEGLIB_H
#define JPEGLIB_H
/*
* First we include the configuration files that record how this
* installation of the JPEG library is set up. jconfig.h can be
* generated automatically for many systems. jmorecfg.h contains
* manual configuration options that most people need not worry about.
*/
#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
#include "jconfig.h" /* widely used configuration options */
#endif
#include "jmorecfg.h" /* seldom changed options */
/* Version ID for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
*/
#define JPEG_LIB_VERSION 62 /* Version 6b */
/* Various constants determining the sizes of things.
* All of these are specified by the JPEG standard, so don't change them
* if you want to be compatible.
*/
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
#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 */
/* 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.
*/
#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
/* Data structures for images (arrays of samples and of DCT coefficients).
* On 80x86 machines, the image arrays are too big for near pointers,
* but the pointer arrays can fit in near memory.
*/
typedef JSAMPLE *JSAMPROW; /* ptr to one image row of pixel samples. */
typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
typedef JBLOCK *JBLOCKROW; /* pointer to one row of coefficient blocks */
typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
typedef JCOEF *JCOEFPTR; /* useful in a couple of places */
/* Types for JPEG compression parameters and working tables. */
/* DCT coefficient quantization tables. */
typedef struct {
/* 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
* the table is created, and set TRUE when it's been output to the file.
* You could suppress output of a table by setting this to TRUE.
* (See jpeg_suppress_tables for an example.)
*/
boolean sent_table; /* TRUE when table has been output */
} JQUANT_TBL;
/* Huffman coding tables. */
typedef struct {
/* These two fields directly represent the contents of a JPEG DHT marker */
UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
/* length k bits; bits[0] is unused */
UINT8 huffval[256]; /* The symbols, in order of incr code length */
/* This field is used only during compression. It's initialized FALSE when
* the table is created, and set TRUE when it's been output to the file.
* You could suppress output of a table by setting this to TRUE.
* (See jpeg_suppress_tables for an example.)
*/
boolean sent_table; /* TRUE when table has been output */
} JHUFF_TBL;
/* Basic info about one component (color channel). */
typedef struct {
/* These values are fixed over the whole image. */
/* For compression, they must be supplied by parameter setup; */
/* for decompression, they are read from the SOF marker. */
int component_id; /* identifier for this component (0..255) */
int component_index; /* its index in SOF or cinfo->comp_info[] */
int h_samp_factor; /* horizontal sampling factor (1..4) */
int v_samp_factor; /* vertical sampling factor (1..4) */
int quant_tbl_no; /* quantization table selector (0..3) */
/* 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) */
/* Remaining fields should be treated as private by applications. */
/* These values are computed during compression or decompression startup: */
/* Component's size in DCT blocks.
* Any dummy blocks added to complete an MCU are not counted; therefore
* these values do not depend on whether a scan is interleaved or not.
*/
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.
*/
int DCT_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)
*/
JDIMENSION downsampled_width; /* actual width in samples */
JDIMENSION downsampled_height; /* actual height in samples */
/* This flag is used only for decompression. In cases where some of the
* components will be ignored (eg grayscale output from YCbCr image),
* we can skip most computations for the unused components.
*/
boolean component_needed; /* do we need the value of this 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 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 * 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 * 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 {
JCS_UNKNOWN, /* error/unspecified */
JCS_GRAYSCALE, /* monochrome */
JCS_RGB, /* red/green/blue */
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
JCS_CMYK, /* C/M/Y/K */
JCS_YCCK /* Y/Cb/Cr/K */
} J_COLOR_SPACE;
/* DCT/IDCT algorithm options. */
typedef enum {
JDCT_ISLOW, /* slow but accurate integer algorithm */
JDCT_IFAST, /* faster, less accurate integer method */
JDCT_FLOAT /* floating-point: accurate, fast on fast HW */
} J_DCT_METHOD;
#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
#define JDCT_DEFAULT JDCT_ISLOW
#endif
#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
#define JDCT_FASTEST JDCT_IFAST
#endif
/* Dithering options for decompression. */
typedef enum {
JDITHER_NONE, /* no dithering */
JDITHER_ORDERED, /* simple ordered dither */
JDITHER_FS /* Floyd-Steinberg error diffusion dither */
} J_DITHER_MODE;
/* Common fields between JPEG compression and decompression master structs. */
#define jpeg_common_fields \
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 */\
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
* jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
*/
struct jpeg_common_struct {
jpeg_common_fields; /* Fields common to both master struct types */
/* Additional fields follow in an actual jpeg_compress_struct or
* jpeg_decompress_struct. All three structs must agree on these
* initial fields! (This would be a lot cleaner in C++.)
*/
};
typedef struct jpeg_common_struct * j_common_ptr;
typedef struct jpeg_compress_struct * j_compress_ptr;
typedef struct jpeg_decompress_struct * j_decompress_ptr;
/* Master record for a compression instance */
struct jpeg_compress_struct {
jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
/* Destination for compressed data */
struct jpeg_destination_mgr * dest;
/* Description of source image --- these fields must be filled in by
* outer application before starting compression. in_color_space must
* be correct before you can even call jpeg_set_defaults().
*/
JDIMENSION image_width; /* input image width */
JDIMENSION image_height; /* input image height */
int input_components; /* # of color components in input image */
J_COLOR_SPACE in_color_space; /* colorspace of input image */
double input_gamma; /* image gamma of input image */
/* Compression parameters --- these fields must be set before calling
* jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
* initialize everything to reasonable defaults, then changing anything
* the application specifically wants to change. That way you won't get
* burnt when new parameters are added. Also note that there are several
* helper routines to simplify changing parameters.
*/
int data_precision; /* bits of precision in image data */
int num_components; /* # of color components in JPEG image */
J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
jpeg_component_info * comp_info;
/* 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 */
JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
/* ptrs to Huffman coding tables, or NULL if not defined */
UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
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 optimize_coding; /* TRUE=optimize entropy encoding parms */
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
J_DCT_METHOD dct_method; /* DCT algorithm selector */
/* The restart interval can be specified in absolute MCUs by setting
* restart_interval, or in MCU rows by setting restart_in_rows
* (in which case the correct restart_interval will be figured
* for each scan).
*/
unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
int restart_in_rows; /* if > 0, MCU rows per restart interval */
/* 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 */
/* ratio is defined by X_density/Y_density even when density_unit=0. */
UINT8 density_unit; /* JFIF code for pixel size units */
UINT16 X_density; /* Horizontal pixel density */
UINT16 Y_density; /* Vertical pixel density */
boolean write_Adobe_marker; /* should an Adobe marker be written? */
/* State variable: index of next scanline to be written to
* jpeg_write_scanlines(). Application may use this to control its
* processing loop, e.g., "while (next_scanline < image_height)".
*/
JDIMENSION next_scanline; /* 0 .. image_height-1 */
/* Remaining fields are known throughout compressor, but generally
* should not be touched by a surrounding application.
*/
/*
* 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 */
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).
* There are v_samp_factor * DCTSIZE sample rows of each component in an
* "iMCU" (interleaved MCU) row.
*/
/*
* These fields are valid during any one scan.
* They describe the components and MCUs actually appearing in the scan.
*/
int comps_in_scan; /* # of JPEG components in this scan */
jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
/* *cur_comp_info[i] describes component that appears i'th in SOS */
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
int blocks_in_MCU; /* # of DCT blocks per 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 */
/*
* Links to compression subobjects (methods and private variables of modules)
*/
struct jpeg_comp_master * master;
struct jpeg_c_main_controller * main;
struct jpeg_c_prep_controller * prep;
struct jpeg_c_coef_controller * coef;
struct jpeg_marker_writer * marker;
struct jpeg_color_converter * cconvert;
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;
};
/* Master record for a decompression instance */
struct jpeg_decompress_struct {
jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
/* Source of compressed data */
struct jpeg_source_mgr * src;
/* Basic description of image --- filled in by jpeg_read_header(). */
/* Application may inspect these values to decide how to process image. */
JDIMENSION image_width; /* nominal image width (from SOF marker) */
JDIMENSION image_height; /* nominal image height */
int num_components; /* # of color components in JPEG image */
J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
/* Decompression processing parameters --- these fields must be set before
* calling jpeg_start_decompress(). Note that jpeg_read_header() initializes
* them to default values.
*/
J_COLOR_SPACE out_color_space; /* colorspace for output */
unsigned int scale_num, scale_denom; /* fraction by which to scale image */
double output_gamma; /* image gamma wanted in output */
J_DCT_METHOD dct_method; /* IDCT algorithm selector */
boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
/* Description of actual output image that will be returned to application.
* These fields are computed by jpeg_start_decompress().
* You can also use jpeg_calc_output_dimensions() to determine these values
* in advance of calling jpeg_start_decompress().
*/
JDIMENSION output_width; /* scaled image width */
JDIMENSION output_height; /* scaled image height */
int out_color_components; /* # of color components in out_color_space */
int output_components; /* # of color components returned */
/* output_components is 1 (a colormap index) when quantizing colors;
* otherwise it equals out_color_components.
*/
int rec_outbuf_height; /* min recommended height of scanline buffer */
/* If the buffer passed to jpeg_read_scanlines() is less than this many rows
* high, space and time will be wasted due to unnecessary data copying.
* Usually rec_outbuf_height will be 1 or 2, at most 4.
*/
/* 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. 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
* datastreams when processing abbreviated JPEG datastreams.
*/
JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
/* ptrs to coefficient quantization tables, or NULL if not defined */
JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
/* ptrs to Huffman coding tables, or NULL if not defined */
/* These parameters are never carried across datastreams, since they
* are given in SOF/SOS markers or defined to be reset by SOI.
*/
int data_precision; /* bits of precision in image data */
jpeg_component_info * comp_info;
/* comp_info[i] describes component that appears i'th in SOF */
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 */
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; 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 */
boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
UINT8 Adobe_transform; /* Color transform code from Adobe marker */
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.
*/
/*
* These fields are computed during decompression startup
*/
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 */
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_scaled_size sample rows of a component per iMCU row.
*/
JSAMPLE * sample_range_limit; /* table for fast range-limiting */
/*
* 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];
/* *cur_comp_info[i] describes component that appears i'th in SOS */
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
int blocks_in_MCU; /* # of DCT blocks per 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 */
/* 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.
*/
int unread_marker;
/*
* Links to decompression subobjects (methods, private variables of modules)
*/
struct jpeg_decomp_master * master;
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;
struct jpeg_upsampler * upsample;
struct jpeg_color_deconverter * cconvert;
struct jpeg_color_quantizer * cquantize;
};
/* "Object" declarations for JPEG modules that may be supplied or called
* directly by the surrounding application.
* As with all objects in the JPEG library, these structs only define the
* publicly visible methods and state variables of a module. Additional
* private fields may exist after the public ones.
*/
/* Error handler object */
struct jpeg_error_mgr {
/* Error exit handler: does not return to caller */
JMETHOD(void, error_exit, (j_common_ptr cinfo));
/* Conditionally emit a trace or warning message */
JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
/* Routine that actually outputs a trace or error message */
JMETHOD(void, output_message, (j_common_ptr cinfo));
/* Format a message string for the most recent JPEG error or message */
JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */
/* Reset error state variables at start of a new image */
JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
/* The message ID code and any parameters are saved here.
* A message can have one string parameter or up to 8 int parameters.
*/
int msg_code;
#define JMSG_STR_PARM_MAX 80
union {
int i[8];
char s[JMSG_STR_PARM_MAX];
} msg_parm;
/* Standard state variables for error facility */
int trace_level; /* max msg_level that will be displayed */
/* For recoverable corrupt-data errors, we emit a warning message,
* but keep going unless emit_message chooses to abort. emit_message
* should count warnings in num_warnings. The surrounding application
* can check for bad data by seeing if num_warnings is nonzero at the
* end of processing.
*/
long num_warnings; /* number of corrupt-data warnings */
/* These fields point to the table(s) of error message strings.
* An application can change the table pointer to switch to a different
* message list (typically, to change the language in which errors are
* reported). Some applications may wish to add additional error codes
* that will be handled by the JPEG library error mechanism; the second
* table pointer is used for this purpose.
*
* First table includes all errors generated by JPEG library itself.
* Error code 0 is reserved for a "no such error string" message.
*/
const char * const * jpeg_message_table; /* Library errors */
int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */
/* Second table can be added by application (see cjpeg/djpeg for example).
* It contains strings numbered first_addon_message..last_addon_message.
*/
const char * const * addon_message_table; /* Non-library errors */
int first_addon_message; /* code for first string in addon table */
int last_addon_message; /* code for last string in addon table */
};
/* Progress monitor object */
struct jpeg_progress_mgr {
JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
long pass_counter; /* work units completed in this pass */
long pass_limit; /* total number of work units in this pass */
int completed_passes; /* passes completed so far */
int total_passes; /* total number of passes expected */
};
/* Data destination object for compression */
struct jpeg_destination_mgr {
JOCTET * next_output_byte; /* => next byte to write in buffer */
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
JMETHOD(void, init_destination, (j_compress_ptr cinfo));
JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
JMETHOD(void, term_destination, (j_compress_ptr cinfo));
};
/* Data source object for decompression */
struct jpeg_source_mgr {
const JOCTET * next_input_byte; /* => next byte to read from buffer */
size_t bytes_in_buffer; /* # of bytes remaining in buffer */
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, int desired));
JMETHOD(void, term_source, (j_decompress_ptr cinfo));
};
/* Memory manager object.
* Allocates "small" objects (a few K total), "large" objects (tens of K),
* and "really big" objects (virtual arrays with backing store if needed).
* The memory manager does not allow individual objects to be freed; rather,
* each created object is assigned to a pool, and whole pools can be freed
* at once. This is faster and more convenient than remembering exactly what
* to free, especially where malloc()/free() are not too speedy.
* NB: alloc routines never return NULL. They exit to error_exit if not
* successful.
*/
#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */
#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */
#define JPOOL_NUMPOOLS 2
typedef struct jvirt_barray_control * jvirt_barray_ptr;
struct jpeg_memory_mgr {
/* Method pointers */
JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
size_t sizeofobject));
JMETHOD(void *, alloc_large, (j_common_ptr cinfo, int pool_id,
size_t sizeofobject));
JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
JDIMENSION samplesperrow,
JDIMENSION numrows));
JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
JDIMENSION blocksperrow,
JDIMENSION numrows));
JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
int pool_id,
boolean pre_zero,
JDIMENSION blocksperrow,
JDIMENSION numrows,
JDIMENSION maxaccess));
JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
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));
};
/* Routine signature for application-supplied marker processing methods.
* Need not pass marker code since it is stored in cinfo->unread_marker.
*/
typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
/* Declarations for routines called by application.
* The JPP macro hides prototype parameters from compilers that can't cope.
* Note JPP requires double parentheses.
*/
#ifdef HAVE_PROTOTYPES
#define JPP(arglist) arglist
#else
#define JPP(arglist) ()
#endif
/* Default error-management setup */
EXTERN(struct jpeg_error_mgr *) jpeg_std_error
JPP((struct jpeg_error_mgr * err));
/* 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_src JPP((j_decompress_ptr cinfo, FILE * infile));
/* Default parameter setup for compression */
EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
/* Compression parameter setup aids */
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,
boolean force_baseline));
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,
const unsigned int *basic_table,
int scale_factor,
boolean force_baseline));
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));
/* Main entry points for compression */
EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
boolean write_all_tables));
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));
/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
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,
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));
/* Decompression startup: read start of JPEG datastream to see what's there */
EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
boolean require_image));
/* Return value is one of: */
#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
* give a suspension return (the stdio source module doesn't).
*/
/* Main entry points for decompression */
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));
/* Additional entry points for buffered-image mode. */
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));
/* 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,
jpeg_marker_parser_method routine));
/* 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));
/* 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));
/* Default restart-marker-resync procedure for use by data source modules */
EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
int desired));
/* These marker codes are exported since applications and data source modules
* are likely to want to use them.
*/
#define JPEG_RST0 0xD0 /* RST0 marker code */
#define JPEG_EOI 0xD9 /* EOI marker code */
#define JPEG_APP0 0xE0 /* APP0 marker code */
#define JPEG_COM 0xFE /* COM marker code */
/*
* The JPEG library modules define JPEG_INTERNALS before including this file.
* The internal structure declarations are read only when that is true.
* Applications using the library should not include jpegint.h, but may wish
* to include jerror.h.
*/
#ifdef JPEG_INTERNALS
#include "jpegint.h" /* fetch private declarations */
#include "jerror.h" /* fetch error codes too */
#endif
#endif /* JPEGLIB_H */

103
jpeg-6b/jutils.c Normal file
View file

@ -0,0 +1,103 @@
/*
* jutils.c
*
* 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.
*
* 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.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#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
};
/*
* Arithmetic utilities
*/
/* 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 below do it the hard way. (The performance cost
* is not all that great, because these routines aren't very heavily used.)
*/
GLOBAL(void)
jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
JSAMPARRAY output_array, int dest_row,
int num_rows, JDIMENSION num_cols)
/* Copy some rows of samples from one place to another.
* num_rows rows are copied from input_array[source_row++]
* to output_array[dest_row++]; these areas may overlap for duplication.
* The source and destination arrays must be at least as wide as num_cols.
*/
{
register JSAMPROW inptr, outptr;
register JDIMENSION count;
register int row;
input_array += source_row;
output_array += dest_row;
for (row = num_rows; row > 0; row--) {
inptr = *input_array++;
outptr = *output_array++;
for (count = num_cols; count > 0; count--)
*outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
}
}

14
jpeg-6b/jversion.h Normal file
View file

@ -0,0 +1,14 @@
/*
* jversion.h
*
* 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.
*
* This file contains software version identification.
*/
#define JVERSION "6b 27-Mar-1998"
#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane"

27
jpeg-6b/readme-zdoom.txt Normal file
View file

@ -0,0 +1,27 @@
This is a stripped version of the Independant JPEG Group's library,
available at <http://www.ijg.org/>. The following features have been
removed to decrease source code size:
* All encoding code.
* All sample applications.
* Most documentation.
* Unix configure scripts.
* Multiple Makefiles.
* Multiple memory managers.
* Disk-based backing store. If you don't have enough memory to decode
a JPEG file, you probably can't play ZDoom either.
* Fast integer DCT routines.
* Floating point DCT routines.
* Arithmetic coding, due to its patented status. (It is not normally
built in the standard version of the library, either.)
* Far pointers. Who cares about 16-bit x86? Not me.
* IDCT scaling.
* Block smoothing.
* Color quantization. Looking it up in the RGB32k table is good enough
for me.
* Transcoding routines.
* Buffered image output.
* Raw data output.
A Unix build of ZDoom should just use the system libjpeg instead of
this code.

View file

@ -1,571 +0,0 @@
/**************************************************************************************************
KPLIB.C: Ken's Picture LIBrary written by Ken Silverman
Copyright (c) 1998-2005 Ken Silverman
Ken Silverman's official web site: http://www.advsys.net/ken
This source file includes routines for decompression of the following picture formats:
JPG,PNG,GIF,PCX,TGA,BMP,CEL
It also includes code to handle ZIP decompression.
Brief history:
1998?: Wrote KPEG, a JPEG viewer for DOS
2000: Wrote KPNG, a PNG viewer for DOS
2001: Combined KPEG&KPNG, ported to Visual C, and made it into a nice library called KPLIB.C
2002: Added support for: TGA,GIF,CEL,ZIP
2003: Added support for: BMP
05/18/2004: Added support for 8/24 bit PCX
I offer this code to the community for the benefit of Jonathon Fowler's Duke3D port.
-Ken S.
**************************************************************************************************/
// [RH] Removed everything but JPEG support.
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include "m_swap.h"
#include "m_fixed.h"
#if !defined(_WIN32) && !defined(__DOS__)
#include <unistd.h>
static __inline unsigned long _lrotl (unsigned long i, int sh)
{ return((i>>(-sh))|(i<<sh)); }
#define _fileno fileno
#else
#include <io.h>
#endif
#if !defined(max)
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#if !defined(min)
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#if defined(__GNUC__)
#define _inline inline
#endif
//use GCC-specific extension to force symbol name to be something in particular to override underscoring.
static int bytesperline, xres, yres, globxoffs, globyoffs;
static unsigned char *frameplace;
static const int pow2mask[32] =
{
0x00000000,0x00000001,0x00000003,0x00000007,
0x0000000f,0x0000001f,0x0000003f,0x0000007f,
0x000000ff,0x000001ff,0x000003ff,0x000007ff,
0x00000fff,0x00001fff,0x00003fff,0x00007fff,
0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
0x000fffff,0x001fffff,0x003fffff,0x007fffff,
0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff,
0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff,
};
//Initialized tables (can't be in union)
//jpg: png:
// crmul 16384 abstab10 4096
// cbmul 16384 hxbit 472
// dct 4608 pow2mask 128*
// colclip 4096
// colclipup8 4096
// colclipup16 4096
// unzig 256
// pow2mask 128*
// dcflagor 64
int palcol[256], paleng;
unsigned char coltype, bitdepth;
//============================ KPEGILIB begins ===============================
//11/01/2000: This code was originally from KPEG.C
// All non 32-bit color drawing was removed
// "Motion" JPG code was removed
// A lot of parameters were added to kpeg() for library usage
static int clipxdim, clipydim;
static int hufquickcnt[8];
static int hufmaxatbit[8][20], hufvalatbit[8][20], hufcnt[8];
static unsigned char hufnumatbit[8][20], huftable[8][256];
static unsigned char gnumcomponents, dcflagor[64];
static int gcompid[4], gcomphsamp[4], gcompvsamp[4], gcompquantab[4];
static int lcompid[4], lcompdc[4], lcompac[4];
static int lcomphsamp[4], lcompvsamp[4], lcomphvsamp[4], lcompquantab[4];
static int lcomphsampmask[4], lcomphsampshift[4], lcompvsampshift[4];
static int quantab[4][64], dct[19][64], lastdc[4], unzig[64];
static const unsigned char pow2char[8] = {1,2,4,8,16,32,64,128};
#define SQRT2 23726566 //(sqrt(2))<<24
#define C182 31000253 //(cos(PI/8)*2)<<24
#define C18S22 43840978 //(cos(PI/8)*sqrt(2)*2)<<24
#define C38S22 18159528 //(cos(PI*3/8)*sqrt(2)*2)<<24
static const int cosqr16[8] = //cosqr16[i] = ((cos(PI*i/16)*sqrt(2))<<24);
{23726566,23270667,21920489,19727919,16777216,13181774,9079764,4628823};
// [RH] Moved the bigger tables into a dynamically allocated struct so that
// they don't waste space if a JPEG is never loaded.
struct kpegtables
{
int hufquickval[8][1024], hufquickbits[8][1024];
int colclip[1024], colclipup8[1024], colclipup16[1024];
int crmul[4096], cbmul[4096];
};
static kpegtables *kpeg;
static void initkpeg ()
{
int i, x, y;
kpeg = new kpegtables;
x = 0; //Back & forth diagonal pattern (aligning bytes for best compression)
for(i=0;i<16;i+=2)
{
for(y=7;y>=0;y--)
if ((unsigned)(i-y) < (unsigned)8) unzig[x++] = (y<<3)+i-y;
for(y=0;y<8;y++)
if ((unsigned)(i+1-y) < (unsigned)8) unzig[x++] = (y<<3)+i+1-y;
}
for(i=63;i>=0;i--) dcflagor[i] = (unsigned char)(1<<(unzig[i]>>3));
for(i=0;i<128;i++) kpeg->colclip[i] = i+128;
for(i=128;i<512;i++) kpeg->colclip[i] = 255;
for(i=512;i<896;i++) kpeg->colclip[i] = 0;
for(i=896;i<1024;i++) kpeg->colclip[i] = i-896;
for(i=0;i<1024;i++)
{
kpeg->colclipup8[i] = (kpeg->colclip[i]<<8);
kpeg->colclipup16[i] = (kpeg->colclip[i]<<16)+0xff000000; //Hack: set alphas to 255
}
for(i=0;i<2048;i++)
{
kpeg->crmul[(i<<1)+0] = (i-1024)*1470104; //1.402*1048576
kpeg->crmul[(i<<1)+1] = (i-1024)*-748830; //-0.71414*1048576
kpeg->cbmul[(i<<1)+0] = (i-1024)*-360857; //-0.34414*1048576
kpeg->cbmul[(i<<1)+1] = (i-1024)*1858077; //1.772*1048576
}
memset((void *)&dct[16][0],0,64*2*sizeof(dct[0][0]));
memset((void *)&dct[18][0],0xa0,64*sizeof(dct[0][0]));
}
static void huffgetval (int index, int curbits, int num, int *daval, int *dabits)
{
int b, v, pow2, *hmax;
hmax = &hufmaxatbit[index][0];
pow2 = pow2mask[curbits-1]+1;
if (num&pow2) v = 1; else v = 0;
for(b=1;b<=16;b++)
{
if (v < hmax[b])
{
*dabits = b;
*daval = huftable[index][hufvalatbit[index][b]+v];
return;
}
pow2 >>= 1; v <<= 1;
if (num&pow2) v++;
}
*dabits = 16;
*daval = 0;
}
int kpegrend (const char *kfilebuf, int kfilength,
unsigned char *daframeplace, int dabytesperline, int daxres, int dayres,
int daglobxoffs, int daglobyoffs)
{
int i, j, v, leng, xdim = 0, ydim = 0, index, prec, restartinterval;
int restartcnt, num, curbits, x, y, z, dctcnt, c, cc, daval, dabits;
int xx, yy, zz, xxx, yyy, r, g, b, t0, t1, t2, t3, t4, t5, t6, t7;
int yv, cr = 0, cb = 0, *dc, *dc2, xxxend, yyyend;
int *hqval, *hqbits, hqcnt, *quanptr;
unsigned char ch, marker, numbits, lnumcomponents, dcflag, *p;
const unsigned char *kfileptr;
if (kpeg == NULL) { initkpeg(); }
kfileptr = (unsigned char *)kfilebuf;
if (*(unsigned short *)kfileptr == 0xd8ff) kfileptr += 2;
else return(-1); //"%s is not a JPEG file\n",filename
restartinterval = 0;
for(i=0;i<4;i++) lastdc[i] = 0;
for(i=0;i<8;i++) hufcnt[i] = 0;
coltype = 0; bitdepth = 8; //For PNGOUT
do
{
ch = *kfileptr++; if (ch != 255) continue;
marker = *kfileptr++;
leng = ((int)kfileptr[0]<<8)+(int)kfileptr[1]-2;
kfileptr += 2;
switch(marker)
{
case 0xc0: case 0xc1: case 0xc2:
//processit!
numbits = *kfileptr++;
ydim = ((int)kfileptr[0]<<8)+(int)kfileptr[1];
xdim = ((int)kfileptr[2]<<8)+(int)kfileptr[3];
//printf("%s: %ld / %ld = %ld\n",filename,xdim*ydim*3,kfilength,(xdim*ydim*3)/kfilength);
frameplace = daframeplace;
bytesperline = dabytesperline;
xres = daxres;
yres = dayres;
globxoffs = daglobxoffs;
globyoffs = daglobyoffs;
gnumcomponents = kfileptr[4];
kfileptr += 5;
for(z=0;z<gnumcomponents;z++)
{
gcompid[z] = kfileptr[0];
gcomphsamp[z] = (kfileptr[1]>>4);
gcompvsamp[z] = (kfileptr[1]&15);
gcompquantab[z] = kfileptr[2];
kfileptr += 3;
}
break;
case 0xc4: //Huffman table
do
{
ch = *kfileptr++; leng--;
if (ch >= 16) { index = ch-12; }
else { index = ch; }
memcpy((void *)&hufnumatbit[index][1],(void *)kfileptr,16); kfileptr += 16;
leng -= 16;
v = 0; hufcnt[index] = 0;
hufquickcnt[index] = 0; c = 0;
for(b=1;b<=16;b++)
{
hufmaxatbit[index][b] = v+hufnumatbit[index][b];
hufvalatbit[index][b] = hufcnt[index]-v;
memcpy((void *)&huftable[index][hufcnt[index]],(void *)kfileptr,(int)hufnumatbit[index][b]);
if (b <= 10)
for(c=0;c<hufnumatbit[index][b];c++)
for(j=(1<<(10-b));j>0;j--)
{
kpeg->hufquickval[index][hufquickcnt[index]] = huftable[index][hufcnt[index]+c];
kpeg->hufquickbits[index][hufquickcnt[index]] = b;
hufquickcnt[index]++;
}
kfileptr += hufnumatbit[index][b];
leng -= hufnumatbit[index][b];
hufcnt[index] += hufnumatbit[index][b];
v = ((v+hufnumatbit[index][b])<<1);
}
} while (leng > 0);
break;
case 0xdb:
do
{
ch = *kfileptr++; leng--;
index = (ch&15);
prec = (ch>>4);
for(z=0;z<64;z++)
{
v = (int)(*kfileptr++);
if (prec) v = (v<<8)+((int)(*kfileptr++));
v <<= 19;
if (unzig[z]&7) v = MulScale24(v,cosqr16[unzig[z]&7]);
if (unzig[z]>>3) v = MulScale24(v,cosqr16[unzig[z]>>3]);
if (index) v >>= 6;
quantab[index][unzig[z]] = v;
}
leng -= 64;
if (prec) leng -= 64;
} while (leng > 0);
break;
case 0xdd:
restartinterval = (((int)kfileptr[0])<<8)+((int)kfileptr[1]);
kfileptr += leng;
break;
case 0xda: case 0xd9:
if ((xdim <= 0) || (ydim <= 0)) return(-1);
lnumcomponents = *kfileptr++;
if (lnumcomponents > 1) coltype = 2;
for(z=0;z<lnumcomponents;z++)
{
lcompid[z] = kfileptr[0];
lcompdc[z] = (kfileptr[1]>>4);
lcompac[z] = (kfileptr[1]&15);
kfileptr += 2;
for(zz=0;zz<gnumcomponents;zz++)
if (lcompid[z] == gcompid[zz])
{
lcomphsamp[z] = gcomphsamp[zz];
lcompvsamp[z] = gcompvsamp[zz];
lcomphvsamp[z] = lcomphsamp[z]*lcompvsamp[z];
lcompquantab[z] = gcompquantab[zz];
for(i=0;i<8;i++)
if (pow2mask[i]+1 == lcomphsamp[z])
{
lcomphsampmask[z] = pow2mask[i];
lcomphsampshift[z] = i;
break;
}
for(i=0;i<8;i++)
if (pow2mask[i]+1 == lcompvsamp[z])
{
lcompvsampshift[z] = i;
break;
}
}
}
//Ss = kfileptr[0];
//Se = kfileptr[1];
//Ah = (kfileptr[2]>>4);
//Al = (kfileptr[2]&15);
kfileptr += 3;
if ((hufcnt[0] == 0) || (hufcnt[4] == 0)) return(-1);
clipxdim = min(xdim+globxoffs,xres);
clipydim = min(ydim+globyoffs,yres);
xx = max(globxoffs,0); xxx = min(globxoffs+xdim,xres);
yy = max(globyoffs,0); yyy = min(globyoffs+ydim,yres);
if ((xx >= xres) || (yy >= yres) || (xxx <= 0) || (yyy <= 0)) return(0);
restartcnt = restartinterval; marker = 0xd0;
num = 0; curbits = 0; x = 0; y = 0;
while (1)
{
if (kfileptr-(unsigned char *)kfilebuf >= kfilength)
lnumcomponents = 0; //rest of file is missing!
dctcnt = 0;
for(c=0;c<lnumcomponents;c++)
{
hqval = &kpeg->hufquickval[lcompac[c]+4][0];
hqbits = &kpeg->hufquickbits[lcompac[c]+4][0];
hqcnt = hufquickcnt[lcompac[c]+4];
quanptr = &quantab[lcompquantab[c]][0];
for(cc=lcomphvsamp[c];cc>0;cc--)
{
dc = &dct[dctcnt][0];
//Get DC
while (curbits < 16) //Getbits
{
ch = *kfileptr++; if (ch == 255) kfileptr++;
num = (num<<8)+((int)ch); curbits += 8;
}
i = ((num>>(curbits-10))&1023);
if (i < hufquickcnt[lcompdc[c]])
{ dabits = kpeg->hufquickbits[lcompdc[c]][i]; daval = kpeg->hufquickval[lcompdc[c]][i]; }
else
huffgetval(lcompdc[c],curbits,num,&daval,&dabits);
curbits -= dabits;
if (daval)
{
while (curbits < 16) //Getbits
{
ch = *kfileptr++; if (ch == 255) kfileptr++;
num = (num<<8)+((int)ch); curbits += 8;
}
v = ((unsigned)num >> (curbits-daval)) & pow2mask[daval];
if (v <= pow2mask[daval-1]) v -= pow2mask[daval];
lastdc[c] += v;
curbits -= daval;
}
dc[0] = lastdc[c]*quanptr[0];
//Get AC
memset((void *)&dc[1],0,63*4);
dcflag = 1;
for(z=1;z<64;z++)
{
while (curbits < 16) //Getbits
{
ch = *kfileptr++; if (ch == 255) kfileptr++;
num = (num<<8)+((int)ch); curbits += 8;
}
i = ((num>>(curbits-10))&1023);
if (i < hqcnt)
{ daval = hqval[i]; curbits -= hqbits[i]; }
else
{
huffgetval(lcompac[c]+4,curbits,num,&daval,&dabits);
curbits -= dabits;
}
if (!daval) break;
z += (daval>>4); if (z >= 64) break;
daval &= 15;
while (curbits < 16) //Getbits
{
ch = *kfileptr++; if (ch == 255) kfileptr++;
num = (num<<8)+((int)ch); curbits += 8;
}
v = ((unsigned)num >> (curbits-daval)) & pow2mask[daval];
if (v <= pow2mask[daval-1]) v -= pow2mask[daval];
dcflag |= dcflagor[z];
dc[unzig[z]] = v*quanptr[unzig[z]];
curbits -= daval;
}
for(z=0;z<8;z++,dc+=8)
{
if (!(dcflag&pow2char[z])) continue;
t3 = dc[2] + dc[6];
t2 = (MulScale32(dc[2]-dc[6],SQRT2<<6)<<2) - t3;
t4 = dc[0] + dc[4]; t5 = dc[0] - dc[4];
t0 = t4+t3; t3 = t4-t3; t1 = t5+t2; t2 = t5-t2;
t4 = (MulScale32(dc[5]-dc[3]+dc[1]-dc[7],C182<<6)<<2);
t7 = dc[1] + dc[7] + dc[5] + dc[3];
t6 = (MulScale32(dc[3]-dc[5],C18S22<<5)<<3) + t4 - t7;
t5 = (MulScale32(dc[1]+dc[7]-dc[5]-dc[3],SQRT2<<6)<<2) - t6;
t4 = (MulScale32(dc[1]-dc[7],C38S22<<6)<<2) - t4 + t5;
dc[0] = t0+t7; dc[7] = t0-t7; dc[1] = t1+t6; dc[6] = t1-t6;
dc[2] = t2+t5; dc[5] = t2-t5; dc[4] = t3+t4; dc[3] = t3-t4;
}
dc = &dct[dctcnt][0];
for(z=7;z>=0;z--,dc++)
{
t3 = dc[2<<3] + dc[6<<3];
t2 = (MulScale32(dc[2<<3]-dc[6<<3],SQRT2<<6)<<2) - t3;
t4 = dc[0<<3] + dc[4<<3]; t5 = dc[0<<3] - dc[4<<3];
t0 = t4+t3; t3 = t4-t3; t1 = t5+t2; t2 = t5-t2;
t4 = (MulScale32(dc[5<<3]-dc[3<<3]+dc[1<<3]-dc[7<<3],C182<<6)<<2);
t7 = dc[1<<3] + dc[7<<3] + dc[5<<3] + dc[3<<3];
t6 = (MulScale32(dc[3<<3]-dc[5<<3],C18S22<<5)<<3) + t4 - t7;
t5 = (MulScale32(dc[1<<3]+dc[7<<3]-dc[5<<3]-dc[3<<3],SQRT2<<6)<<2) - t6;
t4 = (MulScale32(dc[1<<3]-dc[7<<3],C38S22<<6)<<2) - t4 + t5;
dc[0<<3] = t0+t7; dc[7<<3] = t0-t7; dc[1<<3] = t1+t6; dc[6<<3] = t1-t6;
dc[2<<3] = t2+t5; dc[5<<3] = t2-t5; dc[4<<3] = t3+t4; dc[3<<3] = t3-t4;
}
dctcnt++;
}
}
dctcnt = 0; dc = &dct[18][0]; dc2 = &dct[16][0];
r = g = b = 0; cc = 0;
for(yy=0;yy<(lcompvsamp[0]<<3);yy+=8)
for(xx=0;xx<(lcomphsamp[0]<<3);xx+=8,dctcnt++)
{
yyy = y+yy+globyoffs; if ((unsigned)yyy >= (unsigned)clipydim) continue;
xxx = x+xx+globxoffs; if ((unsigned)xxx >= (unsigned)clipxdim) continue;
p = yyy*bytesperline + xxx*4 + frameplace;
if (lnumcomponents > 0) dc = &dct[dctcnt][0];
if (lnumcomponents > 1) dc2 = &dct[lcomphvsamp[0]][((yy>>lcompvsampshift[0])<<3)+(xx>>lcomphsampshift[0])];
xxxend = min(clipxdim-(x+xx+globxoffs),8);
yyyend = min(clipydim-(y+yy+globyoffs),8);
if ((lcomphsamp[0] == 1) && (xxxend == 8))
{
for(yyy=0;yyy<yyyend;yyy++)
{
for(xxx=0;xxx<8;xxx++)
{
yv = dc[xxx];
cr = (dc2[xxx+64]>>13)&~1;
cb = (dc2[xxx]>>13)&~1;
((int *)p)[xxx] = kpeg->colclipup16[(unsigned)(yv+kpeg->crmul[cr+2048])>>22]+
kpeg->colclipup8[(unsigned)(yv+kpeg->crmul[cr+2049]+kpeg->cbmul[cb+2048])>>22]+
kpeg->colclip[(unsigned)(yv+kpeg->cbmul[cb+2049])>>22];
}
p += bytesperline;
dc += 8;
if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8;
}
}
else if ((lcomphsamp[0] == 2) && (xxxend == 8))
{
for(yyy=0;yyy<yyyend;yyy++)
{
for(xxx=0;xxx<8;xxx+=2)
{
yv = dc[xxx];
cr = (dc2[(xxx>>1)+64]>>13)&~1;
cb = (dc2[(xxx>>1)]>>13)&~1;
i = kpeg->crmul[cr+2049]+kpeg->cbmul[cb+2048];
cr = kpeg->crmul[cr+2048];
cb = kpeg->cbmul[cb+2049];
((int *)p)[xxx] = kpeg->colclipup16[(unsigned)(yv+cr)>>22]+
kpeg->colclipup8[(unsigned)(yv+i)>>22]+
kpeg->colclip[(unsigned)(yv+cb)>>22];
yv = dc[xxx+1];
((int *)p)[xxx+1] = kpeg->colclipup16[(unsigned)(yv+cr)>>22]+
kpeg->colclipup8[(unsigned)(yv+i)>>22]+
kpeg->colclip[(unsigned)(yv+cb)>>22];
}
p += bytesperline;
dc += 8;
if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8;
}
}
else
{
for(yyy=0;yyy<yyyend;yyy++)
{
i = 0; j = 1;
for(xxx=0;xxx<xxxend;xxx++)
{
yv = dc[xxx];
j--;
if (!j)
{
j = lcomphsamp[0];
cr = (dc2[i+64]>>13)&~1;
cb = (dc2[i]>>13)&~1;
i++;
}
((int *)p)[xxx] = kpeg->colclipup16[(unsigned)(yv+kpeg->crmul[cr+2048])>>22]+
kpeg->colclipup8[(unsigned)(yv+kpeg->crmul[cr+2049]+kpeg->cbmul[cb+2048])>>22]+
kpeg->colclip[(unsigned)(yv+kpeg->cbmul[cb+2049])>>22];
}
p += bytesperline;
dc += 8;
if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8;
}
}
}
if (lnumcomponents) //do only when not EOF...
{
restartcnt--;
if (!restartcnt)
{
kfileptr += 1-(curbits>>3); curbits = 0;
if ((kfileptr[-2] != 255) || (kfileptr[-1] != marker)) kfileptr--;
marker++; if (marker >= 0xd8) marker = 0xd0;
restartcnt = restartinterval;
for(i=0;i<4;i++) lastdc[i] = 0;
}
}
x += (lcomphsamp[0]<<3);
if (x >= xdim) { x = 0; y += (lcompvsamp[0]<<3); if (y >= ydim) return(0); }
}
default:
kfileptr += leng;
break;
}
} while (kfileptr-(unsigned char *)kfilebuf < kfilength);
return(0);
}
//============================== KPEGILIB ends ==============================

View file

@ -1,3 +1,4 @@
// Emacs style mode select -*- C++ -*- // Emacs style mode select -*- C++ -*-
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
@ -35,6 +36,11 @@
#include <stddef.h> #include <stddef.h>
#include <malloc.h> #include <malloc.h>
#include <stdio.h>
extern "C"
{
#include <jpeglib.h>
}
#include "i_system.h" #include "i_system.h"
#include "m_alloc.h" #include "m_alloc.h"
@ -57,6 +63,7 @@
#include "v_palette.h" #include "v_palette.h"
#include "v_video.h" #include "v_video.h"
#include "v_text.h"
#include "gi.h" #include "gi.h"
#include "cmdlib.h" #include "cmdlib.h"
#include "templates.h" #include "templates.h"
@ -1806,7 +1813,18 @@ void FIMGZTexture::MakeTexture ()
} }
BYTE FPNGTexture::GrayMap[256]; static BYTE GrayMap[256];
static void InitGrayMap()
{
if (GrayMap[0] == GrayMap[255])
{
for (int i = 0; i < 256; ++i)
{
GrayMap[i] = ColorMatcher.Pick (i, i, i);
}
}
}
FPNGTexture::FPNGTexture (int lumpnum, int width, int height, FPNGTexture::FPNGTexture (int lumpnum, int width, int height,
BYTE depth, BYTE colortype, BYTE interlace) BYTE depth, BYTE colortype, BYTE interlace)
@ -1901,13 +1919,7 @@ FPNGTexture::FPNGTexture (int lumpnum, int width, int height,
case 0: // Grayscale case 0: // Grayscale
if (!bAlphaTexture) if (!bAlphaTexture)
{ {
if (GrayMap[0] == GrayMap[255]) InitGrayMap();
{ // Initialize the GrayMap
for (i = 0; i < 256; ++i)
{
GrayMap[i] = ColorMatcher.Pick (i, i, i);
}
}
if (colortype == 0 && havetRNS && trans[0] != 0) if (colortype == 0 && havetRNS && trans[0] != 0)
{ {
bMasked = true; bMasked = true;
@ -2126,9 +2138,81 @@ void FPNGTexture::MakeTexture ()
} }
} }
int kpegrend (const char *kfilebuf, int kfilength, struct FLumpSourceMgr : public jpeg_source_mgr
unsigned char *daframeplace, int dabytesperline, int daxres, int dayres, {
int daglobxoffs, int daglobyoffs); FWadLump &Lump;
JOCTET Buffer[4096];
bool StartOfFile;
FLumpSourceMgr (FWadLump &lump, j_decompress_ptr cinfo)
: Lump (lump)
{
cinfo->src = this;
init_source = InitSource;
fill_input_buffer = FillInputBuffer;
skip_input_data = SkipInputData;
resync_to_restart = jpeg_resync_to_restart;
term_source = TermSource;
bytes_in_buffer = 0;
next_input_byte = NULL;
}
static void InitSource (j_decompress_ptr cinfo)
{
((FLumpSourceMgr *)(cinfo->src))->StartOfFile = true;
}
static boolean FillInputBuffer (j_decompress_ptr cinfo)
{
FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src);
long nbytes = me->Lump.Read (me->Buffer, sizeof(me->Buffer));
if (nbytes <= 0)
{
me->Buffer[0] = (JOCTET)0xFF;
me->Buffer[1] = (JOCTET)JPEG_EOI;
nbytes = 2;
}
me->next_input_byte = me->Buffer;
me->bytes_in_buffer = nbytes;
me->StartOfFile = false;
return TRUE;
}
static void SkipInputData (j_decompress_ptr cinfo, long num_bytes)
{
FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src);
if (num_bytes <= (long)me->bytes_in_buffer)
{
me->bytes_in_buffer -= num_bytes;
me->next_input_byte += num_bytes;
}
else
{
num_bytes -= (long)me->bytes_in_buffer;
me->Lump.Seek (num_bytes, SEEK_CUR);
FillInputBuffer (cinfo);
}
}
static void TermSource (j_decompress_ptr cinfo)
{
}
};
static void JPEG_ErrorExit (j_common_ptr cinfo)
{
(*cinfo->err->output_message) (cinfo);
throw -1;
}
static void JPEG_OutputMessage (j_common_ptr cinfo)
{
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message) (cinfo, buffer);
Printf (TEXTCOLOR_ORANGE "JPEG failure: %s\n", buffer);
}
FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height)
: SourceLump(lumpnum), Pixels(0) : SourceLump(lumpnum), Pixels(0)
@ -2200,36 +2284,94 @@ const BYTE *FJPEGTexture::GetPixels ()
void FJPEGTexture::MakeTexture () void FJPEGTexture::MakeTexture ()
{ {
FMemLump lump = Wads.ReadLump (SourceLump); FWadLump lump = Wads.OpenLumpNum (SourceLump);
BYTE *rgb = new BYTE[Width * Height * 4]; JSAMPLE *buff = NULL;
jpeg_decompress_struct cinfo;
jpeg_error_mgr jerr;
Pixels = new BYTE[Width * Height]; Pixels = new BYTE[Width * Height];
if (kpegrend ((char *)lump.GetMem(), Wads.LumpLength (SourceLump), rgb, Width * 4, Width, Height, 0, 0) < 0)
{ // Failed to read the JPEG
memset (Pixels, 0xBA, Width * Height); memset (Pixels, 0xBA, Width * Height);
}
else
{
BYTE *in, *out;
int x, y, pitch, backstep;
in = rgb; cinfo.err = jpeg_std_error(&jerr);
out = Pixels; cinfo.err->output_message = JPEG_OutputMessage;
cinfo.err->error_exit = JPEG_ErrorExit;
jpeg_create_decompress(&cinfo);
try
{
FLumpSourceMgr sourcemgr(lump, &cinfo);
jpeg_read_header(&cinfo, TRUE);
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
{
Printf (TEXTCOLOR_ORANGE "Unsupported color format\n", Name);
throw -1;
}
if (cinfo.out_color_space == JCS_GRAYSCALE)
{
InitGrayMap();
}
// Convert from source format to paletted, column-major. jpeg_start_decompress(&cinfo);
pitch = Width * 4;
backstep = Height * pitch - 4; int y = 0;
for (x = Width; x > 0; --x) buff = new BYTE[cinfo.output_width * cinfo.output_components];
while (cinfo.output_scanline < cinfo.output_height)
{ {
for (y = Height; y > 0; --y) int num_scanlines = jpeg_read_scanlines(&cinfo, &buff, 1);
BYTE *in = buff;
BYTE *out = Pixels + y;
switch (cinfo.out_color_space)
{ {
*out++ = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3]; case JCS_RGB:
in += pitch; for (int x = Width; x > 0; --x)
{
*out = RGB32k[in[0]>>3][in[1]>>3][in[2]>>3];
out += Height;
in += 3;
} }
in -= backstep; break;
case JCS_GRAYSCALE:
for (int x = Width; x > 0; --x)
{
*out = GrayMap[in[0]];
out += Height;
in += 1;
} }
break;
case JCS_CMYK:
// What are you doing using a CMYK image? :)
for (int x = Width; x > 0; --x)
{
// To be precise, these calculations should use 255, but
// 256 is much faster and virtually indistinguishable.
int r = in[3] - (((256-in[0])*in[3]) >> 8);
int g = in[3] - (((256-in[1])*in[3]) >> 8);
int b = in[3] - (((256-in[2])*in[3]) >> 8);
*out = RGB32k[r >> 3][g >> 3][b >> 3];
out += Height;
in += 4;
}
break;
}
y++;
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
}
catch (int)
{
Printf (TEXTCOLOR_ORANGE " in texture %s\n", Name);
jpeg_destroy_decompress(&cinfo);
}
if (buff != NULL)
{
delete[] buff;
} }
delete[] rgb;
} }
FBuildTexture::FBuildTexture (int tilenum, const BYTE *pixels, int width, int height, int left, int top) FBuildTexture::FBuildTexture (int tilenum, const BYTE *pixels, int width, int height, int left, int top)

View file

@ -206,8 +206,6 @@ protected:
int PaletteSize; int PaletteSize;
DWORD StartOfIDAT; DWORD StartOfIDAT;
static BYTE GrayMap[256];
void MakeTexture (); void MakeTexture ();
}; };

View file

@ -2,11 +2,12 @@ Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005 # Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zdoom", "zdoom.vcproj", "{8049475B-5C87-46F9-9358-635218A4EF18}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zdoom", "zdoom.vcproj", "{8049475B-5C87-46F9-9358-635218A4EF18}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466} = {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}
{1D179D4B-F008-431B-8C72-111F8372584F} = {1D179D4B-F008-431B-8C72-111F8372584F} {1D179D4B-F008-431B-8C72-111F8372584F} = {1D179D4B-F008-431B-8C72-111F8372584F}
{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}
{6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859}
{667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E}
{873F2EEA-24DF-454C-B245-CB9738BA993E} = {873F2EEA-24DF-454C-B245-CB9738BA993E} {873F2EEA-24DF-454C-B245-CB9738BA993E} = {873F2EEA-24DF-454C-B245-CB9738BA993E}
{667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E}
{6077B7D6-349F-4077-B552-3BC302EF5859} = {6077B7D6-349F-4077-B552-3BC302EF5859}
{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib.vcproj", "{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib.vcproj", "{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}"
@ -19,9 +20,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "re2c", "tools\re2c\re2c.vcp
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wadsrc", "wadsrc\wadsrc.vcproj", "{1D179D4B-F008-431B-8C72-111F8372584F}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wadsrc", "wadsrc\wadsrc.vcproj", "{1D179D4B-F008-431B-8C72-111F8372584F}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}
{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} = {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}
{3FFA68B3-9449-4B03-ADEE-194C3638623B} = {3FFA68B3-9449-4B03-ADEE-194C3638623B} {3FFA68B3-9449-4B03-ADEE-194C3638623B} = {3FFA68B3-9449-4B03-ADEE-194C3638623B}
{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8} = {AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}
{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3} = {24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makewad", "tools\makewad\makewad.vcproj", "{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "makewad", "tools\makewad\makewad.vcproj", "{24A19C02-F041-4AB0-A1A1-02E1E88EDBD3}"
@ -33,12 +34,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xlatcc", "tools\xlatcc\xlat
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dehsupp", "tools\dehsupp\dehsupp.vcproj", "{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dehsupp", "tools\dehsupp\dehsupp.vcproj", "{AC64EE8F-F019-4A3E-BCAF-BD1FD072B9C8}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7}
{667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E} = {667D2EE7-C357-49E2-9BAB-0A4A45F0F76E}
{0F80ACBF-460E-44F0-B28E-B3272D1774A7} = {0F80ACBF-460E-44F0-B28E-B3272D1774A7}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "updaterevision", "tools\updaterevision\updaterevision.vcproj", "{6077B7D6-349F-4077-B552-3BC302EF5859}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "updaterevision", "tools\updaterevision\updaterevision.vcproj", "{6077B7D6-349F-4077-B552-3BC302EF5859}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpeg-6b", "jpeg-6b\jpeg-6b.vcproj", "{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -127,6 +130,12 @@ Global
{6077B7D6-349F-4077-B552-3BC302EF5859}.Release|Win32.Build.0 = Release|Win32 {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|Win32.Build.0 = Release|Win32
{6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.ActiveCfg = Release|Win32 {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.ActiveCfg = Release|Win32
{6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.Build.0 = Release|Win32 {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.Build.0 = Release|Win32
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Debug|Win32.ActiveCfg = Debug|Win32
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Debug|Win32.Build.0 = Debug|Win32
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Debug|x64.ActiveCfg = Debug|Win32
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|Win32.ActiveCfg = Release|Win32
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|Win32.Build.0 = Release|Win32
{AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -55,7 +55,7 @@
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1" FavorSizeOrSpeed="1"
OmitFramePointers="true" OmitFramePointers="true"
AdditionalIncludeDirectories="src\win32,src\sound,src,zlib,src\g_shared,src\g_doom,src\g_raven,src\g_heretic,src\g_hexen,src\g_strife;flac" AdditionalIncludeDirectories="src\win32,src\sound,src,zlib,src\g_shared,src\g_doom,src\g_raven,src\g_heretic,src\g_hexen,src\g_strife;flac;jpeg-6b"
PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,USEASM,HAVE_STRUPR,HAVE_FILELENGTH" PreprocessorDefinitions="NDEBUG,WIN32,_WIN32,_WINDOWS,USEASM,HAVE_STRUPR,HAVE_FILELENGTH"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
@ -284,7 +284,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; " AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;flac" AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;flac;jpeg-6b"
PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,USEASM,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH" PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,USEASM,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH"
MinimalRebuild="true" MinimalRebuild="true"
RuntimeLibrary="1" RuntimeLibrary="1"
@ -1924,10 +1924,6 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath=".\src\kplib.cpp"
>
</File>
<File <File
RelativePath=".\src\lumpconfigfile.cpp" RelativePath=".\src\lumpconfigfile.cpp"
> >