Commit dedb7358 authored by virgile devaux's avatar virgile devaux Committed by Davis E. King
Browse files

Feature/upgrade libjpeg (#1769)

* Upgrades dlib's included libjpeg to version 8d

* Overloads load_jpeg to read from memory buffer

* Removes "__inline__" define in jconfig, broke VC build

* Changes buffer size type to size_t
parent f0e1d4e4
...@@ -504,50 +504,72 @@ if (NOT TARGET dlib) ...@@ -504,50 +504,72 @@ if (NOT TARGET dlib)
# If we can't find libjpeg then statically compile it in. # If we can't find libjpeg then statically compile it in.
add_definitions(-DDLIB_JPEG_STATIC) add_definitions(-DDLIB_JPEG_STATIC)
set(source_files ${source_files} set(source_files ${source_files}
external/libjpeg/jcomapi.cpp external/libjpeg/jaricom.c
external/libjpeg/jdapimin.cpp external/libjpeg/jcapimin.c
external/libjpeg/jdapistd.cpp external/libjpeg/jcapistd.c
external/libjpeg/jdatasrc.cpp external/libjpeg/jcarith.c
external/libjpeg/jdcoefct.cpp external/libjpeg/jccoefct.c
external/libjpeg/jdcolor.cpp external/libjpeg/jccolor.c
external/libjpeg/jddctmgr.cpp external/libjpeg/jcdctmgr.c
external/libjpeg/jdhuff.cpp external/libjpeg/jchuff.c
external/libjpeg/jdinput.cpp external/libjpeg/jcinit.c
external/libjpeg/jdmainct.cpp external/libjpeg/jcmainct.c
external/libjpeg/jdmarker.cpp external/libjpeg/jcmarker.c
external/libjpeg/jdmaster.cpp external/libjpeg/jcmaster.c
external/libjpeg/jdmerge.cpp external/libjpeg/jcomapi.c
external/libjpeg/jdphuff.cpp external/libjpeg/jcparam.c
external/libjpeg/jdpostct.cpp external/libjpeg/jcprepct.c
external/libjpeg/jdsample.cpp external/libjpeg/jcsample.c
external/libjpeg/jerror.cpp external/libjpeg/jctrans.c
external/libjpeg/jidctflt.cpp external/libjpeg/jdapimin.c
external/libjpeg/jidctfst.cpp external/libjpeg/jdapistd.c
external/libjpeg/jidctint.cpp external/libjpeg/jdarith.c
external/libjpeg/jidctred.cpp external/libjpeg/jdatadst.c
external/libjpeg/jmemmgr.cpp external/libjpeg/jdatasrc.c
external/libjpeg/jmemnobs.cpp external/libjpeg/jdcoefct.c
external/libjpeg/jquant1.cpp external/libjpeg/jdcolor.c
external/libjpeg/jquant2.cpp external/libjpeg/jddctmgr.c
external/libjpeg/jutils.cpp external/libjpeg/jdhuff.c
external/libjpeg/jcapimin.cpp external/libjpeg/jdinput.c
external/libjpeg/jdatadst.cpp external/libjpeg/jdmainct.c
external/libjpeg/jcparam.cpp external/libjpeg/jdmarker.c
external/libjpeg/jcapistd.cpp external/libjpeg/jdmaster.c
external/libjpeg/jcmarker.cpp external/libjpeg/jdmerge.c
external/libjpeg/jcinit.cpp external/libjpeg/jdpostct.c
external/libjpeg/jcmaster.cpp external/libjpeg/jdsample.c
external/libjpeg/jcdctmgr.cpp external/libjpeg/jdtrans.c
external/libjpeg/jccoefct.cpp external/libjpeg/jerror.c
external/libjpeg/jccolor.cpp external/libjpeg/jerror.h
external/libjpeg/jchuff.cpp external/libjpeg/jfdctflt.c
external/libjpeg/jcmainct.cpp external/libjpeg/jfdctfst.c
external/libjpeg/jcphuff.cpp external/libjpeg/jfdctint.c
external/libjpeg/jcprepct.cpp external/libjpeg/jidctflt.c
external/libjpeg/jcsample.cpp external/libjpeg/jidctfst.c
external/libjpeg/jfdctint.cpp external/libjpeg/jidctint.c
external/libjpeg/jfdctflt.cpp external/libjpeg/jinclude.h
external/libjpeg/jfdctfst.cpp external/libjpeg/jmemansi.c
external/libjpeg/jmemmgr.c
external/libjpeg/jmemname.c
external/libjpeg/jmemnobs.c
external/libjpeg/jpegtran.c
external/libjpeg/jquant1.c
external/libjpeg/jquant2.c
external/libjpeg/jutils.c
external/libjpeg/rdbmp.c
external/libjpeg/rdcolmap.c
external/libjpeg/rdgif.c
external/libjpeg/rdjpgcom.c
external/libjpeg/rdppm.c
external/libjpeg/rdrle.c
external/libjpeg/rdswitch.c
external/libjpeg/rdtarga.c
external/libjpeg/transupp.c
external/libjpeg/wrbmp.c
external/libjpeg/wrgif.c
external/libjpeg/wrjpgcom.c
external/libjpeg/wrppm.c
external/libjpeg/wrrle.c
external/libjpeg/wrtarga.c
) )
endif() endif()
set(source_files ${source_files} set(source_files ${source_files}
......
The Independent JPEG Group's JPEG software The Independent JPEG Group's JPEG software
========================================== ==========================================
README for release 6b of 27-Mar-1998 README for release 8d of 15-Jan-2012
==================================== ====================================
This distribution contains the sixth public release of the Independent JPEG This distribution contains the eighth public release of the Independent JPEG
Group's free JPEG software. You are welcome to redistribute this software and 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. to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
Serious users of this software (particularly those incorporating it into This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
our electronic mailing list. Mailing list members are notified of updates Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
and have a chance to participate in technical discussions, etc. and other members of the Independent JPEG Group.
This software is the work of Tom Lane, Philip Gladstone, Jim Boucher, IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, (also known as JPEG, together with ITU-T SG16).
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 DOCUMENTATION ROADMAP
...@@ -30,27 +26,27 @@ OVERVIEW General description of JPEG and the IJG software. ...@@ -30,27 +26,27 @@ OVERVIEW General description of JPEG and the IJG software.
LEGAL ISSUES Copyright, lack of warranty, terms of distribution. LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
REFERENCES Where to learn more about JPEG. REFERENCES Where to learn more about JPEG.
ARCHIVE LOCATIONS Where to find newer versions of this software. ARCHIVE LOCATIONS Where to find newer versions of this software.
RELATED SOFTWARE Other stuff you should get. ACKNOWLEDGMENTS Special thanks.
FILE FORMAT WARS Software *not* to get. FILE FORMAT WARS Software *not* to get.
TO DO Plans for future IJG releases. TO DO Plans for future IJG releases.
Other documentation files in the distribution are: Other documentation files in the distribution are:
User documentation: User documentation:
install.doc How to configure and install the IJG software. install.txt How to configure and install the IJG software.
usage.doc Usage instructions for cjpeg, djpeg, jpegtran, usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
rdjpgcom, and wrjpgcom. rdjpgcom, and wrjpgcom.
*.1 Unix-style man pages for programs (same info as usage.doc). *.1 Unix-style man pages for programs (same info as usage.txt).
wizard.doc Advanced usage instructions for JPEG wizards only. wizard.txt Advanced usage instructions for JPEG wizards only.
change.log Version-to-version change highlights. change.log Version-to-version change highlights.
Programmer and internal documentation: Programmer and internal documentation:
libjpeg.doc How to use the JPEG library in your own programs. libjpeg.txt How to use the JPEG library in your own programs.
example.c Sample code for calling the JPEG library. example.c Sample code for calling the JPEG library.
structure.doc Overview of the JPEG library's internal structure. structure.txt Overview of the JPEG library's internal structure.
filelist.doc Road map of IJG files. filelist.txt Road map of IJG files.
coderules.doc Coding style rules --- please read if you contribute code. coderules.txt Coding style rules --- please read if you contribute code.
Please read at least the files install.doc and usage.doc. Useful information Please read at least the files install.txt and usage.txt. Some information
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See 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. ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
...@@ -62,24 +58,15 @@ the order listed) before diving into the code. ...@@ -62,24 +58,15 @@ the order listed) before diving into the code.
OVERVIEW OVERVIEW
======== ========
This package contains C software to implement JPEG image compression and This package contains C software to implement JPEG image encoding, decoding,
decompression. JPEG (pronounced "jay-peg") is a standardized compression and transcoding. JPEG (pronounced "jay-peg") is a standardized compression
method for full-color and gray-scale images. JPEG is intended for compressing method for full-color and gray-scale images.
"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 This software implements JPEG baseline, extended-sequential, and progressive
compression processes. Provision is made for supporting all variants of these compression processes. Provision is made for supporting all variants of these
processes, although some uncommon parameter settings aren't implemented yet. processes, although some uncommon parameter settings aren't implemented yet.
For legal reasons, we are not distributing code for the arithmetic-coding We have made no provision for supporting the hierarchical or lossless
variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting processes defined in the standard.
the hierarchical or lossless processes defined in the standard.
We provide a set of library routines for reading and writing JPEG image files, 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 plus two sample applications "cjpeg" and "djpeg", which use the library to
...@@ -91,10 +78,11 @@ considerable functionality beyond the bare JPEG coding/decoding capability; ...@@ -91,10 +78,11 @@ considerable functionality beyond the bare JPEG coding/decoding capability;
for example, the color quantization modules are not strictly part of JPEG for example, the color quantization modules are not strictly part of JPEG
decoding, but they are essential for output to colormapped file formats or decoding, but they are essential for output to colormapped file formats or
colormapped displays. These extra functions can be compiled out of the colormapped displays. These extra functions can be compiled out of the
library if not required for a particular application. We have also included library if not required for a particular application.
"jpegtran", a utility for lossless transcoding between different JPEG
processes, and "rdjpgcom" and "wrjpgcom", two simple applications for We have also included "jpegtran", a utility for lossless transcoding between
inserting and extracting textual comments in JFIF files. 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 The emphasis in designing this software has been on achieving portability and
flexibility, while also making it fast enough to be useful. In particular, flexibility, while also making it fast enough to be useful. In particular,
...@@ -127,7 +115,7 @@ with respect to this software, its quality, accuracy, merchantability, or ...@@ -127,7 +115,7 @@ with respect to this software, its quality, accuracy, merchantability, or
fitness for a particular purpose. This software is provided "AS IS", and you, 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. its user, assume the entire risk as to its quality and accuracy.
This software is copyright (C) 1991-1998, Thomas G. Lane. This software is copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
All Rights Reserved except as specified below. All Rights Reserved except as specified below.
Permission is hereby granted to use, copy, modify, and distribute this Permission is hereby granted to use, copy, modify, and distribute this
...@@ -170,17 +158,8 @@ the foregoing paragraphs do. ...@@ -170,17 +158,8 @@ the foregoing paragraphs do.
The Unix configuration script "configure" was produced with GNU Autoconf. The Unix configuration script "configure" was produced with GNU Autoconf.
It is copyright by the Free Software Foundation but is freely distributable. It is copyright by the Free Software Foundation but is freely distributable.
The same holds for its supporting scripts (config.guess, config.sub, The same holds for its supporting scripts (config.guess, config.sub,
ltconfig, ltmain.sh). Another support script, install-sh, is copyright ltmain.sh). Another support script, install-sh, is copyright by X Consortium
by M.I.T. but is also freely distributable. 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. The IJG distribution formerly included code to read and write GIF files.
To avoid entanglement with the Unisys LZW patent, GIF reading support has To avoid entanglement with the Unisys LZW patent, GIF reading support has
...@@ -198,7 +177,7 @@ We are required to state that ...@@ -198,7 +177,7 @@ We are required to state that
REFERENCES REFERENCES
========== ==========
We highly recommend reading one or more of these references before trying to We recommend reading one or more of these references before trying to
understand the innards of the JPEG software. understand the innards of the JPEG software.
The best short technical introduction to the JPEG compression algorithm is The best short technical introduction to the JPEG compression algorithm is
...@@ -207,7 +186,7 @@ The best short technical introduction to the JPEG compression algorithm is ...@@ -207,7 +186,7 @@ The best short technical introduction to the JPEG compression algorithm is
(Adjacent articles in that issue discuss MPEG motion picture compression, (Adjacent articles in that issue discuss MPEG motion picture compression,
applications of JPEG, and related topics.) If you don't have the CACM issue 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 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 available at http://www.ijg.org/files/wallace.ps.gz. The file (actually
a preprint for an article that appeared in IEEE Trans. Consumer Electronics) a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
omits the sample images that appeared in CACM, but it includes corrections 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 some added material. Note: the Wallace article is copyright ACM and IEEE,
...@@ -222,82 +201,67 @@ code but don't know much about data compression in general. The book's JPEG ...@@ -222,82 +201,67 @@ 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 sample code is far from industrial-strength, but when you are ready to look
at a full implementation, you've got one here... at a full implementation, you've got one here...
The best full description of JPEG is the textbook "JPEG Still Image Data The best currently available description of JPEG is the textbook "JPEG Still
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published Image Data Compression Standard" by William B. Pennebaker and Joan L.
by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp. Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.
The book includes the complete text of the ISO JPEG standards (DIS 10918-1 Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG
and draft DIS 10918-2). This is by far the most complete exposition of JPEG standards (DIS 10918-1 and draft DIS 10918-2).
in existence, and we highly recommend it. Although this is by far the most detailed and comprehensive exposition of
JPEG publicly available, we point out that it is still missing an explanation
The JPEG standard itself is not available electronically; you must order a of the most essential properties and algorithms of the underlying DCT
paper copy through ISO or ITU. (Unless you feel a need to own a certified technology.
official copy, we recommend buying the Pennebaker and Mitchell book instead; If you think that you know about DCT-based JPEG after reading this book,
it's much cheaper and includes a great deal of useful explanatory material.) then you are in delusion. The real fundamentals and corresponding potential
In the USA, copies of the standard may be ordered from ANSI Sales at (212) of DCT-based JPEG are not publicly known so far, and that is the reason for
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI all the mistaken developments taking place in the image coding domain.
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% The original JPEG standard is divided into two parts, Part 1 being the actual
shipping/handling. The standard is divided into two parts, Part 1 being the specification, while Part 2 covers compliance testing methods. Part 1 is
actual specification, while Part 2 covers compliance testing methods. Part 1 titled "Digital Compression and Coding of Continuous-tone Still Images,
is titled "Digital Compression and Coding of Continuous-tone Still Images,
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS 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 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 Continuous-tone Still Images, Part 2: Compliance testing" and has document
numbers ISO/IEC IS 10918-2, ITU-T T.83. numbers ISO/IEC IS 10918-2, ITU-T T.83.
IJG JPEG 8 introduces an implementation of the JPEG SmartScale extension
Some extensions to the original JPEG standard are defined in JPEG Part 3, which is specified in two documents: A contributed document at ITU and ISO
a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG with title "ITU-T JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced
currently does not support any Part 3 extensions. Image Coding", April 2006, Geneva, Switzerland. The latest version of this
document is Revision 3. And a contributed document ISO/IEC JTC1/SC29/WG1 N
5799 with title "Evolution of JPEG", June/July 2011, Berlin, Germany.
The JPEG standard does not specify all details of an interchangeable file The JPEG standard does not specify all details of an interchangeable file
format. For the omitted details we follow the "JFIF" conventions, revision format. For the omitted details we follow the "JFIF" conventions, revision
1.02. A copy of the JFIF spec is available from: 1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report
Literature Department and thus received a formal publication status. It is available as a free
C-Cube Microsystems, Inc. download in PDF format from
1778 McCarthy Blvd. http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
Milpitas, CA 95035 A PostScript version of the JFIF document is available at
phone (408) 944-6300, fax (408) 944-6314 http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at
A PostScript version of this document is available by FTP at http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
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 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 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. 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). 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 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 (Compression tag 7). Copies of this Note can be obtained from
from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision http://www.ijg.org/files/. It is expected that the next revision
of the TIFF spec will replace the 6.0 JPEG design with the Note's design. 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 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 uses our library to implement TIFF/JPEG per the Note.
from ftp://ftp.sgi.com/graphics/tiff/.
ARCHIVE LOCATIONS ARCHIVE LOCATIONS
================= =================
The "official" archive site for this software is ftp.uu.net (Internet The "official" archive site for this software is www.ijg.org.
address 192.48.96.9). The most recent released version can always be found The most recent released version can always be found there in
there in directory graphics/jpeg. This particular version will be archived directory "files". This particular version will be archived as
as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have http://www.ijg.org/files/jpegsrc.v8d.tar.gz, and in Windows-compatible
direct Internet access, UUNET's archives are also available via UUCP; contact "zip" archive format as http://www.ijg.org/files/jpegsr8d.zip.
help@uunet.uu.net for information on retrieving files that way.
The JPEG FAQ (Frequently Asked Questions) article is a source of some
Numerous Internet sites maintain copies of the UUNET files. However, only general information about JPEG.
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/ 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 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/. archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
...@@ -307,79 +271,81 @@ with body ...@@ -307,79 +271,81 @@ with body
send usenet/news.answers/jpeg-faq/part2 send usenet/news.answers/jpeg-faq/part2
RELATED SOFTWARE ACKNOWLEDGMENTS
================ ===============
Thank to Juergen Bruder for providing me with a copy of the common DCT
algorithm article, only to find out that I had come to the same result
in a more direct and comprehensible way with a more generative approach.
Thank to Istvan Sebestyen and Joan L. Mitchell for inviting me to the
ITU JPEG (Study Group 16) meeting in Geneva, Switzerland.
Numerous viewing and image manipulation programs now support JPEG. (Quite a Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
few of them use this library to do so.) The JPEG FAQ described above lists Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
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 Thank to Thomas Richter and Daniel Lee for inviting me to the
PBMPLUS software, which provides many useful operations on PPM-format image ISO/IEC JTC1/SC29/WG1 (also known as JPEG, together with ITU-T SG16)
files. In particular, it can convert PPM images to and from a wide range of meeting in Berlin, Germany.
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, Thank to John Korejwa and Massimo Ballerini for inviting me to
is available from ftp://havefun.stanford.edu/pub/jpeg/. This program fruitful consultations in Boston, MA and Milan, Italy.
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 Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther
is easier to read and modify. Also, the PVRG code supports lossless JPEG, Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel
which we do not. (On the other hand, it doesn't do progressive JPEG.) for corresponding business development.
Thank to Nico Zschach and Dirk Stelling of the technical support team
at the Digital Images company in Halle for providing me with extra
equipment for configuration tests.
Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful
communication about JPEG configuration in Sigma Photo Pro software.
Thank to Andrew Finkenstadt for hosting the ijg.org site.
Last but not least special thank to Thomas G. Lane for the original
design and development of this singular software package.
FILE FORMAT WARS FILE FORMAT WARS
================ ================
Some JPEG programs produce files that are not compatible with our library. The ISO/IEC JTC1/SC29/WG1 standards committee (also known as JPEG, together
The root of the problem is that the ISO JPEG committee failed to specify a with ITU-T SG16) currently promotes different formats containing the name
concrete file format. Some vendors "filled in the blanks" on their own, "JPEG" which is misleading because these formats are incompatible with
creating proprietary formats that no one else could read. (For example, none original DCT-based JPEG and are based on faulty technologies.
of the early commercial JPEG implementations for the Macintosh were able to IJG therefore does not and will not support such momentary mistakes
exchange compressed files.) (see REFERENCES).
There exist also distributions under the name "OpenJPEG" promoting such
The file format we have adopted is called JFIF (see REFERENCES). This format kind of formats which is misleading because they don't support original
has been agreed to by a number of major commercial JPEG vendors, and it has JPEG images.
become the de facto standard. JFIF is a minimal or "low end" representation. We have no sympathy for the promotion of inferior formats. Indeed, one of
We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF the original reasons for developing this free software was to help force
Technical Note #2) for "high end" applications that need to record a lot of convergence on common, interoperable format standards for JPEG files.
additional data about an image. TIFF/JPEG is fairly new and not yet widely Don't use an incompatible file format!
supported, unfortunately. (In any case, our decoder will remain capable of reading existing JPEG
image files indefinitely.)
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 Furthermore, the ISO committee pretends to be "responsible for the popular
be able to read the most common variant of SPIFF. SPIFF has some technical JPEG" in their public reports which is not true because they don't respond to
advantages over JFIF, but its major claim to fame is simply that it is an actual requirements for the maintenance of the original JPEG specification.
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 There are currently distributions in circulation containing the name
standard. IJG intends to support SPIFF once the standard is frozen, but we "libjpeg" which claim to be a "derivative" or "fork" of the original
have not decided whether it should become our default output format or not. libjpeg, but don't have the features and are incompatible with formats
(In any case, our decoder will remain capable of reading JFIF indefinitely.) supported by actual IJG libjpeg distributions. Furthermore, they
violate the license conditions as described under LEGAL ISSUES above.
Various proprietary file formats incorporating JPEG compression also exist. We have no sympathy for the release of misleading and illegal
We have little or no sympathy for the existence of these formats. Indeed, distributions derived from obsolete code bases.
one of the original reasons for developing this free software was to help Don't use an obsolete code base!
force convergence on common, open format standards for JPEG files. Don't
use a proprietary file format!
TO DO TO DO
===== =====
The major thrust for v7 will probably be improvement of visual quality. Version 8 is the first release of a new generation JPEG standard
The current method for scaling the quantization tables is known not to be to overcome the limitations of the original JPEG specification.
very good at low Q values. We also intend to investigate block boundary More features are being prepared for coming releases...
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. Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org.
/*
* cderror.h
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file defines the error and message codes for the cjpeg/djpeg
* applications. These strings are not needed as part of the JPEG library
* proper.
* Edit this file to add new codes, or to translate the message strings to
* some other language.
*/
/*
* 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 CDERROR_H
#define CDERROR_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 /* CDERROR_H */
#endif /* JMESSAGE */
#ifdef JMAKE_ENUM_LIST
typedef enum {
#define JMESSAGE(code,string) code ,
#endif /* JMAKE_ENUM_LIST */
JMESSAGE(JMSG_FIRSTADDONCODE=1000, NULL) /* Must be first entry! */
#ifdef BMP_SUPPORTED
JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format")
JMESSAGE(JERR_BMP_BADDEPTH, "Only 8- and 24-bit BMP files are supported")
JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
JMESSAGE(JTRC_BMP_OS2, "%ux%u 24-bit OS2 BMP image")
JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image")
#endif /* BMP_SUPPORTED */
#ifdef GIF_SUPPORTED
JMESSAGE(JERR_GIF_BUG, "GIF output got confused")
JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d")
JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB")
JMESSAGE(JERR_GIF_IMAGENOTFOUND, "Too few images in GIF file")
JMESSAGE(JERR_GIF_NOT, "Not a GIF file")
JMESSAGE(JTRC_GIF, "%ux%ux%d GIF image")
JMESSAGE(JTRC_GIF_BADVERSION,
"Warning: unexpected GIF version number '%c%c%c'")
JMESSAGE(JTRC_GIF_EXTENSION, "Ignoring GIF extension block of type 0x%02x")
JMESSAGE(JTRC_GIF_NONSQUARE, "Caution: nonsquare pixels in input")
JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file")
JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring")
JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image")
JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
#endif /* GIF_SUPPORTED */
#ifdef PPM_SUPPORTED
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")
JMESSAGE(JTRC_PPM, "%ux%u PPM image")
JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image")
#endif /* PPM_SUPPORTED */
#ifdef RLE_SUPPORTED
JMESSAGE(JERR_RLE_BADERROR, "Bogus error code from RLE library")
JMESSAGE(JERR_RLE_COLORSPACE, "RLE output must be grayscale or RGB")
JMESSAGE(JERR_RLE_DIMENSIONS, "Image dimensions (%ux%u) too large for RLE")
JMESSAGE(JERR_RLE_EMPTY, "Empty RLE file")
JMESSAGE(JERR_RLE_EOF, "Premature EOF in RLE header")
JMESSAGE(JERR_RLE_MEM, "Insufficient memory for RLE header")
JMESSAGE(JERR_RLE_NOT, "Not an RLE file")
JMESSAGE(JERR_RLE_TOOMANYCHANNELS, "Cannot handle %d output channels for RLE")
JMESSAGE(JERR_RLE_UNSUPPORTED, "Cannot handle this RLE setup")
JMESSAGE(JTRC_RLE, "%ux%u full-color RLE file")
JMESSAGE(JTRC_RLE_FULLMAP, "%ux%u full-color RLE file with map of length %d")
JMESSAGE(JTRC_RLE_GRAY, "%ux%u grayscale RLE file")
JMESSAGE(JTRC_RLE_MAPGRAY, "%ux%u grayscale RLE file with map of length %d")
JMESSAGE(JTRC_RLE_MAPPED, "%ux%u colormapped RLE file with map of length %d")
#endif /* RLE_SUPPORTED */
#ifdef TARGA_SUPPORTED
JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format")
JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file")
JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB")
JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image")
JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image")
JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image")
#else
JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled")
#endif /* TARGA_SUPPORTED */
JMESSAGE(JERR_BAD_CMAP_FILE,
"Color map file is invalid or of unsupported format")
JMESSAGE(JERR_TOO_MANY_COLORS,
"Output file format cannot handle %d colormap entries")
JMESSAGE(JERR_UNGETC_FAILED, "ungetc failed")
#ifdef TARGA_SUPPORTED
JMESSAGE(JERR_UNKNOWN_FORMAT,
"Unrecognized input file format --- perhaps you need -targa")
#else
JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
#endif
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
#ifdef JMAKE_ENUM_LIST
JMSG_LASTADDONCODE
} ADDON_MESSAGE_CODE;
#undef JMAKE_ENUM_LIST
#endif /* JMAKE_ENUM_LIST */
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
#undef JMESSAGE
/*
* cdjpeg.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 contains common declarations for the sample applications
* cjpeg and djpeg. It is NOT used by the core JPEG library.
*/
#define JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */
#define JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */
#include "jinclude.h"
#include "jpeglib.h"
#include "jerror.h" /* get library error codes too */
#include "cderror.h" /* get application-specific error codes */
/*
* Object interface for cjpeg's source file decoding modules
*/
typedef struct cjpeg_source_struct * cjpeg_source_ptr;
struct cjpeg_source_struct {
JMETHOD(void, start_input, (j_compress_ptr cinfo,
cjpeg_source_ptr sinfo));
JMETHOD(JDIMENSION, get_pixel_rows, (j_compress_ptr cinfo,
cjpeg_source_ptr sinfo));
JMETHOD(void, finish_input, (j_compress_ptr cinfo,
cjpeg_source_ptr sinfo));
FILE *input_file;
JSAMPARRAY buffer;
JDIMENSION buffer_height;
};
/*
* Object interface for djpeg's output file encoding modules
*/
typedef struct djpeg_dest_struct * djpeg_dest_ptr;
struct djpeg_dest_struct {
/* start_output is called after jpeg_start_decompress finishes.
* The color map will be ready at this time, if one is needed.
*/
JMETHOD(void, start_output, (j_decompress_ptr cinfo,
djpeg_dest_ptr dinfo));
/* Emit the specified number of pixel rows from the buffer. */
JMETHOD(void, put_pixel_rows, (j_decompress_ptr cinfo,
djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied));
/* Finish up at the end of the image. */
JMETHOD(void, finish_output, (j_decompress_ptr cinfo,
djpeg_dest_ptr dinfo));
/* Target file spec; filled in by djpeg.c after object is created. */
FILE * output_file;
/* Output pixel-row buffer. Created by module init or start_output.
* Width is cinfo->output_width * cinfo->output_components;
* height is buffer_height.
*/
JSAMPARRAY buffer;
JDIMENSION buffer_height;
};
/*
* cjpeg/djpeg may need to perform extra passes to convert to or from
* the source/destination file format. The JPEG library does not know
* about these passes, but we'd like them to be counted by the progress
* monitor. We use an expanded progress monitor object to hold the
* additional pass count.
*/
struct cdjpeg_progress_mgr {
struct jpeg_progress_mgr pub; /* fields known to JPEG library */
int completed_extra_passes; /* extra passes completed */
int total_extra_passes; /* total extra */
/* last printed percentage stored here to avoid multiple printouts */
int percent_done;
};
typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
/* Short forms of external names for systems with brain-damaged linkers. */
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jinit_read_bmp jIRdBMP
#define jinit_write_bmp jIWrBMP
#define jinit_read_gif jIRdGIF
#define jinit_write_gif jIWrGIF
#define jinit_read_ppm jIRdPPM
#define jinit_write_ppm jIWrPPM
#define jinit_read_rle jIRdRLE
#define jinit_write_rle jIWrRLE
#define jinit_read_targa jIRdTarga
#define jinit_write_targa jIWrTarga
#define read_quant_tables RdQTables
#define read_scan_script RdScnScript
#define set_quality_ratings SetQRates
#define set_quant_slots SetQSlots
#define set_sample_factors SetSFacts
#define read_color_map RdCMap
#define enable_signal_catcher EnSigCatcher
#define start_progress_monitor StProgMon
#define end_progress_monitor EnProgMon
#define read_stdin RdStdin
#define write_stdout WrStdout
#endif /* NEED_SHORT_EXTERNAL_NAMES */
/* Module selection routines for I/O modules. */
EXTERN(cjpeg_source_ptr) jinit_read_bmp JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_bmp JPP((j_decompress_ptr cinfo,
boolean is_os2));
EXTERN(cjpeg_source_ptr) jinit_read_gif JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_gif JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_ppm JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_ppm JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_rle JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_rle JPP((j_decompress_ptr cinfo));
EXTERN(cjpeg_source_ptr) jinit_read_targa JPP((j_compress_ptr cinfo));
EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo));
/* cjpeg support routines (in rdswitch.c) */
EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
boolean force_baseline));
EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
EXTERN(boolean) set_quality_ratings JPP((j_compress_ptr cinfo, char *arg,
boolean force_baseline));
EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
/* djpeg support routines (in rdcolmap.c) */
EXTERN(void) read_color_map JPP((j_decompress_ptr cinfo, FILE * infile));
/* common support routines (in cdjpeg.c) */
EXTERN(void) enable_signal_catcher JPP((j_common_ptr cinfo));
EXTERN(void) start_progress_monitor JPP((j_common_ptr cinfo,
cd_progress_ptr progress));
EXTERN(void) end_progress_monitor JPP((j_common_ptr cinfo));
EXTERN(boolean) keymatch JPP((char * arg, const char * keyword, int minchars));
EXTERN(FILE *) read_stdin JPP((void));
EXTERN(FILE *) write_stdout JPP((void));
/* miscellaneous useful macros */
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
#define READ_BINARY "r"
#define WRITE_BINARY "w"
#else
#ifdef VMS /* VMS is very nonstandard */
#define READ_BINARY "rb", "ctx=stm"
#define WRITE_BINARY "wb", "ctx=stm"
#else /* standard ANSI-compliant case */
#define READ_BINARY "rb"
#define WRITE_BINARY "wb"
#endif
#endif
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#ifdef VMS
#define EXIT_SUCCESS 1 /* VMS is very nonstandard */
#else
#define EXIT_SUCCESS 0
#endif
#endif
#ifndef EXIT_WARNING
#ifdef VMS
#define EXIT_WARNING 1 /* VMS is very nonstandard */
#else
#define EXIT_WARNING 2
#endif
#endif
/*
* jaricom.c
*
* Developed 1997-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains probability estimation tables for common use in
* arithmetic entropy encoding and decoding routines.
*
* This data represents Table D.3 in the JPEG spec (D.2 in the draft),
* ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81, and Table 24
* in the JBIG spec, ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* The following #define specifies the packing of the four components
* into the compact INT32 representation.
* Note that this formula must match the actual arithmetic encoder
* and decoder implementation. The implementation has to be changed
* if this formula is changed.
* The current organization is leaned on Markus Kuhn's JBIG
* implementation (jbig_tab.c).
*/
#define V(i,a,b,c,d) (((INT32)a << 16) | ((INT32)c << 8) | ((INT32)d << 7) | b)
const INT32 jpeg_aritab[113+1] = {
/*
* Index, Qe_Value, Next_Index_LPS, Next_Index_MPS, Switch_MPS
*/
V( 0, 0x5a1d, 1, 1, 1 ),
V( 1, 0x2586, 14, 2, 0 ),
V( 2, 0x1114, 16, 3, 0 ),
V( 3, 0x080b, 18, 4, 0 ),
V( 4, 0x03d8, 20, 5, 0 ),
V( 5, 0x01da, 23, 6, 0 ),
V( 6, 0x00e5, 25, 7, 0 ),
V( 7, 0x006f, 28, 8, 0 ),
V( 8, 0x0036, 30, 9, 0 ),
V( 9, 0x001a, 33, 10, 0 ),
V( 10, 0x000d, 35, 11, 0 ),
V( 11, 0x0006, 9, 12, 0 ),
V( 12, 0x0003, 10, 13, 0 ),
V( 13, 0x0001, 12, 13, 0 ),
V( 14, 0x5a7f, 15, 15, 1 ),
V( 15, 0x3f25, 36, 16, 0 ),
V( 16, 0x2cf2, 38, 17, 0 ),
V( 17, 0x207c, 39, 18, 0 ),
V( 18, 0x17b9, 40, 19, 0 ),
V( 19, 0x1182, 42, 20, 0 ),
V( 20, 0x0cef, 43, 21, 0 ),
V( 21, 0x09a1, 45, 22, 0 ),
V( 22, 0x072f, 46, 23, 0 ),
V( 23, 0x055c, 48, 24, 0 ),
V( 24, 0x0406, 49, 25, 0 ),
V( 25, 0x0303, 51, 26, 0 ),
V( 26, 0x0240, 52, 27, 0 ),
V( 27, 0x01b1, 54, 28, 0 ),
V( 28, 0x0144, 56, 29, 0 ),
V( 29, 0x00f5, 57, 30, 0 ),
V( 30, 0x00b7, 59, 31, 0 ),
V( 31, 0x008a, 60, 32, 0 ),
V( 32, 0x0068, 62, 33, 0 ),
V( 33, 0x004e, 63, 34, 0 ),
V( 34, 0x003b, 32, 35, 0 ),
V( 35, 0x002c, 33, 9, 0 ),
V( 36, 0x5ae1, 37, 37, 1 ),
V( 37, 0x484c, 64, 38, 0 ),
V( 38, 0x3a0d, 65, 39, 0 ),
V( 39, 0x2ef1, 67, 40, 0 ),
V( 40, 0x261f, 68, 41, 0 ),
V( 41, 0x1f33, 69, 42, 0 ),
V( 42, 0x19a8, 70, 43, 0 ),
V( 43, 0x1518, 72, 44, 0 ),
V( 44, 0x1177, 73, 45, 0 ),
V( 45, 0x0e74, 74, 46, 0 ),
V( 46, 0x0bfb, 75, 47, 0 ),
V( 47, 0x09f8, 77, 48, 0 ),
V( 48, 0x0861, 78, 49, 0 ),
V( 49, 0x0706, 79, 50, 0 ),
V( 50, 0x05cd, 48, 51, 0 ),
V( 51, 0x04de, 50, 52, 0 ),
V( 52, 0x040f, 50, 53, 0 ),
V( 53, 0x0363, 51, 54, 0 ),
V( 54, 0x02d4, 52, 55, 0 ),
V( 55, 0x025c, 53, 56, 0 ),
V( 56, 0x01f8, 54, 57, 0 ),
V( 57, 0x01a4, 55, 58, 0 ),
V( 58, 0x0160, 56, 59, 0 ),
V( 59, 0x0125, 57, 60, 0 ),
V( 60, 0x00f6, 58, 61, 0 ),
V( 61, 0x00cb, 59, 62, 0 ),
V( 62, 0x00ab, 61, 63, 0 ),
V( 63, 0x008f, 61, 32, 0 ),
V( 64, 0x5b12, 65, 65, 1 ),
V( 65, 0x4d04, 80, 66, 0 ),
V( 66, 0x412c, 81, 67, 0 ),
V( 67, 0x37d8, 82, 68, 0 ),
V( 68, 0x2fe8, 83, 69, 0 ),
V( 69, 0x293c, 84, 70, 0 ),
V( 70, 0x2379, 86, 71, 0 ),
V( 71, 0x1edf, 87, 72, 0 ),
V( 72, 0x1aa9, 87, 73, 0 ),
V( 73, 0x174e, 72, 74, 0 ),
V( 74, 0x1424, 72, 75, 0 ),
V( 75, 0x119c, 74, 76, 0 ),
V( 76, 0x0f6b, 74, 77, 0 ),
V( 77, 0x0d51, 75, 78, 0 ),
V( 78, 0x0bb6, 77, 79, 0 ),
V( 79, 0x0a40, 77, 48, 0 ),
V( 80, 0x5832, 80, 81, 1 ),
V( 81, 0x4d1c, 88, 82, 0 ),
V( 82, 0x438e, 89, 83, 0 ),
V( 83, 0x3bdd, 90, 84, 0 ),
V( 84, 0x34ee, 91, 85, 0 ),
V( 85, 0x2eae, 92, 86, 0 ),
V( 86, 0x299a, 93, 87, 0 ),
V( 87, 0x2516, 86, 71, 0 ),
V( 88, 0x5570, 88, 89, 1 ),
V( 89, 0x4ca9, 95, 90, 0 ),
V( 90, 0x44d9, 96, 91, 0 ),
V( 91, 0x3e22, 97, 92, 0 ),
V( 92, 0x3824, 99, 93, 0 ),
V( 93, 0x32b4, 99, 94, 0 ),
V( 94, 0x2e17, 93, 86, 0 ),
V( 95, 0x56a8, 95, 96, 1 ),
V( 96, 0x4f46, 101, 97, 0 ),
V( 97, 0x47e5, 102, 98, 0 ),
V( 98, 0x41cf, 103, 99, 0 ),
V( 99, 0x3c3d, 104, 100, 0 ),
V( 100, 0x375e, 99, 93, 0 ),
V( 101, 0x5231, 105, 102, 0 ),
V( 102, 0x4c0f, 106, 103, 0 ),
V( 103, 0x4639, 107, 104, 0 ),
V( 104, 0x415e, 103, 99, 0 ),
V( 105, 0x5627, 105, 106, 1 ),
V( 106, 0x50e7, 108, 107, 0 ),
V( 107, 0x4b85, 109, 103, 0 ),
V( 108, 0x5597, 110, 109, 0 ),
V( 109, 0x504f, 111, 107, 0 ),
V( 110, 0x5a10, 110, 111, 1 ),
V( 111, 0x5522, 112, 109, 0 ),
V( 112, 0x59eb, 112, 111, 1 ),
/*
* This last entry is used for fixed probability estimate of 0.5
* as suggested in Section 10.3 Table 5 of ITU-T Rec. T.851.
*/
V( 113, 0x5a1d, 113, 113, 0 )
};
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* jcapimin.c * jcapimin.c
* *
* Copyright (C) 1994-1998, Thomas G. Lane. * Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
...@@ -63,14 +64,21 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize) ...@@ -63,14 +64,21 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
cinfo->comp_info = NULL; cinfo->comp_info = NULL;
for (i = 0; i < NUM_QUANT_TBLS; i++) for (i = 0; i < NUM_QUANT_TBLS; i++) {
cinfo->quant_tbl_ptrs[i] = NULL; cinfo->quant_tbl_ptrs[i] = NULL;
cinfo->q_scale_factor[i] = 100;
}
for (i = 0; i < NUM_HUFF_TBLS; i++) { for (i = 0; i < NUM_HUFF_TBLS; i++) {
cinfo->dc_huff_tbl_ptrs[i] = NULL; cinfo->dc_huff_tbl_ptrs[i] = NULL;
cinfo->ac_huff_tbl_ptrs[i] = NULL; cinfo->ac_huff_tbl_ptrs[i] = NULL;
} }
/* Must do it here for emit_dqt in case jpeg_write_tables is used */
cinfo->block_size = DCTSIZE;
cinfo->natural_order = jpeg_natural_order;
cinfo->lim_Se = DCTSIZE2-1;
cinfo->script_space = NULL; cinfo->script_space = NULL;
cinfo->input_gamma = 1.0; /* in case application forgets */ cinfo->input_gamma = 1.0; /* in case application forgets */
...@@ -116,7 +124,7 @@ jpeg_abort_compress (j_compress_ptr cinfo) ...@@ -116,7 +124,7 @@ jpeg_abort_compress (j_compress_ptr cinfo)
*/ */
GLOBAL(void) GLOBAL(void)
jpeg_suppress_tables (j_compress_ptr cinfo, int suppress) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
{ {
int i; int i;
JQUANT_TBL * qtbl; JQUANT_TBL * qtbl;
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
*/ */
GLOBAL(void) GLOBAL(void)
jpeg_start_compress (j_compress_ptr cinfo, int write_all_tables) jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
{ {
if (cinfo->global_state != CSTATE_START) if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
......
/*
* jcarith.c
*
* Developed 1997-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains portable arithmetic entropy encoding routines for JPEG
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
*
* Both sequential and progressive modes are supported in this single module.
*
* Suspension is not currently supported in this module.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
/* Expanded entropy encoder object for arithmetic encoding. */
typedef struct {
struct jpeg_entropy_encoder pub; /* public fields */
INT32 c; /* C register, base of coding interval, layout as in sec. D.1.3 */
INT32 a; /* A register, normalized size of coding interval */
INT32 sc; /* counter for stacked 0xFF values which might overflow */
INT32 zc; /* counter for pending 0x00 output values which might *
* be discarded at the end ("Pacman" termination) */
int ct; /* bit shift counter, determines when next byte will be written */
int buffer; /* buffer for most recent output byte != 0xFF */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
unsigned int restarts_to_go; /* MCUs left in this restart interval */
int next_restart_num; /* next restart number to write (0-7) */
/* Pointers to statistics areas (these workspaces have image lifespan) */
unsigned char * dc_stats[NUM_ARITH_TBLS];
unsigned char * ac_stats[NUM_ARITH_TBLS];
/* Statistics bin for coding with fixed probability 0.5 */
unsigned char fixed_bin[4];
} arith_entropy_encoder;
typedef arith_entropy_encoder * arith_entropy_ptr;
/* The following two definitions specify the allocation chunk size
* for the statistics area.
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
*
* We use a compact representation with 1 byte per statistics bin,
* thus the numbers directly represent byte sizes.
* This 1 byte per statistics bin contains the meaning of the MPS
* (more probable symbol) in the highest bit (mask 0x80), and the
* index into the probability estimation state machine table
* in the lower bits (mask 0x7F).
*/
#define DC_STAT_BINS 64
#define AC_STAT_BINS 256
/* NOTE: Uncomment the following #define if you want to use the
* given formula for calculating the AC conditioning parameter Kx
* for spectral selection progressive coding in section G.1.3.2
* of the spec (Kx = Kmin + SRL (8 + Se - Kmin) 4).
* Although the spec and P&M authors claim that this "has proven
* to give good results for 8 bit precision samples", I'm not
* convinced yet that this is really beneficial.
* Early tests gave only very marginal compression enhancements
* (a few - around 5 or so - bytes even for very large files),
* which would turn out rather negative if we'd suppress the
* DAC (Define Arithmetic Conditioning) marker segments for
* the default parameters in the future.
* Note that currently the marker writing module emits 12-byte
* DAC segments for a full-component scan in a color image.
* This is not worth worrying about IMHO. However, since the
* spec defines the default values to be used if the tables
* are omitted (unlike Huffman tables, which are required
* anyway), one might optimize this behaviour in the future,
* and then it would be disadvantageous to use custom tables if
* they don't provide sufficient gain to exceed the DAC size.
*
* On the other hand, I'd consider it as a reasonable result
* that the conditioning has no significant influence on the
* compression performance. This means that the basic
* statistical model is already rather stable.
*
* Thus, at the moment, we use the default conditioning values
* anyway, and do not use the custom formula.
*
#define CALCULATE_SPECTRAL_CONDITIONING
*/
/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
* We assume that int right shift is unsigned if INT32 right shift is,
* which should be safe.
*/
#ifdef RIGHT_SHIFT_IS_UNSIGNED
#define ISHIFT_TEMPS int ishift_temp;
#define IRIGHT_SHIFT(x,shft) \
((ishift_temp = (x)) < 0 ? \
(ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
(ishift_temp >> (shft)))
#else
#define ISHIFT_TEMPS
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
#endif
LOCAL(void)
emit_byte (int val, j_compress_ptr cinfo)
/* Write next output byte; we do not support suspension in this module. */
{
struct jpeg_destination_mgr * dest = cinfo->dest;
*dest->next_output_byte++ = (JOCTET) val;
if (--dest->free_in_buffer == 0)
if (! (*dest->empty_output_buffer) (cinfo))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
}
/*
* Finish up at the end of an arithmetic-compressed scan.
*/
METHODDEF(void)
finish_pass (j_compress_ptr cinfo)
{
arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
INT32 temp;
/* Section D.1.8: Termination of encoding */
/* Find the e->c in the coding interval with the largest
* number of trailing zero bits */
if ((temp = (e->a - 1 + e->c) & 0xFFFF0000L) < e->c)
e->c = temp + 0x8000L;
else
e->c = temp;
/* Send remaining bytes to output */
e->c <<= e->ct;
if (e->c & 0xF8000000L) {
/* One final overflow has to be handled */
if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer + 1, cinfo);
if (e->buffer + 1 == 0xFF)
emit_byte(0x00, cinfo);
}
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
e->sc = 0;
} else {
if (e->buffer == 0)
++e->zc;
else if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer, cinfo);
}
if (e->sc) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
do {
emit_byte(0xFF, cinfo);
emit_byte(0x00, cinfo);
} while (--e->sc);
}
}
/* Output final bytes only if they are not 0x00 */
if (e->c & 0x7FFF800L) {
if (e->zc) /* output final pending zero bytes */
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte((e->c >> 19) & 0xFF, cinfo);
if (((e->c >> 19) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
if (e->c & 0x7F800L) {
emit_byte((e->c >> 11) & 0xFF, cinfo);
if (((e->c >> 11) & 0xFF) == 0xFF)
emit_byte(0x00, cinfo);
}
}
}
/*
* The core arithmetic encoding routine (common in JPEG and JBIG).
* This needs to go as fast as possible.
* Machine-dependent optimization facilities
* are not utilized in this portable implementation.
* However, this code should be fairly efficient and
* may be a good base for further optimizations anyway.
*
* Parameter 'val' to be encoded may be 0 or 1 (binary decision).
*
* Note: I've added full "Pacman" termination support to the
* byte output routines, which is equivalent to the optional
* Discard_final_zeros procedure (Figure D.15) in the spec.
* Thus, we always produce the shortest possible output
* stream compliant to the spec (no trailing zero bytes,
* except for FF stuffing).
*
* I've also introduced a new scheme for accessing
* the probability estimation state machine table,
* derived from Markus Kuhn's JBIG implementation.
*/
LOCAL(void)
arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
{
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
register unsigned char nl, nm;
register INT32 qe, temp;
register int sv;
/* Fetch values from our compact representation of Table D.3(D.2):
* Qe values and probability estimation state machine
*/
sv = *st;
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
/* Encode & estimation procedures per sections D.1.4 & D.1.5 */
e->a -= qe;
if (val != (sv >> 7)) {
/* Encode the less probable symbol */
if (e->a >= qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency, otherwise code the LPS
* as usual: */
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
} else {
/* Encode the more probable symbol */
if (e->a >= 0x8000L)
return; /* A >= 0x8000 -> ready, no renormalization required */
if (e->a < qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency: */
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
}
/* Renormalization & data output per section D.1.6 */
do {
e->a <<= 1;
e->c <<= 1;
if (--e->ct == 0) {
/* Another byte is ready for output */
temp = e->c >> 19;
if (temp > 0xFF) {
/* Handle overflow over all stacked 0xFF bytes */
if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer + 1, cinfo);
if (e->buffer + 1 == 0xFF)
emit_byte(0x00, cinfo);
}
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
e->sc = 0;
/* Note: The 3 spacer bits in the C register guarantee
* that the new buffer byte can't be 0xFF here
* (see page 160 in the P&M JPEG book). */
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
} else if (temp == 0xFF) {
++e->sc; /* stack 0xFF byte (which might overflow later) */
} else {
/* Output all stacked 0xFF bytes, they will not overflow any more */
if (e->buffer == 0)
++e->zc;
else if (e->buffer >= 0) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
emit_byte(e->buffer, cinfo);
}
if (e->sc) {
if (e->zc)
do emit_byte(0x00, cinfo);
while (--e->zc);
do {
emit_byte(0xFF, cinfo);
emit_byte(0x00, cinfo);
} while (--e->sc);
}
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
}
e->c &= 0x7FFFFL;
e->ct += 8;
}
} while (e->a < 0x8000L);
}
/*
* Emit a restart marker & resynchronize predictions.
*/
LOCAL(void)
emit_restart (j_compress_ptr cinfo, int restart_num)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci;
jpeg_component_info * compptr;
finish_pass(cinfo);
emit_byte(0xFF, cinfo);
emit_byte(JPEG_RST0 + restart_num, cinfo);
/* Re-initialize statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
/* Reset DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->Se) {
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
}
}
/* Reset arithmetic encoding variables */
entropy->c = 0;
entropy->a = 0x10000L;
entropy->sc = 0;
entropy->zc = 0;
entropy->ct = 11;
entropy->buffer = -1; /* empty */
}
/*
* MCU encoding for DC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl;
int v, v2, m;
ISHIFT_TEMPS
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
/* Compute the DC value after the required point transform by Al.
* This is simply an arithmetic right shift.
*/
m = IRIGHT_SHIFT((int) ((*block)[0]), cinfo->Al);
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.4: Encode_DC_DIFF */
if ((v = m - entropy->last_dc_val[ci]) == 0) {
arith_encode(cinfo, st, 0);
entropy->dc_context[ci] = 0; /* zero diff category */
} else {
entropy->last_dc_val[ci] = m;
arith_encode(cinfo, st, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
st += 2; /* Table F.4: SP = S0 + 2 */
entropy->dc_context[ci] = 4; /* small positive diff category */
} else {
v = -v;
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
st += 3; /* Table F.4: SN = S0 + 3 */
entropy->dc_context[ci] = 8; /* small negative diff category */
}
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
arith_encode(cinfo, st, 0);
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] += 8; /* large diff category */
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
}
return TRUE;
}
/*
* MCU encoding for AC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, k, ke;
int v, v2, m;
const int * natural_order;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
natural_order = cinfo->natural_order;
/* Encode the MCU data block */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--)
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value.
*/
if ((v = (*block)[natural_order[ke]]) >= 0) {
if (v >>= cinfo->Al) break;
} else {
v = -v;
if (v >>= cinfo->Al) break;
}
/* Figure F.5: Encode_AC_Coefficients */
for (k = cinfo->Ss; k <= ke; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) {
if ((v = (*block)[natural_order[k]]) >= 0) {
if (v >>= cinfo->Al) {
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 0);
break;
}
} else {
v = -v;
if (v >>= cinfo->Al) {
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 1);
break;
}
}
arith_encode(cinfo, st + 1, 0); st += 3; k++;
}
st += 2;
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
if (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
}
arith_encode(cinfo, st, 0);
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Encode EOB decision only if k <= cinfo->Se */
if (k <= cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 1);
}
return TRUE;
}
/*
* MCU encoding for DC successive approximation refinement scan.
*/
METHODDEF(boolean)
encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char *st;
int Al, blkn;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
st = entropy->fixed_bin; /* use fixed probability estimation */
Al = cinfo->Al;
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
/* We simply emit the Al'th bit of the DC coefficient value. */
arith_encode(cinfo, st, (MCU_data[blkn][0][0] >> Al) & 1);
}
return TRUE;
}
/*
* MCU encoding for AC successive approximation refinement scan.
*/
METHODDEF(boolean)
encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
JBLOCKROW block;
unsigned char *st;
int tbl, k, ke, kex;
int v;
const int * natural_order;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
natural_order = cinfo->natural_order;
/* Encode the MCU data block */
block = MCU_data[0];
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
/* Section G.1.3.3: Encoding of AC coefficients */
/* Establish EOB (end-of-block) index */
for (ke = cinfo->Se; ke > 0; ke--)
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value.
*/
if ((v = (*block)[natural_order[ke]]) >= 0) {
if (v >>= cinfo->Al) break;
} else {
v = -v;
if (v >>= cinfo->Al) break;
}
/* Establish EOBx (previous stage end-of-block) index */
for (kex = ke; kex > 0; kex--)
if ((v = (*block)[natural_order[kex]]) >= 0) {
if (v >>= cinfo->Ah) break;
} else {
v = -v;
if (v >>= cinfo->Ah) break;
}
/* Figure G.10: Encode_AC_Coefficients_SA */
for (k = cinfo->Ss; k <= ke; k++) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
if (k > kex)
arith_encode(cinfo, st, 0); /* EOB decision */
for (;;) {
if ((v = (*block)[natural_order[k]]) >= 0) {
if (v >>= cinfo->Al) {
if (v >> 1) /* previously nonzero coef */
arith_encode(cinfo, st + 2, (v & 1));
else { /* newly nonzero coef */
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 0);
}
break;
}
} else {
v = -v;
if (v >>= cinfo->Al) {
if (v >> 1) /* previously nonzero coef */
arith_encode(cinfo, st + 2, (v & 1));
else { /* newly nonzero coef */
arith_encode(cinfo, st + 1, 1);
arith_encode(cinfo, entropy->fixed_bin, 1);
}
break;
}
}
arith_encode(cinfo, st + 1, 0); st += 3; k++;
}
}
/* Encode EOB decision only if k <= cinfo->Se */
if (k <= cinfo->Se) {
st = entropy->ac_stats[tbl] + 3 * (k - 1);
arith_encode(cinfo, st, 1);
}
return TRUE;
}
/*
* Encode and output one MCU's worth of arithmetic-compressed coefficients.
*/
METHODDEF(boolean)
encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
jpeg_component_info * compptr;
JBLOCKROW block;
unsigned char *st;
int blkn, ci, tbl, k, ke;
int v, v2, m;
const int * natural_order;
/* Emit restart marker if needed */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
emit_restart(cinfo, entropy->next_restart_num);
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
natural_order = cinfo->natural_order;
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
tbl = compptr->dc_tbl_no;
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
/* Figure F.4: Encode_DC_DIFF */
if ((v = (*block)[0] - entropy->last_dc_val[ci]) == 0) {
arith_encode(cinfo, st, 0);
entropy->dc_context[ci] = 0; /* zero diff category */
} else {
entropy->last_dc_val[ci] = (*block)[0];
arith_encode(cinfo, st, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
st += 2; /* Table F.4: SP = S0 + 2 */
entropy->dc_context[ci] = 4; /* small positive diff category */
} else {
v = -v;
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
st += 3; /* Table F.4: SN = S0 + 3 */
entropy->dc_context[ci] = 8; /* small negative diff category */
}
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
arith_encode(cinfo, st, 0);
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
entropy->dc_context[ci] = 0; /* zero diff category */
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
entropy->dc_context[ci] += 8; /* large diff category */
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
if ((ke = cinfo->lim_Se) == 0) continue;
tbl = compptr->ac_tbl_no;
/* Establish EOB (end-of-block) index */
do {
if ((*block)[natural_order[ke]]) break;
} while (--ke);
/* Figure F.5: Encode_AC_Coefficients */
for (k = 0; k < ke;) {
st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 0); /* EOB decision */
while ((v = (*block)[natural_order[++k]]) == 0) {
arith_encode(cinfo, st + 1, 0);
st += 3;
}
arith_encode(cinfo, st + 1, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
arith_encode(cinfo, entropy->fixed_bin, 0);
} else {
v = -v;
arith_encode(cinfo, entropy->fixed_bin, 1);
}
st += 2;
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
arith_encode(cinfo, st, 1);
m = 1;
v2 = v;
if (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st = entropy->ac_stats[tbl] +
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
while (v2 >>= 1) {
arith_encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
}
arith_encode(cinfo, st, 0);
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
arith_encode(cinfo, st, (m & v) ? 1 : 0);
}
/* Encode EOB decision only if k < cinfo->lim_Se */
if (k < cinfo->lim_Se) {
st = entropy->ac_stats[tbl] + 3 * k;
arith_encode(cinfo, st, 1);
}
}
return TRUE;
}
/*
* Initialize for an arithmetic-compressed scan.
*/
METHODDEF(void)
start_pass (j_compress_ptr cinfo, boolean gather_statistics)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci, tbl;
jpeg_component_info * compptr;
if (gather_statistics)
/* Make sure to avoid that in the master control logic!
* We are fully adaptive here and need no extra
* statistics gathering pass!
*/
ERREXIT(cinfo, JERR_NOT_COMPILED);
/* We assume jcmaster.c already validated the progressive scan parameters. */
/* Select execution routines */
if (cinfo->progressive_mode) {
if (cinfo->Ah == 0) {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_first;
else
entropy->pub.encode_mcu = encode_mcu_AC_first;
} else {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_refine;
else
entropy->pub.encode_mcu = encode_mcu_AC_refine;
}
} else
entropy->pub.encode_mcu = encode_mcu;
/* Allocate & initialize requested statistics areas */
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->dc_stats[tbl] == NULL)
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
/* Initialize DC predictions to 0 */
entropy->last_dc_val[ci] = 0;
entropy->dc_context[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->Se) {
tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
if (entropy->ac_stats[tbl] == NULL)
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
#ifdef CALCULATE_SPECTRAL_CONDITIONING
if (cinfo->progressive_mode)
/* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
cinfo->arith_ac_K[tbl] = cinfo->Ss + ((8 + cinfo->Se - cinfo->Ss) >> 4);
#endif
}
}
/* Initialize arithmetic encoding variables */
entropy->c = 0;
entropy->a = 0x10000L;
entropy->sc = 0;
entropy->zc = 0;
entropy->ct = 11;
entropy->buffer = -1; /* empty */
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num = 0;
}
/*
* Module initialization routine for arithmetic entropy encoding.
*/
GLOBAL(void)
jinit_arith_encoder (j_compress_ptr cinfo)
{
arith_entropy_ptr entropy;
int i;
entropy = (arith_entropy_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
SIZEOF(arith_entropy_encoder));
cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
entropy->pub.start_pass = start_pass;
entropy->pub.finish_pass = finish_pass;
/* Mark tables unallocated */
for (i = 0; i < NUM_ARITH_TBLS; i++) {
entropy->dc_stats[i] = NULL;
entropy->ac_stats[i] = NULL;
}
/* Initialize index for fixed probability estimation */
entropy->fixed_bin[0] = 113;
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* jccoefct.c * jccoefct.c
* *
* Copyright (C) 1994-1997, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
...@@ -58,12 +59,12 @@ typedef my_coef_controller * my_coef_ptr; ...@@ -58,12 +59,12 @@ typedef my_coef_controller * my_coef_ptr;
/* Forward declarations */ /* Forward declarations */
METHODDEF(int) compress_data METHODDEF(boolean) compress_data
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#ifdef FULL_COEF_BUFFER_SUPPORTED #ifdef FULL_COEF_BUFFER_SUPPORTED
METHODDEF(int) compress_first_pass METHODDEF(boolean) compress_first_pass
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
METHODDEF(int) compress_output METHODDEF(boolean) compress_output
JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
#endif #endif
...@@ -139,7 +140,7 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) ...@@ -139,7 +140,7 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
* which we index according to the component's SOF position. * which we index according to the component's SOF position.
*/ */
METHODDEF(int) METHODDEF(boolean)
compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
...@@ -149,6 +150,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -149,6 +150,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
int blkn, bi, ci, yindex, yoffset, blockcnt; int blkn, bi, ci, yindex, yoffset, blockcnt;
JDIMENSION ypos, xpos; JDIMENSION ypos, xpos;
jpeg_component_info *compptr; jpeg_component_info *compptr;
forward_DCT_ptr forward_DCT;
/* Loop to write as much as one whole iMCU row */ /* Loop to write as much as one whole iMCU row */
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
...@@ -167,20 +169,22 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -167,20 +169,22 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
blkn = 0; blkn = 0;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
forward_DCT = cinfo->fdct->forward_DCT[compptr->component_index];
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
: compptr->last_col_width; : compptr->last_col_width;
xpos = MCU_col_num * compptr->MCU_sample_width; xpos = MCU_col_num * compptr->MCU_sample_width;
ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */ ypos = yoffset * compptr->DCT_v_scaled_size;
/* ypos == (yoffset+yindex) * DCTSIZE */
for (yindex = 0; yindex < compptr->MCU_height; yindex++) { for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
if (coef->iMCU_row_num < last_iMCU_row || if (coef->iMCU_row_num < last_iMCU_row ||
yoffset+yindex < compptr->last_row_height) { yoffset+yindex < compptr->last_row_height) {
(*cinfo->fdct->forward_DCT) (cinfo, compptr, (*forward_DCT) (cinfo, compptr,
input_buf[compptr->component_index], input_buf[compptr->component_index],
coef->MCU_buffer[blkn], coef->MCU_buffer[blkn],
ypos, xpos, (JDIMENSION) blockcnt); ypos, xpos, (JDIMENSION) blockcnt);
if (blockcnt < compptr->MCU_width) { if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */ /* Create some dummy blocks at the right edge of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], FMEMZERO((void FAR *) coef->MCU_buffer[blkn + blockcnt],
(compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK)); (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
for (bi = blockcnt; bi < compptr->MCU_width; bi++) { for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0]; coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
...@@ -188,14 +192,14 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -188,14 +192,14 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
} }
} else { } else {
/* Create a row of dummy blocks at the bottom of the image. */ /* Create a row of dummy blocks at the bottom of the image. */
jzero_far((void FAR *) coef->MCU_buffer[blkn], FMEMZERO((void FAR *) coef->MCU_buffer[blkn],
compptr->MCU_width * SIZEOF(JBLOCK)); compptr->MCU_width * SIZEOF(JBLOCK));
for (bi = 0; bi < compptr->MCU_width; bi++) { for (bi = 0; bi < compptr->MCU_width; bi++) {
coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0]; coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
} }
} }
blkn += compptr->MCU_width; blkn += compptr->MCU_width;
ypos += DCTSIZE; ypos += compptr->DCT_v_scaled_size;
} }
} }
/* Try to write the MCU. In event of a suspension failure, we will /* Try to write the MCU. In event of a suspension failure, we will
...@@ -241,7 +245,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -241,7 +245,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* at the scan-dependent variables (MCU dimensions, etc). * at the scan-dependent variables (MCU dimensions, etc).
*/ */
METHODDEF(int) METHODDEF(boolean)
compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
...@@ -252,6 +256,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -252,6 +256,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
jpeg_component_info *compptr; jpeg_component_info *compptr;
JBLOCKARRAY buffer; JBLOCKARRAY buffer;
JBLOCKROW thisblockrow, lastblockrow; JBLOCKROW thisblockrow, lastblockrow;
forward_DCT_ptr forward_DCT;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
...@@ -274,19 +279,19 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -274,19 +279,19 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
ndummy = (int) (blocks_across % h_samp_factor); ndummy = (int) (blocks_across % h_samp_factor);
if (ndummy > 0) if (ndummy > 0)
ndummy = h_samp_factor - ndummy; ndummy = h_samp_factor - ndummy;
forward_DCT = cinfo->fdct->forward_DCT[ci];
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call /* Perform DCT for all non-dummy blocks in this iMCU row. Each call
* on forward_DCT processes a complete horizontal row of DCT blocks. * on forward_DCT processes a complete horizontal row of DCT blocks.
*/ */
for (block_row = 0; block_row < block_rows; block_row++) { for (block_row = 0; block_row < block_rows; block_row++) {
thisblockrow = buffer[block_row]; thisblockrow = buffer[block_row];
(*cinfo->fdct->forward_DCT) (cinfo, compptr, (*forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow,
input_buf[ci], thisblockrow, (JDIMENSION) (block_row * compptr->DCT_v_scaled_size),
(JDIMENSION) (block_row * DCTSIZE),
(JDIMENSION) 0, blocks_across); (JDIMENSION) 0, blocks_across);
if (ndummy > 0) { if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */ /* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */ thisblockrow += blocks_across; /* => first dummy block */
jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK)); FMEMZERO((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
lastDC = thisblockrow[-1][0]; lastDC = thisblockrow[-1][0];
for (bi = 0; bi < ndummy; bi++) { for (bi = 0; bi < ndummy; bi++) {
thisblockrow[bi][0] = lastDC; thisblockrow[bi][0] = lastDC;
...@@ -305,7 +310,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -305,7 +310,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
block_row++) { block_row++) {
thisblockrow = buffer[block_row]; thisblockrow = buffer[block_row];
lastblockrow = buffer[block_row-1]; lastblockrow = buffer[block_row-1];
jzero_far((void FAR *) thisblockrow, FMEMZERO((void FAR *) thisblockrow,
(size_t) (blocks_across * SIZEOF(JBLOCK))); (size_t) (blocks_across * SIZEOF(JBLOCK)));
for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
lastDC = lastblockrow[h_samp_factor-1][0]; lastDC = lastblockrow[h_samp_factor-1][0];
...@@ -337,8 +342,8 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) ...@@ -337,8 +342,8 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
* NB: input_buf is ignored; it is likely to be a NULL pointer. * NB: input_buf is ignored; it is likely to be a NULL pointer.
*/ */
METHODDEF(int) METHODDEF(boolean)
compress_output (j_compress_ptr cinfo, JSAMPIMAGE )//input_buf) compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{ {
my_coef_ptr coef = (my_coef_ptr) cinfo->coef; my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION MCU_col_num; /* index of current MCU within row */
...@@ -402,7 +407,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE )//input_buf) ...@@ -402,7 +407,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE )//input_buf)
*/ */
GLOBAL(void) GLOBAL(void)
jinit_c_coef_controller (j_compress_ptr cinfo, int need_full_buffer) jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{ {
my_coef_ptr coef; my_coef_ptr coef;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* jccolor.c * jccolor.c
* *
* Copyright (C) 1991-1996, Thomas G. Lane. * Copyright (C) 1991-1996, Thomas G. Lane.
* Modified 2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
...@@ -19,7 +20,7 @@ typedef struct { ...@@ -19,7 +20,7 @@ typedef struct {
struct jpeg_color_converter pub; /* public fields */ struct jpeg_color_converter pub; /* public fields */
/* Private state for RGB->YCC conversion */ /* Private state for RGB->YCC conversion */
long * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */ INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
} my_color_converter; } my_color_converter;
typedef my_color_converter * my_cconvert_ptr; typedef my_color_converter * my_cconvert_ptr;
...@@ -56,9 +57,9 @@ typedef my_color_converter * my_cconvert_ptr; ...@@ -56,9 +57,9 @@ typedef my_color_converter * my_cconvert_ptr;
*/ */
#define SCALEBITS 16 /* speediest right-shift on some machines */ #define SCALEBITS 16 /* speediest right-shift on some machines */
#define CBCR_OFFSET ((long) CENTERJSAMPLE << SCALEBITS) #define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
#define ONE_HALF ((long) 1 << (SCALEBITS-1)) #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
#define FIX(x) ((long) ((x) * (1L<<SCALEBITS) + 0.5)) #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
/* We allocate one big table and divide it up into eight parts, instead of /* We allocate one big table and divide it up into eight parts, instead of
* doing eight alloc_small requests. This lets us use a single table base * doing eight alloc_small requests. This lets us use a single table base
...@@ -86,13 +87,13 @@ METHODDEF(void) ...@@ -86,13 +87,13 @@ METHODDEF(void)
rgb_ycc_start (j_compress_ptr cinfo) rgb_ycc_start (j_compress_ptr cinfo)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
long * rgb_ycc_tab; INT32 * rgb_ycc_tab;
long i; INT32 i;
/* Allocate and fill in the conversion tables. */ /* Allocate and fill in the conversion tables. */
cconvert->rgb_ycc_tab = rgb_ycc_tab = (long *) cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
(TABLE_SIZE * SIZEOF(long))); (TABLE_SIZE * SIZEOF(INT32)));
for (i = 0; i <= MAXJSAMPLE; i++) { for (i = 0; i <= MAXJSAMPLE; i++) {
rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i; rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
...@@ -132,11 +133,11 @@ rgb_ycc_convert (j_compress_ptr cinfo, ...@@ -132,11 +133,11 @@ rgb_ycc_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
int r, g, b; register int r, g, b;
long * ctab = cconvert->rgb_ycc_tab; register INT32 * ctab = cconvert->rgb_ycc_tab;
JSAMPROW inptr; register JSAMPROW inptr;
JSAMPROW outptr0, outptr1, outptr2; register JSAMPROW outptr0, outptr1, outptr2;
JDIMENSION col; register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width; JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) { while (--num_rows >= 0) {
...@@ -188,11 +189,11 @@ rgb_gray_convert (j_compress_ptr cinfo, ...@@ -188,11 +189,11 @@ rgb_gray_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
int r, g, b; register int r, g, b;
long * ctab = cconvert->rgb_ycc_tab; register INT32 * ctab = cconvert->rgb_ycc_tab;
JSAMPROW inptr; register JSAMPROW inptr;
JSAMPROW outptr; register JSAMPROW outptr;
JDIMENSION col; register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width; JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) { while (--num_rows >= 0) {
...@@ -227,11 +228,11 @@ cmyk_ycck_convert (j_compress_ptr cinfo, ...@@ -227,11 +228,11 @@ cmyk_ycck_convert (j_compress_ptr cinfo,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
int r, g, b; register int r, g, b;
long * ctab = cconvert->rgb_ycc_tab; register INT32 * ctab = cconvert->rgb_ycc_tab;
JSAMPROW inptr; register JSAMPROW inptr;
JSAMPROW outptr0, outptr1, outptr2, outptr3; register JSAMPROW outptr0, outptr1, outptr2, outptr3;
JDIMENSION col; register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width; JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) { while (--num_rows >= 0) {
...@@ -281,9 +282,9 @@ grayscale_convert (j_compress_ptr cinfo, ...@@ -281,9 +282,9 @@ grayscale_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
JSAMPROW inptr; register JSAMPROW inptr;
JSAMPROW outptr; register JSAMPROW outptr;
JDIMENSION col; register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width; JDIMENSION num_cols = cinfo->image_width;
int instride = cinfo->input_components; int instride = cinfo->input_components;
...@@ -299,6 +300,39 @@ grayscale_convert (j_compress_ptr cinfo, ...@@ -299,6 +300,39 @@ grayscale_convert (j_compress_ptr cinfo,
} }
/*
* Convert some rows of samples to the JPEG colorspace.
* No colorspace conversion, but change from interleaved
* to separate-planes representation.
*/
METHODDEF(void)
rgb_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows)
{
register JSAMPROW inptr;
register JSAMPROW outptr0, outptr1, outptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->image_width;
while (--num_rows >= 0) {
inptr = *input_buf++;
outptr0 = output_buf[0][output_row];
outptr1 = output_buf[1][output_row];
outptr2 = output_buf[2][output_row];
output_row++;
for (col = 0; col < num_cols; col++) {
/* We can dispense with GETJSAMPLE() here */
outptr0[col] = inptr[RGB_RED];
outptr1[col] = inptr[RGB_GREEN];
outptr2[col] = inptr[RGB_BLUE];
inptr += RGB_PIXELSIZE;
}
}
}
/* /*
* Convert some rows of samples to the JPEG colorspace. * Convert some rows of samples to the JPEG colorspace.
* This version handles multi-component colorspaces without conversion. * This version handles multi-component colorspaces without conversion.
...@@ -310,10 +344,10 @@ null_convert (j_compress_ptr cinfo, ...@@ -310,10 +344,10 @@ null_convert (j_compress_ptr cinfo,
JSAMPARRAY input_buf, JSAMPIMAGE output_buf, JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
JDIMENSION output_row, int num_rows) JDIMENSION output_row, int num_rows)
{ {
JSAMPROW inptr; register JSAMPROW inptr;
JSAMPROW outptr; register JSAMPROW outptr;
JDIMENSION col; register JDIMENSION col;
int ci; register int ci;
int nc = cinfo->num_components; int nc = cinfo->num_components;
JDIMENSION num_cols = cinfo->image_width; JDIMENSION num_cols = cinfo->image_width;
...@@ -338,7 +372,7 @@ null_convert (j_compress_ptr cinfo, ...@@ -338,7 +372,7 @@ null_convert (j_compress_ptr cinfo,
*/ */
METHODDEF(void) METHODDEF(void)
null_method (j_compress_ptr )//cinfo) null_method (j_compress_ptr cinfo)
{ {
/* no work needed */ /* no work needed */
} }
...@@ -368,11 +402,9 @@ jinit_color_converter (j_compress_ptr cinfo) ...@@ -368,11 +402,9 @@ jinit_color_converter (j_compress_ptr cinfo)
break; break;
case JCS_RGB: case JCS_RGB:
#if RGB_PIXELSIZE != 3
if (cinfo->input_components != RGB_PIXELSIZE) if (cinfo->input_components != RGB_PIXELSIZE)
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
break; break;
#endif /* else share code with YCbCr */
case JCS_YCbCr: case JCS_YCbCr:
if (cinfo->input_components != 3) if (cinfo->input_components != 3)
...@@ -396,22 +428,21 @@ jinit_color_converter (j_compress_ptr cinfo) ...@@ -396,22 +428,21 @@ jinit_color_converter (j_compress_ptr cinfo)
case JCS_GRAYSCALE: case JCS_GRAYSCALE:
if (cinfo->num_components != 1) if (cinfo->num_components != 1)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_GRAYSCALE) if (cinfo->in_color_space == JCS_GRAYSCALE ||
cinfo->in_color_space == JCS_YCbCr)
cconvert->pub.color_convert = grayscale_convert; cconvert->pub.color_convert = grayscale_convert;
else if (cinfo->in_color_space == JCS_RGB) { else if (cinfo->in_color_space == JCS_RGB) {
cconvert->pub.start_pass = rgb_ycc_start; cconvert->pub.start_pass = rgb_ycc_start;
cconvert->pub.color_convert = rgb_gray_convert; cconvert->pub.color_convert = rgb_gray_convert;
} else if (cinfo->in_color_space == JCS_YCbCr) } else
cconvert->pub.color_convert = grayscale_convert;
else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break; break;
case JCS_RGB: case JCS_RGB:
if (cinfo->num_components != 3) if (cinfo->num_components != 3)
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3) if (cinfo->in_color_space == JCS_RGB)
cconvert->pub.color_convert = null_convert; cconvert->pub.color_convert = rgb_convert;
else else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break; break;
......
...@@ -23,7 +23,7 @@ typedef struct { ...@@ -23,7 +23,7 @@ typedef struct {
struct jpeg_forward_dct pub; /* public fields */ struct jpeg_forward_dct pub; /* public fields */
/* Pointer to the DCT routine actually in use */ /* Pointer to the DCT routine actually in use */
forward_DCT_method_ptr do_dct; forward_DCT_method_ptr do_dct[MAX_COMPONENTS];
/* The actual post-DCT divisors --- not identical to the quant table /* The actual post-DCT divisors --- not identical to the quant table
* entries, because of scaling (especially for an unnormalized DCT). * entries, because of scaling (especially for an unnormalized DCT).
...@@ -33,7 +33,7 @@ typedef struct { ...@@ -33,7 +33,7 @@ typedef struct {
#ifdef DCT_FLOAT_SUPPORTED #ifdef DCT_FLOAT_SUPPORTED
/* Same as above for the floating-point case. */ /* Same as above for the floating-point case. */
float_DCT_method_ptr do_float_dct; float_DCT_method_ptr do_float_dct[MAX_COMPONENTS];
FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]; FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
#endif #endif
} my_fdct_controller; } my_fdct_controller;
...@@ -41,6 +41,132 @@ typedef struct { ...@@ -41,6 +41,132 @@ typedef struct {
typedef my_fdct_controller * my_fdct_ptr; typedef my_fdct_controller * my_fdct_ptr;
/* The current scaled-DCT routines require ISLOW-style divisor tables,
* so be sure to compile that code if either ISLOW or SCALING is requested.
*/
#ifdef DCT_ISLOW_SUPPORTED
#define PROVIDE_ISLOW_TABLES
#else
#ifdef DCT_SCALING_SUPPORTED
#define PROVIDE_ISLOW_TABLES
#endif
#endif
/*
* Perform forward DCT on one or more blocks of a component.
*
* The input samples are taken from the sample_data[] array starting at
* position start_row/start_col, and moving to the right for any additional
* blocks. The quantized coefficients are returned in coef_blocks[].
*/
METHODDEF(void)
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks)
/* This version is used for integer DCT implementations. */
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
forward_DCT_method_ptr do_dct = fdct->do_dct[compptr->component_index];
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
JDIMENSION bi;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
/* Perform the DCT */
(*do_dct) (workspace, sample_data, start_col);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register DCTELEM temp, qval;
register int i;
register JCOEFPTR output_ptr = coef_blocks[bi];
for (i = 0; i < DCTSIZE2; i++) {
qval = divisors[i];
temp = workspace[i];
/* Divide the coefficient value by qval, ensuring proper rounding.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
*
* In most files, at least half of the output values will be zero
* (at default quantization settings, more like three-quarters...)
* so we should ensure that this case is fast. On many machines,
* a comparison is enough cheaper than a divide to make a special test
* a win. Since both inputs will be nonnegative, we need only test
* for a < b to discover whether a/b is 0.
* If your machine's division is fast enough, define FAST_DIVIDE.
*/
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b) a /= b
#else
#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
#endif
if (temp < 0) {
temp = -temp;
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
temp = -temp;
} else {
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
}
output_ptr[i] = (JCOEF) temp;
}
}
}
}
#ifdef DCT_FLOAT_SUPPORTED
METHODDEF(void)
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks)
/* This version is used for floating-point DCT implementations. */
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
float_DCT_method_ptr do_dct = fdct->do_float_dct[compptr->component_index];
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
JDIMENSION bi;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
/* Perform the DCT */
(*do_dct) (workspace, sample_data, start_col);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ register FAST_FLOAT temp;
register int i;
register JCOEFPTR output_ptr = coef_blocks[bi];
for (i = 0; i < DCTSIZE2; i++) {
/* Apply the quantization and scaling factor */
temp = workspace[i] * divisors[i];
/* Round to nearest integer.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
* The maximum coefficient size is +-16K (for 12-bit data), so this
* code should work for either 16-bit or 32-bit ints.
*/
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
}
}
}
}
#endif /* DCT_FLOAT_SUPPORTED */
/* /*
* Initialize for a processing pass. * Initialize for a processing pass.
* Verify that all referenced Q-tables are present, and set up * Verify that all referenced Q-tables are present, and set up
...@@ -56,11 +182,170 @@ start_pass_fdctmgr (j_compress_ptr cinfo) ...@@ -56,11 +182,170 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
int ci, qtblno, i; int ci, qtblno, i;
jpeg_component_info *compptr; jpeg_component_info *compptr;
int method = 0;
JQUANT_TBL * qtbl; JQUANT_TBL * qtbl;
DCTELEM * dtbl; DCTELEM * dtbl;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
/* Select the proper DCT routine for this component's scaling */
switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) {
#ifdef DCT_SCALING_SUPPORTED
case ((1 << 8) + 1):
fdct->do_dct[ci] = jpeg_fdct_1x1;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((2 << 8) + 2):
fdct->do_dct[ci] = jpeg_fdct_2x2;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((3 << 8) + 3):
fdct->do_dct[ci] = jpeg_fdct_3x3;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((4 << 8) + 4):
fdct->do_dct[ci] = jpeg_fdct_4x4;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((5 << 8) + 5):
fdct->do_dct[ci] = jpeg_fdct_5x5;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((6 << 8) + 6):
fdct->do_dct[ci] = jpeg_fdct_6x6;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((7 << 8) + 7):
fdct->do_dct[ci] = jpeg_fdct_7x7;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((9 << 8) + 9):
fdct->do_dct[ci] = jpeg_fdct_9x9;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((10 << 8) + 10):
fdct->do_dct[ci] = jpeg_fdct_10x10;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((11 << 8) + 11):
fdct->do_dct[ci] = jpeg_fdct_11x11;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((12 << 8) + 12):
fdct->do_dct[ci] = jpeg_fdct_12x12;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((13 << 8) + 13):
fdct->do_dct[ci] = jpeg_fdct_13x13;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((14 << 8) + 14):
fdct->do_dct[ci] = jpeg_fdct_14x14;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((15 << 8) + 15):
fdct->do_dct[ci] = jpeg_fdct_15x15;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((16 << 8) + 16):
fdct->do_dct[ci] = jpeg_fdct_16x16;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((16 << 8) + 8):
fdct->do_dct[ci] = jpeg_fdct_16x8;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((14 << 8) + 7):
fdct->do_dct[ci] = jpeg_fdct_14x7;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((12 << 8) + 6):
fdct->do_dct[ci] = jpeg_fdct_12x6;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((10 << 8) + 5):
fdct->do_dct[ci] = jpeg_fdct_10x5;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((8 << 8) + 4):
fdct->do_dct[ci] = jpeg_fdct_8x4;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((6 << 8) + 3):
fdct->do_dct[ci] = jpeg_fdct_6x3;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((4 << 8) + 2):
fdct->do_dct[ci] = jpeg_fdct_4x2;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((2 << 8) + 1):
fdct->do_dct[ci] = jpeg_fdct_2x1;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((8 << 8) + 16):
fdct->do_dct[ci] = jpeg_fdct_8x16;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((7 << 8) + 14):
fdct->do_dct[ci] = jpeg_fdct_7x14;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((6 << 8) + 12):
fdct->do_dct[ci] = jpeg_fdct_6x12;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((5 << 8) + 10):
fdct->do_dct[ci] = jpeg_fdct_5x10;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((4 << 8) + 8):
fdct->do_dct[ci] = jpeg_fdct_4x8;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((3 << 8) + 6):
fdct->do_dct[ci] = jpeg_fdct_3x6;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((2 << 8) + 4):
fdct->do_dct[ci] = jpeg_fdct_2x4;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
case ((1 << 8) + 2):
fdct->do_dct[ci] = jpeg_fdct_1x2;
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
break;
#endif
case ((DCTSIZE << 8) + DCTSIZE):
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
fdct->do_dct[ci] = jpeg_fdct_islow;
method = JDCT_ISLOW;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
fdct->do_dct[ci] = jpeg_fdct_ifast;
method = JDCT_IFAST;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
fdct->do_float_dct[ci] = jpeg_fdct_float;
method = JDCT_FLOAT;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
break;
default:
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size);
break;
}
qtblno = compptr->quant_tbl_no; qtblno = compptr->quant_tbl_no;
/* Make sure specified quantization table is present */ /* Make sure specified quantization table is present */
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
...@@ -69,8 +354,8 @@ start_pass_fdctmgr (j_compress_ptr cinfo) ...@@ -69,8 +354,8 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
qtbl = cinfo->quant_tbl_ptrs[qtblno]; qtbl = cinfo->quant_tbl_ptrs[qtblno];
/* Compute divisors for this quant table */ /* Compute divisors for this quant table */
/* We may do this more than once for same table, but it's not a big deal */ /* We may do this more than once for same table, but it's not a big deal */
switch (cinfo->dct_method) { switch (method) {
#ifdef DCT_ISLOW_SUPPORTED #ifdef PROVIDE_ISLOW_TABLES
case JDCT_ISLOW: case JDCT_ISLOW:
/* For LL&M IDCT method, divisors are equal to raw quantization /* For LL&M IDCT method, divisors are equal to raw quantization
* coefficients multiplied by 8 (to counteract scaling). * coefficients multiplied by 8 (to counteract scaling).
...@@ -84,6 +369,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo) ...@@ -84,6 +369,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3; dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
} }
fdct->pub.forward_DCT[ci] = forward_DCT;
break; break;
#endif #endif
#ifdef DCT_IFAST_SUPPORTED #ifdef DCT_IFAST_SUPPORTED
...@@ -96,7 +382,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo) ...@@ -96,7 +382,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
* We apply a further scale factor of 8. * We apply a further scale factor of 8.
*/ */
#define CONST_BITS 14 #define CONST_BITS 14
static const short aanscales[DCTSIZE2] = { static const INT16 aanscales[DCTSIZE2] = {
/* precomputed values scaled up by 14 bits */ /* precomputed values scaled up by 14 bits */
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
...@@ -117,11 +403,12 @@ start_pass_fdctmgr (j_compress_ptr cinfo) ...@@ -117,11 +403,12 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
dtbl = fdct->divisors[qtblno]; dtbl = fdct->divisors[qtblno];
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i < DCTSIZE2; i++) {
dtbl[i] = (DCTELEM) dtbl[i] = (DCTELEM)
DESCALE(MULTIPLY16V16((long) qtbl->quantval[i], DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
(long) aanscales[i]), (INT32) aanscales[i]),
CONST_BITS-3); CONST_BITS-3);
} }
} }
fdct->pub.forward_DCT[ci] = forward_DCT;
break; break;
#endif #endif
#ifdef DCT_FLOAT_SUPPORTED #ifdef DCT_FLOAT_SUPPORTED
...@@ -158,6 +445,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo) ...@@ -158,6 +445,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
} }
} }
} }
fdct->pub.forward_DCT[ci] = forward_DCT_float;
break; break;
#endif #endif
default: default:
...@@ -168,175 +456,6 @@ start_pass_fdctmgr (j_compress_ptr cinfo) ...@@ -168,175 +456,6 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
} }
/*
* Perform forward DCT on one or more blocks of a component.
*
* The input samples are taken from the sample_data[] array starting at
* position start_row/start_col, and moving to the right for any additional
* blocks. The quantized coefficients are returned in coef_blocks[].
*/
METHODDEF(void)
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks)
/* This version is used for integer DCT implementations. */
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
forward_DCT_method_ptr do_dct = fdct->do_dct;
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
JDIMENSION bi;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */
{ DCTELEM *workspaceptr;
JSAMPROW elemptr;
int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
#else
{ int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--) {
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
}
}
#endif
}
}
/* Perform the DCT */
(*do_dct) (workspace);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ DCTELEM temp, qval;
int i;
JCOEFPTR output_ptr = coef_blocks[bi];
for (i = 0; i < DCTSIZE2; i++) {
qval = divisors[i];
temp = workspace[i];
/* Divide the coefficient value by qval, ensuring proper rounding.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
*
* In most files, at least half of the output values will be zero
* (at default quantization settings, more like three-quarters...)
* so we should ensure that this case is fast. On many machines,
* a comparison is enough cheaper than a divide to make a special test
* a win. Since both inputs will be nonnegative, we need only test
* for a < b to discover whether a/b is 0.
* If your machine's division is fast enough, define FAST_DIVIDE.
*/
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b) a /= b
#else
#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
#endif
if (temp < 0) {
temp = -temp;
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
temp = -temp;
} else {
temp += qval>>1; /* for rounding */
DIVIDE_BY(temp, qval);
}
output_ptr[i] = (JCOEF) temp;
}
}
}
}
#ifdef DCT_FLOAT_SUPPORTED
METHODDEF(void)
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks)
/* This version is used for floating-point DCT implementations. */
{
/* This routine is heavily used, so it's worth coding it tightly. */
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
float_DCT_method_ptr do_dct = fdct->do_float_dct;
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
JDIMENSION bi;
sample_data += start_row; /* fold in the vertical offset once */
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
/* Load data into workspace, applying unsigned->signed conversion */
{ FAST_FLOAT *workspaceptr;
JSAMPROW elemptr;
int elemr;
workspaceptr = workspace;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = sample_data[elemr] + start_col;
#if DCTSIZE == 8 /* unroll the inner loop */
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
#else
{ int elemc;
for (elemc = DCTSIZE; elemc > 0; elemc--) {
*workspaceptr++ = (FAST_FLOAT)
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
}
}
#endif
}
}
/* Perform the DCT */
(*do_dct) (workspace);
/* Quantize/descale the coefficients, and store into coef_blocks[] */
{ FAST_FLOAT temp;
int i;
JCOEFPTR output_ptr = coef_blocks[bi];
for (i = 0; i < DCTSIZE2; i++) {
/* Apply the quantization and scaling factor */
temp = workspace[i] * divisors[i];
/* Round to nearest integer.
* Since C does not specify the direction of rounding for negative
* quotients, we have to force the dividend positive for portability.
* The maximum coefficient size is +-16K (for 12-bit data), so this
* code should work for either 16-bit or 32-bit ints.
*/
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
}
}
}
}
#endif /* DCT_FLOAT_SUPPORTED */
/* /*
* Initialize FDCT manager. * Initialize FDCT manager.
*/ */
...@@ -353,30 +472,6 @@ jinit_forward_dct (j_compress_ptr cinfo) ...@@ -353,30 +472,6 @@ jinit_forward_dct (j_compress_ptr cinfo)
cinfo->fdct = (struct jpeg_forward_dct *) fdct; cinfo->fdct = (struct jpeg_forward_dct *) fdct;
fdct->pub.start_pass = start_pass_fdctmgr; fdct->pub.start_pass = start_pass_fdctmgr;
switch (cinfo->dct_method) {
#ifdef DCT_ISLOW_SUPPORTED
case JDCT_ISLOW:
fdct->pub.forward_DCT = forward_DCT;
fdct->do_dct = jpeg_fdct_islow;
break;
#endif
#ifdef DCT_IFAST_SUPPORTED
case JDCT_IFAST:
fdct->pub.forward_DCT = forward_DCT;
fdct->do_dct = jpeg_fdct_ifast;
break;
#endif
#ifdef DCT_FLOAT_SUPPORTED
case JDCT_FLOAT:
fdct->pub.forward_DCT = forward_DCT_float;
fdct->do_float_dct = jpeg_fdct_float;
break;
#endif
default:
ERREXIT(cinfo, JERR_NOT_COMPILED);
break;
}
/* Mark divisor tables unallocated */ /* Mark divisor tables unallocated */
for (i = 0; i < NUM_QUANT_TBLS; i++) { for (i = 0; i < NUM_QUANT_TBLS; i++) {
fdct->divisors[i] = NULL; fdct->divisors[i] = NULL;
......
...@@ -2,22 +2,48 @@ ...@@ -2,22 +2,48 @@
* jchuff.c * jchuff.c
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2006-2009 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
* This file contains Huffman entropy encoding routines. * This file contains Huffman entropy encoding routines.
* Both sequential and progressive modes are supported in this single module.
* *
* Much of the complexity here has to do with supporting output suspension. * Much of the complexity here has to do with supporting output suspension.
* If the data destination module demands suspension, we want to be able to * If the data destination module demands suspension, we want to be able to
* back up to the start of the current MCU. To do this, we copy state * 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 * variables into local working storage, and update them back to the
* permanent JPEG objects only upon successful completion of an MCU. * permanent JPEG objects only upon successful completion of an MCU.
*
* We do not support output suspension for the progressive JPEG mode, since
* the library currently does not allow multiple-scan files to be written
* with output suspension.
*/ */
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jchuff.h" /* Declarations shared with jcphuff.c */
/* The legal range of a DCT coefficient is
* -1024 .. +1023 for 8-bit data;
* -16384 .. +16383 for 12-bit data.
* Hence the magnitude should always fit in 10 or 14 bits respectively.
*/
#if BITS_IN_JSAMPLE == 8
#define MAX_COEF_BITS 10
#else
#define MAX_COEF_BITS 14
#endif
/* Derived data constructed for each Huffman table */
typedef struct {
unsigned int ehufco[256]; /* code for each symbol */
char ehufsi[256]; /* length of code for each symbol */
/* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
} c_derived_tbl;
/* Expanded entropy encoder object for Huffman encoding. /* Expanded entropy encoder object for Huffman encoding.
...@@ -27,7 +53,7 @@ ...@@ -27,7 +53,7 @@
*/ */
typedef struct { typedef struct {
long put_buffer; /* current bit-accumulation buffer */ INT32 put_buffer; /* current bit-accumulation buffer */
int put_bits; /* # of bits now in it */ int put_bits; /* # of bits now in it */
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
} savable_state; } savable_state;
...@@ -65,15 +91,32 @@ typedef struct { ...@@ -65,15 +91,32 @@ typedef struct {
c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ /* Statistics tables for optimization */
long * dc_count_ptrs[NUM_HUFF_TBLS]; long * dc_count_ptrs[NUM_HUFF_TBLS];
long * ac_count_ptrs[NUM_HUFF_TBLS]; long * ac_count_ptrs[NUM_HUFF_TBLS];
#endif
/* Following fields used only in progressive mode */
/* Mode flag: TRUE for optimization, FALSE for actual data output */
boolean gather_statistics;
/* next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
*/
JOCTET * next_output_byte; /* => next byte to write in buffer */
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */
/* Coding status for AC components */
int ac_tbl_no; /* the table number of the single component */
unsigned int EOBRUN; /* run length of EOBs */
unsigned int BE; /* # of buffered correction bits before MCU */
char * bit_buffer; /* buffer for correction bits (1 per char) */
/* packing correction bits tightly would save some space but cost time... */
} huff_entropy_encoder; } huff_entropy_encoder;
typedef huff_entropy_encoder * huff_entropy_ptr; typedef huff_entropy_encoder * huff_entropy_ptr;
/* Working state while writing an MCU. /* Working state while writing an MCU (sequential mode).
* This struct contains all the fields that are needed by subroutines. * This struct contains all the fields that are needed by subroutines.
*/ */
...@@ -84,99 +127,38 @@ typedef struct { ...@@ -84,99 +127,38 @@ typedef struct {
j_compress_ptr cinfo; /* dump_buffer needs access to this */ j_compress_ptr cinfo; /* dump_buffer needs access to this */
} working_state; } working_state;
/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
* buffer can hold. Larger sizes may slightly improve compression, but
* 1000 is already well into the realm of overkill.
* The minimum safe size is 64 bits.
*/
/* Forward declarations */ #define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */
METHODDEF(int) encode_mcu_huff JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
#ifdef ENTROPY_OPT_SUPPORTED
METHODDEF(int) encode_mcu_gather JPP((j_compress_ptr cinfo,
JBLOCKROW *MCU_data));
METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
#endif
/* /* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
* Initialize for a Huffman-compressed scan. * We assume that int right shift is unsigned if INT32 right shift is,
* If gather_statistics is TRUE, we do not output anything during the scan, * which should be safe.
* just count the Huffman symbols used and generate Huffman code tables.
*/ */
METHODDEF(void) #ifdef RIGHT_SHIFT_IS_UNSIGNED
start_pass_huff (j_compress_ptr cinfo, int gather_statistics) #define ISHIFT_TEMPS int ishift_temp;
{ #define IRIGHT_SHIFT(x,shft) \
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; ((ishift_temp = (x)) < 0 ? \
int ci, dctbl, actbl; (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
jpeg_component_info * compptr; (ishift_temp >> (shft)))
if (gather_statistics) {
#ifdef ENTROPY_OPT_SUPPORTED
entropy->pub.encode_mcu = encode_mcu_gather;
entropy->pub.finish_pass = finish_pass_gather;
#else #else
ERREXIT(cinfo, JERR_NOT_COMPILED); #define ISHIFT_TEMPS
#endif #define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
} else {
entropy->pub.encode_mcu = encode_mcu_huff;
entropy->pub.finish_pass = finish_pass_huff;
}
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;
if (gather_statistics) {
#ifdef ENTROPY_OPT_SUPPORTED
/* Check for invalid table indexes */
/* (make_c_derived_tbl does this in the other path) */
if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
/* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->dc_count_ptrs[dctbl] == NULL)
entropy->dc_count_ptrs[dctbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long));
if (entropy->ac_count_ptrs[actbl] == NULL)
entropy->ac_count_ptrs[actbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long));
#endif #endif
} else {
/* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */
jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
& entropy->dc_derived_tbls[dctbl]);
jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
& entropy->ac_derived_tbls[actbl]);
}
/* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 0;
}
/* Initialize bit buffer to empty */
entropy->saved.put_buffer = 0;
entropy->saved.put_bits = 0;
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num = 0;
}
/* /*
* Compute the derived values for a Huffman table. * Compute the derived values for a Huffman table.
* This routine also performs some validation checks on the table. * This routine also performs some validation checks on the table.
*
* Note this is also used by jcphuff.c.
*/ */
GLOBAL(void) LOCAL(void)
jpeg_make_c_derived_tbl (j_compress_ptr cinfo, int isDC, int tblno, jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
c_derived_tbl ** pdtbl) c_derived_tbl ** pdtbl)
{ {
JHUFF_TBL *htbl; JHUFF_TBL *htbl;
...@@ -232,7 +214,7 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, int isDC, int tblno, ...@@ -232,7 +214,7 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, int isDC, int tblno,
/* code is now 1 more than the last code used for codelength si; but /* 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. * it must still fit in si bits, since no code is allowed to be all ones.
*/ */
if (((long) code) >= (((long) 1) << si)) if (((INT32) code) >= (((INT32) 1) << si))
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
code <<= 1; code <<= 1;
si++; si++;
...@@ -264,18 +246,27 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, int isDC, int tblno, ...@@ -264,18 +246,27 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, int isDC, int tblno,
} }
/* Outputting bytes to the file */ /* Outputting bytes to the file.
* NB: these must be called only when actually outputting,
* that is, entropy->gather_statistics == FALSE.
*/
/* Emit a byte, taking 'action' if must suspend. */ /* Emit a byte, taking 'action' if must suspend. */
#define emit_byte(state,val,action) \ #define emit_byte_s(state,val,action) \
{ *(state)->next_output_byte++ = (JOCTET) (val); \ { *(state)->next_output_byte++ = (JOCTET) (val); \
if (--(state)->free_in_buffer == 0) \ if (--(state)->free_in_buffer == 0) \
if (! dump_buffer(state)) \ if (! dump_buffer_s(state)) \
{ action; } } { action; } }
/* Emit a byte */
#define emit_byte_e(entropy,val) \
{ *(entropy)->next_output_byte++ = (JOCTET) (val); \
if (--(entropy)->free_in_buffer == 0) \
dump_buffer_e(entropy); }
LOCAL(int)
dump_buffer (working_state * state) LOCAL(boolean)
dump_buffer_s (working_state * state)
/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ /* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
{ {
struct jpeg_destination_mgr * dest = state->cinfo->dest; struct jpeg_destination_mgr * dest = state->cinfo->dest;
...@@ -289,6 +280,20 @@ dump_buffer (working_state * state) ...@@ -289,6 +280,20 @@ dump_buffer (working_state * state)
} }
LOCAL(void)
dump_buffer_e (huff_entropy_ptr entropy)
/* Empty the output buffer; we do not support suspension in this case. */
{
struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
if (! (*dest->empty_output_buffer) (entropy->cinfo))
ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
/* After a successful buffer dump, must reset buffer pointers */
entropy->next_output_byte = dest->next_output_byte;
entropy->free_in_buffer = dest->free_in_buffer;
}
/* Outputting bits to the file */ /* Outputting bits to the file */
/* Only the right 24 bits of put_buffer are used; the valid bits are /* Only the right 24 bits of put_buffer are used; the valid bits are
...@@ -297,20 +302,20 @@ dump_buffer (working_state * state) ...@@ -297,20 +302,20 @@ dump_buffer (working_state * state)
* between calls, so 24 bits are sufficient. * between calls, so 24 bits are sufficient.
*/ */
inline INLINE
LOCAL(int) LOCAL(boolean)
emit_bits (working_state * state, unsigned int code, int size) emit_bits_s (working_state * state, unsigned int code, int size)
/* Emit some bits; return TRUE if successful, FALSE if must suspend */ /* Emit some bits; return TRUE if successful, FALSE if must suspend */
{ {
/* This routine is heavily used, so it's worth coding tightly. */ /* This routine is heavily used, so it's worth coding tightly. */
long put_buffer = (long) code; register INT32 put_buffer = (INT32) code;
int put_bits = state->cur.put_bits; register int put_bits = state->cur.put_bits;
/* if size is 0, caller used an invalid Huffman table entry */ /* if size is 0, caller used an invalid Huffman table entry */
if (size == 0) if (size == 0)
ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
put_buffer &= (((long) 1)<<size) - 1; /* mask off any extra bits in code */ put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
put_bits += size; /* new number of bits in buffer */ put_bits += size; /* new number of bits in buffer */
...@@ -321,9 +326,9 @@ emit_bits (working_state * state, unsigned int code, int size) ...@@ -321,9 +326,9 @@ emit_bits (working_state * state, unsigned int code, int size)
while (put_bits >= 8) { while (put_bits >= 8) {
int c = (int) ((put_buffer >> 16) & 0xFF); int c = (int) ((put_buffer >> 16) & 0xFF);
emit_byte(state, c, return FALSE); emit_byte_s(state, c, return FALSE);
if (c == 0xFF) { /* need to stuff a zero byte? */ if (c == 0xFF) { /* need to stuff a zero byte? */
emit_byte(state, 0, return FALSE); emit_byte_s(state, 0, return FALSE);
} }
put_buffer <<= 8; put_buffer <<= 8;
put_bits -= 8; put_bits -= 8;
...@@ -336,10 +341,51 @@ emit_bits (working_state * state, unsigned int code, int size) ...@@ -336,10 +341,51 @@ emit_bits (working_state * state, unsigned int code, int size)
} }
LOCAL(int) INLINE
flush_bits (working_state * state) LOCAL(void)
emit_bits_e (huff_entropy_ptr entropy, unsigned int code, int size)
/* Emit some bits, unless we are in gather mode */
{
/* This routine is heavily used, so it's worth coding tightly. */
register INT32 put_buffer = (INT32) code;
register int put_bits = entropy->saved.put_bits;
/* if size is 0, caller used an invalid Huffman table entry */
if (size == 0)
ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
if (entropy->gather_statistics)
return; /* do nothing if we're only getting stats */
put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
put_bits += size; /* new number of bits in buffer */
put_buffer <<= 24 - put_bits; /* align incoming bits */
/* and merge with old buffer contents */
put_buffer |= entropy->saved.put_buffer;
while (put_bits >= 8) {
int c = (int) ((put_buffer >> 16) & 0xFF);
emit_byte_e(entropy, c);
if (c == 0xFF) { /* need to stuff a zero byte? */
emit_byte_e(entropy, 0);
}
put_buffer <<= 8;
put_bits -= 8;
}
entropy->saved.put_buffer = put_buffer; /* update variables */
entropy->saved.put_bits = put_bits;
}
LOCAL(boolean)
flush_bits_s (working_state * state)
{ {
if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ if (! emit_bits_s(state, 0x7F, 7)) /* fill any partial byte with ones */
return FALSE; return FALSE;
state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
state->cur.put_bits = 0; state->cur.put_bits = 0;
...@@ -347,15 +393,534 @@ flush_bits (working_state * state) ...@@ -347,15 +393,534 @@ flush_bits (working_state * state)
} }
LOCAL(void)
flush_bits_e (huff_entropy_ptr entropy)
{
emit_bits_e(entropy, 0x7F, 7); /* fill any partial byte with ones */
entropy->saved.put_buffer = 0; /* and reset bit-buffer to empty */
entropy->saved.put_bits = 0;
}
/*
* Emit (or just count) a Huffman symbol.
*/
INLINE
LOCAL(void)
emit_dc_symbol (huff_entropy_ptr entropy, int tbl_no, int symbol)
{
if (entropy->gather_statistics)
entropy->dc_count_ptrs[tbl_no][symbol]++;
else {
c_derived_tbl * tbl = entropy->dc_derived_tbls[tbl_no];
emit_bits_e(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
}
}
INLINE
LOCAL(void)
emit_ac_symbol (huff_entropy_ptr entropy, int tbl_no, int symbol)
{
if (entropy->gather_statistics)
entropy->ac_count_ptrs[tbl_no][symbol]++;
else {
c_derived_tbl * tbl = entropy->ac_derived_tbls[tbl_no];
emit_bits_e(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
}
}
/*
* Emit bits from a correction bit buffer.
*/
LOCAL(void)
emit_buffered_bits (huff_entropy_ptr entropy, char * bufstart,
unsigned int nbits)
{
if (entropy->gather_statistics)
return; /* no real work */
while (nbits > 0) {
emit_bits_e(entropy, (unsigned int) (*bufstart), 1);
bufstart++;
nbits--;
}
}
/*
* Emit any pending EOBRUN symbol.
*/
LOCAL(void)
emit_eobrun (huff_entropy_ptr entropy)
{
register int temp, nbits;
if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */
temp = entropy->EOBRUN;
nbits = 0;
while ((temp >>= 1))
nbits++;
/* safety check: shouldn't happen given limited correction-bit buffer */
if (nbits > 14)
ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
emit_ac_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
if (nbits)
emit_bits_e(entropy, entropy->EOBRUN, nbits);
entropy->EOBRUN = 0;
/* Emit any buffered correction bits */
emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
entropy->BE = 0;
}
}
/*
* Emit a restart marker & resynchronize predictions.
*/
LOCAL(boolean)
emit_restart_s (working_state * state, int restart_num)
{
int ci;
if (! flush_bits_s(state))
return FALSE;
emit_byte_s(state, 0xFF, return FALSE);
emit_byte_s(state, JPEG_RST0 + restart_num, return FALSE);
/* Re-initialize DC predictions to 0 */
for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
state->cur.last_dc_val[ci] = 0;
/* The restart counter is not updated until we successfully write the MCU. */
return TRUE;
}
LOCAL(void)
emit_restart_e (huff_entropy_ptr entropy, int restart_num)
{
int ci;
emit_eobrun(entropy);
if (! entropy->gather_statistics) {
flush_bits_e(entropy);
emit_byte_e(entropy, 0xFF);
emit_byte_e(entropy, JPEG_RST0 + restart_num);
}
if (entropy->cinfo->Ss == 0) {
/* Re-initialize DC predictions to 0 */
for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
entropy->saved.last_dc_val[ci] = 0;
} else {
/* Re-initialize all AC-related fields to 0 */
entropy->EOBRUN = 0;
entropy->BE = 0;
}
}
/*
* MCU encoding for DC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int temp, temp2;
register int nbits;
int blkn, ci;
int Al = cinfo->Al;
JBLOCKROW block;
jpeg_component_info * compptr;
ISHIFT_TEMPS
entropy->next_output_byte = cinfo->dest->next_output_byte;
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
/* Emit restart marker if needed */
if (cinfo->restart_interval)
if (entropy->restarts_to_go == 0)
emit_restart_e(entropy, entropy->next_restart_num);
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
ci = cinfo->MCU_membership[blkn];
compptr = cinfo->cur_comp_info[ci];
/* Compute the DC value after the required point transform by Al.
* This is simply an arithmetic right shift.
*/
temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
/* DC differences are figured on the point-transformed values. */
temp = temp2 - entropy->saved.last_dc_val[ci];
entropy->saved.last_dc_val[ci] = temp2;
/* Encode the DC coefficient difference per section G.1.2.1 */
temp2 = temp;
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
/* For a negative input, want temp2 = bitwise complement of abs(input) */
/* This code assumes we are on a two's complement machine */
temp2--;
}
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = 0;
while (temp) {
nbits++;
temp >>= 1;
}
/* Check for out-of-range coefficient values.
* Since we're encoding a difference, the range limit is twice as much.
*/
if (nbits > MAX_COEF_BITS+1)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count/emit the Huffman-coded symbol for the number of bits */
emit_dc_symbol(entropy, compptr->dc_tbl_no, nbits);
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (nbits) /* emit_bits rejects calls with size 0 */
emit_bits_e(entropy, (unsigned int) temp2, nbits);
}
cinfo->dest->next_output_byte = entropy->next_output_byte;
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
/* Update restart-interval state too */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
return TRUE;
}
/*
* MCU encoding for AC initial scan (either spectral selection,
* or first pass of successive approximation).
*/
METHODDEF(boolean)
encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int temp, temp2;
register int nbits;
register int r, k;
int Se, Al;
const int * natural_order;
JBLOCKROW block;
entropy->next_output_byte = cinfo->dest->next_output_byte;
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
/* Emit restart marker if needed */
if (cinfo->restart_interval)
if (entropy->restarts_to_go == 0)
emit_restart_e(entropy, entropy->next_restart_num);
Se = cinfo->Se;
Al = cinfo->Al;
natural_order = cinfo->natural_order;
/* Encode the MCU data block */
block = MCU_data[0];
/* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
r = 0; /* r = run length of zeros */
for (k = cinfo->Ss; k <= Se; k++) {
if ((temp = (*block)[natural_order[k]]) == 0) {
r++;
continue;
}
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value; so the code is
* interwoven with finding the abs value (temp) and output bits (temp2).
*/
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
temp >>= Al; /* apply the point transform */
/* For a negative coef, want temp2 = bitwise complement of abs(coef) */
temp2 = ~temp;
} else {
temp >>= Al; /* apply the point transform */
temp2 = temp;
}
/* Watch out for case that nonzero coef is zero after point transform */
if (temp == 0) {
r++;
continue;
}
/* Emit any pending EOBRUN */
if (entropy->EOBRUN > 0)
emit_eobrun(entropy);
/* if run length > 15, must emit special run-length-16 codes (0xF0) */
while (r > 15) {
emit_ac_symbol(entropy, entropy->ac_tbl_no, 0xF0);
r -= 16;
}
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1))
nbits++;
/* Check for out-of-range coefficient values */
if (nbits > MAX_COEF_BITS)
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
/* Count/emit Huffman symbol for run length / number of bits */
emit_ac_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
emit_bits_e(entropy, (unsigned int) temp2, nbits);
r = 0; /* reset zero run length */
}
if (r > 0) { /* If there are trailing zeroes, */
entropy->EOBRUN++; /* count an EOB */
if (entropy->EOBRUN == 0x7FFF)
emit_eobrun(entropy); /* force it out to avoid overflow */
}
cinfo->dest->next_output_byte = entropy->next_output_byte;
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
/* Update restart-interval state too */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
return TRUE;
}
/*
* MCU encoding 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)
encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int temp;
int blkn;
int Al = cinfo->Al;
JBLOCKROW block;
entropy->next_output_byte = cinfo->dest->next_output_byte;
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
/* Emit restart marker if needed */
if (cinfo->restart_interval)
if (entropy->restarts_to_go == 0)
emit_restart_e(entropy, entropy->next_restart_num);
/* Encode the MCU data blocks */
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
block = MCU_data[blkn];
/* We simply emit the Al'th bit of the DC coefficient value. */
temp = (*block)[0];
emit_bits_e(entropy, (unsigned int) (temp >> Al), 1);
}
cinfo->dest->next_output_byte = entropy->next_output_byte;
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
/* Update restart-interval state too */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
return TRUE;
}
/*
* MCU encoding for AC successive approximation refinement scan.
*/
METHODDEF(boolean)
encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
register int temp;
register int r, k;
int EOB;
char *BR_buffer;
unsigned int BR;
int Se, Al;
const int * natural_order;
JBLOCKROW block;
int absvalues[DCTSIZE2];
entropy->next_output_byte = cinfo->dest->next_output_byte;
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
/* Emit restart marker if needed */
if (cinfo->restart_interval)
if (entropy->restarts_to_go == 0)
emit_restart_e(entropy, entropy->next_restart_num);
Se = cinfo->Se;
Al = cinfo->Al;
natural_order = cinfo->natural_order;
/* Encode the MCU data block */
block = MCU_data[0];
/* It is convenient to make a pre-pass to determine the transformed
* coefficients' absolute values and the EOB position.
*/
EOB = 0;
for (k = cinfo->Ss; k <= Se; k++) {
temp = (*block)[natural_order[k]];
/* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. To do this portably
* in C, we shift after obtaining the absolute value.
*/
if (temp < 0)
temp = -temp; /* temp is abs value of input */
temp >>= Al; /* apply the point transform */
absvalues[k] = temp; /* save abs value for main pass */
if (temp == 1)
EOB = k; /* EOB = index of last newly-nonzero coef */
}
/* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
r = 0; /* r = run length of zeros */
BR = 0; /* BR = count of buffered bits added now */
BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
for (k = cinfo->Ss; k <= Se; k++) {
if ((temp = absvalues[k]) == 0) {
r++;
continue;
}
/* Emit any required ZRLs, but not if they can be folded into EOB */
while (r > 15 && k <= EOB) {
/* emit any pending EOBRUN and the BE correction bits */
emit_eobrun(entropy);
/* Emit ZRL */
emit_ac_symbol(entropy, entropy->ac_tbl_no, 0xF0);
r -= 16;
/* Emit buffered correction bits that must be associated with ZRL */
emit_buffered_bits(entropy, BR_buffer, BR);
BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
BR = 0;
}
/* If the coef was previously nonzero, it only needs a correction bit.
* NOTE: a straight translation of the spec's figure G.7 would suggest
* that we also need to test r > 15. But if r > 15, we can only get here
* if k > EOB, which implies that this coefficient is not 1.
*/
if (temp > 1) {
/* The correction bit is the next bit of the absolute value. */
BR_buffer[BR++] = (char) (temp & 1);
continue;
}
/* Emit any pending EOBRUN and the BE correction bits */
emit_eobrun(entropy);
/* Count/emit Huffman symbol for run length / number of bits */
emit_ac_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
/* Emit output bit for newly-nonzero coef */
temp = ((*block)[natural_order[k]] < 0) ? 0 : 1;
emit_bits_e(entropy, (unsigned int) temp, 1);
/* Emit buffered correction bits that must be associated with this code */
emit_buffered_bits(entropy, BR_buffer, BR);
BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
BR = 0;
r = 0; /* reset zero run length */
}
if (r > 0 || BR > 0) { /* If there are trailing zeroes, */
entropy->EOBRUN++; /* count an EOB */
entropy->BE += BR; /* concat my correction bits to older ones */
/* We force out the EOB if we risk either:
* 1. overflow of the EOB counter;
* 2. overflow of the correction bit buffer during the next MCU.
*/
if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
emit_eobrun(entropy);
}
cinfo->dest->next_output_byte = entropy->next_output_byte;
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
/* Update restart-interval state too */
if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) {
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num++;
entropy->next_restart_num &= 7;
}
entropy->restarts_to_go--;
}
return TRUE;
}
/* Encode a single block's worth of coefficients */ /* Encode a single block's worth of coefficients */
LOCAL(int) LOCAL(boolean)
encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
c_derived_tbl *dctbl, c_derived_tbl *actbl) c_derived_tbl *dctbl, c_derived_tbl *actbl)
{ {
int temp, temp2; register int temp, temp2;
int nbits; register int nbits;
int k, r, i; register int k, r, i;
int Se = state->cinfo->lim_Se;
const int * natural_order = state->cinfo->natural_order;
/* Encode the DC coefficient difference per section F.1.2.1 */ /* Encode the DC coefficient difference per section F.1.2.1 */
...@@ -381,26 +946,26 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, ...@@ -381,26 +946,26 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
/* Emit the Huffman-coded symbol for the number of bits */ /* Emit the Huffman-coded symbol for the number of bits */
if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) if (! emit_bits_s(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
return FALSE; return FALSE;
/* Emit that number of bits of the value, if positive, */ /* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */ /* or the complement of its magnitude, if negative. */
if (nbits) /* emit_bits rejects calls with size 0 */ if (nbits) /* emit_bits rejects calls with size 0 */
if (! emit_bits(state, (unsigned int) temp2, nbits)) if (! emit_bits_s(state, (unsigned int) temp2, nbits))
return FALSE; return FALSE;
/* Encode the AC coefficients per section F.1.2.2 */ /* Encode the AC coefficients per section F.1.2.2 */
r = 0; /* r = run length of zeros */ r = 0; /* r = run length of zeros */
for (k = 1; k < DCTSIZE2; k++) { for (k = 1; k <= Se; k++) {
if ((temp = block[jpeg_natural_order[k]]) == 0) { if ((temp = block[natural_order[k]]) == 0) {
r++; r++;
} else { } else {
/* if run length > 15, must emit special run-length-16 codes (0xF0) */ /* if run length > 15, must emit special run-length-16 codes (0xF0) */
while (r > 15) { while (r > 15) {
if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) if (! emit_bits_s(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
return FALSE; return FALSE;
r -= 16; r -= 16;
} }
...@@ -422,12 +987,12 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, ...@@ -422,12 +987,12 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
/* Emit Huffman symbol for run length / number of bits */ /* Emit Huffman symbol for run length / number of bits */
i = (r << 4) + nbits; i = (r << 4) + nbits;
if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) if (! emit_bits_s(state, actbl->ehufco[i], actbl->ehufsi[i]))
return FALSE; return FALSE;
/* Emit that number of bits of the value, if positive, */ /* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */ /* or the complement of its magnitude, if negative. */
if (! emit_bits(state, (unsigned int) temp2, nbits)) if (! emit_bits_s(state, (unsigned int) temp2, nbits))
return FALSE; return FALSE;
r = 0; r = 0;
...@@ -436,43 +1001,18 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, ...@@ -436,43 +1001,18 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
/* If the last coef(s) were zero, emit an end-of-block code */ /* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0) if (r > 0)
if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) if (! emit_bits_s(state, actbl->ehufco[0], actbl->ehufsi[0]))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
/*
* Emit a restart marker & resynchronize predictions.
*/
LOCAL(int)
emit_restart (working_state * state, int restart_num)
{
int ci;
if (! flush_bits(state))
return FALSE;
emit_byte(state, 0xFF, return FALSE);
emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
/* Re-initialize DC predictions to 0 */
for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
state->cur.last_dc_val[ci] = 0;
/* The restart counter is not updated until we successfully write the MCU. */
return TRUE;
}
/* /*
* Encode and output one MCU's worth of Huffman-compressed coefficients. * Encode and output one MCU's worth of Huffman-compressed coefficients.
*/ */
METHODDEF(int) METHODDEF(boolean)
encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
...@@ -489,7 +1029,7 @@ encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) ...@@ -489,7 +1029,7 @@ encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* Emit restart marker if needed */ /* Emit restart marker if needed */
if (cinfo->restart_interval) { if (cinfo->restart_interval) {
if (entropy->restarts_to_go == 0) if (entropy->restarts_to_go == 0)
if (! emit_restart(&state, entropy->next_restart_num)) if (! emit_restart_s(&state, entropy->next_restart_num))
return FALSE; return FALSE;
} }
...@@ -535,6 +1075,17 @@ finish_pass_huff (j_compress_ptr cinfo) ...@@ -535,6 +1075,17 @@ finish_pass_huff (j_compress_ptr cinfo)
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
working_state state; working_state state;
if (cinfo->progressive_mode) {
entropy->next_output_byte = cinfo->dest->next_output_byte;
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
/* Flush out any buffered data */
emit_eobrun(entropy);
flush_bits_e(entropy);
cinfo->dest->next_output_byte = entropy->next_output_byte;
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
} else {
/* Load up working state ... flush_bits needs it */ /* Load up working state ... flush_bits needs it */
state.next_output_byte = cinfo->dest->next_output_byte; state.next_output_byte = cinfo->dest->next_output_byte;
state.free_in_buffer = cinfo->dest->free_in_buffer; state.free_in_buffer = cinfo->dest->free_in_buffer;
...@@ -542,13 +1093,14 @@ finish_pass_huff (j_compress_ptr cinfo) ...@@ -542,13 +1093,14 @@ finish_pass_huff (j_compress_ptr cinfo)
state.cinfo = cinfo; state.cinfo = cinfo;
/* Flush out the last data */ /* Flush out the last data */
if (! flush_bits(&state)) if (! flush_bits_s(&state))
ERREXIT(cinfo, JERR_CANT_SUSPEND); ERREXIT(cinfo, JERR_CANT_SUSPEND);
/* Update state */ /* Update state */
cinfo->dest->next_output_byte = state.next_output_byte; cinfo->dest->next_output_byte = state.next_output_byte;
cinfo->dest->free_in_buffer = state.free_in_buffer; cinfo->dest->free_in_buffer = state.free_in_buffer;
ASSIGN_STATE(entropy->saved, state.cur); ASSIGN_STATE(entropy->saved, state.cur);
}
} }
...@@ -563,8 +1115,6 @@ finish_pass_huff (j_compress_ptr cinfo) ...@@ -563,8 +1115,6 @@ finish_pass_huff (j_compress_ptr cinfo)
* the compressed data. * the compressed data.
*/ */
#ifdef ENTROPY_OPT_SUPPORTED
/* Process a single block's worth of coefficients */ /* Process a single block's worth of coefficients */
...@@ -572,9 +1122,11 @@ LOCAL(void) ...@@ -572,9 +1122,11 @@ LOCAL(void)
htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
long dc_counts[], long ac_counts[]) long dc_counts[], long ac_counts[])
{ {
int temp; register int temp;
int nbits; register int nbits;
int k, r; register int k, r;
int Se = cinfo->lim_Se;
const int * natural_order = cinfo->natural_order;
/* Encode the DC coefficient difference per section F.1.2.1 */ /* Encode the DC coefficient difference per section F.1.2.1 */
...@@ -601,8 +1153,8 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, ...@@ -601,8 +1153,8 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
r = 0; /* r = run length of zeros */ r = 0; /* r = run length of zeros */
for (k = 1; k < DCTSIZE2; k++) { for (k = 1; k <= Se; k++) {
if ((temp = block[jpeg_natural_order[k]]) == 0) { if ((temp = block[natural_order[k]]) == 0) {
r++; r++;
} else { } else {
/* if run length > 15, must emit special run-length-16 codes (0xF0) */ /* if run length > 15, must emit special run-length-16 codes (0xF0) */
...@@ -641,7 +1193,7 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, ...@@ -641,7 +1193,7 @@ htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
* No data is actually output, so no suspension return is possible. * No data is actually output, so no suspension return is possible.
*/ */
METHODDEF(int) METHODDEF(boolean)
encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
...@@ -675,7 +1227,6 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) ...@@ -675,7 +1227,6 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
/* /*
* Generate the best Huffman code table for the given counts, fill htbl. * Generate the best Huffman code table for the given counts, fill htbl.
* Note this is also used by jcphuff.c.
* *
* The JPEG standard requires that no symbol be assigned a codeword of all * The JPEG standard requires that no symbol be assigned a codeword of all
* one bits (so that padding bits added at the end of a compressed segment * one bits (so that padding bits added at the end of a compressed segment
...@@ -701,11 +1252,11 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) ...@@ -701,11 +1252,11 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
* So the extra complexity of an optimal algorithm doesn't seem worthwhile. * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
*/ */
GLOBAL(void) LOCAL(void)
jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
{ {
#define MAX_CLEN 32 /* assumed maximum initial code length */ #define MAX_CLEN 32 /* assumed maximum initial code length */
unsigned short bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
int codesize[257]; /* codesize[k] = code length of symbol k */ int codesize[257]; /* codesize[k] = code length of symbol k */
int others[257]; /* next symbol in current branch of tree */ int others[257]; /* next symbol in current branch of tree */
int c1, c2; int c1, c2;
...@@ -827,7 +1378,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) ...@@ -827,7 +1378,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
for (i = 1; i <= MAX_CLEN; i++) { for (i = 1; i <= MAX_CLEN; i++) {
for (j = 0; j <= 255; j++) { for (j = 0; j <= 255; j++) {
if (codesize[j] == i) { if (codesize[j] == i) {
htbl->huffval[p] = (unsigned char) j; htbl->huffval[p] = (UINT8) j;
p++; p++;
} }
} }
...@@ -846,41 +1397,156 @@ METHODDEF(void) ...@@ -846,41 +1397,156 @@ METHODDEF(void)
finish_pass_gather (j_compress_ptr cinfo) finish_pass_gather (j_compress_ptr cinfo)
{ {
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int ci, dctbl, actbl; int ci, tbl;
jpeg_component_info * compptr; jpeg_component_info * compptr;
JHUFF_TBL **htblptr; JHUFF_TBL **htblptr;
int did_dc[NUM_HUFF_TBLS]; boolean did_dc[NUM_HUFF_TBLS];
int did_ac[NUM_HUFF_TBLS]; boolean did_ac[NUM_HUFF_TBLS];
/* It's important not to apply jpeg_gen_optimal_table more than once /* It's important not to apply jpeg_gen_optimal_table more than once
* per table, because it clobbers the input frequency counts! * per table, because it clobbers the input frequency counts!
*/ */
if (cinfo->progressive_mode)
/* Flush out buffered data (all we care about is counting the EOB symbol) */
emit_eobrun(entropy);
MEMZERO(did_dc, SIZEOF(did_dc)); MEMZERO(did_dc, SIZEOF(did_dc));
MEMZERO(did_ac, SIZEOF(did_ac)); MEMZERO(did_ac, SIZEOF(did_ac));
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
dctbl = compptr->dc_tbl_no; /* DC needs no table for refinement scan */
actbl = compptr->ac_tbl_no; if (cinfo->Ss == 0 && cinfo->Ah == 0) {
if (! did_dc[dctbl]) { tbl = compptr->dc_tbl_no;
htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; if (! did_dc[tbl]) {
htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
if (*htblptr == NULL) if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[tbl]);
did_dc[dctbl] = TRUE; did_dc[tbl] = TRUE;
}
} }
if (! did_ac[actbl]) { /* AC needs no table when not present */
htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; if (cinfo->Se) {
tbl = compptr->ac_tbl_no;
if (! did_ac[tbl]) {
htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
if (*htblptr == NULL) if (*htblptr == NULL)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[tbl]);
did_ac[actbl] = TRUE; did_ac[tbl] = TRUE;
}
} }
} }
} }
#endif /* ENTROPY_OPT_SUPPORTED */ /*
* Initialize for a Huffman-compressed scan.
* If gather_statistics is TRUE, we do not output anything during the scan,
* just count the Huffman symbols used and generate Huffman code tables.
*/
METHODDEF(void)
start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
{
huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
int ci, tbl;
jpeg_component_info * compptr;
if (gather_statistics)
entropy->pub.finish_pass = finish_pass_gather;
else
entropy->pub.finish_pass = finish_pass_huff;
if (cinfo->progressive_mode) {
entropy->cinfo = cinfo;
entropy->gather_statistics = gather_statistics;
/* We assume jcmaster.c already validated the scan parameters. */
/* Select execution routine */
if (cinfo->Ah == 0) {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_first;
else
entropy->pub.encode_mcu = encode_mcu_AC_first;
} else {
if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_refine;
else {
entropy->pub.encode_mcu = encode_mcu_AC_refine;
/* AC refinement needs a correction bit buffer */
if (entropy->bit_buffer == NULL)
entropy->bit_buffer = (char *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
MAX_CORR_BITS * SIZEOF(char));
}
}
/* Initialize AC stuff */
entropy->ac_tbl_no = cinfo->cur_comp_info[0]->ac_tbl_no;
entropy->EOBRUN = 0;
entropy->BE = 0;
} else {
if (gather_statistics)
entropy->pub.encode_mcu = encode_mcu_gather;
else
entropy->pub.encode_mcu = encode_mcu_huff;
}
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
tbl = compptr->dc_tbl_no;
if (gather_statistics) {
/* Check for invalid table index */
/* (make_c_derived_tbl does this in the other path) */
if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
/* Allocate and zero the statistics tables */
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
if (entropy->dc_count_ptrs[tbl] == NULL)
entropy->dc_count_ptrs[tbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
MEMZERO(entropy->dc_count_ptrs[tbl], 257 * SIZEOF(long));
} else {
/* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */
jpeg_make_c_derived_tbl(cinfo, TRUE, tbl,
& entropy->dc_derived_tbls[tbl]);
}
/* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 0;
}
/* AC needs no table when not present */
if (cinfo->Se) {
tbl = compptr->ac_tbl_no;
if (gather_statistics) {
if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
if (entropy->ac_count_ptrs[tbl] == NULL)
entropy->ac_count_ptrs[tbl] = (long *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * SIZEOF(long));
MEMZERO(entropy->ac_count_ptrs[tbl], 257 * SIZEOF(long));
} else {
jpeg_make_c_derived_tbl(cinfo, FALSE, tbl,
& entropy->ac_derived_tbls[tbl]);
}
}
}
/* Initialize bit buffer to empty */
entropy->saved.put_buffer = 0;
entropy->saved.put_bits = 0;
/* Initialize restart stuff */
entropy->restarts_to_go = cinfo->restart_interval;
entropy->next_restart_num = 0;
}
/* /*
...@@ -902,8 +1568,9 @@ jinit_huff_encoder (j_compress_ptr cinfo) ...@@ -902,8 +1568,9 @@ jinit_huff_encoder (j_compress_ptr cinfo)
/* Mark tables unallocated */ /* Mark tables unallocated */
for (i = 0; i < NUM_HUFF_TBLS; i++) { for (i = 0; i < NUM_HUFF_TBLS; i++) {
entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
#ifdef ENTROPY_OPT_SUPPORTED
entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
#endif
} }
if (cinfo->progressive_mode)
entropy->bit_buffer = NULL; /* needed only in AC refinement scan */
} }
/*
* jchuff.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 encoding routines
* that are shared between the sequential encoder (jchuff.c) and the
* progressive encoder (jcphuff.c). No other modules need to see these.
*/
/* The legal range of a DCT coefficient is
* -1024 .. +1023 for 8-bit data;
* -16384 .. +16383 for 12-bit data.
* Hence the magnitude should always fit in 10 or 14 bits respectively.
*/
#if BITS_IN_JSAMPLE == 8
#define MAX_COEF_BITS 10
#else
#define MAX_COEF_BITS 14
#endif
/* Derived data constructed for each Huffman table */
typedef struct {
unsigned int ehufco[256]; /* code for each symbol */
char ehufsi[256]; /* length of code for each symbol */
/* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
} c_derived_tbl;
/* Short forms of external names for systems with brain-damaged linkers. */
#ifdef NEED_SHORT_EXTERNAL_NAMES
#define jpeg_make_c_derived_tbl jMkCDerived
#define jpeg_gen_optimal_table jGenOptTbl
#endif /* NEED_SHORT_EXTERNAL_NAMES */
/* Expand a Huffman table definition into the derived format */
EXTERN(void) jpeg_make_c_derived_tbl
JPP((j_compress_ptr cinfo, int isDC, int tblno,
c_derived_tbl ** pdtbl));
/* Generate an optimal table definition given the specified counts */
EXTERN(void) jpeg_gen_optimal_table
JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
...@@ -41,22 +41,15 @@ jinit_compress_master (j_compress_ptr cinfo) ...@@ -41,22 +41,15 @@ jinit_compress_master (j_compress_ptr cinfo)
/* Forward DCT */ /* Forward DCT */
jinit_forward_dct(cinfo); jinit_forward_dct(cinfo);
/* Entropy encoding: either Huffman or arithmetic coding. */ /* Entropy encoding: either Huffman or arithmetic coding. */
if (cinfo->arith_code) { if (cinfo->arith_code)
ERREXIT(cinfo, JERR_ARITH_NOTIMPL); jinit_arith_encoder(cinfo);
} else { else {
if (cinfo->progressive_mode) {
#ifdef C_PROGRESSIVE_SUPPORTED
jinit_phuff_encoder(cinfo);
#else
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else
jinit_huff_encoder(cinfo); jinit_huff_encoder(cinfo);
} }
/* Need a full-image coefficient buffer in any multi-pass mode. */ /* Need a full-image coefficient buffer in any multi-pass mode. */
jinit_c_coef_controller(cinfo, jinit_c_coef_controller(cinfo,
(int) (cinfo->num_scans > 1 || cinfo->optimize_coding)); (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo); jinit_marker_writer(cinfo);
......
...@@ -30,7 +30,7 @@ typedef struct { ...@@ -30,7 +30,7 @@ typedef struct {
JDIMENSION cur_iMCU_row; /* number of current iMCU row */ JDIMENSION cur_iMCU_row; /* number of current iMCU row */
JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
int suspended; /* remember if we suspended output */ boolean suspended; /* remember if we suspended output */
J_BUF_MODE pass_mode; /* current operating mode */ J_BUF_MODE pass_mode; /* current operating mode */
/* If using just a strip buffer, this points to the entire set of buffers /* If using just a strip buffer, this points to the entire set of buffers
...@@ -118,17 +118,17 @@ process_data_simple_main (j_compress_ptr cinfo, ...@@ -118,17 +118,17 @@ process_data_simple_main (j_compress_ptr cinfo,
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
/* Read input data if we haven't filled the main buffer yet */ /* Read input data if we haven't filled the main buffer yet */
if (main->rowgroup_ctr < DCTSIZE) if (main->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
(*cinfo->prep->pre_process_data) (cinfo, (*cinfo->prep->pre_process_data) (cinfo,
input_buf, in_row_ctr, in_rows_avail, input_buf, in_row_ctr, in_rows_avail,
main->buffer, &main->rowgroup_ctr, main->buffer, &main->rowgroup_ctr,
(JDIMENSION) DCTSIZE); (JDIMENSION) cinfo->min_DCT_v_scaled_size);
/* If we don't have a full iMCU row buffered, return to application for /* If we don't have a full iMCU row buffered, return to application for
* more data. Note that preprocessor will always pad to fill the iMCU row * more data. Note that preprocessor will always pad to fill the iMCU row
* at the bottom of the image. * at the bottom of the image.
*/ */
if (main->rowgroup_ctr != DCTSIZE) if (main->rowgroup_ctr != (JDIMENSION) cinfo->min_DCT_v_scaled_size)
return; return;
/* Send the completed row to the compressor */ /* Send the completed row to the compressor */
...@@ -173,7 +173,7 @@ process_data_buffer_main (j_compress_ptr cinfo, ...@@ -173,7 +173,7 @@ process_data_buffer_main (j_compress_ptr cinfo,
my_main_ptr main = (my_main_ptr) cinfo->main; my_main_ptr main = (my_main_ptr) cinfo->main;
int ci; int ci;
jpeg_component_info *compptr; jpeg_component_info *compptr;
int writing = (main->pass_mode != JBUF_CRANK_DEST); boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
/* Realign the virtual buffers if at the start of an iMCU row. */ /* Realign the virtual buffers if at the start of an iMCU row. */
...@@ -242,7 +242,7 @@ process_data_buffer_main (j_compress_ptr cinfo, ...@@ -242,7 +242,7 @@ process_data_buffer_main (j_compress_ptr cinfo,
*/ */
GLOBAL(void) GLOBAL(void)
jinit_c_main_controller (j_compress_ptr cinfo, int need_full_buffer) jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
{ {
my_main_ptr main; my_main_ptr main;
int ci; int ci;
...@@ -269,10 +269,10 @@ jinit_c_main_controller (j_compress_ptr cinfo, int need_full_buffer) ...@@ -269,10 +269,10 @@ jinit_c_main_controller (j_compress_ptr cinfo, int need_full_buffer)
ci++, compptr++) { ci++, compptr++) {
main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
compptr->width_in_blocks * DCTSIZE, compptr->width_in_blocks * compptr->DCT_h_scaled_size,
(JDIMENSION) jround_up((long) compptr->height_in_blocks, (JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor) * DCTSIZE, (long) compptr->v_samp_factor) * DCTSIZE,
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); (JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
} }
#else #else
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
...@@ -286,8 +286,8 @@ jinit_c_main_controller (j_compress_ptr cinfo, int need_full_buffer) ...@@ -286,8 +286,8 @@ jinit_c_main_controller (j_compress_ptr cinfo, int need_full_buffer)
ci++, compptr++) { ci++, compptr++) {
main->buffer[ci] = (*cinfo->mem->alloc_sarray) main->buffer[ci] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE, ((j_common_ptr) cinfo, JPOOL_IMAGE,
compptr->width_in_blocks * DCTSIZE, compptr->width_in_blocks * compptr->DCT_h_scaled_size,
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); (JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
} }
} }
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* jcmarker.c * jcmarker.c
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
...@@ -153,21 +154,22 @@ emit_dqt (j_compress_ptr cinfo, int index) ...@@ -153,21 +154,22 @@ emit_dqt (j_compress_ptr cinfo, int index)
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index); ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
prec = 0; prec = 0;
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i <= cinfo->lim_Se; i++) {
if (qtbl->quantval[i] > 255) if (qtbl->quantval[cinfo->natural_order[i]] > 255)
prec = 1; prec = 1;
} }
if (! qtbl->sent_table) { if (! qtbl->sent_table) {
emit_marker(cinfo, M_DQT); emit_marker(cinfo, M_DQT);
emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2); emit_2bytes(cinfo,
prec ? cinfo->lim_Se * 2 + 2 + 1 + 2 : cinfo->lim_Se + 1 + 1 + 2);
emit_byte(cinfo, index + (prec<<4)); emit_byte(cinfo, index + (prec<<4));
for (i = 0; i < DCTSIZE2; i++) { for (i = 0; i <= cinfo->lim_Se; i++) {
/* The table entries must be emitted in zigzag order. */ /* The table entries must be emitted in zigzag order. */
unsigned int qval = qtbl->quantval[jpeg_natural_order[i]]; unsigned int qval = qtbl->quantval[cinfo->natural_order[i]];
if (prec) if (prec)
emit_byte(cinfo, (int) (qval >> 8)); emit_byte(cinfo, (int) (qval >> 8));
emit_byte(cinfo, (int) (qval & 0xFF)); emit_byte(cinfo, (int) (qval & 0xFF));
...@@ -181,7 +183,7 @@ emit_dqt (j_compress_ptr cinfo, int index) ...@@ -181,7 +183,7 @@ emit_dqt (j_compress_ptr cinfo, int index)
LOCAL(void) LOCAL(void)
emit_dht (j_compress_ptr cinfo, int index, int is_ac) emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
/* Emit a DHT marker */ /* Emit a DHT marker */
{ {
JHUFF_TBL * htbl; JHUFF_TBL * htbl;
...@@ -219,7 +221,7 @@ emit_dht (j_compress_ptr cinfo, int index, int is_ac) ...@@ -219,7 +221,7 @@ emit_dht (j_compress_ptr cinfo, int index, int is_ac)
LOCAL(void) LOCAL(void)
emit_dac (j_compress_ptr )//cinfo) emit_dac (j_compress_ptr cinfo)
/* Emit a DAC marker */ /* Emit a DAC marker */
/* Since the useful info is so small, we want to emit all the tables in */ /* Since the useful info is so small, we want to emit all the tables in */
/* one DAC marker. Therefore this routine does its own scan of the table. */ /* one DAC marker. Therefore this routine does its own scan of the table. */
...@@ -235,7 +237,11 @@ emit_dac (j_compress_ptr )//cinfo) ...@@ -235,7 +237,11 @@ emit_dac (j_compress_ptr )//cinfo)
for (i = 0; i < cinfo->comps_in_scan; i++) { for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i]; compptr = cinfo->cur_comp_info[i];
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0)
dc_in_use[compptr->dc_tbl_no] = 1; dc_in_use[compptr->dc_tbl_no] = 1;
/* AC needs no table when not present */
if (cinfo->Se)
ac_in_use[compptr->ac_tbl_no] = 1; ac_in_use[compptr->ac_tbl_no] = 1;
} }
...@@ -243,6 +249,7 @@ emit_dac (j_compress_ptr )//cinfo) ...@@ -243,6 +249,7 @@ emit_dac (j_compress_ptr )//cinfo)
for (i = 0; i < NUM_ARITH_TBLS; i++) for (i = 0; i < NUM_ARITH_TBLS; i++)
length += dc_in_use[i] + ac_in_use[i]; length += dc_in_use[i] + ac_in_use[i];
if (length) {
emit_marker(cinfo, M_DAC); emit_marker(cinfo, M_DAC);
emit_2bytes(cinfo, length*2 + 2); emit_2bytes(cinfo, length*2 + 2);
...@@ -257,6 +264,7 @@ emit_dac (j_compress_ptr )//cinfo) ...@@ -257,6 +264,7 @@ emit_dac (j_compress_ptr )//cinfo)
emit_byte(cinfo, cinfo->arith_ac_K[i]); emit_byte(cinfo, cinfo->arith_ac_K[i]);
} }
} }
}
#endif /* C_ARITH_CODING_SUPPORTED */ #endif /* C_ARITH_CODING_SUPPORTED */
} }
...@@ -285,13 +293,13 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code) ...@@ -285,13 +293,13 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */ emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
/* Make sure image isn't bigger than SOF field can handle */ /* Make sure image isn't bigger than SOF field can handle */
if ((long) cinfo->image_height > 65535L || if ((long) cinfo->jpeg_height > 65535L ||
(long) cinfo->image_width > 65535L) (long) cinfo->jpeg_width > 65535L)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535); ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
emit_byte(cinfo, cinfo->data_precision); emit_byte(cinfo, cinfo->data_precision);
emit_2bytes(cinfo, (int) cinfo->image_height); emit_2bytes(cinfo, (int) cinfo->jpeg_height);
emit_2bytes(cinfo, (int) cinfo->image_width); emit_2bytes(cinfo, (int) cinfo->jpeg_width);
emit_byte(cinfo, cinfo->num_components); emit_byte(cinfo, cinfo->num_components);
...@@ -320,22 +328,16 @@ emit_sos (j_compress_ptr cinfo) ...@@ -320,22 +328,16 @@ emit_sos (j_compress_ptr cinfo)
for (i = 0; i < cinfo->comps_in_scan; i++) { for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i]; compptr = cinfo->cur_comp_info[i];
emit_byte(cinfo, compptr->component_id); emit_byte(cinfo, compptr->component_id);
td = compptr->dc_tbl_no;
ta = compptr->ac_tbl_no; /* We emit 0 for unused field(s); this is recommended by the P&M text
if (cinfo->progressive_mode) {
/* Progressive mode: only DC or only AC tables are used in one scan;
* furthermore, Huffman coding of DC refinement uses no table at all.
* We emit 0 for unused field(s); this is recommended by the P&M text
* but does not seem to be specified in the standard. * but does not seem to be specified in the standard.
*/ */
if (cinfo->Ss == 0) {
ta = 0; /* DC scan */ /* DC needs no table for refinement scan */
if (cinfo->Ah != 0 && !cinfo->arith_code) td = cinfo->Ss == 0 && cinfo->Ah == 0 ? compptr->dc_tbl_no : 0;
td = 0; /* no DC table either */ /* AC needs no table when not present */
} else { ta = cinfo->Se ? compptr->ac_tbl_no : 0;
td = 0; /* AC scan */
}
}
emit_byte(cinfo, (td << 4) + ta); emit_byte(cinfo, (td << 4) + ta);
} }
...@@ -345,6 +347,22 @@ emit_sos (j_compress_ptr cinfo) ...@@ -345,6 +347,22 @@ emit_sos (j_compress_ptr cinfo)
} }
LOCAL(void)
emit_pseudo_sos (j_compress_ptr cinfo)
/* Emit a pseudo SOS marker */
{
emit_marker(cinfo, M_SOS);
emit_2bytes(cinfo, 2 + 1 + 3); /* length */
emit_byte(cinfo, 0); /* Ns */
emit_byte(cinfo, 0); /* Ss */
emit_byte(cinfo, cinfo->block_size * cinfo->block_size - 1); /* Se */
emit_byte(cinfo, 0); /* Ah/Al */
}
LOCAL(void) LOCAL(void)
emit_jfif_app0 (j_compress_ptr cinfo) emit_jfif_app0 (j_compress_ptr cinfo)
/* Emit a JFIF-compliant APP0 marker */ /* Emit a JFIF-compliant APP0 marker */
...@@ -484,7 +502,7 @@ write_file_header (j_compress_ptr cinfo) ...@@ -484,7 +502,7 @@ write_file_header (j_compress_ptr cinfo)
/* /*
* Write frame header. * Write frame header.
* This consists of DQT and SOFn markers. * This consists of DQT and SOFn markers, and a conditional pseudo SOS marker.
* Note that we do not emit the SOF until we have emitted the DQT(s). * Note that we do not emit the SOF until we have emitted the DQT(s).
* This avoids compatibility problems with incorrect implementations that * This avoids compatibility problems with incorrect implementations that
* try to error-check the quant table numbers as soon as they see the SOF. * try to error-check the quant table numbers as soon as they see the SOF.
...@@ -494,7 +512,7 @@ METHODDEF(void) ...@@ -494,7 +512,7 @@ METHODDEF(void)
write_frame_header (j_compress_ptr cinfo) write_frame_header (j_compress_ptr cinfo)
{ {
int ci, prec; int ci, prec;
int is_baseline; boolean is_baseline;
jpeg_component_info *compptr; jpeg_component_info *compptr;
/* Emit DQT for each quantization table. /* Emit DQT for each quantization table.
...@@ -511,7 +529,7 @@ write_frame_header (j_compress_ptr cinfo) ...@@ -511,7 +529,7 @@ write_frame_header (j_compress_ptr cinfo)
* Note we assume that Huffman table numbers won't be changed later. * Note we assume that Huffman table numbers won't be changed later.
*/ */
if (cinfo->arith_code || cinfo->progressive_mode || if (cinfo->arith_code || cinfo->progressive_mode ||
cinfo->data_precision != 8) { cinfo->data_precision != 8 || cinfo->block_size != DCTSIZE) {
is_baseline = FALSE; is_baseline = FALSE;
} else { } else {
is_baseline = TRUE; is_baseline = TRUE;
...@@ -529,7 +547,10 @@ write_frame_header (j_compress_ptr cinfo) ...@@ -529,7 +547,10 @@ write_frame_header (j_compress_ptr cinfo)
/* Emit the proper SOF marker */ /* Emit the proper SOF marker */
if (cinfo->arith_code) { if (cinfo->arith_code) {
emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF10); /* SOF code for progressive arithmetic */
else
emit_sof(cinfo, M_SOF9); /* SOF code for sequential arithmetic */
} else { } else {
if (cinfo->progressive_mode) if (cinfo->progressive_mode)
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
...@@ -538,6 +559,10 @@ write_frame_header (j_compress_ptr cinfo) ...@@ -538,6 +559,10 @@ write_frame_header (j_compress_ptr cinfo)
else else
emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */ emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
} }
/* Check to emit pseudo SOS marker */
if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE)
emit_pseudo_sos(cinfo);
} }
...@@ -566,21 +591,14 @@ write_scan_header (j_compress_ptr cinfo) ...@@ -566,21 +591,14 @@ write_scan_header (j_compress_ptr cinfo)
*/ */
for (i = 0; i < cinfo->comps_in_scan; i++) { for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i]; compptr = cinfo->cur_comp_info[i];
if (cinfo->progressive_mode) { /* DC needs no table for refinement scan */
/* Progressive mode: only DC or only AC tables are used in one scan */ if (cinfo->Ss == 0 && cinfo->Ah == 0)
if (cinfo->Ss == 0) {
if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
} else {
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
}
} else {
/* Sequential mode: need both DC and AC tables */
emit_dht(cinfo, compptr->dc_tbl_no, FALSE); emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
/* AC needs no table when not present */
if (cinfo->Se)
emit_dht(cinfo, compptr->ac_tbl_no, TRUE); emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
} }
} }
}
/* Emit DRI if required --- note that DRI value could change for each scan. /* Emit DRI if required --- note that DRI value could change for each scan.
* We avoid wasting space with unnecessary DRIs, however. * We avoid wasting space with unnecessary DRIs, however.
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* jcmaster.c * jcmaster.c
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
...@@ -42,23 +43,220 @@ typedef my_comp_master * my_master_ptr; ...@@ -42,23 +43,220 @@ typedef my_comp_master * my_master_ptr;
* Support routines that do various essential calculations. * Support routines that do various essential calculations.
*/ */
/*
* Compute JPEG image dimensions and related values.
* NOTE: this is exported for possible use by application.
* Hence it mustn't do anything that can't be done twice.
*/
GLOBAL(void)
jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
/* Do computations that are needed before master selection phase */
{
#ifdef DCT_SCALING_SUPPORTED
/* Sanity check on input image dimensions to prevent overflow in
* following calculation.
* We do check jpeg_width and jpeg_height in initial_setup below,
* but image_width and image_height can come from arbitrary data,
* and we need some space for multiplication by block_size.
*/
if (((long) cinfo->image_width >> 24) || ((long) cinfo->image_height >> 24))
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
/* Compute actual JPEG image dimensions and DCT scaling choices. */
if (cinfo->scale_num >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/1 scaling */
cinfo->jpeg_width = cinfo->image_width * cinfo->block_size;
cinfo->jpeg_height = cinfo->image_height * cinfo->block_size;
cinfo->min_DCT_h_scaled_size = 1;
cinfo->min_DCT_v_scaled_size = 1;
} else if (cinfo->scale_num * 2 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/2 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 2L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 2L);
cinfo->min_DCT_h_scaled_size = 2;
cinfo->min_DCT_v_scaled_size = 2;
} else if (cinfo->scale_num * 3 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/3 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 3L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 3L);
cinfo->min_DCT_h_scaled_size = 3;
cinfo->min_DCT_v_scaled_size = 3;
} else if (cinfo->scale_num * 4 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/4 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 4L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 4L);
cinfo->min_DCT_h_scaled_size = 4;
cinfo->min_DCT_v_scaled_size = 4;
} else if (cinfo->scale_num * 5 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/5 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 5L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 5L);
cinfo->min_DCT_h_scaled_size = 5;
cinfo->min_DCT_v_scaled_size = 5;
} else if (cinfo->scale_num * 6 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/6 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 6L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 6L);
cinfo->min_DCT_h_scaled_size = 6;
cinfo->min_DCT_v_scaled_size = 6;
} else if (cinfo->scale_num * 7 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/7 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 7L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 7L);
cinfo->min_DCT_h_scaled_size = 7;
cinfo->min_DCT_v_scaled_size = 7;
} else if (cinfo->scale_num * 8 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/8 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 8L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 8L);
cinfo->min_DCT_h_scaled_size = 8;
cinfo->min_DCT_v_scaled_size = 8;
} else if (cinfo->scale_num * 9 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/9 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 9L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 9L);
cinfo->min_DCT_h_scaled_size = 9;
cinfo->min_DCT_v_scaled_size = 9;
} else if (cinfo->scale_num * 10 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/10 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 10L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 10L);
cinfo->min_DCT_h_scaled_size = 10;
cinfo->min_DCT_v_scaled_size = 10;
} else if (cinfo->scale_num * 11 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/11 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 11L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 11L);
cinfo->min_DCT_h_scaled_size = 11;
cinfo->min_DCT_v_scaled_size = 11;
} else if (cinfo->scale_num * 12 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/12 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 12L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 12L);
cinfo->min_DCT_h_scaled_size = 12;
cinfo->min_DCT_v_scaled_size = 12;
} else if (cinfo->scale_num * 13 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/13 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 13L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 13L);
cinfo->min_DCT_h_scaled_size = 13;
cinfo->min_DCT_v_scaled_size = 13;
} else if (cinfo->scale_num * 14 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/14 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 14L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 14L);
cinfo->min_DCT_h_scaled_size = 14;
cinfo->min_DCT_v_scaled_size = 14;
} else if (cinfo->scale_num * 15 >= cinfo->scale_denom * cinfo->block_size) {
/* Provide block_size/15 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 15L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 15L);
cinfo->min_DCT_h_scaled_size = 15;
cinfo->min_DCT_v_scaled_size = 15;
} else {
/* Provide block_size/16 scaling */
cinfo->jpeg_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 16L);
cinfo->jpeg_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 16L);
cinfo->min_DCT_h_scaled_size = 16;
cinfo->min_DCT_v_scaled_size = 16;
}
#else /* !DCT_SCALING_SUPPORTED */
/* Hardwire it to "no scaling" */
cinfo->jpeg_width = cinfo->image_width;
cinfo->jpeg_height = cinfo->image_height;
cinfo->min_DCT_h_scaled_size = DCTSIZE;
cinfo->min_DCT_v_scaled_size = DCTSIZE;
#endif /* DCT_SCALING_SUPPORTED */
}
LOCAL(void)
jpeg_calc_trans_dimensions (j_compress_ptr cinfo)
{
if (cinfo->min_DCT_h_scaled_size != cinfo->min_DCT_v_scaled_size)
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
cinfo->min_DCT_h_scaled_size, cinfo->min_DCT_v_scaled_size);
cinfo->block_size = cinfo->min_DCT_h_scaled_size;
}
LOCAL(void) LOCAL(void)
initial_setup (j_compress_ptr cinfo) initial_setup (j_compress_ptr cinfo, boolean transcode_only)
/* Do computations that are needed before master selection phase */ /* Do computations that are needed before master selection phase */
{ {
int ci; int ci, ssize;
jpeg_component_info *compptr; jpeg_component_info *compptr;
long samplesperrow; long samplesperrow;
JDIMENSION jd_samplesperrow; JDIMENSION jd_samplesperrow;
if (transcode_only)
jpeg_calc_trans_dimensions(cinfo);
else
jpeg_calc_jpeg_dimensions(cinfo);
/* Sanity check on block_size */
if (cinfo->block_size < 1 || cinfo->block_size > 16)
ERREXIT2(cinfo, JERR_BAD_DCTSIZE, cinfo->block_size, cinfo->block_size);
/* Derive natural_order from block_size */
switch (cinfo->block_size) {
case 2: cinfo->natural_order = jpeg_natural_order2; break;
case 3: cinfo->natural_order = jpeg_natural_order3; break;
case 4: cinfo->natural_order = jpeg_natural_order4; break;
case 5: cinfo->natural_order = jpeg_natural_order5; break;
case 6: cinfo->natural_order = jpeg_natural_order6; break;
case 7: cinfo->natural_order = jpeg_natural_order7; break;
default: cinfo->natural_order = jpeg_natural_order; break;
}
/* Derive lim_Se from block_size */
cinfo->lim_Se = cinfo->block_size < DCTSIZE ?
cinfo->block_size * cinfo->block_size - 1 : DCTSIZE2-1;
/* Sanity check on image dimensions */ /* Sanity check on image dimensions */
if (cinfo->image_height <= 0 || cinfo->image_width <= 0 if (cinfo->jpeg_height <= 0 || cinfo->jpeg_width <= 0 ||
|| cinfo->num_components <= 0 || cinfo->input_components <= 0) cinfo->num_components <= 0 || cinfo->input_components <= 0)
ERREXIT(cinfo, JERR_EMPTY_IMAGE); ERREXIT(cinfo, JERR_EMPTY_IMAGE);
/* Make sure image isn't bigger than I can handle */ /* Make sure image isn't bigger than I can handle */
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || if ((long) cinfo->jpeg_height > (long) JPEG_MAX_DIMENSION ||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) (long) cinfo->jpeg_width > (long) JPEG_MAX_DIMENSION)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
/* Width of an input scanline must be representable as JDIMENSION. */ /* Width of an input scanline must be representable as JDIMENSION. */
...@@ -95,22 +293,52 @@ initial_setup (j_compress_ptr cinfo) ...@@ -95,22 +293,52 @@ initial_setup (j_compress_ptr cinfo)
ci++, compptr++) { ci++, compptr++) {
/* Fill in the correct component_index value; don't rely on application */ /* Fill in the correct component_index value; don't rely on application */
compptr->component_index = ci; compptr->component_index = ci;
/* For compression, we never do DCT scaling. */ /* In selecting the actual DCT scaling for each component, we try to
compptr->DCT_scaled_size = DCTSIZE; * scale down the chroma components via DCT scaling rather than downsampling.
* This saves time if the downsampler gets to use 1:1 scaling.
* Note this code adapts subsampling ratios which are powers of 2.
*/
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_h_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
ssize = 1;
#ifdef DCT_SCALING_SUPPORTED
while (cinfo->min_DCT_v_scaled_size * ssize <=
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
ssize = ssize * 2;
}
#endif
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
/* We don't support DCT ratios larger than 2. */
if (compptr->DCT_h_scaled_size > compptr->DCT_v_scaled_size * 2)
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
/* Size in DCT blocks */ /* Size in DCT blocks */
compptr->width_in_blocks = (JDIMENSION) compptr->width_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, jdiv_round_up((long) cinfo->jpeg_width * (long) compptr->h_samp_factor,
(long) (cinfo->max_h_samp_factor * DCTSIZE)); (long) (cinfo->max_h_samp_factor * cinfo->block_size));
compptr->height_in_blocks = (JDIMENSION) compptr->height_in_blocks = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, jdiv_round_up((long) cinfo->jpeg_height * (long) compptr->v_samp_factor,
(long) (cinfo->max_v_samp_factor * DCTSIZE)); (long) (cinfo->max_v_samp_factor * cinfo->block_size));
/* Size in samples */ /* Size in samples */
compptr->downsampled_width = (JDIMENSION) compptr->downsampled_width = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, jdiv_round_up((long) cinfo->jpeg_width *
(long) cinfo->max_h_samp_factor); (long) (compptr->h_samp_factor * compptr->DCT_h_scaled_size),
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
compptr->downsampled_height = (JDIMENSION) compptr->downsampled_height = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, jdiv_round_up((long) cinfo->jpeg_height *
(long) cinfo->max_v_samp_factor); (long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size),
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
/* Mark component needed (this flag isn't actually used for compression) */ /* Mark component needed (this flag isn't actually used for compression) */
compptr->component_needed = TRUE; compptr->component_needed = TRUE;
} }
...@@ -119,8 +347,8 @@ initial_setup (j_compress_ptr cinfo) ...@@ -119,8 +347,8 @@ initial_setup (j_compress_ptr cinfo)
* main controller will call coefficient controller). * main controller will call coefficient controller).
*/ */
cinfo->total_iMCU_rows = (JDIMENSION) cinfo->total_iMCU_rows = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, jdiv_round_up((long) cinfo->jpeg_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE)); (long) (cinfo->max_v_samp_factor * cinfo->block_size));
} }
...@@ -135,7 +363,7 @@ validate_script (j_compress_ptr cinfo) ...@@ -135,7 +363,7 @@ validate_script (j_compress_ptr cinfo)
const jpeg_scan_info * scanptr; const jpeg_scan_info * scanptr;
int scanno, ncomps, ci, coefi, thisi; int scanno, ncomps, ci, coefi, thisi;
int Ss, Se, Ah, Al; int Ss, Se, Ah, Al;
int component_sent[MAX_COMPONENTS]; boolean component_sent[MAX_COMPONENTS];
#ifdef C_PROGRESSIVE_SUPPORTED #ifdef C_PROGRESSIVE_SUPPORTED
int * last_bitpos_ptr; int * last_bitpos_ptr;
int last_bitpos[MAX_COMPONENTS][DCTSIZE2]; int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
...@@ -260,6 +488,39 @@ validate_script (j_compress_ptr cinfo) ...@@ -260,6 +488,39 @@ validate_script (j_compress_ptr cinfo)
} }
} }
LOCAL(void)
reduce_script (j_compress_ptr cinfo)
/* Adapt scan script for use with reduced block size;
* assume that script has been validated before.
*/
{
jpeg_scan_info * scanptr;
int idxout, idxin;
/* Circumvent const declaration for this function */
scanptr = (jpeg_scan_info *) cinfo->scan_info;
idxout = 0;
for (idxin = 0; idxin < cinfo->num_scans; idxin++) {
/* After skipping, idxout becomes smaller than idxin */
if (idxin != idxout)
/* Copy rest of data;
* note we stay in given chunk of allocated memory.
*/
scanptr[idxout] = scanptr[idxin];
if (scanptr[idxout].Ss > cinfo->lim_Se)
/* Entire scan out of range - skip this entry */
continue;
if (scanptr[idxout].Se > cinfo->lim_Se)
/* Limit scan to end of block */
scanptr[idxout].Se = cinfo->lim_Se;
idxout++;
}
cinfo->num_scans = idxout;
}
#endif /* C_MULTISCAN_FILES_SUPPORTED */ #endif /* C_MULTISCAN_FILES_SUPPORTED */
...@@ -280,10 +541,13 @@ select_scan_parameters (j_compress_ptr cinfo) ...@@ -280,10 +541,13 @@ select_scan_parameters (j_compress_ptr cinfo)
cinfo->cur_comp_info[ci] = cinfo->cur_comp_info[ci] =
&cinfo->comp_info[scanptr->component_index[ci]]; &cinfo->comp_info[scanptr->component_index[ci]];
} }
if (cinfo->progressive_mode) {
cinfo->Ss = scanptr->Ss; cinfo->Ss = scanptr->Ss;
cinfo->Se = scanptr->Se; cinfo->Se = scanptr->Se;
cinfo->Ah = scanptr->Ah; cinfo->Ah = scanptr->Ah;
cinfo->Al = scanptr->Al; cinfo->Al = scanptr->Al;
return;
}
} }
else else
#endif #endif
...@@ -296,11 +560,11 @@ select_scan_parameters (j_compress_ptr cinfo) ...@@ -296,11 +560,11 @@ select_scan_parameters (j_compress_ptr cinfo)
for (ci = 0; ci < cinfo->num_components; ci++) { for (ci = 0; ci < cinfo->num_components; ci++) {
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci]; cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
} }
}
cinfo->Ss = 0; cinfo->Ss = 0;
cinfo->Se = DCTSIZE2-1; cinfo->Se = cinfo->block_size * cinfo->block_size - 1;
cinfo->Ah = 0; cinfo->Ah = 0;
cinfo->Al = 0; cinfo->Al = 0;
}
} }
...@@ -325,7 +589,7 @@ per_scan_setup (j_compress_ptr cinfo) ...@@ -325,7 +589,7 @@ per_scan_setup (j_compress_ptr cinfo)
compptr->MCU_width = 1; compptr->MCU_width = 1;
compptr->MCU_height = 1; compptr->MCU_height = 1;
compptr->MCU_blocks = 1; compptr->MCU_blocks = 1;
compptr->MCU_sample_width = DCTSIZE; compptr->MCU_sample_width = compptr->DCT_h_scaled_size;
compptr->last_col_width = 1; compptr->last_col_width = 1;
/* For noninterleaved scans, it is convenient to define last_row_height /* For noninterleaved scans, it is convenient to define last_row_height
* as the number of block rows present in the last iMCU row. * as the number of block rows present in the last iMCU row.
...@@ -347,11 +611,11 @@ per_scan_setup (j_compress_ptr cinfo) ...@@ -347,11 +611,11 @@ per_scan_setup (j_compress_ptr cinfo)
/* Overall image size in MCUs */ /* Overall image size in MCUs */
cinfo->MCUs_per_row = (JDIMENSION) cinfo->MCUs_per_row = (JDIMENSION)
jdiv_round_up((long) cinfo->image_width, jdiv_round_up((long) cinfo->jpeg_width,
(long) (cinfo->max_h_samp_factor*DCTSIZE)); (long) (cinfo->max_h_samp_factor * cinfo->block_size));
cinfo->MCU_rows_in_scan = (JDIMENSION) cinfo->MCU_rows_in_scan = (JDIMENSION)
jdiv_round_up((long) cinfo->image_height, jdiv_round_up((long) cinfo->jpeg_height,
(long) (cinfo->max_v_samp_factor*DCTSIZE)); (long) (cinfo->max_v_samp_factor * cinfo->block_size));
cinfo->blocks_in_MCU = 0; cinfo->blocks_in_MCU = 0;
...@@ -361,7 +625,7 @@ per_scan_setup (j_compress_ptr cinfo) ...@@ -361,7 +625,7 @@ per_scan_setup (j_compress_ptr cinfo)
compptr->MCU_width = compptr->h_samp_factor; compptr->MCU_width = compptr->h_samp_factor;
compptr->MCU_height = compptr->v_samp_factor; compptr->MCU_height = compptr->v_samp_factor;
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE; compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_h_scaled_size;
/* Figure number of non-dummy blocks in last MCU column & row */ /* Figure number of non-dummy blocks in last MCU column & row */
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
if (tmp == 0) tmp = compptr->MCU_width; if (tmp == 0) tmp = compptr->MCU_width;
...@@ -433,7 +697,7 @@ prepare_for_pass (j_compress_ptr cinfo) ...@@ -433,7 +697,7 @@ prepare_for_pass (j_compress_ptr cinfo)
/* Do Huffman optimization for a scan after the first one. */ /* Do Huffman optimization for a scan after the first one. */
select_scan_parameters(cinfo); select_scan_parameters(cinfo);
per_scan_setup(cinfo); per_scan_setup(cinfo);
if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) { if (cinfo->Ss != 0 || cinfo->Ah == 0) {
(*cinfo->entropy->start_pass) (cinfo, TRUE); (*cinfo->entropy->start_pass) (cinfo, TRUE);
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
master->pub.call_pass_startup = FALSE; master->pub.call_pass_startup = FALSE;
...@@ -540,7 +804,7 @@ finish_pass_master (j_compress_ptr cinfo) ...@@ -540,7 +804,7 @@ finish_pass_master (j_compress_ptr cinfo)
*/ */
GLOBAL(void) GLOBAL(void)
jinit_c_master_control (j_compress_ptr cinfo, int transcode_only) jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
{ {
my_master_ptr master; my_master_ptr master;
...@@ -554,11 +818,13 @@ jinit_c_master_control (j_compress_ptr cinfo, int transcode_only) ...@@ -554,11 +818,13 @@ jinit_c_master_control (j_compress_ptr cinfo, int transcode_only)
master->pub.is_last_pass = FALSE; master->pub.is_last_pass = FALSE;
/* Validate parameters, determine derived values */ /* Validate parameters, determine derived values */
initial_setup(cinfo); initial_setup(cinfo, transcode_only);
if (cinfo->scan_info != NULL) { if (cinfo->scan_info != NULL) {
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
validate_script(cinfo); validate_script(cinfo);
if (cinfo->block_size < DCTSIZE)
reduce_script(cinfo);
#else #else
ERREXIT(cinfo, JERR_NOT_COMPILED); ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif #endif
...@@ -567,8 +833,10 @@ jinit_c_master_control (j_compress_ptr cinfo, int transcode_only) ...@@ -567,8 +833,10 @@ jinit_c_master_control (j_compress_ptr cinfo, int transcode_only)
cinfo->num_scans = 1; cinfo->num_scans = 1;
} }
if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */ if ((cinfo->progressive_mode || cinfo->block_size < DCTSIZE) &&
cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ !cinfo->arith_code) /* TEMPORARY HACK ??? */
/* assume default tables no good for progressive or downscale mode */
cinfo->optimize_coding = TRUE;
/* Initialize my private state */ /* Initialize my private state */
if (transcode_only) { if (transcode_only) {
......
/* jconfig.h. Generated automatically by configure. */ /* jconfig.h. Generated automatically by configure. */
/* jconfig.cfg --- source file edited by configure script */
/* see jconfig.doc for explanations */ /* see jconfig.doc for explanations */
#define HAVE_PROTOTYPES #define HAVE_PROTOTYPES
...@@ -20,7 +19,6 @@ ...@@ -20,7 +19,6 @@
#ifdef JPEG_INTERNALS #ifdef JPEG_INTERNALS
#undef RIGHT_SHIFT_IS_UNSIGNED #undef RIGHT_SHIFT_IS_UNSIGNED
#define INLINE __inline__
/* These are for configuring the JPEG memory manager. */ /* These are for configuring the JPEG memory manager. */
#undef DEFAULT_MAX_MEM #undef DEFAULT_MAX_MEM
#undef NO_MKTEMP #undef NO_MKTEMP
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* jcparam.c * jcparam.c
* *
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2008 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
...@@ -22,7 +23,7 @@ ...@@ -22,7 +23,7 @@
GLOBAL(void) GLOBAL(void)
jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table, const unsigned int *basic_table,
int scale_factor, int force_baseline) int scale_factor, boolean force_baseline)
/* Define a quantization table equal to the basic_table times /* Define a quantization table equal to the basic_table times
* a scale factor (given as a percentage). * a scale factor (given as a percentage).
* If force_baseline is TRUE, the computed quantization table entries * If force_baseline is TRUE, the computed quantization table entries
...@@ -52,7 +53,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, ...@@ -52,7 +53,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
if (force_baseline && temp > 255L) if (force_baseline && temp > 255L)
temp = 255L; /* limit to baseline range if requested */ temp = 255L; /* limit to baseline range if requested */
(*qtblptr)->quantval[i] = (unsigned short) temp; (*qtblptr)->quantval[i] = (UINT16) temp;
} }
/* Initialize sent_table FALSE so table will be written to JPEG file. */ /* Initialize sent_table FALSE so table will be written to JPEG file. */
...@@ -60,20 +61,11 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, ...@@ -60,20 +61,11 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
} }
GLOBAL(void) /* These are the sample quantization tables given in JPEG spec section K.1.
jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
int force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables
* and a straight percentage-scaling quality scale. In most cases it's better
* to use jpeg_set_quality (below); this entry point is provided for
* applications that insist on a linear percentage scaling.
*/
{
/* These are the sample quantization tables given in JPEG spec section K.1.
* The spec says that the values given produce "good" quality, and * The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality. * when divided by 2, "very good" quality.
*/ */
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
16, 11, 10, 16, 24, 40, 51, 61, 16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55, 12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56, 14, 13, 16, 24, 40, 57, 69, 56,
...@@ -82,8 +74,8 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, ...@@ -82,8 +74,8 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
24, 35, 55, 64, 81, 104, 113, 92, 24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101, 49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99 72, 92, 95, 98, 112, 100, 103, 99
}; };
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
17, 18, 24, 47, 99, 99, 99, 99, 17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99,
...@@ -92,8 +84,33 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, ...@@ -92,8 +84,33 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99 99, 99, 99, 99, 99, 99, 99, 99
}; };
GLOBAL(void)
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables
* and straight percentage-scaling quality scales.
* This entry point allows different scalings for luminance and chrominance.
*/
{
/* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
cinfo->q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
cinfo->q_scale_factor[1], force_baseline);
}
GLOBAL(void)
jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables
* and a straight percentage-scaling quality scale. In most cases it's better
* to use jpeg_set_quality (below); this entry point is provided for
* applications that insist on a linear percentage scaling.
*/
{
/* Set up two quantization tables using the specified scaling */ /* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
scale_factor, force_baseline); scale_factor, force_baseline);
...@@ -129,7 +146,7 @@ jpeg_quality_scaling (int quality) ...@@ -129,7 +146,7 @@ jpeg_quality_scaling (int quality)
GLOBAL(void) GLOBAL(void)
jpeg_set_quality (j_compress_ptr cinfo, int quality, int force_baseline) jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
/* Set or change the 'quality' (quantization) setting, using default tables. /* Set or change the 'quality' (quantization) setting, using default tables.
* This is the standard quality-adjusting entry point for typical user * This is the standard quality-adjusting entry point for typical user
* interfaces; only those who want detailed control over quantization tables * interfaces; only those who want detailed control over quantization tables
...@@ -150,7 +167,7 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, int force_baseline) ...@@ -150,7 +167,7 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, int force_baseline)
LOCAL(void) LOCAL(void)
add_huff_table (j_compress_ptr cinfo, add_huff_table (j_compress_ptr cinfo,
JHUFF_TBL **htblptr, const unsigned char *bits, const unsigned char *val) JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
/* Define a Huffman table */ /* Define a Huffman table */
{ {
int nsymbols, len; int nsymbols, len;
...@@ -171,7 +188,7 @@ add_huff_table (j_compress_ptr cinfo, ...@@ -171,7 +188,7 @@ add_huff_table (j_compress_ptr cinfo,
if (nsymbols < 1 || nsymbols > 256) if (nsymbols < 1 || nsymbols > 256)
ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(unsigned char)); MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
/* Initialize sent_table FALSE so table will be written to JPEG file. */ /* Initialize sent_table FALSE so table will be written to JPEG file. */
(*htblptr)->sent_table = FALSE; (*htblptr)->sent_table = FALSE;
...@@ -183,19 +200,19 @@ std_huff_tables (j_compress_ptr cinfo) ...@@ -183,19 +200,19 @@ std_huff_tables (j_compress_ptr cinfo)
/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
/* IMPORTANT: these are only valid for 8-bit data precision! */ /* IMPORTANT: these are only valid for 8-bit data precision! */
{ {
static const unsigned char bits_dc_luminance[17] = static const UINT8 bits_dc_luminance[17] =
{ /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
static const unsigned char val_dc_luminance[] = static const UINT8 val_dc_luminance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const unsigned char bits_dc_chrominance[17] = static const UINT8 bits_dc_chrominance[17] =
{ /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
static const unsigned char val_dc_chrominance[] = static const UINT8 val_dc_chrominance[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
static const unsigned char bits_ac_luminance[17] = static const UINT8 bits_ac_luminance[17] =
{ /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
static const unsigned char val_ac_luminance[] = static const UINT8 val_ac_luminance[] =
{ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
...@@ -218,9 +235,9 @@ std_huff_tables (j_compress_ptr cinfo) ...@@ -218,9 +235,9 @@ std_huff_tables (j_compress_ptr cinfo)
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa }; 0xf9, 0xfa };
static const unsigned char bits_ac_chrominance[17] = static const UINT8 bits_ac_chrominance[17] =
{ /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
static const unsigned char val_ac_chrominance[] = static const UINT8 val_ac_chrominance[] =
{ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
...@@ -284,6 +301,8 @@ jpeg_set_defaults (j_compress_ptr cinfo) ...@@ -284,6 +301,8 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Initialize everything not dependent on the color space */ /* Initialize everything not dependent on the color space */
cinfo->scale_num = 1; /* 1:1 scaling */
cinfo->scale_denom = 1;
cinfo->data_precision = BITS_IN_JSAMPLE; cinfo->data_precision = BITS_IN_JSAMPLE;
/* Set up two quantization tables using default quality of 75 */ /* Set up two quantization tables using default quality of 75 */
jpeg_set_quality(cinfo, 75, TRUE); jpeg_set_quality(cinfo, 75, TRUE);
...@@ -320,6 +339,9 @@ jpeg_set_defaults (j_compress_ptr cinfo) ...@@ -320,6 +339,9 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* By default, use the simpler non-cosited sampling alignment */ /* By default, use the simpler non-cosited sampling alignment */
cinfo->CCIR601_sampling = FALSE; cinfo->CCIR601_sampling = FALSE;
/* By default, apply fancy downsampling */
cinfo->do_fancy_downsampling = TRUE;
/* No input smoothing */ /* No input smoothing */
cinfo->smoothing_factor = 0; cinfo->smoothing_factor = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment