mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 06:42:08 +00:00
- use stb-image for JPEG decoding.
the statically provided library did not provide any advantage over it whatsoever and even libjpeg-turbo's better performance cannot really play out here so ease of use and getting rid of a dependency wins.
This commit is contained in:
parent
d0a955fef0
commit
4baabf98c4
45 changed files with 5 additions and 23544 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,3 +30,4 @@
|
||||||
/build2
|
/build2
|
||||||
/build_vc2019-64
|
/build_vc2019-64
|
||||||
/build_vc2019-32
|
/build_vc2019-32
|
||||||
|
/build__
|
||||||
|
|
|
@ -214,7 +214,6 @@ endmacro()
|
||||||
option( NO_OPENAL "Disable OpenAL sound support" OFF )
|
option( NO_OPENAL "Disable OpenAL sound support" OFF )
|
||||||
|
|
||||||
find_package( BZip2 )
|
find_package( BZip2 )
|
||||||
find_package( JPEG )
|
|
||||||
find_package( VPX )
|
find_package( VPX )
|
||||||
find_package( ZLIB )
|
find_package( ZLIB )
|
||||||
find_package( WebP )
|
find_package( WebP )
|
||||||
|
@ -349,7 +348,6 @@ set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_C_F
|
||||||
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
||||||
|
|
||||||
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
||||||
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
|
||||||
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
||||||
option(FORCE_INTERNAL_ASMJIT "Use internal asmjit" ON)
|
option(FORCE_INTERNAL_ASMJIT "Use internal asmjit" ON)
|
||||||
mark_as_advanced( FORCE_INTERNAL_ASMJIT )
|
mark_as_advanced( FORCE_INTERNAL_ASMJIT )
|
||||||
|
@ -401,16 +399,6 @@ if( ${HAVE_VM_JIT} )
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if( JPEG_FOUND AND NOT FORCE_INTERNAL_JPEG )
|
|
||||||
message( STATUS "Using system jpeg library, includes found at ${JPEG_INCLUDE_DIR}" )
|
|
||||||
else()
|
|
||||||
message( STATUS "Using internal jpeg library" )
|
|
||||||
add_subdirectory( libraries/jpeg )
|
|
||||||
set( JPEG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/jpeg )
|
|
||||||
set( JPEG_LIBRARIES jpeg )
|
|
||||||
set( JPEG_LIBRARY jpeg )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
if( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
||||||
message( STATUS "Using system bzip2 library, includes found at ${BZIP2_INCLUDE_DIR}" )
|
message( STATUS "Using system bzip2 library, includes found at ${BZIP2_INCLUDE_DIR}" )
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
cmake_minimum_required( VERSION 3.1.0 )
|
|
||||||
|
|
||||||
make_release_only()
|
|
||||||
|
|
||||||
if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE )
|
|
||||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -fomit-frame-pointer" )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library( jpeg STATIC
|
|
||||||
jaricom.c
|
|
||||||
jcomapi.c
|
|
||||||
jdapimin.c
|
|
||||||
jdapistd.c
|
|
||||||
jdarith.c
|
|
||||||
jdatasrc.c
|
|
||||||
jdcoefct.c
|
|
||||||
jdcolor.c
|
|
||||||
jddctmgr.c
|
|
||||||
jdhuff.c
|
|
||||||
jdinput.c
|
|
||||||
jdmainct.c
|
|
||||||
jdmarker.c
|
|
||||||
jdmaster.c
|
|
||||||
jdmerge.c
|
|
||||||
jdpostct.c
|
|
||||||
jdsample.c
|
|
||||||
jerror.c
|
|
||||||
jidctflt.c
|
|
||||||
jidctfst.c
|
|
||||||
jidctint.c
|
|
||||||
jmemansi.c
|
|
||||||
jmemmgr.c
|
|
||||||
jquant1.c
|
|
||||||
jquant2.c
|
|
||||||
jutils.c )
|
|
||||||
target_link_libraries( jpeg )
|
|
|
@ -1,378 +0,0 @@
|
||||||
The Independent JPEG Group's JPEG software
|
|
||||||
==========================================
|
|
||||||
|
|
||||||
README for release 9c of 14-Jan-2018
|
|
||||||
====================================
|
|
||||||
|
|
||||||
This distribution contains the ninth public release of the Independent JPEG
|
|
||||||
Group's free JPEG software. You are welcome to redistribute this software and
|
|
||||||
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
|
|
||||||
|
|
||||||
This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone,
|
|
||||||
Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson,
|
|
||||||
Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers,
|
|
||||||
and other members of the Independent JPEG Group.
|
|
||||||
|
|
||||||
IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee
|
|
||||||
(previously known as JPEG, together with ITU-T SG16).
|
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION ROADMAP
|
|
||||||
=====================
|
|
||||||
|
|
||||||
This file contains the following sections:
|
|
||||||
|
|
||||||
OVERVIEW General description of JPEG and the IJG software.
|
|
||||||
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
|
|
||||||
REFERENCES Where to learn more about JPEG.
|
|
||||||
ARCHIVE LOCATIONS Where to find newer versions of this software.
|
|
||||||
ACKNOWLEDGMENTS Special thanks.
|
|
||||||
FILE FORMAT WARS Software *not* to get.
|
|
||||||
TO DO Plans for future IJG releases.
|
|
||||||
|
|
||||||
Other documentation files in the distribution are:
|
|
||||||
|
|
||||||
User documentation:
|
|
||||||
install.txt How to configure and install the IJG software.
|
|
||||||
usage.txt Usage instructions for cjpeg, djpeg, jpegtran,
|
|
||||||
rdjpgcom, and wrjpgcom.
|
|
||||||
*.1 Unix-style man pages for programs (same info as usage.txt).
|
|
||||||
wizard.txt Advanced usage instructions for JPEG wizards only.
|
|
||||||
change.log Version-to-version change highlights.
|
|
||||||
Programmer and internal documentation:
|
|
||||||
libjpeg.txt How to use the JPEG library in your own programs.
|
|
||||||
example.c Sample code for calling the JPEG library.
|
|
||||||
structure.txt Overview of the JPEG library's internal structure.
|
|
||||||
filelist.txt Road map of IJG files.
|
|
||||||
coderules.txt Coding style rules --- please read if you contribute code.
|
|
||||||
|
|
||||||
Please read at least the files install.txt and usage.txt. Some information
|
|
||||||
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
|
|
||||||
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
|
|
||||||
|
|
||||||
If you want to understand how the JPEG code works, we suggest reading one or
|
|
||||||
more of the REFERENCES, then looking at the documentation files (in roughly
|
|
||||||
the order listed) before diving into the code.
|
|
||||||
|
|
||||||
|
|
||||||
OVERVIEW
|
|
||||||
========
|
|
||||||
|
|
||||||
This package contains C software to implement JPEG image encoding, decoding,
|
|
||||||
and transcoding. JPEG (pronounced "jay-peg") is a standardized compression
|
|
||||||
method for full-color and grayscale images.
|
|
||||||
|
|
||||||
This software implements JPEG baseline, extended-sequential, and progressive
|
|
||||||
compression processes. Provision is made for supporting all variants of these
|
|
||||||
processes, although some uncommon parameter settings aren't implemented yet.
|
|
||||||
We have made no provision for supporting the hierarchical or lossless
|
|
||||||
processes defined in the standard.
|
|
||||||
|
|
||||||
We provide a set of library routines for reading and writing JPEG image files,
|
|
||||||
plus two sample applications "cjpeg" and "djpeg", which use the library to
|
|
||||||
perform conversion between JPEG and some other popular image file formats.
|
|
||||||
The library is intended to be reused in other applications.
|
|
||||||
|
|
||||||
In order to support file conversion and viewing software, we have included
|
|
||||||
considerable functionality beyond the bare JPEG coding/decoding capability;
|
|
||||||
for example, the color quantization modules are not strictly part of JPEG
|
|
||||||
decoding, but they are essential for output to colormapped file formats or
|
|
||||||
colormapped displays. These extra functions can be compiled out of the
|
|
||||||
library if not required for a particular application.
|
|
||||||
|
|
||||||
We have also included "jpegtran", a utility for lossless transcoding between
|
|
||||||
different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple
|
|
||||||
applications for inserting and extracting textual comments in JFIF files.
|
|
||||||
|
|
||||||
The emphasis in designing this software has been on achieving portability and
|
|
||||||
flexibility, while also making it fast enough to be useful. In particular,
|
|
||||||
the software is not intended to be read as a tutorial on JPEG. (See the
|
|
||||||
REFERENCES section for introductory material.) Rather, it is intended to
|
|
||||||
be reliable, portable, industrial-strength code. We do not claim to have
|
|
||||||
achieved that goal in every aspect of the software, but we strive for it.
|
|
||||||
|
|
||||||
We welcome the use of this software as a component of commercial products.
|
|
||||||
No royalty is required, but we do ask for an acknowledgement in product
|
|
||||||
documentation, as described under LEGAL ISSUES.
|
|
||||||
|
|
||||||
|
|
||||||
LEGAL ISSUES
|
|
||||||
============
|
|
||||||
|
|
||||||
In plain English:
|
|
||||||
|
|
||||||
1. We don't promise that this software works. (But if you find any bugs,
|
|
||||||
please let us know!)
|
|
||||||
2. You can use this software for whatever you want. You don't have to pay us.
|
|
||||||
3. You may not pretend that you wrote this software. If you use it in a
|
|
||||||
program, you must acknowledge somewhere in your documentation that
|
|
||||||
you've used the IJG code.
|
|
||||||
|
|
||||||
In legalese:
|
|
||||||
|
|
||||||
The authors make NO WARRANTY or representation, either express or implied,
|
|
||||||
with respect to this software, its quality, accuracy, merchantability, or
|
|
||||||
fitness for a particular purpose. This software is provided "AS IS", and you,
|
|
||||||
its user, assume the entire risk as to its quality and accuracy.
|
|
||||||
|
|
||||||
This software is copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding.
|
|
||||||
All Rights Reserved except as specified below.
|
|
||||||
|
|
||||||
Permission is hereby granted to use, copy, modify, and distribute this
|
|
||||||
software (or portions thereof) for any purpose, without fee, subject to these
|
|
||||||
conditions:
|
|
||||||
(1) If any part of the source code for this software is distributed, then this
|
|
||||||
README file must be included, with this copyright and no-warranty notice
|
|
||||||
unaltered; and any additions, deletions, or changes to the original files
|
|
||||||
must be clearly indicated in accompanying documentation.
|
|
||||||
(2) If only executable code is distributed, then the accompanying
|
|
||||||
documentation must state that "this software is based in part on the work of
|
|
||||||
the Independent JPEG Group".
|
|
||||||
(3) Permission for use of this software is granted only if the user accepts
|
|
||||||
full responsibility for any undesirable consequences; the authors accept
|
|
||||||
NO LIABILITY for damages of any kind.
|
|
||||||
|
|
||||||
These conditions apply to any software derived from or based on the IJG code,
|
|
||||||
not just to the unmodified library. If you use our work, you ought to
|
|
||||||
acknowledge us.
|
|
||||||
|
|
||||||
Permission is NOT granted for the use of any IJG author's name or company name
|
|
||||||
in advertising or publicity relating to this software or products derived from
|
|
||||||
it. This software may be referred to only as "the Independent JPEG Group's
|
|
||||||
software".
|
|
||||||
|
|
||||||
We specifically permit and encourage the use of this software as the basis of
|
|
||||||
commercial products, provided that all warranty or liability claims are
|
|
||||||
assumed by the product vendor.
|
|
||||||
|
|
||||||
|
|
||||||
The Unix configuration script "configure" was produced with GNU Autoconf.
|
|
||||||
It is copyright by the Free Software Foundation but is freely distributable.
|
|
||||||
The same holds for its supporting scripts (config.guess, config.sub,
|
|
||||||
ltmain.sh). Another support script, install-sh, is copyright by X Consortium
|
|
||||||
but is also freely distributable.
|
|
||||||
|
|
||||||
The IJG distribution formerly included code to read and write GIF files.
|
|
||||||
To avoid entanglement with the Unisys LZW patent (now expired), GIF reading
|
|
||||||
support has been removed altogether, and the GIF writer has been simplified
|
|
||||||
to produce "uncompressed GIFs". This technique does not use the LZW
|
|
||||||
algorithm; the resulting GIF files are larger than usual, but are readable
|
|
||||||
by all standard GIF decoders.
|
|
||||||
|
|
||||||
|
|
||||||
REFERENCES
|
|
||||||
==========
|
|
||||||
|
|
||||||
We recommend reading one or more of these references before trying to
|
|
||||||
understand the innards of the JPEG software.
|
|
||||||
|
|
||||||
The best short technical introduction to the JPEG compression algorithm is
|
|
||||||
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
|
|
||||||
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
|
|
||||||
(Adjacent articles in that issue discuss MPEG motion picture compression,
|
|
||||||
applications of JPEG, and related topics.) If you don't have the CACM issue
|
|
||||||
handy, a PDF file containing a revised version of Wallace's article is
|
|
||||||
available at http://www.ijg.org/files/Wallace.JPEG.pdf. The file (actually
|
|
||||||
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
|
|
||||||
omits the sample images that appeared in CACM, but it includes corrections
|
|
||||||
and some added material. Note: the Wallace article is copyright ACM and IEEE,
|
|
||||||
and it may not be used for commercial purposes.
|
|
||||||
|
|
||||||
A somewhat less technical, more leisurely introduction to JPEG can be found in
|
|
||||||
"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
|
|
||||||
M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
|
|
||||||
good explanations and example C code for a multitude of compression methods
|
|
||||||
including JPEG. It is an excellent source if you are comfortable reading C
|
|
||||||
code but don't know much about data compression in general. The book's JPEG
|
|
||||||
sample code is far from industrial-strength, but when you are ready to look
|
|
||||||
at a full implementation, you've got one here...
|
|
||||||
|
|
||||||
The best currently available description of JPEG is the textbook "JPEG Still
|
|
||||||
Image Data Compression Standard" by William B. Pennebaker and Joan L.
|
|
||||||
Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.
|
|
||||||
Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG
|
|
||||||
standards (DIS 10918-1 and draft DIS 10918-2).
|
|
||||||
Although this is by far the most detailed and comprehensive exposition of
|
|
||||||
JPEG publicly available, we point out that it is still missing an explanation
|
|
||||||
of the most essential properties and algorithms of the underlying DCT
|
|
||||||
technology.
|
|
||||||
If you think that you know about DCT-based JPEG after reading this book,
|
|
||||||
then you are in delusion. The real fundamentals and corresponding potential
|
|
||||||
of DCT-based JPEG are not publicly known so far, and that is the reason for
|
|
||||||
all the mistaken developments taking place in the image coding domain.
|
|
||||||
|
|
||||||
The original JPEG standard is divided into two parts, Part 1 being the actual
|
|
||||||
specification, while Part 2 covers compliance testing methods. Part 1 is
|
|
||||||
titled "Digital Compression and Coding of Continuous-tone Still Images,
|
|
||||||
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
|
|
||||||
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
|
|
||||||
Continuous-tone Still Images, Part 2: Compliance testing" and has document
|
|
||||||
numbers ISO/IEC IS 10918-2, ITU-T T.83.
|
|
||||||
IJG JPEG 8 introduced an implementation of the JPEG SmartScale extension
|
|
||||||
which is specified in two documents: A contributed document at ITU and ISO
|
|
||||||
with title "ITU-T JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced
|
|
||||||
Image Coding", April 2006, Geneva, Switzerland. The latest version of this
|
|
||||||
document is Revision 3. And a contributed document ISO/IEC JTC1/SC29/WG1 N
|
|
||||||
5799 with title "Evolution of JPEG", June/July 2011, Berlin, Germany.
|
|
||||||
IJG JPEG 9 introduces a reversible color transform for improved lossless
|
|
||||||
compression which is described in a contributed document ISO/IEC JTC1/SC29/
|
|
||||||
WG1 N 6080 with title "JPEG 9 Lossless Coding", June/July 2012, Paris,
|
|
||||||
France.
|
|
||||||
|
|
||||||
The JPEG standard does not specify all details of an interchangeable file
|
|
||||||
format. For the omitted details we follow the "JFIF" conventions, version 2.
|
|
||||||
JFIF version 1 has been adopted as Recommendation ITU-T T.871 (05/2011) :
|
|
||||||
Information technology - Digital compression and coding of continuous-tone
|
|
||||||
still images: JPEG File Interchange Format (JFIF). It is available as a
|
|
||||||
free download in PDF file format from http://www.itu.int/rec/T-REC-T.871.
|
|
||||||
A PDF file of the older JFIF document is available at
|
|
||||||
http://www.w3.org/Graphics/JPEG/jfif3.pdf.
|
|
||||||
|
|
||||||
The TIFF 6.0 file format specification can be obtained by FTP from
|
|
||||||
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
|
|
||||||
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
|
|
||||||
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
|
|
||||||
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
|
|
||||||
(Compression tag 7). Copies of this Note can be obtained from
|
|
||||||
http://www.ijg.org/files/. It is expected that the next revision
|
|
||||||
of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
|
|
||||||
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
|
|
||||||
uses our library to implement TIFF/JPEG per the Note.
|
|
||||||
|
|
||||||
|
|
||||||
ARCHIVE LOCATIONS
|
|
||||||
=================
|
|
||||||
|
|
||||||
The "official" archive site for this software is www.ijg.org.
|
|
||||||
The most recent released version can always be found there in
|
|
||||||
directory "files". This particular version will be archived as
|
|
||||||
http://www.ijg.org/files/jpegsrc.v9c.tar.gz, and in Windows-compatible
|
|
||||||
"zip" archive format as http://www.ijg.org/files/jpegsr9c.zip.
|
|
||||||
|
|
||||||
The JPEG FAQ (Frequently Asked Questions) article is a source of some
|
|
||||||
general information about JPEG.
|
|
||||||
It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
|
|
||||||
and other news.answers archive sites, including the official news.answers
|
|
||||||
archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
|
|
||||||
If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
|
|
||||||
with body
|
|
||||||
send usenet/news.answers/jpeg-faq/part1
|
|
||||||
send usenet/news.answers/jpeg-faq/part2
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
|
|
||||||
Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
|
|
||||||
|
|
||||||
Thank to Thomas Richter and Daniel Lee for inviting me to the
|
|
||||||
ISO/IEC JTC1/SC29/WG1 (previously known as JPEG, together with ITU-T SG16)
|
|
||||||
meeting in Berlin, Germany.
|
|
||||||
|
|
||||||
Thank to John Korejwa and Massimo Ballerini for inviting me to
|
|
||||||
fruitful consultations in Boston, MA and Milan, Italy.
|
|
||||||
|
|
||||||
Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther
|
|
||||||
Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel
|
|
||||||
for corresponding business development.
|
|
||||||
|
|
||||||
Thank to Nico Zschach and Dirk Stelling of the technical support team
|
|
||||||
at the Digital Images company in Halle for providing me with extra
|
|
||||||
equipment for configuration tests.
|
|
||||||
|
|
||||||
Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful
|
|
||||||
communication about JPEG configuration in Sigma Photo Pro software.
|
|
||||||
|
|
||||||
Thank to Andrew Finkenstadt for hosting the ijg.org site.
|
|
||||||
|
|
||||||
Thank to Thomas G. Lane for the original design and development of
|
|
||||||
this singular software package.
|
|
||||||
|
|
||||||
Thank to Lars Goehler, Andreas Heinecke, Sebastian Fuss, Yvonne Roebert,
|
|
||||||
Andrej Werner, and Ulf-Dietrich Braumann for support and public relations.
|
|
||||||
|
|
||||||
|
|
||||||
FILE FORMAT WARS
|
|
||||||
================
|
|
||||||
|
|
||||||
The ISO/IEC JTC1/SC29/WG1 standards committee (previously known as JPEG,
|
|
||||||
together with ITU-T SG16) currently promotes different formats containing
|
|
||||||
the name "JPEG" which is misleading because these formats are incompatible
|
|
||||||
with original DCT-based JPEG and are based on faulty technologies.
|
|
||||||
IJG therefore does not and will not support such momentary mistakes
|
|
||||||
(see REFERENCES).
|
|
||||||
There exist also distributions under the name "OpenJPEG" promoting such
|
|
||||||
kind of formats which is misleading because they don't support original
|
|
||||||
JPEG images.
|
|
||||||
We have no sympathy for the promotion of inferior formats. Indeed, one of
|
|
||||||
the original reasons for developing this free software was to help force
|
|
||||||
convergence on common, interoperable format standards for JPEG files.
|
|
||||||
Don't use an incompatible file format!
|
|
||||||
(In any case, our decoder will remain capable of reading existing JPEG
|
|
||||||
image files indefinitely.)
|
|
||||||
|
|
||||||
The ISO committee pretends to be "responsible for the popular JPEG" in their
|
|
||||||
public reports which is not true because they don't respond to actual
|
|
||||||
requirements for the maintenance of the original JPEG specification.
|
|
||||||
Furthermore, the ISO committee pretends to "ensure interoperability" with
|
|
||||||
their standards which is not true because their "standards" support only
|
|
||||||
application-specific and proprietary use cases and contain mathematically
|
|
||||||
incorrect code.
|
|
||||||
|
|
||||||
There are currently different distributions in circulation containing the
|
|
||||||
name "libjpeg" which is misleading because they don't have the features and
|
|
||||||
are incompatible with formats supported by actual IJG libjpeg distributions.
|
|
||||||
One of those fakes is released by members of the ISO committee and just uses
|
|
||||||
the name of libjpeg for misdirection of people, similar to the abuse of the
|
|
||||||
name JPEG as described above, while having nothing in common with actual IJG
|
|
||||||
libjpeg distributions and containing mathematically incorrect code.
|
|
||||||
The other one claims to be a "derivative" or "fork" of the original libjpeg,
|
|
||||||
but violates the license conditions as described under LEGAL ISSUES above
|
|
||||||
and violates basic C programming properties.
|
|
||||||
We have no sympathy for the release of misleading, incorrect and illegal
|
|
||||||
distributions derived from obsolete code bases.
|
|
||||||
Don't use an obsolete code base!
|
|
||||||
|
|
||||||
According to the UCC (Uniform Commercial Code) law, IJG has the lawful and
|
|
||||||
legal right to foreclose on certain standardization bodies and other
|
|
||||||
institutions or corporations that knowingly perform substantial and
|
|
||||||
systematic deceptive acts and practices, fraud, theft, and damaging of the
|
|
||||||
value of the people of this planet without their knowing, willing and
|
|
||||||
intentional consent.
|
|
||||||
The titles, ownership, and rights of these institutions and all their assets
|
|
||||||
are now duly secured and held in trust for the free people of this planet.
|
|
||||||
People of the planet, on every country, may have a financial interest in
|
|
||||||
the assets of these former principals, agents, and beneficiaries of the
|
|
||||||
foreclosed institutions and corporations.
|
|
||||||
IJG asserts what is: that each man, woman, and child has unalienable value
|
|
||||||
and rights granted and deposited in them by the Creator and not any one of
|
|
||||||
the people is subordinate to any artificial principality, corporate fiction
|
|
||||||
or the special interest of another without their appropriate knowing,
|
|
||||||
willing and intentional consent made by contract or accommodation agreement.
|
|
||||||
IJG expresses that which already was.
|
|
||||||
The people have already determined and demanded that public administration
|
|
||||||
entities, national governments, and their supporting judicial systems must
|
|
||||||
be fully transparent, accountable, and liable.
|
|
||||||
IJG has secured the value for all concerned free people of the planet.
|
|
||||||
|
|
||||||
A partial list of foreclosed institutions and corporations ("Hall of Shame")
|
|
||||||
is currently prepared and will be published later.
|
|
||||||
|
|
||||||
|
|
||||||
TO DO
|
|
||||||
=====
|
|
||||||
|
|
||||||
Version 9 is the second release of a new generation JPEG standard
|
|
||||||
to overcome the limitations of the original JPEG specification,
|
|
||||||
and is the first true source reference JPEG codec.
|
|
||||||
More features are being prepared for coming releases...
|
|
||||||
|
|
||||||
Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org.
|
|
|
@ -1,153 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 )
|
|
||||||
};
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
* jcomapi.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains application interface routines that are used for both
|
|
||||||
* compression and decompression.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Abort processing of a JPEG compression or decompression operation,
|
|
||||||
* but don't destroy the object itself.
|
|
||||||
*
|
|
||||||
* For this, we merely clean up all the nonpermanent memory pools.
|
|
||||||
* Note that temp files (virtual arrays) are not allowed to belong to
|
|
||||||
* the permanent pool, so we will be able to close all temp files here.
|
|
||||||
* Closing a data source or destination, if necessary, is the application's
|
|
||||||
* responsibility.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_abort (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
int pool;
|
|
||||||
|
|
||||||
/* Do nothing if called on a not-initialized or destroyed JPEG object. */
|
|
||||||
if (cinfo->mem == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Releasing pools in reverse order might help avoid fragmentation
|
|
||||||
* with some (brain-damaged) malloc libraries.
|
|
||||||
*/
|
|
||||||
for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
|
|
||||||
(*cinfo->mem->free_pool) (cinfo, pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset overall state for possible reuse of object */
|
|
||||||
if (cinfo->is_decompressor) {
|
|
||||||
cinfo->global_state = DSTATE_START;
|
|
||||||
/* Try to keep application from accessing now-deleted marker list.
|
|
||||||
* A bit kludgy to do it here, but this is the most central place.
|
|
||||||
*/
|
|
||||||
((j_decompress_ptr) cinfo)->marker_list = NULL;
|
|
||||||
} else {
|
|
||||||
cinfo->global_state = CSTATE_START;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Destruction of a JPEG object.
|
|
||||||
*
|
|
||||||
* Everything gets deallocated except the master jpeg_compress_struct itself
|
|
||||||
* and the error manager struct. Both of these are supplied by the application
|
|
||||||
* and must be freed, if necessary, by the application. (Often they are on
|
|
||||||
* the stack and so don't need to be freed anyway.)
|
|
||||||
* Closing a data source or destination, if necessary, is the application's
|
|
||||||
* responsibility.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_destroy (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* We need only tell the memory manager to release everything. */
|
|
||||||
/* NB: mem pointer is NULL if memory mgr failed to initialize. */
|
|
||||||
if (cinfo->mem != NULL)
|
|
||||||
(*cinfo->mem->self_destruct) (cinfo);
|
|
||||||
cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */
|
|
||||||
cinfo->global_state = 0; /* mark it destroyed */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convenience routines for allocating quantization and Huffman tables.
|
|
||||||
* (Would jutils.c be a more reasonable place to put these?)
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(JQUANT_TBL *)
|
|
||||||
jpeg_alloc_quant_table (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
JQUANT_TBL *tbl;
|
|
||||||
|
|
||||||
tbl = (JQUANT_TBL *)
|
|
||||||
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL));
|
|
||||||
tbl->sent_table = FALSE; /* make sure this is false in any new table */
|
|
||||||
return tbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLOBAL(JHUFF_TBL *)
|
|
||||||
jpeg_alloc_huff_table (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
JHUFF_TBL *tbl;
|
|
||||||
|
|
||||||
tbl = (JHUFF_TBL *)
|
|
||||||
(*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
|
|
||||||
tbl->sent_table = FALSE; /* make sure this is false in any new table */
|
|
||||||
return tbl;
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
|
|
||||||
/* see jconfig.doc for explanations */
|
|
||||||
|
|
||||||
#define HAVE_PROTOTYPES
|
|
||||||
#define HAVE_UNSIGNED_CHAR
|
|
||||||
#define HAVE_UNSIGNED_SHORT
|
|
||||||
/* #define void char */
|
|
||||||
/* #define const */
|
|
||||||
#undef CHAR_IS_UNSIGNED
|
|
||||||
#define HAVE_STDDEF_H
|
|
||||||
#define HAVE_STDLIB_H
|
|
||||||
#undef NEED_BSD_STRINGS
|
|
||||||
#undef NEED_SYS_TYPES_H
|
|
||||||
|
|
||||||
/* Define "boolean" as unsigned char, not int, per Windows custom */
|
|
||||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
|
||||||
typedef unsigned char boolean;
|
|
||||||
#endif
|
|
||||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
|
||||||
|
|
||||||
#ifndef FALSE
|
|
||||||
#define FALSE 0
|
|
||||||
#endif
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JPEG_INTERNALS
|
|
||||||
|
|
||||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
|
||||||
|
|
||||||
#endif /* JPEG_INTERNALS */
|
|
|
@ -1,399 +0,0 @@
|
||||||
/*
|
|
||||||
* jdapimin.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
|
||||||
* Modified 2009-2013 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains application interface code for the decompression half
|
|
||||||
* of the JPEG library. These are the "minimum" API routines that may be
|
|
||||||
* needed in either the normal full-decompression case or the
|
|
||||||
* transcoding-only case.
|
|
||||||
*
|
|
||||||
* Most of the routines intended to be called directly by an application
|
|
||||||
* are in this file or in jdapistd.c. But also see jcomapi.c for routines
|
|
||||||
* shared by compression and decompression, and jdtrans.c for the transcoding
|
|
||||||
* case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialization of a JPEG decompression object.
|
|
||||||
* The error manager must already be set up (in case memory manager fails).
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Guard against version mismatches between library and caller. */
|
|
||||||
cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
|
|
||||||
if (version != JPEG_LIB_VERSION)
|
|
||||||
ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
|
|
||||||
if (structsize != SIZEOF(struct jpeg_decompress_struct))
|
|
||||||
ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
|
|
||||||
(int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
|
|
||||||
|
|
||||||
/* For debugging purposes, we zero the whole master structure.
|
|
||||||
* But the application has already set the err pointer, and may have set
|
|
||||||
* client_data, so we have to save and restore those fields.
|
|
||||||
* Note: if application hasn't set client_data, tools like Purify may
|
|
||||||
* complain here.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
struct jpeg_error_mgr * err = cinfo->err;
|
|
||||||
void * client_data = cinfo->client_data; /* ignore Purify complaint here */
|
|
||||||
MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
|
|
||||||
cinfo->err = err;
|
|
||||||
cinfo->client_data = client_data;
|
|
||||||
}
|
|
||||||
cinfo->is_decompressor = TRUE;
|
|
||||||
|
|
||||||
/* Initialize a memory manager instance for this object */
|
|
||||||
jinit_memory_mgr((j_common_ptr) cinfo);
|
|
||||||
|
|
||||||
/* Zero out pointers to permanent structures. */
|
|
||||||
cinfo->progress = NULL;
|
|
||||||
cinfo->src = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_QUANT_TBLS; i++)
|
|
||||||
cinfo->quant_tbl_ptrs[i] = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
|
||||||
cinfo->dc_huff_tbl_ptrs[i] = NULL;
|
|
||||||
cinfo->ac_huff_tbl_ptrs[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize marker processor so application can override methods
|
|
||||||
* for COM, APPn markers before calling jpeg_read_header.
|
|
||||||
*/
|
|
||||||
cinfo->marker_list = NULL;
|
|
||||||
jinit_marker_reader(cinfo);
|
|
||||||
|
|
||||||
/* And initialize the overall input controller. */
|
|
||||||
jinit_input_controller(cinfo);
|
|
||||||
|
|
||||||
/* OK, I'm ready */
|
|
||||||
cinfo->global_state = DSTATE_START;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Destruction of a JPEG decompression object
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_destroy_decompress (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Abort processing of a JPEG decompression operation,
|
|
||||||
* but don't destroy the object itself.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_abort_decompress (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
jpeg_abort((j_common_ptr) cinfo); /* use common routine */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set default decompression parameters.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
default_decompress_parms (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
int cid0, cid1, cid2;
|
|
||||||
|
|
||||||
/* Guess the input colorspace, and set output colorspace accordingly. */
|
|
||||||
/* Note application may override our guesses. */
|
|
||||||
switch (cinfo->num_components) {
|
|
||||||
case 1:
|
|
||||||
cinfo->jpeg_color_space = JCS_GRAYSCALE;
|
|
||||||
cinfo->out_color_space = JCS_GRAYSCALE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
cid0 = cinfo->comp_info[0].component_id;
|
|
||||||
cid1 = cinfo->comp_info[1].component_id;
|
|
||||||
cid2 = cinfo->comp_info[2].component_id;
|
|
||||||
|
|
||||||
/* First try to guess from the component IDs */
|
|
||||||
if (cid0 == 0x01 && cid1 == 0x02 && cid2 == 0x03)
|
|
||||||
cinfo->jpeg_color_space = JCS_YCbCr;
|
|
||||||
else if (cid0 == 0x01 && cid1 == 0x22 && cid2 == 0x23)
|
|
||||||
cinfo->jpeg_color_space = JCS_BG_YCC;
|
|
||||||
else if (cid0 == 0x52 && cid1 == 0x47 && cid2 == 0x42)
|
|
||||||
cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
|
|
||||||
else if (cid0 == 0x72 && cid1 == 0x67 && cid2 == 0x62)
|
|
||||||
cinfo->jpeg_color_space = JCS_BG_RGB; /* ASCII 'r', 'g', 'b' */
|
|
||||||
else if (cinfo->saw_JFIF_marker)
|
|
||||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
|
||||||
else if (cinfo->saw_Adobe_marker) {
|
|
||||||
switch (cinfo->Adobe_transform) {
|
|
||||||
case 0:
|
|
||||||
cinfo->jpeg_color_space = JCS_RGB;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
cinfo->jpeg_color_space = JCS_YCbCr;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
|
|
||||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
|
|
||||||
cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
|
|
||||||
}
|
|
||||||
/* Always guess RGB is proper output colorspace. */
|
|
||||||
cinfo->out_color_space = JCS_RGB;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
if (cinfo->saw_Adobe_marker) {
|
|
||||||
switch (cinfo->Adobe_transform) {
|
|
||||||
case 0:
|
|
||||||
cinfo->jpeg_color_space = JCS_CMYK;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
cinfo->jpeg_color_space = JCS_YCCK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
|
|
||||||
cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* No special markers, assume straight CMYK. */
|
|
||||||
cinfo->jpeg_color_space = JCS_CMYK;
|
|
||||||
}
|
|
||||||
cinfo->out_color_space = JCS_CMYK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
cinfo->jpeg_color_space = JCS_UNKNOWN;
|
|
||||||
cinfo->out_color_space = JCS_UNKNOWN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set defaults for other decompression parameters. */
|
|
||||||
cinfo->scale_num = cinfo->block_size; /* 1:1 scaling */
|
|
||||||
cinfo->scale_denom = cinfo->block_size;
|
|
||||||
cinfo->output_gamma = 1.0;
|
|
||||||
cinfo->buffered_image = FALSE;
|
|
||||||
cinfo->raw_data_out = FALSE;
|
|
||||||
cinfo->dct_method = JDCT_DEFAULT;
|
|
||||||
cinfo->do_fancy_upsampling = TRUE;
|
|
||||||
cinfo->do_block_smoothing = TRUE;
|
|
||||||
cinfo->quantize_colors = FALSE;
|
|
||||||
/* We set these in case application only sets quantize_colors. */
|
|
||||||
cinfo->dither_mode = JDITHER_FS;
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
cinfo->two_pass_quantize = TRUE;
|
|
||||||
#else
|
|
||||||
cinfo->two_pass_quantize = FALSE;
|
|
||||||
#endif
|
|
||||||
cinfo->desired_number_of_colors = 256;
|
|
||||||
cinfo->colormap = NULL;
|
|
||||||
/* Initialize for no mode change in buffered-image mode. */
|
|
||||||
cinfo->enable_1pass_quant = FALSE;
|
|
||||||
cinfo->enable_external_quant = FALSE;
|
|
||||||
cinfo->enable_2pass_quant = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decompression startup: read start of JPEG datastream to see what's there.
|
|
||||||
* Need only initialize JPEG object and supply a data source before calling.
|
|
||||||
*
|
|
||||||
* This routine will read as far as the first SOS marker (ie, actual start of
|
|
||||||
* compressed data), and will save all tables and parameters in the JPEG
|
|
||||||
* object. It will also initialize the decompression parameters to default
|
|
||||||
* values, and finally return JPEG_HEADER_OK. On return, the application may
|
|
||||||
* adjust the decompression parameters and then call jpeg_start_decompress.
|
|
||||||
* (Or, if the application only wanted to determine the image parameters,
|
|
||||||
* the data need not be decompressed. In that case, call jpeg_abort or
|
|
||||||
* jpeg_destroy to release any temporary space.)
|
|
||||||
* If an abbreviated (tables only) datastream is presented, the routine will
|
|
||||||
* return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
|
|
||||||
* re-use the JPEG object to read the abbreviated image datastream(s).
|
|
||||||
* It is unnecessary (but OK) to call jpeg_abort in this case.
|
|
||||||
* The JPEG_SUSPENDED return code only occurs if the data source module
|
|
||||||
* requests suspension of the decompressor. In this case the application
|
|
||||||
* should load more source data and then re-call jpeg_read_header to resume
|
|
||||||
* processing.
|
|
||||||
* If a non-suspending data source is used and require_image is TRUE, then the
|
|
||||||
* return code need not be inspected since only JPEG_HEADER_OK is possible.
|
|
||||||
*
|
|
||||||
* This routine is now just a front end to jpeg_consume_input, with some
|
|
||||||
* extra error checking.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(int)
|
|
||||||
jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
|
|
||||||
{
|
|
||||||
int retcode;
|
|
||||||
|
|
||||||
if (cinfo->global_state != DSTATE_START &&
|
|
||||||
cinfo->global_state != DSTATE_INHEADER)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
|
|
||||||
retcode = jpeg_consume_input(cinfo);
|
|
||||||
|
|
||||||
switch (retcode) {
|
|
||||||
case JPEG_REACHED_SOS:
|
|
||||||
retcode = JPEG_HEADER_OK;
|
|
||||||
break;
|
|
||||||
case JPEG_REACHED_EOI:
|
|
||||||
if (require_image) /* Complain if application wanted an image */
|
|
||||||
ERREXIT(cinfo, JERR_NO_IMAGE);
|
|
||||||
/* Reset to start state; it would be safer to require the application to
|
|
||||||
* call jpeg_abort, but we can't change it now for compatibility reasons.
|
|
||||||
* A side effect is to free any temporary memory (there shouldn't be any).
|
|
||||||
*/
|
|
||||||
jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
|
|
||||||
retcode = JPEG_HEADER_TABLES_ONLY;
|
|
||||||
break;
|
|
||||||
case JPEG_SUSPENDED:
|
|
||||||
/* no work */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Consume data in advance of what the decompressor requires.
|
|
||||||
* This can be called at any time once the decompressor object has
|
|
||||||
* been created and a data source has been set up.
|
|
||||||
*
|
|
||||||
* This routine is essentially a state machine that handles a couple
|
|
||||||
* of critical state-transition actions, namely initial setup and
|
|
||||||
* transition from header scanning to ready-for-start_decompress.
|
|
||||||
* All the actual input is done via the input controller's consume_input
|
|
||||||
* method.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(int)
|
|
||||||
jpeg_consume_input (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
int retcode = JPEG_SUSPENDED;
|
|
||||||
|
|
||||||
/* NB: every possible DSTATE value should be listed in this switch */
|
|
||||||
switch (cinfo->global_state) {
|
|
||||||
case DSTATE_START:
|
|
||||||
/* Start-of-datastream actions: reset appropriate modules */
|
|
||||||
(*cinfo->inputctl->reset_input_controller) (cinfo);
|
|
||||||
/* Initialize application's data source module */
|
|
||||||
(*cinfo->src->init_source) (cinfo);
|
|
||||||
cinfo->global_state = DSTATE_INHEADER;
|
|
||||||
/*FALLTHROUGH*/
|
|
||||||
case DSTATE_INHEADER:
|
|
||||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
|
||||||
if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
|
|
||||||
/* Set up default parameters based on header data */
|
|
||||||
default_decompress_parms(cinfo);
|
|
||||||
/* Set global state: ready for start_decompress */
|
|
||||||
cinfo->global_state = DSTATE_READY;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DSTATE_READY:
|
|
||||||
/* Can't advance past first SOS until start_decompress is called */
|
|
||||||
retcode = JPEG_REACHED_SOS;
|
|
||||||
break;
|
|
||||||
case DSTATE_PRELOAD:
|
|
||||||
case DSTATE_PRESCAN:
|
|
||||||
case DSTATE_SCANNING:
|
|
||||||
case DSTATE_RAW_OK:
|
|
||||||
case DSTATE_BUFIMAGE:
|
|
||||||
case DSTATE_BUFPOST:
|
|
||||||
case DSTATE_STOPPING:
|
|
||||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
}
|
|
||||||
return retcode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Have we finished reading the input file?
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(boolean)
|
|
||||||
jpeg_input_complete (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* Check for valid jpeg object */
|
|
||||||
if (cinfo->global_state < DSTATE_START ||
|
|
||||||
cinfo->global_state > DSTATE_STOPPING)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
return cinfo->inputctl->eoi_reached;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Is there more than one scan?
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(boolean)
|
|
||||||
jpeg_has_multiple_scans (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* Only valid after jpeg_read_header completes */
|
|
||||||
if (cinfo->global_state < DSTATE_READY ||
|
|
||||||
cinfo->global_state > DSTATE_STOPPING)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
return cinfo->inputctl->has_multiple_scans;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish JPEG decompression.
|
|
||||||
*
|
|
||||||
* This will normally just verify the file trailer and release temp storage.
|
|
||||||
*
|
|
||||||
* Returns FALSE if suspended. The return value need be inspected only if
|
|
||||||
* a suspending data source is used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(boolean)
|
|
||||||
jpeg_finish_decompress (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
if ((cinfo->global_state == DSTATE_SCANNING ||
|
|
||||||
cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
|
|
||||||
/* Terminate final pass of non-buffered mode */
|
|
||||||
if (cinfo->output_scanline < cinfo->output_height)
|
|
||||||
ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
|
|
||||||
(*cinfo->master->finish_output_pass) (cinfo);
|
|
||||||
cinfo->global_state = DSTATE_STOPPING;
|
|
||||||
} else if (cinfo->global_state == DSTATE_BUFIMAGE) {
|
|
||||||
/* Finishing after a buffered-image operation */
|
|
||||||
cinfo->global_state = DSTATE_STOPPING;
|
|
||||||
} else if (cinfo->global_state != DSTATE_STOPPING) {
|
|
||||||
/* STOPPING = repeat call after a suspension, anything else is error */
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
}
|
|
||||||
/* Read until EOI */
|
|
||||||
while (! cinfo->inputctl->eoi_reached) {
|
|
||||||
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
|
|
||||||
return FALSE; /* Suspend, come back later */
|
|
||||||
}
|
|
||||||
/* Do final cleanup */
|
|
||||||
(*cinfo->src->term_source) (cinfo);
|
|
||||||
/* We can use jpeg_abort to release memory and reset global_state */
|
|
||||||
jpeg_abort((j_common_ptr) cinfo);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
|
@ -1,276 +0,0 @@
|
||||||
/*
|
|
||||||
* jdapistd.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
|
||||||
* Modified 2002-2013 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains application interface code for the decompression half
|
|
||||||
* of the JPEG library. These are the "standard" API routines that are
|
|
||||||
* used in the normal full-decompression case. They are not used by a
|
|
||||||
* transcoding-only application. Note that if an application links in
|
|
||||||
* jpeg_start_decompress, it will end up linking in the entire decompressor.
|
|
||||||
* We thus must separate this file from jdapimin.c to avoid linking the
|
|
||||||
* whole decompression library into a transcoder.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decompression initialization.
|
|
||||||
* jpeg_read_header must be completed before calling this.
|
|
||||||
*
|
|
||||||
* If a multipass operating mode was selected, this will do all but the
|
|
||||||
* last pass, and thus may take a great deal of time.
|
|
||||||
*
|
|
||||||
* Returns FALSE if suspended. The return value need be inspected only if
|
|
||||||
* a suspending data source is used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(boolean)
|
|
||||||
jpeg_start_decompress (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
if (cinfo->global_state == DSTATE_READY) {
|
|
||||||
/* First call: initialize master control, select active modules */
|
|
||||||
jinit_master_decompress(cinfo);
|
|
||||||
if (cinfo->buffered_image) {
|
|
||||||
/* No more work here; expecting jpeg_start_output next */
|
|
||||||
cinfo->global_state = DSTATE_BUFIMAGE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
cinfo->global_state = DSTATE_PRELOAD;
|
|
||||||
}
|
|
||||||
if (cinfo->global_state == DSTATE_PRELOAD) {
|
|
||||||
/* If file has multiple scans, absorb them all into the coef buffer */
|
|
||||||
if (cinfo->inputctl->has_multiple_scans) {
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
for (;;) {
|
|
||||||
int retcode;
|
|
||||||
/* Call progress monitor hook if present */
|
|
||||||
if (cinfo->progress != NULL)
|
|
||||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
|
||||||
/* Absorb some more input */
|
|
||||||
retcode = (*cinfo->inputctl->consume_input) (cinfo);
|
|
||||||
if (retcode == JPEG_SUSPENDED)
|
|
||||||
return FALSE;
|
|
||||||
if (retcode == JPEG_REACHED_EOI)
|
|
||||||
break;
|
|
||||||
/* Advance progress counter if appropriate */
|
|
||||||
if (cinfo->progress != NULL &&
|
|
||||||
(retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
|
|
||||||
if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
|
|
||||||
/* jdmaster underestimated number of scans; ratchet up one scan */
|
|
||||||
cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
|
||||||
}
|
|
||||||
cinfo->output_scan_number = cinfo->input_scan_number;
|
|
||||||
} else if (cinfo->global_state != DSTATE_PRESCAN)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
/* Perform any dummy output passes, and set up for the final pass */
|
|
||||||
return output_pass_setup(cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up for an output pass, and perform any dummy pass(es) needed.
|
|
||||||
* Common subroutine for jpeg_start_decompress and jpeg_start_output.
|
|
||||||
* Entry: global_state = DSTATE_PRESCAN only if previously suspended.
|
|
||||||
* Exit: If done, returns TRUE and sets global_state for proper output mode.
|
|
||||||
* If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(boolean)
|
|
||||||
output_pass_setup (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
if (cinfo->global_state != DSTATE_PRESCAN) {
|
|
||||||
/* First call: do pass setup */
|
|
||||||
(*cinfo->master->prepare_for_output_pass) (cinfo);
|
|
||||||
cinfo->output_scanline = 0;
|
|
||||||
cinfo->global_state = DSTATE_PRESCAN;
|
|
||||||
}
|
|
||||||
/* Loop over any required dummy passes */
|
|
||||||
while (cinfo->master->is_dummy_pass) {
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
/* Crank through the dummy pass */
|
|
||||||
while (cinfo->output_scanline < cinfo->output_height) {
|
|
||||||
JDIMENSION last_scanline;
|
|
||||||
/* Call progress monitor hook if present */
|
|
||||||
if (cinfo->progress != NULL) {
|
|
||||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
|
||||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
|
||||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
|
||||||
}
|
|
||||||
/* Process some data */
|
|
||||||
last_scanline = cinfo->output_scanline;
|
|
||||||
(*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
|
|
||||||
&cinfo->output_scanline, (JDIMENSION) 0);
|
|
||||||
if (cinfo->output_scanline == last_scanline)
|
|
||||||
return FALSE; /* No progress made, must suspend */
|
|
||||||
}
|
|
||||||
/* Finish up dummy pass, and set up for another one */
|
|
||||||
(*cinfo->master->finish_output_pass) (cinfo);
|
|
||||||
(*cinfo->master->prepare_for_output_pass) (cinfo);
|
|
||||||
cinfo->output_scanline = 0;
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
#endif /* QUANT_2PASS_SUPPORTED */
|
|
||||||
}
|
|
||||||
/* Ready for application to drive output pass through
|
|
||||||
* jpeg_read_scanlines or jpeg_read_raw_data.
|
|
||||||
*/
|
|
||||||
cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read some scanlines of data from the JPEG decompressor.
|
|
||||||
*
|
|
||||||
* The return value will be the number of lines actually read.
|
|
||||||
* This may be less than the number requested in several cases,
|
|
||||||
* including bottom of image, data source suspension, and operating
|
|
||||||
* modes that emit multiple scanlines at a time.
|
|
||||||
*
|
|
||||||
* Note: we warn about excess calls to jpeg_read_scanlines() since
|
|
||||||
* this likely signals an application programmer error. However,
|
|
||||||
* an oversize buffer (max_lines > scanlines remaining) is not an error.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(JDIMENSION)
|
|
||||||
jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
|
|
||||||
JDIMENSION max_lines)
|
|
||||||
{
|
|
||||||
JDIMENSION row_ctr;
|
|
||||||
|
|
||||||
if (cinfo->global_state != DSTATE_SCANNING)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
|
||||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call progress monitor hook if present */
|
|
||||||
if (cinfo->progress != NULL) {
|
|
||||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
|
||||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
|
||||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process some data */
|
|
||||||
row_ctr = 0;
|
|
||||||
(*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
|
|
||||||
cinfo->output_scanline += row_ctr;
|
|
||||||
return row_ctr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Alternate entry point to read raw data.
|
|
||||||
* Processes exactly one iMCU row per call, unless suspended.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(JDIMENSION)
|
|
||||||
jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
|
|
||||||
JDIMENSION max_lines)
|
|
||||||
{
|
|
||||||
JDIMENSION lines_per_iMCU_row;
|
|
||||||
|
|
||||||
if (cinfo->global_state != DSTATE_RAW_OK)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
if (cinfo->output_scanline >= cinfo->output_height) {
|
|
||||||
WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call progress monitor hook if present */
|
|
||||||
if (cinfo->progress != NULL) {
|
|
||||||
cinfo->progress->pass_counter = (long) cinfo->output_scanline;
|
|
||||||
cinfo->progress->pass_limit = (long) cinfo->output_height;
|
|
||||||
(*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that at least one iMCU row can be returned. */
|
|
||||||
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_v_scaled_size;
|
|
||||||
if (max_lines < lines_per_iMCU_row)
|
|
||||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
|
||||||
|
|
||||||
/* Decompress directly into user's buffer. */
|
|
||||||
if (! (*cinfo->coef->decompress_data) (cinfo, data))
|
|
||||||
return 0; /* suspension forced, can do nothing more */
|
|
||||||
|
|
||||||
/* OK, we processed one iMCU row. */
|
|
||||||
cinfo->output_scanline += lines_per_iMCU_row;
|
|
||||||
return lines_per_iMCU_row;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Additional entry points for buffered-image mode. */
|
|
||||||
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for an output pass in buffered-image mode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(boolean)
|
|
||||||
jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
|
|
||||||
{
|
|
||||||
if (cinfo->global_state != DSTATE_BUFIMAGE &&
|
|
||||||
cinfo->global_state != DSTATE_PRESCAN)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
/* Limit scan number to valid range */
|
|
||||||
if (scan_number <= 0)
|
|
||||||
scan_number = 1;
|
|
||||||
if (cinfo->inputctl->eoi_reached &&
|
|
||||||
scan_number > cinfo->input_scan_number)
|
|
||||||
scan_number = cinfo->input_scan_number;
|
|
||||||
cinfo->output_scan_number = scan_number;
|
|
||||||
/* Perform any dummy output passes, and set up for the real pass */
|
|
||||||
return output_pass_setup(cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish up after an output pass in buffered-image mode.
|
|
||||||
*
|
|
||||||
* Returns FALSE if suspended. The return value need be inspected only if
|
|
||||||
* a suspending data source is used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(boolean)
|
|
||||||
jpeg_finish_output (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
if ((cinfo->global_state == DSTATE_SCANNING ||
|
|
||||||
cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
|
|
||||||
/* Terminate this pass. */
|
|
||||||
/* We do not require the whole pass to have been completed. */
|
|
||||||
(*cinfo->master->finish_output_pass) (cinfo);
|
|
||||||
cinfo->global_state = DSTATE_BUFPOST;
|
|
||||||
} else if (cinfo->global_state != DSTATE_BUFPOST) {
|
|
||||||
/* BUFPOST = repeat call after a suspension, anything else is error */
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
}
|
|
||||||
/* Read markers looking for SOS or EOI */
|
|
||||||
while (cinfo->input_scan_number <= cinfo->output_scan_number &&
|
|
||||||
! cinfo->inputctl->eoi_reached) {
|
|
||||||
if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
|
|
||||||
return FALSE; /* Suspend, come back later */
|
|
||||||
}
|
|
||||||
cinfo->global_state = DSTATE_BUFIMAGE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
|
|
@ -1,796 +0,0 @@
|
||||||
/*
|
|
||||||
* jdarith.c
|
|
||||||
*
|
|
||||||
* Developed 1997-2015 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains portable arithmetic entropy decoding routines for JPEG
|
|
||||||
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
|
|
||||||
*
|
|
||||||
* Both sequential and progressive modes are supported in this single module.
|
|
||||||
*
|
|
||||||
* Suspension is not currently supported in this module.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Expanded entropy decoder object for arithmetic decoding. */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_entropy_decoder pub; /* public fields */
|
|
||||||
|
|
||||||
INT32 c; /* C register, base of coding interval + input bit buffer */
|
|
||||||
INT32 a; /* A register, normalized size of coding interval */
|
|
||||||
int ct; /* bit shift counter, # of bits left in bit buffer part of C */
|
|
||||||
/* init: ct = -16 */
|
|
||||||
/* run: ct = 0..7 */
|
|
||||||
/* error: ct = -1 */
|
|
||||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
|
||||||
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
|
|
||||||
|
|
||||||
unsigned int restarts_to_go; /* MCUs left in this restart interval */
|
|
||||||
|
|
||||||
/* Pointers to statistics areas (these workspaces have image lifespan) */
|
|
||||||
unsigned char * dc_stats[NUM_ARITH_TBLS];
|
|
||||||
unsigned char * ac_stats[NUM_ARITH_TBLS];
|
|
||||||
|
|
||||||
/* Statistics bin for coding with fixed probability 0.5 */
|
|
||||||
unsigned char fixed_bin[4];
|
|
||||||
} arith_entropy_decoder;
|
|
||||||
|
|
||||||
typedef arith_entropy_decoder * arith_entropy_ptr;
|
|
||||||
|
|
||||||
/* The following two definitions specify the allocation chunk size
|
|
||||||
* for the statistics area.
|
|
||||||
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
|
|
||||||
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
|
|
||||||
*
|
|
||||||
* We use a compact representation with 1 byte per statistics bin,
|
|
||||||
* thus the numbers directly represent byte sizes.
|
|
||||||
* This 1 byte per statistics bin contains the meaning of the MPS
|
|
||||||
* (more probable symbol) in the highest bit (mask 0x80), and the
|
|
||||||
* index into the probability estimation state machine table
|
|
||||||
* in the lower bits (mask 0x7F).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DC_STAT_BINS 64
|
|
||||||
#define AC_STAT_BINS 256
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(int)
|
|
||||||
get_byte (j_decompress_ptr cinfo)
|
|
||||||
/* Read next input byte; we do not support suspension in this module. */
|
|
||||||
{
|
|
||||||
struct jpeg_source_mgr * src = cinfo->src;
|
|
||||||
|
|
||||||
if (src->bytes_in_buffer == 0)
|
|
||||||
if (! (*src->fill_input_buffer) (cinfo))
|
|
||||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
|
||||||
src->bytes_in_buffer--;
|
|
||||||
return GETJOCTET(*src->next_input_byte++);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The core arithmetic decoding routine (common in JPEG and JBIG).
|
|
||||||
* This needs to go as fast as possible.
|
|
||||||
* Machine-dependent optimization facilities
|
|
||||||
* are not utilized in this portable implementation.
|
|
||||||
* However, this code should be fairly efficient and
|
|
||||||
* may be a good base for further optimizations anyway.
|
|
||||||
*
|
|
||||||
* Return value is 0 or 1 (binary decision).
|
|
||||||
*
|
|
||||||
* Note: I've changed the handling of the code base & bit
|
|
||||||
* buffer register C compared to other implementations
|
|
||||||
* based on the standards layout & procedures.
|
|
||||||
* While it also contains both the actual base of the
|
|
||||||
* coding interval (16 bits) and the next-bits buffer,
|
|
||||||
* the cut-point between these two parts is floating
|
|
||||||
* (instead of fixed) with the bit shift counter CT.
|
|
||||||
* Thus, we also need only one (variable instead of
|
|
||||||
* fixed size) shift for the LPS/MPS decision, and
|
|
||||||
* we can do away with any renormalization update
|
|
||||||
* of C (except for new data insertion, of course).
|
|
||||||
*
|
|
||||||
* I've also introduced a new scheme for accessing
|
|
||||||
* the probability estimation state machine table,
|
|
||||||
* derived from Markus Kuhn's JBIG implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(int)
|
|
||||||
arith_decode (j_decompress_ptr cinfo, unsigned char *st)
|
|
||||||
{
|
|
||||||
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
register unsigned char nl, nm;
|
|
||||||
register INT32 qe, temp;
|
|
||||||
register int sv, data;
|
|
||||||
|
|
||||||
/* Renormalization & data input per section D.2.6 */
|
|
||||||
while (e->a < 0x8000L) {
|
|
||||||
if (--e->ct < 0) {
|
|
||||||
/* Need to fetch next data byte */
|
|
||||||
if (cinfo->unread_marker)
|
|
||||||
data = 0; /* stuff zero data */
|
|
||||||
else {
|
|
||||||
data = get_byte(cinfo); /* read next input byte */
|
|
||||||
if (data == 0xFF) { /* zero stuff or marker code */
|
|
||||||
do data = get_byte(cinfo);
|
|
||||||
while (data == 0xFF); /* swallow extra 0xFF bytes */
|
|
||||||
if (data == 0)
|
|
||||||
data = 0xFF; /* discard stuffed zero byte */
|
|
||||||
else {
|
|
||||||
/* Note: Different from the Huffman decoder, hitting
|
|
||||||
* a marker while processing the compressed data
|
|
||||||
* segment is legal in arithmetic coding.
|
|
||||||
* The convention is to supply zero data
|
|
||||||
* then until decoding is complete.
|
|
||||||
*/
|
|
||||||
cinfo->unread_marker = data;
|
|
||||||
data = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e->c = (e->c << 8) | data; /* insert data into C register */
|
|
||||||
if ((e->ct += 8) < 0) /* update bit shift counter */
|
|
||||||
/* Need more initial bytes */
|
|
||||||
if (++e->ct == 0)
|
|
||||||
/* Got 2 initial bytes -> re-init A and exit loop */
|
|
||||||
e->a = 0x8000L; /* => e->a = 0x10000L after loop exit */
|
|
||||||
}
|
|
||||||
e->a <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fetch values from our compact representation of Table D.3(D.2):
|
|
||||||
* Qe values and probability estimation state machine
|
|
||||||
*/
|
|
||||||
sv = *st;
|
|
||||||
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
|
|
||||||
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
|
|
||||||
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
|
|
||||||
|
|
||||||
/* Decode & estimation procedures per sections D.2.4 & D.2.5 */
|
|
||||||
temp = e->a - qe;
|
|
||||||
e->a = temp;
|
|
||||||
temp <<= e->ct;
|
|
||||||
if (e->c >= temp) {
|
|
||||||
e->c -= temp;
|
|
||||||
/* Conditional LPS (less probable symbol) exchange */
|
|
||||||
if (e->a < qe) {
|
|
||||||
e->a = qe;
|
|
||||||
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
|
|
||||||
} else {
|
|
||||||
e->a = qe;
|
|
||||||
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
|
|
||||||
sv ^= 0x80; /* Exchange LPS/MPS */
|
|
||||||
}
|
|
||||||
} else if (e->a < 0x8000L) {
|
|
||||||
/* Conditional MPS (more probable symbol) exchange */
|
|
||||||
if (e->a < qe) {
|
|
||||||
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
|
|
||||||
sv ^= 0x80; /* Exchange LPS/MPS */
|
|
||||||
} else {
|
|
||||||
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sv >> 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for a restart marker & resynchronize decoder.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
process_restart (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
int ci;
|
|
||||||
jpeg_component_info * compptr;
|
|
||||||
|
|
||||||
/* Advance past the RSTn marker */
|
|
||||||
if (! (*cinfo->marker->read_restart_marker) (cinfo))
|
|
||||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
|
||||||
|
|
||||||
/* Re-initialize statistics areas */
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
|
|
||||||
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
|
|
||||||
/* Reset DC predictions to 0 */
|
|
||||||
entropy->last_dc_val[ci] = 0;
|
|
||||||
entropy->dc_context[ci] = 0;
|
|
||||||
}
|
|
||||||
if ((! cinfo->progressive_mode && cinfo->lim_Se) ||
|
|
||||||
(cinfo->progressive_mode && cinfo->Ss)) {
|
|
||||||
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset arithmetic decoding variables */
|
|
||||||
entropy->c = 0;
|
|
||||||
entropy->a = 0;
|
|
||||||
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
|
|
||||||
|
|
||||||
/* Reset restart counter */
|
|
||||||
entropy->restarts_to_go = cinfo->restart_interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Arithmetic MCU decoding.
|
|
||||||
* Each of these routines decodes and returns one MCU's worth of
|
|
||||||
* arithmetic-compressed coefficients.
|
|
||||||
* The coefficients are reordered from zigzag order into natural array order,
|
|
||||||
* but are not dequantized.
|
|
||||||
*
|
|
||||||
* The i'th block of the MCU is stored into the block pointed to by
|
|
||||||
* MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MCU decoding for DC initial scan (either spectral selection,
|
|
||||||
* or first pass of successive approximation).
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
|
||||||
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
JBLOCKROW block;
|
|
||||||
unsigned char *st;
|
|
||||||
int blkn, ci, tbl, sign;
|
|
||||||
int v, m;
|
|
||||||
|
|
||||||
/* Process restart marker if needed */
|
|
||||||
if (cinfo->restart_interval) {
|
|
||||||
if (entropy->restarts_to_go == 0)
|
|
||||||
process_restart(cinfo);
|
|
||||||
entropy->restarts_to_go--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
|
||||||
|
|
||||||
/* Outer loop handles each block in the MCU */
|
|
||||||
|
|
||||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
|
||||||
block = MCU_data[blkn];
|
|
||||||
ci = cinfo->MCU_membership[blkn];
|
|
||||||
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
|
|
||||||
|
|
||||||
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
|
|
||||||
|
|
||||||
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
|
|
||||||
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
|
|
||||||
|
|
||||||
/* Figure F.19: Decode_DC_DIFF */
|
|
||||||
if (arith_decode(cinfo, st) == 0)
|
|
||||||
entropy->dc_context[ci] = 0;
|
|
||||||
else {
|
|
||||||
/* Figure F.21: Decoding nonzero value v */
|
|
||||||
/* Figure F.22: Decoding the sign of v */
|
|
||||||
sign = arith_decode(cinfo, st + 1);
|
|
||||||
st += 2; st += sign;
|
|
||||||
/* Figure F.23: Decoding the magnitude category of v */
|
|
||||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
|
||||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
|
||||||
while (arith_decode(cinfo, st)) {
|
|
||||||
if ((m <<= 1) == 0x8000) {
|
|
||||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
|
||||||
entropy->ct = -1; /* magnitude overflow */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
st += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
|
|
||||||
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
|
|
||||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
|
||||||
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
|
|
||||||
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
|
|
||||||
else
|
|
||||||
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
|
|
||||||
v = m;
|
|
||||||
/* Figure F.24: Decoding the magnitude bit pattern of v */
|
|
||||||
st += 14;
|
|
||||||
while (m >>= 1)
|
|
||||||
if (arith_decode(cinfo, st)) v |= m;
|
|
||||||
v += 1; if (sign) v = -v;
|
|
||||||
entropy->last_dc_val[ci] += v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */
|
|
||||||
(*block)[0] = (JCOEF) (entropy->last_dc_val[ci] << cinfo->Al);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MCU decoding for AC initial scan (either spectral selection,
|
|
||||||
* or first pass of successive approximation).
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
|
||||||
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
JBLOCKROW block;
|
|
||||||
unsigned char *st;
|
|
||||||
int tbl, sign, k;
|
|
||||||
int v, m;
|
|
||||||
const int * natural_order;
|
|
||||||
|
|
||||||
/* Process restart marker if needed */
|
|
||||||
if (cinfo->restart_interval) {
|
|
||||||
if (entropy->restarts_to_go == 0)
|
|
||||||
process_restart(cinfo);
|
|
||||||
entropy->restarts_to_go--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
|
||||||
|
|
||||||
natural_order = cinfo->natural_order;
|
|
||||||
|
|
||||||
/* There is always only one block per MCU */
|
|
||||||
block = MCU_data[0];
|
|
||||||
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
|
|
||||||
|
|
||||||
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
|
|
||||||
|
|
||||||
/* Figure F.20: Decode_AC_coefficients */
|
|
||||||
k = cinfo->Ss - 1;
|
|
||||||
do {
|
|
||||||
st = entropy->ac_stats[tbl] + 3 * k;
|
|
||||||
if (arith_decode(cinfo, st)) break; /* EOB flag */
|
|
||||||
for (;;) {
|
|
||||||
k++;
|
|
||||||
if (arith_decode(cinfo, st + 1)) break;
|
|
||||||
st += 3;
|
|
||||||
if (k >= cinfo->Se) {
|
|
||||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
|
||||||
entropy->ct = -1; /* spectral overflow */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Figure F.21: Decoding nonzero value v */
|
|
||||||
/* Figure F.22: Decoding the sign of v */
|
|
||||||
sign = arith_decode(cinfo, entropy->fixed_bin);
|
|
||||||
st += 2;
|
|
||||||
/* Figure F.23: Decoding the magnitude category of v */
|
|
||||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
|
||||||
if (arith_decode(cinfo, st)) {
|
|
||||||
m <<= 1;
|
|
||||||
st = entropy->ac_stats[tbl] +
|
|
||||||
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
|
|
||||||
while (arith_decode(cinfo, st)) {
|
|
||||||
if ((m <<= 1) == 0x8000) {
|
|
||||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
|
||||||
entropy->ct = -1; /* magnitude overflow */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
st += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v = m;
|
|
||||||
/* Figure F.24: Decoding the magnitude bit pattern of v */
|
|
||||||
st += 14;
|
|
||||||
while (m >>= 1)
|
|
||||||
if (arith_decode(cinfo, st)) v |= m;
|
|
||||||
v += 1; if (sign) v = -v;
|
|
||||||
/* Scale and output coefficient in natural (dezigzagged) order */
|
|
||||||
(*block)[natural_order[k]] = (JCOEF) (v << cinfo->Al);
|
|
||||||
} while (k < cinfo->Se);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MCU decoding for DC successive approximation refinement scan.
|
|
||||||
* Note: we assume such scans can be multi-component,
|
|
||||||
* although the spec is not very clear on the point.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
|
||||||
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
unsigned char *st;
|
|
||||||
int p1, blkn;
|
|
||||||
|
|
||||||
/* Process restart marker if needed */
|
|
||||||
if (cinfo->restart_interval) {
|
|
||||||
if (entropy->restarts_to_go == 0)
|
|
||||||
process_restart(cinfo);
|
|
||||||
entropy->restarts_to_go--;
|
|
||||||
}
|
|
||||||
|
|
||||||
st = entropy->fixed_bin; /* use fixed probability estimation */
|
|
||||||
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
|
||||||
|
|
||||||
/* Outer loop handles each block in the MCU */
|
|
||||||
|
|
||||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
|
||||||
/* Encoded data is simply the next bit of the two's-complement DC value */
|
|
||||||
if (arith_decode(cinfo, st))
|
|
||||||
MCU_data[blkn][0][0] |= p1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MCU decoding for AC successive approximation refinement scan.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
|
||||||
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
JBLOCKROW block;
|
|
||||||
JCOEFPTR thiscoef;
|
|
||||||
unsigned char *st;
|
|
||||||
int tbl, k, kex;
|
|
||||||
int p1, m1;
|
|
||||||
const int * natural_order;
|
|
||||||
|
|
||||||
/* Process restart marker if needed */
|
|
||||||
if (cinfo->restart_interval) {
|
|
||||||
if (entropy->restarts_to_go == 0)
|
|
||||||
process_restart(cinfo);
|
|
||||||
entropy->restarts_to_go--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
|
||||||
|
|
||||||
natural_order = cinfo->natural_order;
|
|
||||||
|
|
||||||
/* There is always only one block per MCU */
|
|
||||||
block = MCU_data[0];
|
|
||||||
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
|
|
||||||
|
|
||||||
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
|
||||||
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
|
|
||||||
|
|
||||||
/* Establish EOBx (previous stage end-of-block) index */
|
|
||||||
kex = cinfo->Se;
|
|
||||||
do {
|
|
||||||
if ((*block)[natural_order[kex]]) break;
|
|
||||||
} while (--kex);
|
|
||||||
|
|
||||||
k = cinfo->Ss - 1;
|
|
||||||
do {
|
|
||||||
st = entropy->ac_stats[tbl] + 3 * k;
|
|
||||||
if (k >= kex)
|
|
||||||
if (arith_decode(cinfo, st)) break; /* EOB flag */
|
|
||||||
for (;;) {
|
|
||||||
thiscoef = *block + natural_order[++k];
|
|
||||||
if (*thiscoef) { /* previously nonzero coef */
|
|
||||||
if (arith_decode(cinfo, st + 2)) {
|
|
||||||
if (*thiscoef < 0)
|
|
||||||
*thiscoef += m1;
|
|
||||||
else
|
|
||||||
*thiscoef += p1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (arith_decode(cinfo, st + 1)) { /* newly nonzero coef */
|
|
||||||
if (arith_decode(cinfo, entropy->fixed_bin))
|
|
||||||
*thiscoef = m1;
|
|
||||||
else
|
|
||||||
*thiscoef = p1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
st += 3;
|
|
||||||
if (k >= cinfo->Se) {
|
|
||||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
|
||||||
entropy->ct = -1; /* spectral overflow */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (k < cinfo->Se);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decode one MCU's worth of arithmetic-compressed coefficients.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
|
||||||
decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
jpeg_component_info * compptr;
|
|
||||||
JBLOCKROW block;
|
|
||||||
unsigned char *st;
|
|
||||||
int blkn, ci, tbl, sign, k;
|
|
||||||
int v, m;
|
|
||||||
const int * natural_order;
|
|
||||||
|
|
||||||
/* Process restart marker if needed */
|
|
||||||
if (cinfo->restart_interval) {
|
|
||||||
if (entropy->restarts_to_go == 0)
|
|
||||||
process_restart(cinfo);
|
|
||||||
entropy->restarts_to_go--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
|
||||||
|
|
||||||
natural_order = cinfo->natural_order;
|
|
||||||
|
|
||||||
/* Outer loop handles each block in the MCU */
|
|
||||||
|
|
||||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
|
||||||
block = MCU_data[blkn];
|
|
||||||
ci = cinfo->MCU_membership[blkn];
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
|
|
||||||
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
|
|
||||||
|
|
||||||
tbl = compptr->dc_tbl_no;
|
|
||||||
|
|
||||||
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
|
|
||||||
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
|
|
||||||
|
|
||||||
/* Figure F.19: Decode_DC_DIFF */
|
|
||||||
if (arith_decode(cinfo, st) == 0)
|
|
||||||
entropy->dc_context[ci] = 0;
|
|
||||||
else {
|
|
||||||
/* Figure F.21: Decoding nonzero value v */
|
|
||||||
/* Figure F.22: Decoding the sign of v */
|
|
||||||
sign = arith_decode(cinfo, st + 1);
|
|
||||||
st += 2; st += sign;
|
|
||||||
/* Figure F.23: Decoding the magnitude category of v */
|
|
||||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
|
||||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
|
||||||
while (arith_decode(cinfo, st)) {
|
|
||||||
if ((m <<= 1) == 0x8000) {
|
|
||||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
|
||||||
entropy->ct = -1; /* magnitude overflow */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
st += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
|
|
||||||
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
|
|
||||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
|
||||||
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
|
|
||||||
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
|
|
||||||
else
|
|
||||||
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
|
|
||||||
v = m;
|
|
||||||
/* Figure F.24: Decoding the magnitude bit pattern of v */
|
|
||||||
st += 14;
|
|
||||||
while (m >>= 1)
|
|
||||||
if (arith_decode(cinfo, st)) v |= m;
|
|
||||||
v += 1; if (sign) v = -v;
|
|
||||||
entropy->last_dc_val[ci] += v;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*block)[0] = (JCOEF) entropy->last_dc_val[ci];
|
|
||||||
|
|
||||||
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
|
|
||||||
|
|
||||||
if (cinfo->lim_Se == 0) continue;
|
|
||||||
tbl = compptr->ac_tbl_no;
|
|
||||||
k = 0;
|
|
||||||
|
|
||||||
/* Figure F.20: Decode_AC_coefficients */
|
|
||||||
do {
|
|
||||||
st = entropy->ac_stats[tbl] + 3 * k;
|
|
||||||
if (arith_decode(cinfo, st)) break; /* EOB flag */
|
|
||||||
for (;;) {
|
|
||||||
k++;
|
|
||||||
if (arith_decode(cinfo, st + 1)) break;
|
|
||||||
st += 3;
|
|
||||||
if (k >= cinfo->lim_Se) {
|
|
||||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
|
||||||
entropy->ct = -1; /* spectral overflow */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Figure F.21: Decoding nonzero value v */
|
|
||||||
/* Figure F.22: Decoding the sign of v */
|
|
||||||
sign = arith_decode(cinfo, entropy->fixed_bin);
|
|
||||||
st += 2;
|
|
||||||
/* Figure F.23: Decoding the magnitude category of v */
|
|
||||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
|
||||||
if (arith_decode(cinfo, st)) {
|
|
||||||
m <<= 1;
|
|
||||||
st = entropy->ac_stats[tbl] +
|
|
||||||
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
|
|
||||||
while (arith_decode(cinfo, st)) {
|
|
||||||
if ((m <<= 1) == 0x8000) {
|
|
||||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
|
||||||
entropy->ct = -1; /* magnitude overflow */
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
st += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v = m;
|
|
||||||
/* Figure F.24: Decoding the magnitude bit pattern of v */
|
|
||||||
st += 14;
|
|
||||||
while (m >>= 1)
|
|
||||||
if (arith_decode(cinfo, st)) v |= m;
|
|
||||||
v += 1; if (sign) v = -v;
|
|
||||||
(*block)[natural_order[k]] = (JCOEF) v;
|
|
||||||
} while (k < cinfo->lim_Se);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for an arithmetic-compressed scan.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
|
||||||
int ci, tbl;
|
|
||||||
jpeg_component_info * compptr;
|
|
||||||
|
|
||||||
if (cinfo->progressive_mode) {
|
|
||||||
/* Validate progressive scan parameters */
|
|
||||||
if (cinfo->Ss == 0) {
|
|
||||||
if (cinfo->Se != 0)
|
|
||||||
goto bad;
|
|
||||||
} else {
|
|
||||||
/* need not check Ss/Se < 0 since they came from unsigned bytes */
|
|
||||||
if (cinfo->Se < cinfo->Ss || cinfo->Se > cinfo->lim_Se)
|
|
||||||
goto bad;
|
|
||||||
/* AC scans may have only one component */
|
|
||||||
if (cinfo->comps_in_scan != 1)
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (cinfo->Ah != 0) {
|
|
||||||
/* Successive approximation refinement scan: must have Al = Ah-1. */
|
|
||||||
if (cinfo->Ah-1 != cinfo->Al)
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (cinfo->Al > 13) { /* need not check for < 0 */
|
|
||||||
bad:
|
|
||||||
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
|
|
||||||
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
|
|
||||||
}
|
|
||||||
/* Update progression status, and verify that scan order is legal.
|
|
||||||
* Note that inter-scan inconsistencies are treated as warnings
|
|
||||||
* not fatal errors ... not clear if this is right way to behave.
|
|
||||||
*/
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
|
|
||||||
int *coef_bit_ptr = & cinfo->coef_bits[cindex][0];
|
|
||||||
if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
|
|
||||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
|
|
||||||
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
|
|
||||||
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
|
|
||||||
if (cinfo->Ah != expected)
|
|
||||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
|
|
||||||
coef_bit_ptr[coefi] = cinfo->Al;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Select MCU decoding routine */
|
|
||||||
if (cinfo->Ah == 0) {
|
|
||||||
if (cinfo->Ss == 0)
|
|
||||||
entropy->pub.decode_mcu = decode_mcu_DC_first;
|
|
||||||
else
|
|
||||||
entropy->pub.decode_mcu = decode_mcu_AC_first;
|
|
||||||
} else {
|
|
||||||
if (cinfo->Ss == 0)
|
|
||||||
entropy->pub.decode_mcu = decode_mcu_DC_refine;
|
|
||||||
else
|
|
||||||
entropy->pub.decode_mcu = decode_mcu_AC_refine;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
|
|
||||||
* This ought to be an error condition, but we make it a warning.
|
|
||||||
*/
|
|
||||||
if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 ||
|
|
||||||
(cinfo->Se < DCTSIZE2 && cinfo->Se != cinfo->lim_Se))
|
|
||||||
WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
|
|
||||||
/* Select MCU decoding routine */
|
|
||||||
entropy->pub.decode_mcu = decode_mcu;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate & initialize requested statistics areas */
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
|
|
||||||
tbl = compptr->dc_tbl_no;
|
|
||||||
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
|
|
||||||
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
|
|
||||||
if (entropy->dc_stats[tbl] == NULL)
|
|
||||||
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
|
|
||||||
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
|
|
||||||
/* Initialize DC predictions to 0 */
|
|
||||||
entropy->last_dc_val[ci] = 0;
|
|
||||||
entropy->dc_context[ci] = 0;
|
|
||||||
}
|
|
||||||
if ((! cinfo->progressive_mode && cinfo->lim_Se) ||
|
|
||||||
(cinfo->progressive_mode && cinfo->Ss)) {
|
|
||||||
tbl = compptr->ac_tbl_no;
|
|
||||||
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
|
|
||||||
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
|
|
||||||
if (entropy->ac_stats[tbl] == NULL)
|
|
||||||
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
|
|
||||||
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize arithmetic decoding variables */
|
|
||||||
entropy->c = 0;
|
|
||||||
entropy->a = 0;
|
|
||||||
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
|
|
||||||
|
|
||||||
/* Initialize restart counter */
|
|
||||||
entropy->restarts_to_go = cinfo->restart_interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish up at the end of an arithmetic-compressed scan.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
finish_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* no work necessary here */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module initialization routine for arithmetic entropy decoding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_arith_decoder (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
arith_entropy_ptr entropy;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
entropy = (arith_entropy_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(arith_entropy_decoder));
|
|
||||||
cinfo->entropy = &entropy->pub;
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (cinfo->progressive_mode) {
|
|
||||||
/* Create progression status table */
|
|
||||||
int *coef_bit_ptr, ci;
|
|
||||||
cinfo->coef_bits = (int (*)[DCTSIZE2])
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
cinfo->num_components*DCTSIZE2*SIZEOF(int));
|
|
||||||
coef_bit_ptr = & cinfo->coef_bits[0][0];
|
|
||||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
|
||||||
for (i = 0; i < DCTSIZE2; i++)
|
|
||||||
*coef_bit_ptr++ = -1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,275 +0,0 @@
|
||||||
/*
|
|
||||||
* jdatasrc.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
|
||||||
* Modified 2009-2015 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains decompression data source routines for the case of
|
|
||||||
* reading JPEG data from memory or from a file (or any stdio stream).
|
|
||||||
* While these routines are sufficient for most applications,
|
|
||||||
* some will want to use a different source manager.
|
|
||||||
* IMPORTANT: we assume that fread() will correctly transcribe an array of
|
|
||||||
* JOCTETs from 8-bit-wide elements on external storage. If char is wider
|
|
||||||
* than 8 bits on your machine, you may need to do some tweaking.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
#include "jerror.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Expanded data source object for stdio input */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_source_mgr pub; /* public fields */
|
|
||||||
|
|
||||||
FILE * infile; /* source stream */
|
|
||||||
JOCTET * buffer; /* start of buffer */
|
|
||||||
boolean start_of_file; /* have we gotten any data yet? */
|
|
||||||
} my_source_mgr;
|
|
||||||
|
|
||||||
typedef my_source_mgr * my_src_ptr;
|
|
||||||
|
|
||||||
#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize source --- called by jpeg_read_header
|
|
||||||
* before any data is actually read.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
init_source (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
||||||
|
|
||||||
/* We reset the empty-input-file flag for each image,
|
|
||||||
* but we don't clear the input buffer.
|
|
||||||
* This is correct behavior for reading a series of images from one source.
|
|
||||||
*/
|
|
||||||
src->start_of_file = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
init_mem_source (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* no work necessary here */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill the input buffer --- called whenever buffer is emptied.
|
|
||||||
*
|
|
||||||
* In typical applications, this should read fresh data into the buffer
|
|
||||||
* (ignoring the current state of next_input_byte & bytes_in_buffer),
|
|
||||||
* reset the pointer & count to the start of the buffer, and return TRUE
|
|
||||||
* indicating that the buffer has been reloaded. It is not necessary to
|
|
||||||
* fill the buffer entirely, only to obtain at least one more byte.
|
|
||||||
*
|
|
||||||
* There is no such thing as an EOF return. If the end of the file has been
|
|
||||||
* reached, the routine has a choice of ERREXIT() or inserting fake data into
|
|
||||||
* the buffer. In most cases, generating a warning message and inserting a
|
|
||||||
* fake EOI marker is the best course of action --- this will allow the
|
|
||||||
* decompressor to output however much of the image is there. However,
|
|
||||||
* the resulting error message is misleading if the real problem is an empty
|
|
||||||
* input file, so we handle that case specially.
|
|
||||||
*
|
|
||||||
* In applications that need to be able to suspend compression due to input
|
|
||||||
* not being available yet, a FALSE return indicates that no more data can be
|
|
||||||
* obtained right now, but more may be forthcoming later. In this situation,
|
|
||||||
* the decompressor will return to its caller (with an indication of the
|
|
||||||
* number of scanlines it has read, if any). The application should resume
|
|
||||||
* decompression after it has loaded more data into the input buffer. Note
|
|
||||||
* that there are substantial restrictions on the use of suspension --- see
|
|
||||||
* the documentation.
|
|
||||||
*
|
|
||||||
* When suspending, the decompressor will back up to a convenient restart point
|
|
||||||
* (typically the start of the current MCU). next_input_byte & bytes_in_buffer
|
|
||||||
* indicate where the restart point will be if the current call returns FALSE.
|
|
||||||
* Data beyond this point must be rescanned after resumption, so move it to
|
|
||||||
* the front of the buffer rather than discarding it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
|
||||||
fill_input_buffer (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
||||||
size_t nbytes;
|
|
||||||
|
|
||||||
nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
|
|
||||||
|
|
||||||
if (nbytes <= 0) {
|
|
||||||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
|
||||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
|
||||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
|
||||||
/* Insert a fake EOI marker */
|
|
||||||
src->buffer[0] = (JOCTET) 0xFF;
|
|
||||||
src->buffer[1] = (JOCTET) JPEG_EOI;
|
|
||||||
nbytes = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
src->pub.next_input_byte = src->buffer;
|
|
||||||
src->pub.bytes_in_buffer = nbytes;
|
|
||||||
src->start_of_file = FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHODDEF(boolean)
|
|
||||||
fill_mem_input_buffer (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
static const JOCTET mybuffer[4] = {
|
|
||||||
(JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The whole JPEG data is expected to reside in the supplied memory
|
|
||||||
* buffer, so any request for more data beyond the given buffer size
|
|
||||||
* is treated as an error.
|
|
||||||
*/
|
|
||||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
|
||||||
|
|
||||||
/* Insert a fake EOI marker */
|
|
||||||
|
|
||||||
cinfo->src->next_input_byte = mybuffer;
|
|
||||||
cinfo->src->bytes_in_buffer = 2;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Skip data --- used to skip over a potentially large amount of
|
|
||||||
* uninteresting data (such as an APPn marker).
|
|
||||||
*
|
|
||||||
* Writers of suspendable-input applications must note that skip_input_data
|
|
||||||
* is not granted the right to give a suspension return. If the skip extends
|
|
||||||
* beyond the data currently in the buffer, the buffer can be marked empty so
|
|
||||||
* that the next read will cause a fill_input_buffer call that can suspend.
|
|
||||||
* Arranging for additional bytes to be discarded before reloading the input
|
|
||||||
* buffer is the application writer's problem.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
|
||||||
{
|
|
||||||
struct jpeg_source_mgr * src = cinfo->src;
|
|
||||||
|
|
||||||
/* Just a dumb implementation for now. Could use fseek() except
|
|
||||||
* it doesn't work on pipes. Not clear that being smart is worth
|
|
||||||
* any trouble anyway --- large skips are infrequent.
|
|
||||||
*/
|
|
||||||
if (num_bytes > 0) {
|
|
||||||
while (num_bytes > (long) src->bytes_in_buffer) {
|
|
||||||
num_bytes -= (long) src->bytes_in_buffer;
|
|
||||||
(void) (*src->fill_input_buffer) (cinfo);
|
|
||||||
/* note we assume that fill_input_buffer will never return FALSE,
|
|
||||||
* so suspension need not be handled.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
src->next_input_byte += (size_t) num_bytes;
|
|
||||||
src->bytes_in_buffer -= (size_t) num_bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* An additional method that can be provided by data source modules is the
|
|
||||||
* resync_to_restart method for error recovery in the presence of RST markers.
|
|
||||||
* For the moment, this source module just uses the default resync method
|
|
||||||
* provided by the JPEG library. That method assumes that no backtracking
|
|
||||||
* is possible.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Terminate source --- called by jpeg_finish_decompress
|
|
||||||
* after all data has been read. Often a no-op.
|
|
||||||
*
|
|
||||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
|
||||||
* application must deal with any cleanup that should happen even
|
|
||||||
* for error exit.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
term_source (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* no work necessary here */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prepare for input from a stdio stream.
|
|
||||||
* The caller must have already opened the stream, and is responsible
|
|
||||||
* for closing it after finishing decompression.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
|
|
||||||
{
|
|
||||||
my_src_ptr src;
|
|
||||||
|
|
||||||
/* The source object and input buffer are made permanent so that a series
|
|
||||||
* of JPEG images can be read from the same file by calling jpeg_stdio_src
|
|
||||||
* only before the first one. (If we discarded the buffer at the end of
|
|
||||||
* one image, we'd likely lose the start of the next one.)
|
|
||||||
* This makes it unsafe to use this manager and a different source
|
|
||||||
* manager serially with the same JPEG object. Caveat programmer.
|
|
||||||
*/
|
|
||||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
|
||||||
cinfo->src = (struct jpeg_source_mgr *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
SIZEOF(my_source_mgr));
|
|
||||||
src = (my_src_ptr) cinfo->src;
|
|
||||||
src->buffer = (JOCTET *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
INPUT_BUF_SIZE * SIZEOF(JOCTET));
|
|
||||||
}
|
|
||||||
|
|
||||||
src = (my_src_ptr) cinfo->src;
|
|
||||||
src->pub.init_source = init_source;
|
|
||||||
src->pub.fill_input_buffer = fill_input_buffer;
|
|
||||||
src->pub.skip_input_data = skip_input_data;
|
|
||||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
|
||||||
src->pub.term_source = term_source;
|
|
||||||
src->infile = infile;
|
|
||||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
|
||||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prepare for input from a supplied memory buffer.
|
|
||||||
* The buffer must contain the whole JPEG data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_mem_src (j_decompress_ptr cinfo,
|
|
||||||
const unsigned char * inbuffer, unsigned long insize)
|
|
||||||
{
|
|
||||||
struct jpeg_source_mgr * src;
|
|
||||||
|
|
||||||
if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
|
|
||||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
|
||||||
|
|
||||||
/* The source object is made permanent so that a series of JPEG images
|
|
||||||
* can be read from the same buffer by calling jpeg_mem_src only before
|
|
||||||
* the first one.
|
|
||||||
*/
|
|
||||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
|
||||||
cinfo->src = (struct jpeg_source_mgr *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
SIZEOF(struct jpeg_source_mgr));
|
|
||||||
}
|
|
||||||
|
|
||||||
src = cinfo->src;
|
|
||||||
src->init_source = init_mem_source;
|
|
||||||
src->fill_input_buffer = fill_mem_input_buffer;
|
|
||||||
src->skip_input_data = skip_input_data;
|
|
||||||
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
|
||||||
src->term_source = term_source;
|
|
||||||
src->bytes_in_buffer = (size_t) insize;
|
|
||||||
src->next_input_byte = (const JOCTET *) inbuffer;
|
|
||||||
}
|
|
|
@ -1,741 +0,0 @@
|
||||||
/*
|
|
||||||
* jdcoefct.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
|
||||||
* Modified 2002-2011 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains the coefficient buffer controller for decompression.
|
|
||||||
* This controller is the top level of the JPEG decompressor proper.
|
|
||||||
* The coefficient buffer lies between entropy decoding and inverse-DCT steps.
|
|
||||||
*
|
|
||||||
* In buffered-image mode, this controller is the interface between
|
|
||||||
* input-oriented processing and output-oriented processing.
|
|
||||||
* Also, the input side (only) is used when reading a file for transcoding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
/* Block smoothing is only applicable for progressive JPEG, so: */
|
|
||||||
#ifndef D_PROGRESSIVE_SUPPORTED
|
|
||||||
#undef BLOCK_SMOOTHING_SUPPORTED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Private buffer controller object */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_d_coef_controller pub; /* public fields */
|
|
||||||
|
|
||||||
/* These variables keep track of the current location of the input side. */
|
|
||||||
/* cinfo->input_iMCU_row is also used for this. */
|
|
||||||
JDIMENSION MCU_ctr; /* counts MCUs processed in current row */
|
|
||||||
int MCU_vert_offset; /* counts MCU rows within iMCU row */
|
|
||||||
int MCU_rows_per_iMCU_row; /* number of such rows needed */
|
|
||||||
|
|
||||||
/* The output side's location is represented by cinfo->output_iMCU_row. */
|
|
||||||
|
|
||||||
/* In single-pass modes, it's sufficient to buffer just one MCU.
|
|
||||||
* We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
|
|
||||||
* and let the entropy decoder write into that workspace each time.
|
|
||||||
* (On 80x86, the workspace is FAR even though it's not really very big;
|
|
||||||
* this is to keep the module interfaces unchanged when a large coefficient
|
|
||||||
* buffer is necessary.)
|
|
||||||
* In multi-pass modes, this array points to the current MCU's blocks
|
|
||||||
* within the virtual arrays; it is used only by the input side.
|
|
||||||
*/
|
|
||||||
JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
|
|
||||||
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
/* In multi-pass modes, we need a virtual block array for each component. */
|
|
||||||
jvirt_barray_ptr whole_image[MAX_COMPONENTS];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
|
||||||
/* When doing block smoothing, we latch coefficient Al values here */
|
|
||||||
int * coef_bits_latch;
|
|
||||||
#define SAVED_COEFS 6 /* we save coef_bits[0..5] */
|
|
||||||
#endif
|
|
||||||
} my_coef_controller;
|
|
||||||
|
|
||||||
typedef my_coef_controller * my_coef_ptr;
|
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
METHODDEF(int) decompress_onepass
|
|
||||||
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
METHODDEF(int) decompress_data
|
|
||||||
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
|
|
||||||
#endif
|
|
||||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
|
||||||
LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
|
|
||||||
METHODDEF(int) decompress_smooth_data
|
|
||||||
JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
start_iMCU_row (j_decompress_ptr cinfo)
|
|
||||||
/* Reset within-iMCU-row counters for a new row (input side) */
|
|
||||||
{
|
|
||||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
|
||||||
|
|
||||||
/* In an interleaved scan, an MCU row is the same as an iMCU row.
|
|
||||||
* In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
|
|
||||||
* But at the bottom of the image, process only what's left.
|
|
||||||
*/
|
|
||||||
if (cinfo->comps_in_scan > 1) {
|
|
||||||
coef->MCU_rows_per_iMCU_row = 1;
|
|
||||||
} else {
|
|
||||||
if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
|
|
||||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
|
|
||||||
else
|
|
||||||
coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
coef->MCU_ctr = 0;
|
|
||||||
coef->MCU_vert_offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for an input processing pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_input_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
cinfo->input_iMCU_row = 0;
|
|
||||||
start_iMCU_row(cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for an output processing pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_output_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
|
||||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
|
||||||
|
|
||||||
/* If multipass, check to see whether to use block smoothing on this pass */
|
|
||||||
if (coef->pub.coef_arrays != NULL) {
|
|
||||||
if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
|
|
||||||
coef->pub.decompress_data = decompress_smooth_data;
|
|
||||||
else
|
|
||||||
coef->pub.decompress_data = decompress_data;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
cinfo->output_iMCU_row = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decompress and return some data in the single-pass case.
|
|
||||||
* Always attempts to emit one fully interleaved MCU row ("iMCU" row).
|
|
||||||
* Input and output must run in lockstep since we have only a one-MCU buffer.
|
|
||||||
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
|
|
||||||
*
|
|
||||||
* NB: output_buf contains a plane for each component in image,
|
|
||||||
* which we index according to the component's SOF position.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(int)
|
|
||||||
decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|
||||||
{
|
|
||||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
|
||||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
|
||||||
JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
|
|
||||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
|
||||||
int blkn, ci, xindex, yindex, yoffset, useful_width;
|
|
||||||
JSAMPARRAY output_ptr;
|
|
||||||
JDIMENSION start_col, output_col;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
inverse_DCT_method_ptr inverse_DCT;
|
|
||||||
|
|
||||||
/* Loop to process as much as one whole iMCU row */
|
|
||||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
|
||||||
yoffset++) {
|
|
||||||
for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
|
|
||||||
MCU_col_num++) {
|
|
||||||
/* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
|
|
||||||
if (cinfo->lim_Se) /* can bypass in DC only case */
|
|
||||||
FMEMZERO((void FAR *) coef->MCU_buffer[0],
|
|
||||||
(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
|
|
||||||
if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
|
|
||||||
/* Suspension forced; update state counters and exit */
|
|
||||||
coef->MCU_vert_offset = yoffset;
|
|
||||||
coef->MCU_ctr = MCU_col_num;
|
|
||||||
return JPEG_SUSPENDED;
|
|
||||||
}
|
|
||||||
/* Determine where data should go in output_buf and do the IDCT thing.
|
|
||||||
* We skip dummy blocks at the right and bottom edges (but blkn gets
|
|
||||||
* incremented past them!). Note the inner loop relies on having
|
|
||||||
* allocated the MCU_buffer[] blocks sequentially.
|
|
||||||
*/
|
|
||||||
blkn = 0; /* index of current DCT block within MCU */
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
/* Don't bother to IDCT an uninteresting component. */
|
|
||||||
if (! compptr->component_needed) {
|
|
||||||
blkn += compptr->MCU_blocks;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
|
|
||||||
useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
|
|
||||||
: compptr->last_col_width;
|
|
||||||
output_ptr = output_buf[compptr->component_index] +
|
|
||||||
yoffset * compptr->DCT_v_scaled_size;
|
|
||||||
start_col = MCU_col_num * compptr->MCU_sample_width;
|
|
||||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
|
||||||
if (cinfo->input_iMCU_row < last_iMCU_row ||
|
|
||||||
yoffset+yindex < compptr->last_row_height) {
|
|
||||||
output_col = start_col;
|
|
||||||
for (xindex = 0; xindex < useful_width; xindex++) {
|
|
||||||
(*inverse_DCT) (cinfo, compptr,
|
|
||||||
(JCOEFPTR) coef->MCU_buffer[blkn+xindex],
|
|
||||||
output_ptr, output_col);
|
|
||||||
output_col += compptr->DCT_h_scaled_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
blkn += compptr->MCU_width;
|
|
||||||
output_ptr += compptr->DCT_v_scaled_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
|
||||||
coef->MCU_ctr = 0;
|
|
||||||
}
|
|
||||||
/* Completed the iMCU row, advance counters for next one */
|
|
||||||
cinfo->output_iMCU_row++;
|
|
||||||
if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
|
|
||||||
start_iMCU_row(cinfo);
|
|
||||||
return JPEG_ROW_COMPLETED;
|
|
||||||
}
|
|
||||||
/* Completed the scan */
|
|
||||||
(*cinfo->inputctl->finish_input_pass) (cinfo);
|
|
||||||
return JPEG_SCAN_COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dummy consume-input routine for single-pass operation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(int)
|
|
||||||
dummy_consume_data (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
return JPEG_SUSPENDED; /* Always indicate nothing was done */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Consume input data and store it in the full-image coefficient buffer.
|
|
||||||
* We read as much as one fully interleaved MCU row ("iMCU" row) per call,
|
|
||||||
* ie, v_samp_factor block rows for each component in the scan.
|
|
||||||
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(int)
|
|
||||||
consume_data (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
|
||||||
JDIMENSION MCU_col_num; /* index of current MCU within row */
|
|
||||||
int blkn, ci, xindex, yindex, yoffset;
|
|
||||||
JDIMENSION start_col;
|
|
||||||
JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
|
|
||||||
JBLOCKROW buffer_ptr;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
|
|
||||||
/* Align the virtual buffers for the components used in this scan. */
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
buffer[ci] = (*cinfo->mem->access_virt_barray)
|
|
||||||
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
|
|
||||||
cinfo->input_iMCU_row * compptr->v_samp_factor,
|
|
||||||
(JDIMENSION) compptr->v_samp_factor, TRUE);
|
|
||||||
/* Note: entropy decoder expects buffer to be zeroed,
|
|
||||||
* but this is handled automatically by the memory manager
|
|
||||||
* because we requested a pre-zeroed array.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop to process one whole iMCU row */
|
|
||||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
|
||||||
yoffset++) {
|
|
||||||
for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
|
|
||||||
MCU_col_num++) {
|
|
||||||
/* Construct list of pointers to DCT blocks belonging to this MCU */
|
|
||||||
blkn = 0; /* index of current DCT block within MCU */
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
start_col = MCU_col_num * compptr->MCU_width;
|
|
||||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
|
||||||
buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
|
|
||||||
for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
|
|
||||||
coef->MCU_buffer[blkn++] = buffer_ptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Try to fetch the MCU. */
|
|
||||||
if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
|
|
||||||
/* Suspension forced; update state counters and exit */
|
|
||||||
coef->MCU_vert_offset = yoffset;
|
|
||||||
coef->MCU_ctr = MCU_col_num;
|
|
||||||
return JPEG_SUSPENDED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Completed an MCU row, but perhaps not an iMCU row */
|
|
||||||
coef->MCU_ctr = 0;
|
|
||||||
}
|
|
||||||
/* Completed the iMCU row, advance counters for next one */
|
|
||||||
if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
|
|
||||||
start_iMCU_row(cinfo);
|
|
||||||
return JPEG_ROW_COMPLETED;
|
|
||||||
}
|
|
||||||
/* Completed the scan */
|
|
||||||
(*cinfo->inputctl->finish_input_pass) (cinfo);
|
|
||||||
return JPEG_SCAN_COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decompress and return some data in the multi-pass case.
|
|
||||||
* Always attempts to emit one fully interleaved MCU row ("iMCU" row).
|
|
||||||
* Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
|
|
||||||
*
|
|
||||||
* NB: output_buf contains a plane for each component in image.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(int)
|
|
||||||
decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|
||||||
{
|
|
||||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
|
||||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
|
||||||
JDIMENSION block_num;
|
|
||||||
int ci, block_row, block_rows;
|
|
||||||
JBLOCKARRAY buffer;
|
|
||||||
JBLOCKROW buffer_ptr;
|
|
||||||
JSAMPARRAY output_ptr;
|
|
||||||
JDIMENSION output_col;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
inverse_DCT_method_ptr inverse_DCT;
|
|
||||||
|
|
||||||
/* Force some input to be done if we are getting ahead of the input. */
|
|
||||||
while (cinfo->input_scan_number < cinfo->output_scan_number ||
|
|
||||||
(cinfo->input_scan_number == cinfo->output_scan_number &&
|
|
||||||
cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
|
|
||||||
if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
|
|
||||||
return JPEG_SUSPENDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK, output from the virtual arrays. */
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Don't bother to IDCT an uninteresting component. */
|
|
||||||
if (! compptr->component_needed)
|
|
||||||
continue;
|
|
||||||
/* Align the virtual buffer for this component. */
|
|
||||||
buffer = (*cinfo->mem->access_virt_barray)
|
|
||||||
((j_common_ptr) cinfo, coef->whole_image[ci],
|
|
||||||
cinfo->output_iMCU_row * compptr->v_samp_factor,
|
|
||||||
(JDIMENSION) compptr->v_samp_factor, FALSE);
|
|
||||||
/* Count non-dummy DCT block rows in this iMCU row. */
|
|
||||||
if (cinfo->output_iMCU_row < last_iMCU_row)
|
|
||||||
block_rows = compptr->v_samp_factor;
|
|
||||||
else {
|
|
||||||
/* NB: can't use last_row_height here; it is input-side-dependent! */
|
|
||||||
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
|
||||||
if (block_rows == 0) block_rows = compptr->v_samp_factor;
|
|
||||||
}
|
|
||||||
inverse_DCT = cinfo->idct->inverse_DCT[ci];
|
|
||||||
output_ptr = output_buf[ci];
|
|
||||||
/* Loop over all DCT blocks to be processed. */
|
|
||||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
|
||||||
buffer_ptr = buffer[block_row];
|
|
||||||
output_col = 0;
|
|
||||||
for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
|
|
||||||
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
|
|
||||||
output_ptr, output_col);
|
|
||||||
buffer_ptr++;
|
|
||||||
output_col += compptr->DCT_h_scaled_size;
|
|
||||||
}
|
|
||||||
output_ptr += compptr->DCT_v_scaled_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
|
|
||||||
return JPEG_ROW_COMPLETED;
|
|
||||||
return JPEG_SCAN_COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This code applies interblock smoothing as described by section K.8
|
|
||||||
* of the JPEG standard: the first 5 AC coefficients are estimated from
|
|
||||||
* the DC values of a DCT block and its 8 neighboring blocks.
|
|
||||||
* We apply smoothing only for progressive JPEG decoding, and only if
|
|
||||||
* the coefficients it can estimate are not yet known to full precision.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Natural-order array positions of the first 5 zigzag-order coefficients */
|
|
||||||
#define Q01_POS 1
|
|
||||||
#define Q10_POS 8
|
|
||||||
#define Q20_POS 16
|
|
||||||
#define Q11_POS 9
|
|
||||||
#define Q02_POS 2
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine whether block smoothing is applicable and safe.
|
|
||||||
* We also latch the current states of the coef_bits[] entries for the
|
|
||||||
* AC coefficients; otherwise, if the input side of the decompressor
|
|
||||||
* advances into a new scan, we might think the coefficients are known
|
|
||||||
* more accurately than they really are.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(boolean)
|
|
||||||
smoothing_ok (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
|
||||||
boolean smoothing_useful = FALSE;
|
|
||||||
int ci, coefi;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
JQUANT_TBL * qtable;
|
|
||||||
int * coef_bits;
|
|
||||||
int * coef_bits_latch;
|
|
||||||
|
|
||||||
if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Allocate latch area if not already done */
|
|
||||||
if (coef->coef_bits_latch == NULL)
|
|
||||||
coef->coef_bits_latch = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
cinfo->num_components *
|
|
||||||
(SAVED_COEFS * SIZEOF(int)));
|
|
||||||
coef_bits_latch = coef->coef_bits_latch;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* All components' quantization values must already be latched. */
|
|
||||||
if ((qtable = compptr->quant_table) == NULL)
|
|
||||||
return FALSE;
|
|
||||||
/* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
|
|
||||||
if (qtable->quantval[0] == 0 ||
|
|
||||||
qtable->quantval[Q01_POS] == 0 ||
|
|
||||||
qtable->quantval[Q10_POS] == 0 ||
|
|
||||||
qtable->quantval[Q20_POS] == 0 ||
|
|
||||||
qtable->quantval[Q11_POS] == 0 ||
|
|
||||||
qtable->quantval[Q02_POS] == 0)
|
|
||||||
return FALSE;
|
|
||||||
/* DC values must be at least partly known for all components. */
|
|
||||||
coef_bits = cinfo->coef_bits[ci];
|
|
||||||
if (coef_bits[0] < 0)
|
|
||||||
return FALSE;
|
|
||||||
/* Block smoothing is helpful if some AC coefficients remain inaccurate. */
|
|
||||||
for (coefi = 1; coefi <= 5; coefi++) {
|
|
||||||
coef_bits_latch[coefi] = coef_bits[coefi];
|
|
||||||
if (coef_bits[coefi] != 0)
|
|
||||||
smoothing_useful = TRUE;
|
|
||||||
}
|
|
||||||
coef_bits_latch += SAVED_COEFS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return smoothing_useful;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Variant of decompress_data for use when doing block smoothing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(int)
|
|
||||||
decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
|
||||||
{
|
|
||||||
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
|
|
||||||
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
|
|
||||||
JDIMENSION block_num, last_block_column;
|
|
||||||
int ci, block_row, block_rows, access_rows;
|
|
||||||
JBLOCKARRAY buffer;
|
|
||||||
JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
|
|
||||||
JSAMPARRAY output_ptr;
|
|
||||||
JDIMENSION output_col;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
inverse_DCT_method_ptr inverse_DCT;
|
|
||||||
boolean first_row, last_row;
|
|
||||||
JBLOCK workspace;
|
|
||||||
int *coef_bits;
|
|
||||||
JQUANT_TBL *quanttbl;
|
|
||||||
INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
|
|
||||||
int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
|
|
||||||
int Al, pred;
|
|
||||||
|
|
||||||
/* Force some input to be done if we are getting ahead of the input. */
|
|
||||||
while (cinfo->input_scan_number <= cinfo->output_scan_number &&
|
|
||||||
! cinfo->inputctl->eoi_reached) {
|
|
||||||
if (cinfo->input_scan_number == cinfo->output_scan_number) {
|
|
||||||
/* If input is working on current scan, we ordinarily want it to
|
|
||||||
* have completed the current row. But if input scan is DC,
|
|
||||||
* we want it to keep one row ahead so that next block row's DC
|
|
||||||
* values are up to date.
|
|
||||||
*/
|
|
||||||
JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
|
|
||||||
if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
|
|
||||||
return JPEG_SUSPENDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK, output from the virtual arrays. */
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Don't bother to IDCT an uninteresting component. */
|
|
||||||
if (! compptr->component_needed)
|
|
||||||
continue;
|
|
||||||
/* Count non-dummy DCT block rows in this iMCU row. */
|
|
||||||
if (cinfo->output_iMCU_row < last_iMCU_row) {
|
|
||||||
block_rows = compptr->v_samp_factor;
|
|
||||||
access_rows = block_rows * 2; /* this and next iMCU row */
|
|
||||||
last_row = FALSE;
|
|
||||||
} else {
|
|
||||||
/* NB: can't use last_row_height here; it is input-side-dependent! */
|
|
||||||
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
|
||||||
if (block_rows == 0) block_rows = compptr->v_samp_factor;
|
|
||||||
access_rows = block_rows; /* this iMCU row only */
|
|
||||||
last_row = TRUE;
|
|
||||||
}
|
|
||||||
/* Align the virtual buffer for this component. */
|
|
||||||
if (cinfo->output_iMCU_row > 0) {
|
|
||||||
access_rows += compptr->v_samp_factor; /* prior iMCU row too */
|
|
||||||
buffer = (*cinfo->mem->access_virt_barray)
|
|
||||||
((j_common_ptr) cinfo, coef->whole_image[ci],
|
|
||||||
(cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
|
|
||||||
(JDIMENSION) access_rows, FALSE);
|
|
||||||
buffer += compptr->v_samp_factor; /* point to current iMCU row */
|
|
||||||
first_row = FALSE;
|
|
||||||
} else {
|
|
||||||
buffer = (*cinfo->mem->access_virt_barray)
|
|
||||||
((j_common_ptr) cinfo, coef->whole_image[ci],
|
|
||||||
(JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
|
|
||||||
first_row = TRUE;
|
|
||||||
}
|
|
||||||
/* Fetch component-dependent info */
|
|
||||||
coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
|
|
||||||
quanttbl = compptr->quant_table;
|
|
||||||
Q00 = quanttbl->quantval[0];
|
|
||||||
Q01 = quanttbl->quantval[Q01_POS];
|
|
||||||
Q10 = quanttbl->quantval[Q10_POS];
|
|
||||||
Q20 = quanttbl->quantval[Q20_POS];
|
|
||||||
Q11 = quanttbl->quantval[Q11_POS];
|
|
||||||
Q02 = quanttbl->quantval[Q02_POS];
|
|
||||||
inverse_DCT = cinfo->idct->inverse_DCT[ci];
|
|
||||||
output_ptr = output_buf[ci];
|
|
||||||
/* Loop over all DCT blocks to be processed. */
|
|
||||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
|
||||||
buffer_ptr = buffer[block_row];
|
|
||||||
if (first_row && block_row == 0)
|
|
||||||
prev_block_row = buffer_ptr;
|
|
||||||
else
|
|
||||||
prev_block_row = buffer[block_row-1];
|
|
||||||
if (last_row && block_row == block_rows-1)
|
|
||||||
next_block_row = buffer_ptr;
|
|
||||||
else
|
|
||||||
next_block_row = buffer[block_row+1];
|
|
||||||
/* We fetch the surrounding DC values using a sliding-register approach.
|
|
||||||
* Initialize all nine here so as to do the right thing on narrow pics.
|
|
||||||
*/
|
|
||||||
DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
|
|
||||||
DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
|
|
||||||
DC7 = DC8 = DC9 = (int) next_block_row[0][0];
|
|
||||||
output_col = 0;
|
|
||||||
last_block_column = compptr->width_in_blocks - 1;
|
|
||||||
for (block_num = 0; block_num <= last_block_column; block_num++) {
|
|
||||||
/* Fetch current DCT block into workspace so we can modify it. */
|
|
||||||
jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
|
|
||||||
/* Update DC values */
|
|
||||||
if (block_num < last_block_column) {
|
|
||||||
DC3 = (int) prev_block_row[1][0];
|
|
||||||
DC6 = (int) buffer_ptr[1][0];
|
|
||||||
DC9 = (int) next_block_row[1][0];
|
|
||||||
}
|
|
||||||
/* Compute coefficient estimates per K.8.
|
|
||||||
* An estimate is applied only if coefficient is still zero,
|
|
||||||
* and is not known to be fully accurate.
|
|
||||||
*/
|
|
||||||
/* AC01 */
|
|
||||||
if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
|
|
||||||
num = 36 * Q00 * (DC4 - DC6);
|
|
||||||
if (num >= 0) {
|
|
||||||
pred = (int) (((Q01<<7) + num) / (Q01<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
} else {
|
|
||||||
pred = (int) (((Q01<<7) - num) / (Q01<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
pred = -pred;
|
|
||||||
}
|
|
||||||
workspace[1] = (JCOEF) pred;
|
|
||||||
}
|
|
||||||
/* AC10 */
|
|
||||||
if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
|
|
||||||
num = 36 * Q00 * (DC2 - DC8);
|
|
||||||
if (num >= 0) {
|
|
||||||
pred = (int) (((Q10<<7) + num) / (Q10<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
} else {
|
|
||||||
pred = (int) (((Q10<<7) - num) / (Q10<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
pred = -pred;
|
|
||||||
}
|
|
||||||
workspace[8] = (JCOEF) pred;
|
|
||||||
}
|
|
||||||
/* AC20 */
|
|
||||||
if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
|
|
||||||
num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
|
|
||||||
if (num >= 0) {
|
|
||||||
pred = (int) (((Q20<<7) + num) / (Q20<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
} else {
|
|
||||||
pred = (int) (((Q20<<7) - num) / (Q20<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
pred = -pred;
|
|
||||||
}
|
|
||||||
workspace[16] = (JCOEF) pred;
|
|
||||||
}
|
|
||||||
/* AC11 */
|
|
||||||
if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
|
|
||||||
num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
|
|
||||||
if (num >= 0) {
|
|
||||||
pred = (int) (((Q11<<7) + num) / (Q11<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
} else {
|
|
||||||
pred = (int) (((Q11<<7) - num) / (Q11<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
pred = -pred;
|
|
||||||
}
|
|
||||||
workspace[9] = (JCOEF) pred;
|
|
||||||
}
|
|
||||||
/* AC02 */
|
|
||||||
if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
|
|
||||||
num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
|
|
||||||
if (num >= 0) {
|
|
||||||
pred = (int) (((Q02<<7) + num) / (Q02<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
} else {
|
|
||||||
pred = (int) (((Q02<<7) - num) / (Q02<<8));
|
|
||||||
if (Al > 0 && pred >= (1<<Al))
|
|
||||||
pred = (1<<Al)-1;
|
|
||||||
pred = -pred;
|
|
||||||
}
|
|
||||||
workspace[2] = (JCOEF) pred;
|
|
||||||
}
|
|
||||||
/* OK, do the IDCT */
|
|
||||||
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
|
|
||||||
output_ptr, output_col);
|
|
||||||
/* Advance for next column */
|
|
||||||
DC1 = DC2; DC2 = DC3;
|
|
||||||
DC4 = DC5; DC5 = DC6;
|
|
||||||
DC7 = DC8; DC8 = DC9;
|
|
||||||
buffer_ptr++, prev_block_row++, next_block_row++;
|
|
||||||
output_col += compptr->DCT_h_scaled_size;
|
|
||||||
}
|
|
||||||
output_ptr += compptr->DCT_v_scaled_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
|
|
||||||
return JPEG_ROW_COMPLETED;
|
|
||||||
return JPEG_SCAN_COMPLETED;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* BLOCK_SMOOTHING_SUPPORTED */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize coefficient buffer controller.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
|
|
||||||
{
|
|
||||||
my_coef_ptr coef;
|
|
||||||
|
|
||||||
coef = (my_coef_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_coef_controller));
|
|
||||||
cinfo->coef = (struct jpeg_d_coef_controller *) coef;
|
|
||||||
coef->pub.start_input_pass = start_input_pass;
|
|
||||||
coef->pub.start_output_pass = start_output_pass;
|
|
||||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
|
||||||
coef->coef_bits_latch = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Create the coefficient buffer. */
|
|
||||||
if (need_full_buffer) {
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
/* Allocate a full-image virtual array for each component, */
|
|
||||||
/* padded to a multiple of samp_factor DCT blocks in each direction. */
|
|
||||||
/* Note we ask for a pre-zeroed array. */
|
|
||||||
int ci, access_rows;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
access_rows = compptr->v_samp_factor;
|
|
||||||
#ifdef BLOCK_SMOOTHING_SUPPORTED
|
|
||||||
/* If block smoothing could be used, need a bigger window */
|
|
||||||
if (cinfo->progressive_mode)
|
|
||||||
access_rows *= 3;
|
|
||||||
#endif
|
|
||||||
coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
|
|
||||||
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
|
|
||||||
(long) compptr->h_samp_factor),
|
|
||||||
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
|
|
||||||
(long) compptr->v_samp_factor),
|
|
||||||
(JDIMENSION) access_rows);
|
|
||||||
}
|
|
||||||
coef->pub.consume_data = consume_data;
|
|
||||||
coef->pub.decompress_data = decompress_data;
|
|
||||||
coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
/* We only need a single-MCU buffer. */
|
|
||||||
JBLOCKROW buffer;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
buffer = (JBLOCKROW)
|
|
||||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
|
|
||||||
for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
|
|
||||||
coef->MCU_buffer[i] = buffer + i;
|
|
||||||
}
|
|
||||||
if (cinfo->lim_Se == 0) /* DC only case: want to bypass later */
|
|
||||||
FMEMZERO((void FAR *) buffer,
|
|
||||||
(size_t) (D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)));
|
|
||||||
coef->pub.consume_data = dummy_consume_data;
|
|
||||||
coef->pub.decompress_data = decompress_onepass;
|
|
||||||
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,731 +0,0 @@
|
||||||
/*
|
|
||||||
* jdcolor.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
|
||||||
* Modified 2011-2017 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 output colorspace conversion routines.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if RANGE_BITS < 2
|
|
||||||
/* Deliberate syntax err */
|
|
||||||
Sorry, this code requires 2 or more range extension bits.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Private subobject */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_color_deconverter pub; /* public fields */
|
|
||||||
|
|
||||||
/* Private state for YCbCr->RGB and BG_YCC->RGB conversion */
|
|
||||||
int * Cr_r_tab; /* => table for Cr to R conversion */
|
|
||||||
int * Cb_b_tab; /* => table for Cb to B conversion */
|
|
||||||
INT32 * Cr_g_tab; /* => table for Cr to G conversion */
|
|
||||||
INT32 * Cb_g_tab; /* => table for Cb to G conversion */
|
|
||||||
|
|
||||||
/* Private state for RGB->Y conversion */
|
|
||||||
INT32 * rgb_y_tab; /* => table for RGB to Y conversion */
|
|
||||||
} my_color_deconverter;
|
|
||||||
|
|
||||||
typedef my_color_deconverter * my_cconvert_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
/*************** YCbCr -> RGB conversion: most common case **************/
|
|
||||||
/*************** BG_YCC -> RGB conversion: less common case **************/
|
|
||||||
/*************** RGB -> Y conversion: less common case **************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011),
|
|
||||||
* previously known as Recommendation CCIR 601-1, except that Cb and Cr
|
|
||||||
* are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
|
|
||||||
* sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999.
|
|
||||||
* sYCC (standard luma-chroma-chroma color space with extended gamut)
|
|
||||||
* is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F.
|
|
||||||
* bg-sRGB and bg-sYCC (big gamut standard color spaces)
|
|
||||||
* are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G.
|
|
||||||
* Note that the derived conversion coefficients given in some of these
|
|
||||||
* documents are imprecise. The general conversion equations are
|
|
||||||
*
|
|
||||||
* R = Y + K * (1 - Kr) * Cr
|
|
||||||
* G = Y - K * (Kb * (1 - Kb) * Cb + Kr * (1 - Kr) * Cr) / (1 - Kr - Kb)
|
|
||||||
* B = Y + K * (1 - Kb) * Cb
|
|
||||||
*
|
|
||||||
* Y = Kr * R + (1 - Kr - Kb) * G + Kb * B
|
|
||||||
*
|
|
||||||
* With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993
|
|
||||||
* from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC,
|
|
||||||
* the conversion equations to be implemented are therefore
|
|
||||||
*
|
|
||||||
* R = Y + 1.402 * Cr
|
|
||||||
* G = Y - 0.344136286 * Cb - 0.714136286 * Cr
|
|
||||||
* B = Y + 1.772 * Cb
|
|
||||||
*
|
|
||||||
* Y = 0.299 * R + 0.587 * G + 0.114 * B
|
|
||||||
*
|
|
||||||
* where Cb and Cr represent the incoming values less CENTERJSAMPLE.
|
|
||||||
* For bg-sYCC, with K = 4, the equations are
|
|
||||||
*
|
|
||||||
* R = Y + 2.804 * Cr
|
|
||||||
* G = Y - 0.688272572 * Cb - 1.428272572 * Cr
|
|
||||||
* B = Y + 3.544 * Cb
|
|
||||||
*
|
|
||||||
* To avoid floating-point arithmetic, we represent the fractional constants
|
|
||||||
* as integers scaled up by 2^16 (about 4 digits precision); we have to divide
|
|
||||||
* the products by 2^16, with appropriate rounding, to get the correct answer.
|
|
||||||
* Notice that Y, being an integral input, does not contribute any fraction
|
|
||||||
* so it need not participate in the rounding.
|
|
||||||
*
|
|
||||||
* For even more speed, we avoid doing any multiplications in the inner loop
|
|
||||||
* by precalculating the constants times Cb and Cr for all possible values.
|
|
||||||
* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
|
|
||||||
* for 9-bit to 12-bit samples it is still acceptable. It's not very
|
|
||||||
* reasonable for 16-bit samples, but if you want lossless storage you
|
|
||||||
* shouldn't be changing colorspace anyway.
|
|
||||||
* The Cr=>R and Cb=>B values can be rounded to integers in advance; the
|
|
||||||
* values for the G calculation are left scaled up, since we must add them
|
|
||||||
* together before rounding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
|
||||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
|
||||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
|
||||||
|
|
||||||
/* We allocate one big table for RGB->Y conversion and divide it up into
|
|
||||||
* three parts, instead of doing three alloc_small requests. This lets us
|
|
||||||
* use a single table base address, which can be held in a register in the
|
|
||||||
* inner loops on many machines (more than can hold all three addresses,
|
|
||||||
* anyway).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define R_Y_OFF 0 /* offset to R => Y section */
|
|
||||||
#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
|
|
||||||
#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
|
|
||||||
#define TABLE_SIZE (3*(MAXJSAMPLE+1))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
build_ycc_rgb_table (j_decompress_ptr cinfo)
|
|
||||||
/* Normal case, sYCC */
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
|
||||||
int i;
|
|
||||||
INT32 x;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
cconvert->Cr_r_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
cconvert->Cb_b_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
cconvert->Cr_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
cconvert->Cb_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
|
|
||||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
|
||||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
|
||||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
|
||||||
/* Cr=>R value is nearest int to 1.402 * x */
|
|
||||||
cconvert->Cr_r_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cb=>B value is nearest int to 1.772 * x */
|
|
||||||
cconvert->Cb_b_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cr=>G value is scaled-up -0.714136286 * x */
|
|
||||||
cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
|
|
||||||
/* Cb=>G value is scaled-up -0.344136286 * x */
|
|
||||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
|
||||||
cconvert->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
|
|
||||||
/* Wide gamut case, bg-sYCC */
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
|
||||||
int i;
|
|
||||||
INT32 x;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
cconvert->Cr_r_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
cconvert->Cb_b_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
cconvert->Cr_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
cconvert->Cb_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
|
|
||||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
|
||||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
|
||||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
|
||||||
/* Cr=>R value is nearest int to 2.804 * x */
|
|
||||||
cconvert->Cr_r_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cb=>B value is nearest int to 3.544 * x */
|
|
||||||
cconvert->Cb_b_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cr=>G value is scaled-up -1.428272572 * x */
|
|
||||||
cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
|
|
||||||
/* Cb=>G value is scaled-up -0.688272572 * x */
|
|
||||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
|
||||||
cconvert->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert some rows of samples to the output colorspace.
|
|
||||||
*
|
|
||||||
* Note that we change from noninterleaved, one-plane-per-component format
|
|
||||||
* to interleaved-pixel format. The output buffer is therefore three times
|
|
||||||
* as wide as the input buffer.
|
|
||||||
* A starting row offset is provided only for the input buffer. The caller
|
|
||||||
* can easily adjust the passed output_buf value to accommodate any row
|
|
||||||
* offset required on that side.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
ycc_rgb_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
|
||||||
register int y, cb, cr;
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr0, inptr1, inptr2;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
/* copy these pointers into registers if possible */
|
|
||||||
register JSAMPLE * range_limit = cinfo->sample_range_limit;
|
|
||||||
register int * Crrtab = cconvert->Cr_r_tab;
|
|
||||||
register int * Cbbtab = cconvert->Cb_b_tab;
|
|
||||||
register INT32 * Crgtab = cconvert->Cr_g_tab;
|
|
||||||
register INT32 * Cbgtab = cconvert->Cb_g_tab;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
inptr0 = input_buf[0][input_row];
|
|
||||||
inptr1 = input_buf[1][input_row];
|
|
||||||
inptr2 = input_buf[2][input_row];
|
|
||||||
input_row++;
|
|
||||||
outptr = *output_buf++;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
y = GETJSAMPLE(inptr0[col]);
|
|
||||||
cb = GETJSAMPLE(inptr1[col]);
|
|
||||||
cr = GETJSAMPLE(inptr2[col]);
|
|
||||||
/* Range-limiting is essential due to noise introduced by DCT losses,
|
|
||||||
* for extended gamut (sYCC) and wide gamut (bg-sYCC) encodings.
|
|
||||||
*/
|
|
||||||
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
|
|
||||||
outptr[RGB_GREEN] = range_limit[y +
|
|
||||||
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
||||||
SCALEBITS))];
|
|
||||||
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
|
|
||||||
outptr += RGB_PIXELSIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************** Cases other than YCC -> RGB ****************/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for RGB->grayscale colorspace conversion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
build_rgb_y_table (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
|
||||||
INT32 * rgb_y_tab;
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
/* Allocate and fill in the conversion tables. */
|
|
||||||
cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(TABLE_SIZE * SIZEOF(INT32)));
|
|
||||||
|
|
||||||
for (i = 0; i <= MAXJSAMPLE; i++) {
|
|
||||||
rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i;
|
|
||||||
rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i;
|
|
||||||
rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert RGB to grayscale.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
rgb_gray_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
|
||||||
register INT32 * ctab = cconvert->rgb_y_tab;
|
|
||||||
register int r, g, b;
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr0, inptr1, inptr2;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
inptr0 = input_buf[0][input_row];
|
|
||||||
inptr1 = input_buf[1][input_row];
|
|
||||||
inptr2 = input_buf[2][input_row];
|
|
||||||
input_row++;
|
|
||||||
outptr = *output_buf++;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
r = GETJSAMPLE(inptr0[col]);
|
|
||||||
g = GETJSAMPLE(inptr1[col]);
|
|
||||||
b = GETJSAMPLE(inptr2[col]);
|
|
||||||
/* Y */
|
|
||||||
outptr[col] = (JSAMPLE)
|
|
||||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
|
||||||
>> SCALEBITS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
|
|
||||||
* (inverse color transform).
|
|
||||||
* This can be seen as an adaption of the general YCbCr->RGB
|
|
||||||
* conversion equation with Kr = Kb = 0, while replacing the
|
|
||||||
* normalization by modulo calculation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
rgb1_rgb_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
register int r, g, b;
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr0, inptr1, inptr2;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
inptr0 = input_buf[0][input_row];
|
|
||||||
inptr1 = input_buf[1][input_row];
|
|
||||||
inptr2 = input_buf[2][input_row];
|
|
||||||
input_row++;
|
|
||||||
outptr = *output_buf++;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
r = GETJSAMPLE(inptr0[col]);
|
|
||||||
g = GETJSAMPLE(inptr1[col]);
|
|
||||||
b = GETJSAMPLE(inptr2[col]);
|
|
||||||
/* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
|
|
||||||
* (modulo) operator is equivalent to the bitmask operator AND.
|
|
||||||
*/
|
|
||||||
outptr[RGB_RED] = (JSAMPLE) ((r + g - CENTERJSAMPLE) & MAXJSAMPLE);
|
|
||||||
outptr[RGB_GREEN] = (JSAMPLE) g;
|
|
||||||
outptr[RGB_BLUE] = (JSAMPLE) ((b + g - CENTERJSAMPLE) & MAXJSAMPLE);
|
|
||||||
outptr += RGB_PIXELSIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* [R-G,G,B-G] to grayscale conversion with modulo calculation
|
|
||||||
* (inverse color transform).
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
rgb1_gray_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
|
||||||
register INT32 * ctab = cconvert->rgb_y_tab;
|
|
||||||
register int r, g, b;
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr0, inptr1, inptr2;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
inptr0 = input_buf[0][input_row];
|
|
||||||
inptr1 = input_buf[1][input_row];
|
|
||||||
inptr2 = input_buf[2][input_row];
|
|
||||||
input_row++;
|
|
||||||
outptr = *output_buf++;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
r = GETJSAMPLE(inptr0[col]);
|
|
||||||
g = GETJSAMPLE(inptr1[col]);
|
|
||||||
b = GETJSAMPLE(inptr2[col]);
|
|
||||||
/* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
|
|
||||||
* (modulo) operator is equivalent to the bitmask operator AND.
|
|
||||||
*/
|
|
||||||
r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE;
|
|
||||||
b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE;
|
|
||||||
/* Y */
|
|
||||||
outptr[col] = (JSAMPLE)
|
|
||||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
|
||||||
>> SCALEBITS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* No colorspace change, but conversion from separate-planes
|
|
||||||
* to interleaved representation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
rgb_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr0, inptr1, inptr2;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
inptr0 = input_buf[0][input_row];
|
|
||||||
inptr1 = input_buf[1][input_row];
|
|
||||||
inptr2 = input_buf[2][input_row];
|
|
||||||
input_row++;
|
|
||||||
outptr = *output_buf++;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
/* We can dispense with GETJSAMPLE() here */
|
|
||||||
outptr[RGB_RED] = inptr0[col];
|
|
||||||
outptr[RGB_GREEN] = inptr1[col];
|
|
||||||
outptr[RGB_BLUE] = inptr2[col];
|
|
||||||
outptr += RGB_PIXELSIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Color conversion for no colorspace change: just copy the data,
|
|
||||||
* converting from separate-planes to interleaved representation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
null_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
int ci;
|
|
||||||
register int nc = cinfo->num_components;
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
for (ci = 0; ci < nc; ci++) {
|
|
||||||
inptr = input_buf[ci][input_row];
|
|
||||||
outptr = output_buf[0] + ci;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
*outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
|
|
||||||
outptr += nc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input_row++;
|
|
||||||
output_buf++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Color conversion for grayscale: just copy the data.
|
|
||||||
* This also works for YCC -> grayscale conversion, in which
|
|
||||||
* we just copy the Y (luminance) component and ignore chrominance.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
grayscale_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
|
|
||||||
num_rows, cinfo->output_width);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert grayscale to RGB: just duplicate the graylevel three times.
|
|
||||||
* This is provided to support applications that don't want to cope
|
|
||||||
* with grayscale as a separate case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
gray_rgb_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
inptr = input_buf[0][input_row++];
|
|
||||||
outptr = *output_buf++;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
/* We can dispense with GETJSAMPLE() here */
|
|
||||||
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
|
||||||
outptr += RGB_PIXELSIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Adobe-style YCCK->CMYK conversion.
|
|
||||||
* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
|
|
||||||
* conversion as above, while passing K (black) unchanged.
|
|
||||||
* We assume build_ycc_rgb_table has been called.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
ycck_cmyk_convert (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
|
||||||
register int y, cb, cr;
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
register JSAMPROW inptr0, inptr1, inptr2, inptr3;
|
|
||||||
register JDIMENSION col;
|
|
||||||
JDIMENSION num_cols = cinfo->output_width;
|
|
||||||
/* copy these pointers into registers if possible */
|
|
||||||
register JSAMPLE * range_limit = cinfo->sample_range_limit;
|
|
||||||
register int * Crrtab = cconvert->Cr_r_tab;
|
|
||||||
register int * Cbbtab = cconvert->Cb_b_tab;
|
|
||||||
register INT32 * Crgtab = cconvert->Cr_g_tab;
|
|
||||||
register INT32 * Cbgtab = cconvert->Cb_g_tab;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
while (--num_rows >= 0) {
|
|
||||||
inptr0 = input_buf[0][input_row];
|
|
||||||
inptr1 = input_buf[1][input_row];
|
|
||||||
inptr2 = input_buf[2][input_row];
|
|
||||||
inptr3 = input_buf[3][input_row];
|
|
||||||
input_row++;
|
|
||||||
outptr = *output_buf++;
|
|
||||||
for (col = 0; col < num_cols; col++) {
|
|
||||||
y = GETJSAMPLE(inptr0[col]);
|
|
||||||
cb = GETJSAMPLE(inptr1[col]);
|
|
||||||
cr = GETJSAMPLE(inptr2[col]);
|
|
||||||
/* Range-limiting is essential due to noise introduced by DCT losses,
|
|
||||||
* and for extended gamut encodings (sYCC).
|
|
||||||
*/
|
|
||||||
outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
|
|
||||||
outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
|
|
||||||
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
||||||
SCALEBITS)))];
|
|
||||||
outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
|
|
||||||
/* K passes through unchanged */
|
|
||||||
outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
|
|
||||||
outptr += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Empty method for start_pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass_dcolor (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* no work needed */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module initialization routine for output colorspace conversion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_color_deconverter (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_cconvert_ptr cconvert;
|
|
||||||
int ci;
|
|
||||||
|
|
||||||
cconvert = (my_cconvert_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_color_deconverter));
|
|
||||||
cinfo->cconvert = &cconvert->pub;
|
|
||||||
cconvert->pub.start_pass = start_pass_dcolor;
|
|
||||||
|
|
||||||
/* Make sure num_components agrees with jpeg_color_space */
|
|
||||||
switch (cinfo->jpeg_color_space) {
|
|
||||||
case JCS_GRAYSCALE:
|
|
||||||
if (cinfo->num_components != 1)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_RGB:
|
|
||||||
case JCS_YCbCr:
|
|
||||||
case JCS_BG_RGB:
|
|
||||||
case JCS_BG_YCC:
|
|
||||||
if (cinfo->num_components != 3)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_CMYK:
|
|
||||||
case JCS_YCCK:
|
|
||||||
if (cinfo->num_components != 4)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* JCS_UNKNOWN can be anything */
|
|
||||||
if (cinfo->num_components < 1)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Support color transform only for RGB colorspaces */
|
|
||||||
if (cinfo->color_transform &&
|
|
||||||
cinfo->jpeg_color_space != JCS_RGB &&
|
|
||||||
cinfo->jpeg_color_space != JCS_BG_RGB)
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
|
|
||||||
/* Set out_color_components and conversion method based on requested space.
|
|
||||||
* Also clear the component_needed flags for any unused components,
|
|
||||||
* so that earlier pipeline stages can avoid useless computation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (cinfo->out_color_space) {
|
|
||||||
case JCS_GRAYSCALE:
|
|
||||||
cinfo->out_color_components = 1;
|
|
||||||
switch (cinfo->jpeg_color_space) {
|
|
||||||
case JCS_GRAYSCALE:
|
|
||||||
case JCS_YCbCr:
|
|
||||||
case JCS_BG_YCC:
|
|
||||||
cconvert->pub.color_convert = grayscale_convert;
|
|
||||||
/* For color->grayscale conversion, only the Y (0) component is needed */
|
|
||||||
for (ci = 1; ci < cinfo->num_components; ci++)
|
|
||||||
cinfo->comp_info[ci].component_needed = FALSE;
|
|
||||||
break;
|
|
||||||
case JCS_RGB:
|
|
||||||
switch (cinfo->color_transform) {
|
|
||||||
case JCT_NONE:
|
|
||||||
cconvert->pub.color_convert = rgb_gray_convert;
|
|
||||||
break;
|
|
||||||
case JCT_SUBTRACT_GREEN:
|
|
||||||
cconvert->pub.color_convert = rgb1_gray_convert;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
}
|
|
||||||
build_rgb_y_table(cinfo);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_RGB:
|
|
||||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
|
||||||
switch (cinfo->jpeg_color_space) {
|
|
||||||
case JCS_GRAYSCALE:
|
|
||||||
cconvert->pub.color_convert = gray_rgb_convert;
|
|
||||||
break;
|
|
||||||
case JCS_YCbCr:
|
|
||||||
cconvert->pub.color_convert = ycc_rgb_convert;
|
|
||||||
build_ycc_rgb_table(cinfo);
|
|
||||||
break;
|
|
||||||
case JCS_BG_YCC:
|
|
||||||
cconvert->pub.color_convert = ycc_rgb_convert;
|
|
||||||
build_bg_ycc_rgb_table(cinfo);
|
|
||||||
break;
|
|
||||||
case JCS_RGB:
|
|
||||||
switch (cinfo->color_transform) {
|
|
||||||
case JCT_NONE:
|
|
||||||
cconvert->pub.color_convert = rgb_convert;
|
|
||||||
break;
|
|
||||||
case JCT_SUBTRACT_GREEN:
|
|
||||||
cconvert->pub.color_convert = rgb1_rgb_convert;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_BG_RGB:
|
|
||||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
|
||||||
if (cinfo->jpeg_color_space == JCS_BG_RGB) {
|
|
||||||
switch (cinfo->color_transform) {
|
|
||||||
case JCT_NONE:
|
|
||||||
cconvert->pub.color_convert = rgb_convert;
|
|
||||||
break;
|
|
||||||
case JCT_SUBTRACT_GREEN:
|
|
||||||
cconvert->pub.color_convert = rgb1_rgb_convert;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_CMYK:
|
|
||||||
cinfo->out_color_components = 4;
|
|
||||||
switch (cinfo->jpeg_color_space) {
|
|
||||||
case JCS_YCCK:
|
|
||||||
cconvert->pub.color_convert = ycck_cmyk_convert;
|
|
||||||
build_ycc_rgb_table(cinfo);
|
|
||||||
break;
|
|
||||||
case JCS_CMYK:
|
|
||||||
cconvert->pub.color_convert = null_convert;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Permit null conversion to same output space */
|
|
||||||
if (cinfo->out_color_space == cinfo->jpeg_color_space) {
|
|
||||||
cinfo->out_color_components = cinfo->num_components;
|
|
||||||
cconvert->pub.color_convert = null_convert;
|
|
||||||
} else /* unsupported non-null conversion */
|
|
||||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cinfo->quantize_colors)
|
|
||||||
cinfo->output_components = 1; /* single colormapped output component */
|
|
||||||
else
|
|
||||||
cinfo->output_components = cinfo->out_color_components;
|
|
||||||
}
|
|
|
@ -1,416 +0,0 @@
|
||||||
/*
|
|
||||||
* jdct.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
|
||||||
* Modified 2002-2017 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 include file contains common declarations for the forward and
|
|
||||||
* inverse DCT modules. These declarations are private to the DCT managers
|
|
||||||
* (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
|
|
||||||
* The individual DCT algorithms are kept in separate files to ease
|
|
||||||
* machine-dependent tuning (e.g., assembly coding).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A forward DCT routine is given a pointer to an input sample array and
|
|
||||||
* a pointer to a work area of type DCTELEM[]; the DCT is to be performed
|
|
||||||
* in-place in that buffer. Type DCTELEM is int for 8-bit samples, INT32
|
|
||||||
* for 12-bit samples. (NOTE: Floating-point DCT implementations use an
|
|
||||||
* array of type FAST_FLOAT, instead.)
|
|
||||||
* The input data is to be fetched from the sample array starting at a
|
|
||||||
* specified column. (Any row offset needed will be applied to the array
|
|
||||||
* pointer before it is passed to the FDCT code.)
|
|
||||||
* Note that the number of samples fetched by the FDCT routine is
|
|
||||||
* DCT_h_scaled_size * DCT_v_scaled_size.
|
|
||||||
* The DCT outputs are returned scaled up by a factor of 8; they therefore
|
|
||||||
* have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
|
|
||||||
* convention improves accuracy in integer implementations and saves some
|
|
||||||
* work in floating-point ones.
|
|
||||||
* Quantization of the output coefficients is done by jcdctmgr.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
typedef int DCTELEM; /* 16 or 32 bits is fine */
|
|
||||||
#else
|
|
||||||
typedef INT32 DCTELEM; /* must have 32 bits */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data,
|
|
||||||
JSAMPARRAY sample_data,
|
|
||||||
JDIMENSION start_col));
|
|
||||||
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data,
|
|
||||||
JSAMPARRAY sample_data,
|
|
||||||
JDIMENSION start_col));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
|
|
||||||
* to an output sample array. The routine must dequantize the input data as
|
|
||||||
* well as perform the IDCT; for dequantization, it uses the multiplier table
|
|
||||||
* pointed to by compptr->dct_table. The output data is to be placed into the
|
|
||||||
* sample array starting at a specified column. (Any row offset needed will
|
|
||||||
* be applied to the array pointer before it is passed to the IDCT code.)
|
|
||||||
* Note that the number of samples emitted by the IDCT routine is
|
|
||||||
* DCT_h_scaled_size * DCT_v_scaled_size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each IDCT routine has its own ideas about the best dct_table element type.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
|
|
||||||
#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */
|
|
||||||
#else
|
|
||||||
typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */
|
|
||||||
#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */
|
|
||||||
#endif
|
|
||||||
typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each IDCT routine is responsible for range-limiting its results and
|
|
||||||
* converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
|
|
||||||
* be quite far out of range if the input data is corrupt, so a bulletproof
|
|
||||||
* range-limiting step is required. We use a mask-and-table-lookup method
|
|
||||||
* to do the combined operations quickly, assuming that RANGE_CENTER
|
|
||||||
* (defined in jpegint.h) is a power of 2. See the comments with
|
|
||||||
* prepare_range_limit_table (in jdmaster.c) for more info.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RANGE_MASK (RANGE_CENTER * 2 - 1)
|
|
||||||
#define RANGE_SUBSET (RANGE_CENTER - CENTERJSAMPLE)
|
|
||||||
|
|
||||||
#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit - RANGE_SUBSET)
|
|
||||||
|
|
||||||
|
|
||||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
|
||||||
|
|
||||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
|
||||||
#define jpeg_fdct_islow jFDislow
|
|
||||||
#define jpeg_fdct_ifast jFDifast
|
|
||||||
#define jpeg_fdct_float jFDfloat
|
|
||||||
#define jpeg_fdct_7x7 jFD7x7
|
|
||||||
#define jpeg_fdct_6x6 jFD6x6
|
|
||||||
#define jpeg_fdct_5x5 jFD5x5
|
|
||||||
#define jpeg_fdct_4x4 jFD4x4
|
|
||||||
#define jpeg_fdct_3x3 jFD3x3
|
|
||||||
#define jpeg_fdct_2x2 jFD2x2
|
|
||||||
#define jpeg_fdct_1x1 jFD1x1
|
|
||||||
#define jpeg_fdct_9x9 jFD9x9
|
|
||||||
#define jpeg_fdct_10x10 jFD10x10
|
|
||||||
#define jpeg_fdct_11x11 jFD11x11
|
|
||||||
#define jpeg_fdct_12x12 jFD12x12
|
|
||||||
#define jpeg_fdct_13x13 jFD13x13
|
|
||||||
#define jpeg_fdct_14x14 jFD14x14
|
|
||||||
#define jpeg_fdct_15x15 jFD15x15
|
|
||||||
#define jpeg_fdct_16x16 jFD16x16
|
|
||||||
#define jpeg_fdct_16x8 jFD16x8
|
|
||||||
#define jpeg_fdct_14x7 jFD14x7
|
|
||||||
#define jpeg_fdct_12x6 jFD12x6
|
|
||||||
#define jpeg_fdct_10x5 jFD10x5
|
|
||||||
#define jpeg_fdct_8x4 jFD8x4
|
|
||||||
#define jpeg_fdct_6x3 jFD6x3
|
|
||||||
#define jpeg_fdct_4x2 jFD4x2
|
|
||||||
#define jpeg_fdct_2x1 jFD2x1
|
|
||||||
#define jpeg_fdct_8x16 jFD8x16
|
|
||||||
#define jpeg_fdct_7x14 jFD7x14
|
|
||||||
#define jpeg_fdct_6x12 jFD6x12
|
|
||||||
#define jpeg_fdct_5x10 jFD5x10
|
|
||||||
#define jpeg_fdct_4x8 jFD4x8
|
|
||||||
#define jpeg_fdct_3x6 jFD3x6
|
|
||||||
#define jpeg_fdct_2x4 jFD2x4
|
|
||||||
#define jpeg_fdct_1x2 jFD1x2
|
|
||||||
#define jpeg_idct_islow jRDislow
|
|
||||||
#define jpeg_idct_ifast jRDifast
|
|
||||||
#define jpeg_idct_float jRDfloat
|
|
||||||
#define jpeg_idct_7x7 jRD7x7
|
|
||||||
#define jpeg_idct_6x6 jRD6x6
|
|
||||||
#define jpeg_idct_5x5 jRD5x5
|
|
||||||
#define jpeg_idct_4x4 jRD4x4
|
|
||||||
#define jpeg_idct_3x3 jRD3x3
|
|
||||||
#define jpeg_idct_2x2 jRD2x2
|
|
||||||
#define jpeg_idct_1x1 jRD1x1
|
|
||||||
#define jpeg_idct_9x9 jRD9x9
|
|
||||||
#define jpeg_idct_10x10 jRD10x10
|
|
||||||
#define jpeg_idct_11x11 jRD11x11
|
|
||||||
#define jpeg_idct_12x12 jRD12x12
|
|
||||||
#define jpeg_idct_13x13 jRD13x13
|
|
||||||
#define jpeg_idct_14x14 jRD14x14
|
|
||||||
#define jpeg_idct_15x15 jRD15x15
|
|
||||||
#define jpeg_idct_16x16 jRD16x16
|
|
||||||
#define jpeg_idct_16x8 jRD16x8
|
|
||||||
#define jpeg_idct_14x7 jRD14x7
|
|
||||||
#define jpeg_idct_12x6 jRD12x6
|
|
||||||
#define jpeg_idct_10x5 jRD10x5
|
|
||||||
#define jpeg_idct_8x4 jRD8x4
|
|
||||||
#define jpeg_idct_6x3 jRD6x3
|
|
||||||
#define jpeg_idct_4x2 jRD4x2
|
|
||||||
#define jpeg_idct_2x1 jRD2x1
|
|
||||||
#define jpeg_idct_8x16 jRD8x16
|
|
||||||
#define jpeg_idct_7x14 jRD7x14
|
|
||||||
#define jpeg_idct_6x12 jRD6x12
|
|
||||||
#define jpeg_idct_5x10 jRD5x10
|
|
||||||
#define jpeg_idct_4x8 jRD4x8
|
|
||||||
#define jpeg_idct_3x6 jRD3x8
|
|
||||||
#define jpeg_idct_2x4 jRD2x4
|
|
||||||
#define jpeg_idct_1x2 jRD1x2
|
|
||||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
|
||||||
|
|
||||||
/* Extern declarations for the forward and inverse DCT routines. */
|
|
||||||
|
|
||||||
EXTERN(void) jpeg_fdct_islow
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_ifast
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_float
|
|
||||||
JPP((FAST_FLOAT * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_7x7
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_6x6
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_5x5
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_4x4
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_3x3
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_2x2
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_1x1
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_9x9
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_10x10
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_11x11
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_12x12
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_13x13
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_14x14
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_15x15
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_16x16
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_16x8
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_14x7
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_12x6
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_10x5
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_8x4
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_6x3
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_4x2
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_2x1
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_8x16
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_7x14
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_6x12
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_5x10
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_4x8
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_3x6
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_2x4
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
EXTERN(void) jpeg_fdct_1x2
|
|
||||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
|
||||||
|
|
||||||
EXTERN(void) jpeg_idct_islow
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_ifast
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_float
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_7x7
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_6x6
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_5x5
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_4x4
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_3x3
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_2x2
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_1x1
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_9x9
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_10x10
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_11x11
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_12x12
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_13x13
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_14x14
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_15x15
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_16x16
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_16x8
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_14x7
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_12x6
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_10x5
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_8x4
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_6x3
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_4x2
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_2x1
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_8x16
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_7x14
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_6x12
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_5x10
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_4x8
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_3x6
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_2x4
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
EXTERN(void) jpeg_idct_1x2
|
|
||||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros for handling fixed-point arithmetic; these are used by many
|
|
||||||
* but not all of the DCT/IDCT modules.
|
|
||||||
*
|
|
||||||
* All values are expected to be of type INT32.
|
|
||||||
* Fractional constants are scaled left by CONST_BITS bits.
|
|
||||||
* CONST_BITS is defined within each module using these macros,
|
|
||||||
* and may differ from one module to the next.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ONE ((INT32) 1)
|
|
||||||
#define CONST_SCALE (ONE << CONST_BITS)
|
|
||||||
|
|
||||||
/* Convert a positive real constant to an integer scaled by CONST_SCALE.
|
|
||||||
* Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
|
|
||||||
* thus causing a lot of useless floating-point operations at run time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
|
|
||||||
|
|
||||||
/* Descale and correctly round an INT32 value that's scaled by N bits.
|
|
||||||
* We assume RIGHT_SHIFT rounds towards minus infinity, so adding
|
|
||||||
* the fudge factor is correct for either sign of X.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
|
|
||||||
|
|
||||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
|
||||||
* This macro is used only when the two inputs will actually be no more than
|
|
||||||
* 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
|
|
||||||
* full 32x32 multiply. This provides a useful speedup on many machines.
|
|
||||||
* Unfortunately there is no way to specify a 16x16->32 multiply portably
|
|
||||||
* in C, but some C compilers will do the right thing if you provide the
|
|
||||||
* correct combination of casts.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
|
|
||||||
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const)))
|
|
||||||
#endif
|
|
||||||
#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
|
|
||||||
#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MULTIPLY16C16 /* default definition */
|
|
||||||
#define MULTIPLY16C16(var,const) ((var) * (const))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Same except both inputs are variables. */
|
|
||||||
|
|
||||||
#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
|
|
||||||
#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MULTIPLY16V16 /* default definition */
|
|
||||||
#define MULTIPLY16V16(var1,var2) ((var1) * (var2))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Like RIGHT_SHIFT, but applies to a DCTELEM.
|
|
||||||
* We assume that int right shift is unsigned if INT32 right shift is.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
|
||||||
#define ISHIFT_TEMPS DCTELEM ishift_temp;
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
|
|
||||||
#else
|
|
||||||
#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
|
|
||||||
#endif
|
|
||||||
#define IRIGHT_SHIFT(x,shft) \
|
|
||||||
((ishift_temp = (x)) < 0 ? \
|
|
||||||
(ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
|
|
||||||
(ishift_temp >> (shft)))
|
|
||||||
#else
|
|
||||||
#define ISHIFT_TEMPS
|
|
||||||
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
|
|
||||||
#endif
|
|
|
@ -1,384 +0,0 @@
|
||||||
/*
|
|
||||||
* jddctmgr.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
|
||||||
* Modified 2002-2013 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains the inverse-DCT management logic.
|
|
||||||
* This code selects a particular IDCT implementation to be used,
|
|
||||||
* and it performs related housekeeping chores. No code in this file
|
|
||||||
* is executed per IDCT step, only during output pass setup.
|
|
||||||
*
|
|
||||||
* Note that the IDCT routines are responsible for performing coefficient
|
|
||||||
* dequantization as well as the IDCT proper. This module sets up the
|
|
||||||
* dequantization multiplier table needed by the IDCT routine.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The decompressor input side (jdinput.c) saves away the appropriate
|
|
||||||
* quantization table for each component at the start of the first scan
|
|
||||||
* involving that component. (This is necessary in order to correctly
|
|
||||||
* decode files that reuse Q-table slots.)
|
|
||||||
* When we are ready to make an output pass, the saved Q-table is converted
|
|
||||||
* to a multiplier table that will actually be used by the IDCT routine.
|
|
||||||
* The multiplier table contents are IDCT-method-dependent. To support
|
|
||||||
* application changes in IDCT method between scans, we can remake the
|
|
||||||
* multiplier tables if necessary.
|
|
||||||
* In buffered-image mode, the first output pass may occur before any data
|
|
||||||
* has been seen for some components, and thus before their Q-tables have
|
|
||||||
* been saved away. To handle this case, multiplier tables are preset
|
|
||||||
* to zeroes; the result of the IDCT will be a neutral gray level.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Private subobject for this module */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_inverse_dct pub; /* public fields */
|
|
||||||
|
|
||||||
/* This array contains the IDCT method code that each multiplier table
|
|
||||||
* is currently set up for, or -1 if it's not yet set up.
|
|
||||||
* The actual multiplier tables are pointed to by dct_table in the
|
|
||||||
* per-component comp_info structures.
|
|
||||||
*/
|
|
||||||
int cur_method[MAX_COMPONENTS];
|
|
||||||
} my_idct_controller;
|
|
||||||
|
|
||||||
typedef my_idct_controller * my_idct_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
/* Allocated multiplier tables: big enough for any supported variant */
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
ISLOW_MULT_TYPE islow_array[DCTSIZE2];
|
|
||||||
#ifdef DCT_IFAST_SUPPORTED
|
|
||||||
IFAST_MULT_TYPE ifast_array[DCTSIZE2];
|
|
||||||
#endif
|
|
||||||
#ifdef DCT_FLOAT_SUPPORTED
|
|
||||||
FLOAT_MULT_TYPE float_array[DCTSIZE2];
|
|
||||||
#endif
|
|
||||||
} multiplier_table;
|
|
||||||
|
|
||||||
|
|
||||||
/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
|
|
||||||
* so be sure to compile that code if either ISLOW or SCALING is requested.
|
|
||||||
*/
|
|
||||||
#ifdef DCT_ISLOW_SUPPORTED
|
|
||||||
#define PROVIDE_ISLOW_TABLES
|
|
||||||
#else
|
|
||||||
#ifdef IDCT_SCALING_SUPPORTED
|
|
||||||
#define PROVIDE_ISLOW_TABLES
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prepare for an output pass.
|
|
||||||
* Here we select the proper IDCT routine for each component and build
|
|
||||||
* a matching multiplier table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
|
|
||||||
int ci, i;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
int method = 0;
|
|
||||||
inverse_DCT_method_ptr method_ptr = NULL;
|
|
||||||
JQUANT_TBL * qtbl;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Select the proper IDCT routine for this component's scaling */
|
|
||||||
switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) {
|
|
||||||
#ifdef IDCT_SCALING_SUPPORTED
|
|
||||||
case ((1 << 8) + 1):
|
|
||||||
method_ptr = jpeg_idct_1x1;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((2 << 8) + 2):
|
|
||||||
method_ptr = jpeg_idct_2x2;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((3 << 8) + 3):
|
|
||||||
method_ptr = jpeg_idct_3x3;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((4 << 8) + 4):
|
|
||||||
method_ptr = jpeg_idct_4x4;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((5 << 8) + 5):
|
|
||||||
method_ptr = jpeg_idct_5x5;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((6 << 8) + 6):
|
|
||||||
method_ptr = jpeg_idct_6x6;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((7 << 8) + 7):
|
|
||||||
method_ptr = jpeg_idct_7x7;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((9 << 8) + 9):
|
|
||||||
method_ptr = jpeg_idct_9x9;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((10 << 8) + 10):
|
|
||||||
method_ptr = jpeg_idct_10x10;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((11 << 8) + 11):
|
|
||||||
method_ptr = jpeg_idct_11x11;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((12 << 8) + 12):
|
|
||||||
method_ptr = jpeg_idct_12x12;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((13 << 8) + 13):
|
|
||||||
method_ptr = jpeg_idct_13x13;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((14 << 8) + 14):
|
|
||||||
method_ptr = jpeg_idct_14x14;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((15 << 8) + 15):
|
|
||||||
method_ptr = jpeg_idct_15x15;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((16 << 8) + 16):
|
|
||||||
method_ptr = jpeg_idct_16x16;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((16 << 8) + 8):
|
|
||||||
method_ptr = jpeg_idct_16x8;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((14 << 8) + 7):
|
|
||||||
method_ptr = jpeg_idct_14x7;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((12 << 8) + 6):
|
|
||||||
method_ptr = jpeg_idct_12x6;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((10 << 8) + 5):
|
|
||||||
method_ptr = jpeg_idct_10x5;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((8 << 8) + 4):
|
|
||||||
method_ptr = jpeg_idct_8x4;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((6 << 8) + 3):
|
|
||||||
method_ptr = jpeg_idct_6x3;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((4 << 8) + 2):
|
|
||||||
method_ptr = jpeg_idct_4x2;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((2 << 8) + 1):
|
|
||||||
method_ptr = jpeg_idct_2x1;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((8 << 8) + 16):
|
|
||||||
method_ptr = jpeg_idct_8x16;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((7 << 8) + 14):
|
|
||||||
method_ptr = jpeg_idct_7x14;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((6 << 8) + 12):
|
|
||||||
method_ptr = jpeg_idct_6x12;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((5 << 8) + 10):
|
|
||||||
method_ptr = jpeg_idct_5x10;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((4 << 8) + 8):
|
|
||||||
method_ptr = jpeg_idct_4x8;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((3 << 8) + 6):
|
|
||||||
method_ptr = jpeg_idct_3x6;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((2 << 8) + 4):
|
|
||||||
method_ptr = jpeg_idct_2x4;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
case ((1 << 8) + 2):
|
|
||||||
method_ptr = jpeg_idct_1x2;
|
|
||||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case ((DCTSIZE << 8) + DCTSIZE):
|
|
||||||
switch (cinfo->dct_method) {
|
|
||||||
#ifdef DCT_ISLOW_SUPPORTED
|
|
||||||
case JDCT_ISLOW:
|
|
||||||
method_ptr = jpeg_idct_islow;
|
|
||||||
method = JDCT_ISLOW;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef DCT_IFAST_SUPPORTED
|
|
||||||
case JDCT_IFAST:
|
|
||||||
method_ptr = jpeg_idct_ifast;
|
|
||||||
method = JDCT_IFAST;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef DCT_FLOAT_SUPPORTED
|
|
||||||
case JDCT_FLOAT:
|
|
||||||
method_ptr = jpeg_idct_float;
|
|
||||||
method = JDCT_FLOAT;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
|
|
||||||
compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
idct->pub.inverse_DCT[ci] = method_ptr;
|
|
||||||
/* Create multiplier table from quant table.
|
|
||||||
* However, we can skip this if the component is uninteresting
|
|
||||||
* or if we already built the table. Also, if no quant table
|
|
||||||
* has yet been saved for the component, we leave the
|
|
||||||
* multiplier table all-zero; we'll be reading zeroes from the
|
|
||||||
* coefficient controller's buffer anyway.
|
|
||||||
*/
|
|
||||||
if (! compptr->component_needed || idct->cur_method[ci] == method)
|
|
||||||
continue;
|
|
||||||
qtbl = compptr->quant_table;
|
|
||||||
if (qtbl == NULL) /* happens if no data yet for component */
|
|
||||||
continue;
|
|
||||||
idct->cur_method[ci] = method;
|
|
||||||
switch (method) {
|
|
||||||
#ifdef PROVIDE_ISLOW_TABLES
|
|
||||||
case JDCT_ISLOW:
|
|
||||||
{
|
|
||||||
/* For LL&M IDCT method, multipliers are equal to raw quantization
|
|
||||||
* coefficients, but are stored as ints to ensure access efficiency.
|
|
||||||
*/
|
|
||||||
ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
|
||||||
for (i = 0; i < DCTSIZE2; i++) {
|
|
||||||
ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef DCT_IFAST_SUPPORTED
|
|
||||||
case JDCT_IFAST:
|
|
||||||
{
|
|
||||||
/* For AA&N IDCT method, multipliers are equal to quantization
|
|
||||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
|
||||||
* scalefactor[0] = 1
|
|
||||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
|
||||||
* For integer operation, the multiplier table is to be scaled by
|
|
||||||
* IFAST_SCALE_BITS.
|
|
||||||
*/
|
|
||||||
IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
|
|
||||||
#define CONST_BITS 14
|
|
||||||
static const INT16 aanscales[DCTSIZE2] = {
|
|
||||||
/* precomputed values scaled up by 14 bits */
|
|
||||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
|
||||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
|
||||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
|
||||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
|
||||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
|
||||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
|
||||||
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
|
||||||
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
|
||||||
};
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
for (i = 0; i < DCTSIZE2; i++) {
|
|
||||||
ifmtbl[i] = (IFAST_MULT_TYPE)
|
|
||||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
|
||||||
(INT32) aanscales[i]),
|
|
||||||
CONST_BITS-IFAST_SCALE_BITS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef DCT_FLOAT_SUPPORTED
|
|
||||||
case JDCT_FLOAT:
|
|
||||||
{
|
|
||||||
/* For float AA&N IDCT method, multipliers are equal to quantization
|
|
||||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
|
||||||
* scalefactor[0] = 1
|
|
||||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
|
||||||
* We apply a further scale factor of 1/8.
|
|
||||||
*/
|
|
||||||
FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
|
|
||||||
int row, col;
|
|
||||||
static const double aanscalefactor[DCTSIZE] = {
|
|
||||||
1.0, 1.387039845, 1.306562965, 1.175875602,
|
|
||||||
1.0, 0.785694958, 0.541196100, 0.275899379
|
|
||||||
};
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
for (row = 0; row < DCTSIZE; row++) {
|
|
||||||
for (col = 0; col < DCTSIZE; col++) {
|
|
||||||
fmtbl[i] = (FLOAT_MULT_TYPE)
|
|
||||||
((double) qtbl->quantval[i] *
|
|
||||||
aanscalefactor[row] * aanscalefactor[col] * 0.125);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize IDCT manager.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_inverse_dct (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_idct_ptr idct;
|
|
||||||
int ci;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
|
|
||||||
idct = (my_idct_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_idct_controller));
|
|
||||||
cinfo->idct = &idct->pub;
|
|
||||||
idct->pub.start_pass = start_pass;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Allocate and pre-zero a multiplier table for each component */
|
|
||||||
compptr->dct_table =
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(multiplier_table));
|
|
||||||
MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
|
|
||||||
/* Mark multiplier table not yet set up for any method */
|
|
||||||
idct->cur_method[ci] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,662 +0,0 @@
|
||||||
/*
|
|
||||||
* jdinput.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
|
||||||
* Modified 2002-2013 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains input control logic for the JPEG decompressor.
|
|
||||||
* These routines are concerned with controlling the decompressor's input
|
|
||||||
* processing (marker reading and coefficient decoding). The actual input
|
|
||||||
* reading is done in jdmarker.c, jdhuff.c, and jdarith.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Private state */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_input_controller pub; /* public fields */
|
|
||||||
|
|
||||||
int inheaders; /* Nonzero until first SOS is reached */
|
|
||||||
} my_input_controller;
|
|
||||||
|
|
||||||
typedef my_input_controller * my_inputctl_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Routines to calculate various quantities related to the size of the image.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute output image dimensions and related values.
|
|
||||||
* NOTE: this is exported for possible use by application.
|
|
||||||
* Hence it mustn't do anything that can't be done twice.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_core_output_dimensions (j_decompress_ptr cinfo)
|
|
||||||
/* Do computations that are needed before master selection phase.
|
|
||||||
* This function is used for transcoding and full decompression.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
#ifdef IDCT_SCALING_SUPPORTED
|
|
||||||
int ci;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
|
|
||||||
/* Compute actual output image dimensions and DCT scaling choices. */
|
|
||||||
if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom) {
|
|
||||||
/* Provide 1/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 1;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 1;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 2) {
|
|
||||||
/* Provide 2/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 2L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 2L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 2;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 2;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 3) {
|
|
||||||
/* Provide 3/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 3L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 3L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 3;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 3;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 4) {
|
|
||||||
/* Provide 4/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 4L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 4L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 4;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 4;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 5) {
|
|
||||||
/* Provide 5/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 5L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 5L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 5;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 5;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 6) {
|
|
||||||
/* Provide 6/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 6L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 6L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 6;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 6;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 7) {
|
|
||||||
/* Provide 7/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 7L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 7L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 7;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 7;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 8) {
|
|
||||||
/* Provide 8/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 8L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 8L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 8;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 8;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 9) {
|
|
||||||
/* Provide 9/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 9L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 9L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 9;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 9;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 10) {
|
|
||||||
/* Provide 10/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 10L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 10L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 10;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 10;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 11) {
|
|
||||||
/* Provide 11/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 11L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 11L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 11;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 11;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 12) {
|
|
||||||
/* Provide 12/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 12L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 12L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 12;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 12;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 13) {
|
|
||||||
/* Provide 13/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 13L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 13L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 13;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 13;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 14) {
|
|
||||||
/* Provide 14/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 14L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 14L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 14;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 14;
|
|
||||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 15) {
|
|
||||||
/* Provide 15/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 15L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 15L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 15;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 15;
|
|
||||||
} else {
|
|
||||||
/* Provide 16/block_size scaling */
|
|
||||||
cinfo->output_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * 16L, (long) cinfo->block_size);
|
|
||||||
cinfo->output_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * 16L, (long) cinfo->block_size);
|
|
||||||
cinfo->min_DCT_h_scaled_size = 16;
|
|
||||||
cinfo->min_DCT_v_scaled_size = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Recompute dimensions of components */
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size;
|
|
||||||
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !IDCT_SCALING_SUPPORTED */
|
|
||||||
|
|
||||||
/* Hardwire it to "no scaling" */
|
|
||||||
cinfo->output_width = cinfo->image_width;
|
|
||||||
cinfo->output_height = cinfo->image_height;
|
|
||||||
/* initial_setup has already initialized DCT_scaled_size,
|
|
||||||
* and has computed unscaled downsampled_width and downsampled_height.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* IDCT_SCALING_SUPPORTED */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
initial_setup (j_decompress_ptr cinfo)
|
|
||||||
/* Called once, when first SOS marker is reached */
|
|
||||||
{
|
|
||||||
int ci;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
|
|
||||||
/* Make sure image isn't bigger than I can handle */
|
|
||||||
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
|
|
||||||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
|
|
||||||
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
|
|
||||||
|
|
||||||
/* Only 8 to 12 bits data precision are supported for DCT based JPEG */
|
|
||||||
if (cinfo->data_precision < 8 || cinfo->data_precision > 12)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
|
||||||
|
|
||||||
/* Check that number of components won't exceed internal array sizes */
|
|
||||||
if (cinfo->num_components > MAX_COMPONENTS)
|
|
||||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
|
|
||||||
MAX_COMPONENTS);
|
|
||||||
|
|
||||||
/* Compute maximum sampling factors; check factor validity */
|
|
||||||
cinfo->max_h_samp_factor = 1;
|
|
||||||
cinfo->max_v_samp_factor = 1;
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
|
|
||||||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_SAMPLING);
|
|
||||||
cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
|
|
||||||
compptr->h_samp_factor);
|
|
||||||
cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
|
|
||||||
compptr->v_samp_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Derive block_size, natural_order, and lim_Se */
|
|
||||||
if (cinfo->is_baseline || (cinfo->progressive_mode &&
|
|
||||||
cinfo->comps_in_scan)) { /* no pseudo SOS marker */
|
|
||||||
cinfo->block_size = DCTSIZE;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
} else
|
|
||||||
switch (cinfo->Se) {
|
|
||||||
case (1*1-1):
|
|
||||||
cinfo->block_size = 1;
|
|
||||||
cinfo->natural_order = jpeg_natural_order; /* not needed */
|
|
||||||
cinfo->lim_Se = cinfo->Se;
|
|
||||||
break;
|
|
||||||
case (2*2-1):
|
|
||||||
cinfo->block_size = 2;
|
|
||||||
cinfo->natural_order = jpeg_natural_order2;
|
|
||||||
cinfo->lim_Se = cinfo->Se;
|
|
||||||
break;
|
|
||||||
case (3*3-1):
|
|
||||||
cinfo->block_size = 3;
|
|
||||||
cinfo->natural_order = jpeg_natural_order3;
|
|
||||||
cinfo->lim_Se = cinfo->Se;
|
|
||||||
break;
|
|
||||||
case (4*4-1):
|
|
||||||
cinfo->block_size = 4;
|
|
||||||
cinfo->natural_order = jpeg_natural_order4;
|
|
||||||
cinfo->lim_Se = cinfo->Se;
|
|
||||||
break;
|
|
||||||
case (5*5-1):
|
|
||||||
cinfo->block_size = 5;
|
|
||||||
cinfo->natural_order = jpeg_natural_order5;
|
|
||||||
cinfo->lim_Se = cinfo->Se;
|
|
||||||
break;
|
|
||||||
case (6*6-1):
|
|
||||||
cinfo->block_size = 6;
|
|
||||||
cinfo->natural_order = jpeg_natural_order6;
|
|
||||||
cinfo->lim_Se = cinfo->Se;
|
|
||||||
break;
|
|
||||||
case (7*7-1):
|
|
||||||
cinfo->block_size = 7;
|
|
||||||
cinfo->natural_order = jpeg_natural_order7;
|
|
||||||
cinfo->lim_Se = cinfo->Se;
|
|
||||||
break;
|
|
||||||
case (8*8-1):
|
|
||||||
cinfo->block_size = 8;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (9*9-1):
|
|
||||||
cinfo->block_size = 9;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (10*10-1):
|
|
||||||
cinfo->block_size = 10;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (11*11-1):
|
|
||||||
cinfo->block_size = 11;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (12*12-1):
|
|
||||||
cinfo->block_size = 12;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (13*13-1):
|
|
||||||
cinfo->block_size = 13;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (14*14-1):
|
|
||||||
cinfo->block_size = 14;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (15*15-1):
|
|
||||||
cinfo->block_size = 15;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
case (16*16-1):
|
|
||||||
cinfo->block_size = 16;
|
|
||||||
cinfo->natural_order = jpeg_natural_order;
|
|
||||||
cinfo->lim_Se = DCTSIZE2-1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
|
|
||||||
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We initialize DCT_scaled_size and min_DCT_scaled_size to block_size.
|
|
||||||
* In the full decompressor,
|
|
||||||
* this will be overridden by jpeg_calc_output_dimensions in jdmaster.c;
|
|
||||||
* but in the transcoder,
|
|
||||||
* jpeg_calc_output_dimensions is not used, so we must do it here.
|
|
||||||
*/
|
|
||||||
cinfo->min_DCT_h_scaled_size = cinfo->block_size;
|
|
||||||
cinfo->min_DCT_v_scaled_size = cinfo->block_size;
|
|
||||||
|
|
||||||
/* Compute dimensions of components */
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
compptr->DCT_h_scaled_size = cinfo->block_size;
|
|
||||||
compptr->DCT_v_scaled_size = cinfo->block_size;
|
|
||||||
/* Size in DCT blocks */
|
|
||||||
compptr->width_in_blocks = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
|
||||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
|
||||||
compptr->height_in_blocks = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
|
||||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
|
||||||
/* downsampled_width and downsampled_height will also be overridden by
|
|
||||||
* jdmaster.c if we are doing full decompression. The transcoder library
|
|
||||||
* doesn't use these values, but the calling application might.
|
|
||||||
*/
|
|
||||||
/* Size in samples */
|
|
||||||
compptr->downsampled_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
|
||||||
(long) cinfo->max_h_samp_factor);
|
|
||||||
compptr->downsampled_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
|
||||||
(long) cinfo->max_v_samp_factor);
|
|
||||||
/* Mark component needed, until color conversion says otherwise */
|
|
||||||
compptr->component_needed = TRUE;
|
|
||||||
/* Mark no quantization table yet saved for component */
|
|
||||||
compptr->quant_table = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute number of fully interleaved MCU rows. */
|
|
||||||
cinfo->total_iMCU_rows = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height,
|
|
||||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
|
||||||
|
|
||||||
/* Decide whether file contains multiple scans */
|
|
||||||
if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
|
|
||||||
cinfo->inputctl->has_multiple_scans = TRUE;
|
|
||||||
else
|
|
||||||
cinfo->inputctl->has_multiple_scans = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
per_scan_setup (j_decompress_ptr cinfo)
|
|
||||||
/* Do computations that are needed before processing a JPEG scan */
|
|
||||||
/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
|
|
||||||
{
|
|
||||||
int ci, mcublks, tmp;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
|
|
||||||
if (cinfo->comps_in_scan == 1) {
|
|
||||||
|
|
||||||
/* Noninterleaved (single-component) scan */
|
|
||||||
compptr = cinfo->cur_comp_info[0];
|
|
||||||
|
|
||||||
/* Overall image size in MCUs */
|
|
||||||
cinfo->MCUs_per_row = compptr->width_in_blocks;
|
|
||||||
cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
|
|
||||||
|
|
||||||
/* For noninterleaved scan, always one block per MCU */
|
|
||||||
compptr->MCU_width = 1;
|
|
||||||
compptr->MCU_height = 1;
|
|
||||||
compptr->MCU_blocks = 1;
|
|
||||||
compptr->MCU_sample_width = compptr->DCT_h_scaled_size;
|
|
||||||
compptr->last_col_width = 1;
|
|
||||||
/* For noninterleaved scans, it is convenient to define last_row_height
|
|
||||||
* as the number of block rows present in the last iMCU row.
|
|
||||||
*/
|
|
||||||
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
|
||||||
if (tmp == 0) tmp = compptr->v_samp_factor;
|
|
||||||
compptr->last_row_height = tmp;
|
|
||||||
|
|
||||||
/* Prepare array describing MCU composition */
|
|
||||||
cinfo->blocks_in_MCU = 1;
|
|
||||||
cinfo->MCU_membership[0] = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Interleaved (multi-component) scan */
|
|
||||||
if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
|
|
||||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
|
|
||||||
MAX_COMPS_IN_SCAN);
|
|
||||||
|
|
||||||
/* Overall image size in MCUs */
|
|
||||||
cinfo->MCUs_per_row = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width,
|
|
||||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
|
||||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height,
|
|
||||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
|
||||||
|
|
||||||
cinfo->blocks_in_MCU = 0;
|
|
||||||
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
/* Sampling factors give # of blocks of component in each MCU */
|
|
||||||
compptr->MCU_width = compptr->h_samp_factor;
|
|
||||||
compptr->MCU_height = compptr->v_samp_factor;
|
|
||||||
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
|
|
||||||
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_h_scaled_size;
|
|
||||||
/* Figure number of non-dummy blocks in last MCU column & row */
|
|
||||||
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
|
|
||||||
if (tmp == 0) tmp = compptr->MCU_width;
|
|
||||||
compptr->last_col_width = tmp;
|
|
||||||
tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
|
|
||||||
if (tmp == 0) tmp = compptr->MCU_height;
|
|
||||||
compptr->last_row_height = tmp;
|
|
||||||
/* Prepare array describing MCU composition */
|
|
||||||
mcublks = compptr->MCU_blocks;
|
|
||||||
if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
|
|
||||||
while (mcublks-- > 0) {
|
|
||||||
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Save away a copy of the Q-table referenced by each component present
|
|
||||||
* in the current scan, unless already saved during a prior scan.
|
|
||||||
*
|
|
||||||
* In a multiple-scan JPEG file, the encoder could assign different components
|
|
||||||
* the same Q-table slot number, but change table definitions between scans
|
|
||||||
* so that each component uses a different Q-table. (The IJG encoder is not
|
|
||||||
* currently capable of doing this, but other encoders might.) Since we want
|
|
||||||
* to be able to dequantize all the components at the end of the file, this
|
|
||||||
* means that we have to save away the table actually used for each component.
|
|
||||||
* We do this by copying the table at the start of the first scan containing
|
|
||||||
* the component.
|
|
||||||
* The JPEG spec prohibits the encoder from changing the contents of a Q-table
|
|
||||||
* slot between scans of a component using that slot. If the encoder does so
|
|
||||||
* anyway, this decoder will simply use the Q-table values that were current
|
|
||||||
* at the start of the first scan for the component.
|
|
||||||
*
|
|
||||||
* The decompressor output side looks only at the saved quant tables,
|
|
||||||
* not at the current Q-table slots.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
latch_quant_tables (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
int ci, qtblno;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
JQUANT_TBL * qtbl;
|
|
||||||
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
|
||||||
/* No work if we already saved Q-table for this component */
|
|
||||||
if (compptr->quant_table != NULL)
|
|
||||||
continue;
|
|
||||||
/* Make sure specified quantization table is present */
|
|
||||||
qtblno = compptr->quant_tbl_no;
|
|
||||||
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
|
|
||||||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
|
|
||||||
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
|
|
||||||
/* OK, save away the quantization table */
|
|
||||||
qtbl = (JQUANT_TBL *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(JQUANT_TBL));
|
|
||||||
MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
|
|
||||||
compptr->quant_table = qtbl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize the input modules to read a scan of compressed data.
|
|
||||||
* The first call to this is done by jdmaster.c after initializing
|
|
||||||
* the entire decompressor (during jpeg_start_decompress).
|
|
||||||
* Subsequent calls come from consume_markers, below.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_input_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
per_scan_setup(cinfo);
|
|
||||||
latch_quant_tables(cinfo);
|
|
||||||
(*cinfo->entropy->start_pass) (cinfo);
|
|
||||||
(*cinfo->coef->start_input_pass) (cinfo);
|
|
||||||
cinfo->inputctl->consume_input = cinfo->coef->consume_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish up after inputting a compressed-data scan.
|
|
||||||
* This is called by the coefficient controller after it's read all
|
|
||||||
* the expected data of the scan.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
finish_input_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
(*cinfo->entropy->finish_pass) (cinfo);
|
|
||||||
cinfo->inputctl->consume_input = consume_markers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read JPEG markers before, between, or after compressed-data scans.
|
|
||||||
* Change state as necessary when a new scan is reached.
|
|
||||||
* Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
|
|
||||||
*
|
|
||||||
* The consume_input method pointer points either here or to the
|
|
||||||
* coefficient controller's consume_data routine, depending on whether
|
|
||||||
* we are reading a compressed data segment or inter-segment markers.
|
|
||||||
*
|
|
||||||
* Note: This function should NOT return a pseudo SOS marker (with zero
|
|
||||||
* component number) to the caller. A pseudo marker received by
|
|
||||||
* read_markers is processed and then skipped for other markers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(int)
|
|
||||||
consume_markers (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
|
|
||||||
int val;
|
|
||||||
|
|
||||||
if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
|
|
||||||
return JPEG_REACHED_EOI;
|
|
||||||
|
|
||||||
for (;;) { /* Loop to pass pseudo SOS marker */
|
|
||||||
val = (*cinfo->marker->read_markers) (cinfo);
|
|
||||||
|
|
||||||
switch (val) {
|
|
||||||
case JPEG_REACHED_SOS: /* Found SOS */
|
|
||||||
if (inputctl->inheaders) { /* 1st SOS */
|
|
||||||
if (inputctl->inheaders == 1)
|
|
||||||
initial_setup(cinfo);
|
|
||||||
if (cinfo->comps_in_scan == 0) { /* pseudo SOS marker */
|
|
||||||
inputctl->inheaders = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
inputctl->inheaders = 0;
|
|
||||||
/* Note: start_input_pass must be called by jdmaster.c
|
|
||||||
* before any more input can be consumed. jdapimin.c is
|
|
||||||
* responsible for enforcing this sequencing.
|
|
||||||
*/
|
|
||||||
} else { /* 2nd or later SOS marker */
|
|
||||||
if (! inputctl->pub.has_multiple_scans)
|
|
||||||
ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
|
|
||||||
if (cinfo->comps_in_scan == 0) /* unexpected pseudo SOS marker */
|
|
||||||
break;
|
|
||||||
start_input_pass(cinfo);
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
case JPEG_REACHED_EOI: /* Found EOI */
|
|
||||||
inputctl->pub.eoi_reached = TRUE;
|
|
||||||
if (inputctl->inheaders) { /* Tables-only datastream, apparently */
|
|
||||||
if (cinfo->marker->saw_SOF)
|
|
||||||
ERREXIT(cinfo, JERR_SOF_NO_SOS);
|
|
||||||
} else {
|
|
||||||
/* Prevent infinite loop in coef ctlr's decompress_data routine
|
|
||||||
* if user set output_scan_number larger than number of scans.
|
|
||||||
*/
|
|
||||||
if (cinfo->output_scan_number > cinfo->input_scan_number)
|
|
||||||
cinfo->output_scan_number = cinfo->input_scan_number;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
case JPEG_SUSPENDED:
|
|
||||||
return val;
|
|
||||||
default:
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset state to begin a fresh datastream.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
reset_input_controller (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
|
|
||||||
|
|
||||||
inputctl->pub.consume_input = consume_markers;
|
|
||||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
|
||||||
inputctl->pub.eoi_reached = FALSE;
|
|
||||||
inputctl->inheaders = 1;
|
|
||||||
/* Reset other modules */
|
|
||||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
|
||||||
(*cinfo->marker->reset_marker_reader) (cinfo);
|
|
||||||
/* Reset progression state -- would be cleaner if entropy decoder did this */
|
|
||||||
cinfo->coef_bits = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize the input controller module.
|
|
||||||
* This is called only once, when the decompression object is created.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_input_controller (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_inputctl_ptr inputctl;
|
|
||||||
|
|
||||||
/* Create subobject in permanent pool */
|
|
||||||
inputctl = (my_inputctl_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
SIZEOF(my_input_controller));
|
|
||||||
cinfo->inputctl = &inputctl->pub;
|
|
||||||
/* Initialize method pointers */
|
|
||||||
inputctl->pub.consume_input = consume_markers;
|
|
||||||
inputctl->pub.reset_input_controller = reset_input_controller;
|
|
||||||
inputctl->pub.start_input_pass = start_input_pass;
|
|
||||||
inputctl->pub.finish_input_pass = finish_input_pass;
|
|
||||||
/* Initialize state: can't use reset_input_controller since we don't
|
|
||||||
* want to try to reset other modules yet.
|
|
||||||
*/
|
|
||||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
|
||||||
inputctl->pub.eoi_reached = FALSE;
|
|
||||||
inputctl->inheaders = 1;
|
|
||||||
}
|
|
|
@ -1,507 +0,0 @@
|
||||||
/*
|
|
||||||
* jdmainct.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
|
||||||
* Modified 2002-2016 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains the main buffer controller for decompression.
|
|
||||||
* The main buffer lies between the JPEG decompressor proper and the
|
|
||||||
* post-processor; it holds downsampled data in the JPEG colorspace.
|
|
||||||
*
|
|
||||||
* Note that this code is bypassed in raw-data mode, since the application
|
|
||||||
* supplies the equivalent of the main buffer in that case.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In the current system design, the main buffer need never be a full-image
|
|
||||||
* buffer; any full-height buffers will be found inside the coefficient or
|
|
||||||
* postprocessing controllers. Nonetheless, the main controller is not
|
|
||||||
* trivial. Its responsibility is to provide context rows for upsampling/
|
|
||||||
* rescaling, and doing this in an efficient fashion is a bit tricky.
|
|
||||||
*
|
|
||||||
* Postprocessor input data is counted in "row groups". A row group is
|
|
||||||
* defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size)
|
|
||||||
* sample rows of each component. (We require DCT_scaled_size values to be
|
|
||||||
* chosen such that these numbers are integers. In practice DCT_scaled_size
|
|
||||||
* values will likely be powers of two, so we actually have the stronger
|
|
||||||
* condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
|
|
||||||
* Upsampling will typically produce max_v_samp_factor pixel rows from each
|
|
||||||
* row group (times any additional scale factor that the upsampler is
|
|
||||||
* applying).
|
|
||||||
*
|
|
||||||
* The coefficient controller will deliver data to us one iMCU row at a time;
|
|
||||||
* each iMCU row contains v_samp_factor * DCT_v_scaled_size sample rows, or
|
|
||||||
* exactly min_DCT_v_scaled_size row groups. (This amount of data corresponds
|
|
||||||
* to one row of MCUs when the image is fully interleaved.) Note that the
|
|
||||||
* number of sample rows varies across components, but the number of row
|
|
||||||
* groups does not. Some garbage sample rows may be included in the last iMCU
|
|
||||||
* row at the bottom of the image.
|
|
||||||
*
|
|
||||||
* Depending on the vertical scaling algorithm used, the upsampler may need
|
|
||||||
* access to the sample row(s) above and below its current input row group.
|
|
||||||
* The upsampler is required to set need_context_rows TRUE at global selection
|
|
||||||
* time if so. When need_context_rows is FALSE, this controller can simply
|
|
||||||
* obtain one iMCU row at a time from the coefficient controller and dole it
|
|
||||||
* out as row groups to the postprocessor.
|
|
||||||
*
|
|
||||||
* When need_context_rows is TRUE, this controller guarantees that the buffer
|
|
||||||
* passed to postprocessing contains at least one row group's worth of samples
|
|
||||||
* above and below the row group(s) being processed. Note that the context
|
|
||||||
* rows "above" the first passed row group appear at negative row offsets in
|
|
||||||
* the passed buffer. At the top and bottom of the image, the required
|
|
||||||
* context rows are manufactured by duplicating the first or last real sample
|
|
||||||
* row; this avoids having special cases in the upsampling inner loops.
|
|
||||||
*
|
|
||||||
* The amount of context is fixed at one row group just because that's a
|
|
||||||
* convenient number for this controller to work with. The existing
|
|
||||||
* upsamplers really only need one sample row of context. An upsampler
|
|
||||||
* supporting arbitrary output rescaling might wish for more than one row
|
|
||||||
* group of context when shrinking the image; tough, we don't handle that.
|
|
||||||
* (This is justified by the assumption that downsizing will be handled mostly
|
|
||||||
* by adjusting the DCT_scaled_size values, so that the actual scale factor at
|
|
||||||
* the upsample step needn't be much less than one.)
|
|
||||||
*
|
|
||||||
* To provide the desired context, we have to retain the last two row groups
|
|
||||||
* of one iMCU row while reading in the next iMCU row. (The last row group
|
|
||||||
* can't be processed until we have another row group for its below-context,
|
|
||||||
* and so we have to save the next-to-last group too for its above-context.)
|
|
||||||
* We could do this most simply by copying data around in our buffer, but
|
|
||||||
* that'd be very slow. We can avoid copying any data by creating a rather
|
|
||||||
* strange pointer structure. Here's how it works. We allocate a workspace
|
|
||||||
* consisting of M+2 row groups (where M = min_DCT_v_scaled_size is the number
|
|
||||||
* of row groups per iMCU row). We create two sets of redundant pointers to
|
|
||||||
* the workspace. Labeling the physical row groups 0 to M+1, the synthesized
|
|
||||||
* pointer lists look like this:
|
|
||||||
* M+1 M-1
|
|
||||||
* master pointer --> 0 master pointer --> 0
|
|
||||||
* 1 1
|
|
||||||
* ... ...
|
|
||||||
* M-3 M-3
|
|
||||||
* M-2 M
|
|
||||||
* M-1 M+1
|
|
||||||
* M M-2
|
|
||||||
* M+1 M-1
|
|
||||||
* 0 0
|
|
||||||
* We read alternate iMCU rows using each master pointer; thus the last two
|
|
||||||
* row groups of the previous iMCU row remain un-overwritten in the workspace.
|
|
||||||
* The pointer lists are set up so that the required context rows appear to
|
|
||||||
* be adjacent to the proper places when we pass the pointer lists to the
|
|
||||||
* upsampler.
|
|
||||||
*
|
|
||||||
* The above pictures describe the normal state of the pointer lists.
|
|
||||||
* At top and bottom of the image, we diddle the pointer lists to duplicate
|
|
||||||
* the first or last sample row as necessary (this is cheaper than copying
|
|
||||||
* sample rows around).
|
|
||||||
*
|
|
||||||
* This scheme breaks down if M < 2, ie, min_DCT_v_scaled_size is 1. In that
|
|
||||||
* situation each iMCU row provides only one row group so the buffering logic
|
|
||||||
* must be different (eg, we must read two iMCU rows before we can emit the
|
|
||||||
* first row group). For now, we simply do not support providing context
|
|
||||||
* rows when min_DCT_v_scaled_size is 1. That combination seems unlikely to
|
|
||||||
* be worth providing --- if someone wants a 1/8th-size preview, they probably
|
|
||||||
* want it quick and dirty, so a context-free upsampler is sufficient.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Private buffer controller object */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_d_main_controller pub; /* public fields */
|
|
||||||
|
|
||||||
/* Pointer to allocated workspace (M or M+2 row groups). */
|
|
||||||
JSAMPARRAY buffer[MAX_COMPONENTS];
|
|
||||||
|
|
||||||
JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */
|
|
||||||
JDIMENSION rowgroups_avail; /* row groups available to postprocessor */
|
|
||||||
|
|
||||||
/* Remaining fields are only used in the context case. */
|
|
||||||
|
|
||||||
boolean buffer_full; /* Have we gotten an iMCU row from decoder? */
|
|
||||||
|
|
||||||
/* These are the master pointers to the funny-order pointer lists. */
|
|
||||||
JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */
|
|
||||||
|
|
||||||
int whichptr; /* indicates which pointer set is now in use */
|
|
||||||
int context_state; /* process_data state machine status */
|
|
||||||
JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */
|
|
||||||
} my_main_controller;
|
|
||||||
|
|
||||||
typedef my_main_controller * my_main_ptr;
|
|
||||||
|
|
||||||
/* context_state values: */
|
|
||||||
#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */
|
|
||||||
#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */
|
|
||||||
#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */
|
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
METHODDEF(void) process_data_simple_main
|
|
||||||
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|
||||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
|
|
||||||
METHODDEF(void) process_data_context_main
|
|
||||||
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|
||||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
METHODDEF(void) process_data_crank_post
|
|
||||||
JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
|
|
||||||
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
alloc_funny_pointers (j_decompress_ptr cinfo)
|
|
||||||
/* Allocate space for the funny pointer lists.
|
|
||||||
* This is done only once, not once per pass.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
my_main_ptr mainp = (my_main_ptr) cinfo->main;
|
|
||||||
int ci, rgroup;
|
|
||||||
int M = cinfo->min_DCT_v_scaled_size;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
JSAMPARRAY xbuf;
|
|
||||||
|
|
||||||
/* Get top-level space for component array pointers.
|
|
||||||
* We alloc both arrays with one call to save a few cycles.
|
|
||||||
*/
|
|
||||||
mainp->xbuffer[0] = (JSAMPIMAGE)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
|
|
||||||
mainp->xbuffer[1] = mainp->xbuffer[0] + cinfo->num_components;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
|
||||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
|
||||||
/* Get space for pointer lists --- M+4 row groups in each list.
|
|
||||||
* We alloc both pointer lists with one call to save a few cycles.
|
|
||||||
*/
|
|
||||||
xbuf = (JSAMPARRAY)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
|
|
||||||
xbuf += rgroup; /* want one row group at negative offsets */
|
|
||||||
mainp->xbuffer[0][ci] = xbuf;
|
|
||||||
xbuf += rgroup * (M + 4);
|
|
||||||
mainp->xbuffer[1][ci] = xbuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
make_funny_pointers (j_decompress_ptr cinfo)
|
|
||||||
/* Create the funny pointer lists discussed in the comments above.
|
|
||||||
* The actual workspace is already allocated (in mainp->buffer),
|
|
||||||
* and the space for the pointer lists is allocated too.
|
|
||||||
* This routine just fills in the curiously ordered lists.
|
|
||||||
* This will be repeated at the beginning of each pass.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
my_main_ptr mainp = (my_main_ptr) cinfo->main;
|
|
||||||
int ci, i, rgroup;
|
|
||||||
int M = cinfo->min_DCT_v_scaled_size;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
JSAMPARRAY buf, xbuf0, xbuf1;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
|
||||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
|
||||||
xbuf0 = mainp->xbuffer[0][ci];
|
|
||||||
xbuf1 = mainp->xbuffer[1][ci];
|
|
||||||
/* First copy the workspace pointers as-is */
|
|
||||||
buf = mainp->buffer[ci];
|
|
||||||
for (i = 0; i < rgroup * (M + 2); i++) {
|
|
||||||
xbuf0[i] = xbuf1[i] = buf[i];
|
|
||||||
}
|
|
||||||
/* In the second list, put the last four row groups in swapped order */
|
|
||||||
for (i = 0; i < rgroup * 2; i++) {
|
|
||||||
xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
|
|
||||||
xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
|
|
||||||
}
|
|
||||||
/* The wraparound pointers at top and bottom will be filled later
|
|
||||||
* (see set_wraparound_pointers, below). Initially we want the "above"
|
|
||||||
* pointers to duplicate the first actual data line. This only needs
|
|
||||||
* to happen in xbuffer[0].
|
|
||||||
*/
|
|
||||||
for (i = 0; i < rgroup; i++) {
|
|
||||||
xbuf0[i - rgroup] = xbuf0[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
set_wraparound_pointers (j_decompress_ptr cinfo)
|
|
||||||
/* Set up the "wraparound" pointers at top and bottom of the pointer lists.
|
|
||||||
* This changes the pointer list state from top-of-image to the normal state.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
my_main_ptr mainp = (my_main_ptr) cinfo->main;
|
|
||||||
int ci, i, rgroup;
|
|
||||||
int M = cinfo->min_DCT_v_scaled_size;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
JSAMPARRAY xbuf0, xbuf1;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
|
||||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
|
||||||
xbuf0 = mainp->xbuffer[0][ci];
|
|
||||||
xbuf1 = mainp->xbuffer[1][ci];
|
|
||||||
for (i = 0; i < rgroup; i++) {
|
|
||||||
xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
|
|
||||||
xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
|
|
||||||
xbuf0[rgroup*(M+2) + i] = xbuf0[i];
|
|
||||||
xbuf1[rgroup*(M+2) + i] = xbuf1[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
set_bottom_pointers (j_decompress_ptr cinfo)
|
|
||||||
/* Change the pointer lists to duplicate the last sample row at the bottom
|
|
||||||
* of the image. whichptr indicates which xbuffer holds the final iMCU row.
|
|
||||||
* Also sets rowgroups_avail to indicate number of nondummy row groups in row.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
my_main_ptr mainp = (my_main_ptr) cinfo->main;
|
|
||||||
int ci, i, rgroup, iMCUheight, rows_left;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
JSAMPARRAY xbuf;
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Count sample rows in one iMCU row and in one row group */
|
|
||||||
iMCUheight = compptr->v_samp_factor * compptr->DCT_v_scaled_size;
|
|
||||||
rgroup = iMCUheight / cinfo->min_DCT_v_scaled_size;
|
|
||||||
/* Count nondummy sample rows remaining for this component */
|
|
||||||
rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
|
|
||||||
if (rows_left == 0) rows_left = iMCUheight;
|
|
||||||
/* Count nondummy row groups. Should get same answer for each component,
|
|
||||||
* so we need only do it once.
|
|
||||||
*/
|
|
||||||
if (ci == 0) {
|
|
||||||
mainp->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
|
|
||||||
}
|
|
||||||
/* Duplicate the last real sample row rgroup*2 times; this pads out the
|
|
||||||
* last partial rowgroup and ensures at least one full rowgroup of context.
|
|
||||||
*/
|
|
||||||
xbuf = mainp->xbuffer[mainp->whichptr][ci];
|
|
||||||
for (i = 0; i < rgroup * 2; i++) {
|
|
||||||
xbuf[rows_left + i] = xbuf[rows_left-1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for a processing pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
|
||||||
{
|
|
||||||
my_main_ptr mainp = (my_main_ptr) cinfo->main;
|
|
||||||
|
|
||||||
switch (pass_mode) {
|
|
||||||
case JBUF_PASS_THRU:
|
|
||||||
if (cinfo->upsample->need_context_rows) {
|
|
||||||
mainp->pub.process_data = process_data_context_main;
|
|
||||||
make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
|
|
||||||
mainp->whichptr = 0; /* Read first iMCU row into xbuffer[0] */
|
|
||||||
mainp->context_state = CTX_PREPARE_FOR_IMCU;
|
|
||||||
mainp->iMCU_row_ctr = 0;
|
|
||||||
mainp->buffer_full = FALSE; /* Mark buffer empty */
|
|
||||||
} else {
|
|
||||||
/* Simple case with no context needed */
|
|
||||||
mainp->pub.process_data = process_data_simple_main;
|
|
||||||
mainp->rowgroup_ctr = mainp->rowgroups_avail; /* Mark buffer empty */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
case JBUF_CRANK_DEST:
|
|
||||||
/* For last pass of 2-pass quantization, just crank the postprocessor */
|
|
||||||
mainp->pub.process_data = process_data_crank_post;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process some data.
|
|
||||||
* This handles the simple case where no context is required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
process_data_simple_main (j_decompress_ptr cinfo,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
{
|
|
||||||
my_main_ptr mainp = (my_main_ptr) cinfo->main;
|
|
||||||
|
|
||||||
/* Read input data if we haven't filled the main buffer yet */
|
|
||||||
if (mainp->rowgroup_ctr >= mainp->rowgroups_avail) {
|
|
||||||
if (! (*cinfo->coef->decompress_data) (cinfo, mainp->buffer))
|
|
||||||
return; /* suspension forced, can do nothing more */
|
|
||||||
mainp->rowgroup_ctr = 0; /* OK, we have an iMCU row to work with */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note: at the bottom of the image, we may pass extra garbage row groups
|
|
||||||
* to the postprocessor. The postprocessor has to check for bottom
|
|
||||||
* of image anyway (at row resolution), so no point in us doing it too.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Feed the postprocessor */
|
|
||||||
(*cinfo->post->post_process_data) (cinfo, mainp->buffer,
|
|
||||||
&mainp->rowgroup_ctr, mainp->rowgroups_avail,
|
|
||||||
output_buf, out_row_ctr, out_rows_avail);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process some data.
|
|
||||||
* This handles the case where context rows must be provided.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
process_data_context_main (j_decompress_ptr cinfo,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
{
|
|
||||||
my_main_ptr mainp = (my_main_ptr) cinfo->main;
|
|
||||||
|
|
||||||
/* Read input data if we haven't filled the main buffer yet */
|
|
||||||
if (! mainp->buffer_full) {
|
|
||||||
if (! (*cinfo->coef->decompress_data) (cinfo,
|
|
||||||
mainp->xbuffer[mainp->whichptr]))
|
|
||||||
return; /* suspension forced, can do nothing more */
|
|
||||||
mainp->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
|
|
||||||
mainp->iMCU_row_ctr++; /* count rows received */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Postprocessor typically will not swallow all the input data it is handed
|
|
||||||
* in one call (due to filling the output buffer first). Must be prepared
|
|
||||||
* to exit and restart. This switch lets us keep track of how far we got.
|
|
||||||
* Note that each case falls through to the next on successful completion.
|
|
||||||
*/
|
|
||||||
switch (mainp->context_state) {
|
|
||||||
case CTX_POSTPONED_ROW:
|
|
||||||
/* Call postprocessor using previously set pointers for postponed row */
|
|
||||||
(*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
|
|
||||||
&mainp->rowgroup_ctr, mainp->rowgroups_avail,
|
|
||||||
output_buf, out_row_ctr, out_rows_avail);
|
|
||||||
if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
|
|
||||||
return; /* Need to suspend */
|
|
||||||
mainp->context_state = CTX_PREPARE_FOR_IMCU;
|
|
||||||
if (*out_row_ctr >= out_rows_avail)
|
|
||||||
return; /* Postprocessor exactly filled output buf */
|
|
||||||
/*FALLTHROUGH*/
|
|
||||||
case CTX_PREPARE_FOR_IMCU:
|
|
||||||
/* Prepare to process first M-1 row groups of this iMCU row */
|
|
||||||
mainp->rowgroup_ctr = 0;
|
|
||||||
mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1);
|
|
||||||
/* Check for bottom of image: if so, tweak pointers to "duplicate"
|
|
||||||
* the last sample row, and adjust rowgroups_avail to ignore padding rows.
|
|
||||||
*/
|
|
||||||
if (mainp->iMCU_row_ctr == cinfo->total_iMCU_rows)
|
|
||||||
set_bottom_pointers(cinfo);
|
|
||||||
mainp->context_state = CTX_PROCESS_IMCU;
|
|
||||||
/*FALLTHROUGH*/
|
|
||||||
case CTX_PROCESS_IMCU:
|
|
||||||
/* Call postprocessor using previously set pointers */
|
|
||||||
(*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr],
|
|
||||||
&mainp->rowgroup_ctr, mainp->rowgroups_avail,
|
|
||||||
output_buf, out_row_ctr, out_rows_avail);
|
|
||||||
if (mainp->rowgroup_ctr < mainp->rowgroups_avail)
|
|
||||||
return; /* Need to suspend */
|
|
||||||
/* After the first iMCU, change wraparound pointers to normal state */
|
|
||||||
if (mainp->iMCU_row_ctr == 1)
|
|
||||||
set_wraparound_pointers(cinfo);
|
|
||||||
/* Prepare to load new iMCU row using other xbuffer list */
|
|
||||||
mainp->whichptr ^= 1; /* 0=>1 or 1=>0 */
|
|
||||||
mainp->buffer_full = FALSE;
|
|
||||||
/* Still need to process last row group of this iMCU row, */
|
|
||||||
/* which is saved at index M+1 of the other xbuffer */
|
|
||||||
mainp->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1);
|
|
||||||
mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2);
|
|
||||||
mainp->context_state = CTX_POSTPONED_ROW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process some data.
|
|
||||||
* Final pass of two-pass quantization: just call the postprocessor.
|
|
||||||
* Source data will be the postprocessor controller's internal buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
process_data_crank_post (j_decompress_ptr cinfo,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
{
|
|
||||||
(*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
|
|
||||||
(JDIMENSION *) NULL, (JDIMENSION) 0,
|
|
||||||
output_buf, out_row_ctr, out_rows_avail);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* QUANT_2PASS_SUPPORTED */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize main buffer controller.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
|
|
||||||
{
|
|
||||||
my_main_ptr mainp;
|
|
||||||
int ci, rgroup, ngroups;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
|
|
||||||
mainp = (my_main_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_main_controller));
|
|
||||||
cinfo->main = &mainp->pub;
|
|
||||||
mainp->pub.start_pass = start_pass_main;
|
|
||||||
|
|
||||||
if (need_full_buffer) /* shouldn't happen */
|
|
||||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
|
||||||
|
|
||||||
/* Allocate the workspace.
|
|
||||||
* ngroups is the number of row groups we need.
|
|
||||||
*/
|
|
||||||
if (cinfo->upsample->need_context_rows) {
|
|
||||||
if (cinfo->min_DCT_v_scaled_size < 2) /* unsupported, see comments above */
|
|
||||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
|
||||||
alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
|
|
||||||
ngroups = cinfo->min_DCT_v_scaled_size + 2;
|
|
||||||
} else {
|
|
||||||
/* There are always min_DCT_v_scaled_size row groups in an iMCU row. */
|
|
||||||
ngroups = cinfo->min_DCT_v_scaled_size;
|
|
||||||
mainp->rowgroups_avail = (JDIMENSION) ngroups;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
|
||||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
|
||||||
mainp->buffer[ci] = (*cinfo->mem->alloc_sarray)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size),
|
|
||||||
(JDIMENSION) (rgroup * ngroups));
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,538 +0,0 @@
|
||||||
/*
|
|
||||||
* jdmaster.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
|
||||||
* Modified 2002-2017 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains master control logic for the JPEG decompressor.
|
|
||||||
* These routines are concerned with selecting the modules to be executed
|
|
||||||
* and with determining the number of passes and the work to be done in each
|
|
||||||
* pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Private state */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_decomp_master pub; /* public fields */
|
|
||||||
|
|
||||||
int pass_number; /* # of passes completed */
|
|
||||||
|
|
||||||
boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
|
|
||||||
|
|
||||||
/* Saved references to initialized quantizer modules,
|
|
||||||
* in case we need to switch modes.
|
|
||||||
*/
|
|
||||||
struct jpeg_color_quantizer * quantizer_1pass;
|
|
||||||
struct jpeg_color_quantizer * quantizer_2pass;
|
|
||||||
} my_decomp_master;
|
|
||||||
|
|
||||||
typedef my_decomp_master * my_master_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine whether merged upsample/color conversion should be used.
|
|
||||||
* CRUCIAL: this must match the actual capabilities of jdmerge.c!
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(boolean)
|
|
||||||
use_merged_upsample (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
|
||||||
/* Merging is the equivalent of plain box-filter upsampling. */
|
|
||||||
/* The following condition is only needed if fancy shall select
|
|
||||||
* a different upsampling method. In our current implementation
|
|
||||||
* fancy only affects the DCT scaling, thus we can use fancy
|
|
||||||
* upsampling and merged upsample simultaneously, in particular
|
|
||||||
* with scaled DCT sizes larger than the default DCTSIZE.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
if (cinfo->do_fancy_upsampling)
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
if (cinfo->CCIR601_sampling)
|
|
||||||
return FALSE;
|
|
||||||
/* jdmerge.c only supports YCC=>RGB color conversion */
|
|
||||||
if ((cinfo->jpeg_color_space != JCS_YCbCr &&
|
|
||||||
cinfo->jpeg_color_space != JCS_BG_YCC) ||
|
|
||||||
cinfo->num_components != 3 ||
|
|
||||||
cinfo->out_color_space != JCS_RGB ||
|
|
||||||
cinfo->out_color_components != RGB_PIXELSIZE ||
|
|
||||||
cinfo->color_transform)
|
|
||||||
return FALSE;
|
|
||||||
/* and it only handles 2h1v or 2h2v sampling ratios */
|
|
||||||
if (cinfo->comp_info[0].h_samp_factor != 2 ||
|
|
||||||
cinfo->comp_info[1].h_samp_factor != 1 ||
|
|
||||||
cinfo->comp_info[2].h_samp_factor != 1 ||
|
|
||||||
cinfo->comp_info[0].v_samp_factor > 2 ||
|
|
||||||
cinfo->comp_info[1].v_samp_factor != 1 ||
|
|
||||||
cinfo->comp_info[2].v_samp_factor != 1)
|
|
||||||
return FALSE;
|
|
||||||
/* furthermore, it doesn't work if we've scaled the IDCTs differently */
|
|
||||||
if (cinfo->comp_info[0].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
|
|
||||||
cinfo->comp_info[1].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
|
|
||||||
cinfo->comp_info[2].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
|
|
||||||
cinfo->comp_info[0].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size ||
|
|
||||||
cinfo->comp_info[1].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size ||
|
|
||||||
cinfo->comp_info[2].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size)
|
|
||||||
return FALSE;
|
|
||||||
/* ??? also need to test for upsample-time rescaling, when & if supported */
|
|
||||||
return TRUE; /* by golly, it'll work... */
|
|
||||||
#else
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute output image dimensions and related values.
|
|
||||||
* NOTE: this is exported for possible use by application.
|
|
||||||
* Hence it mustn't do anything that can't be done twice.
|
|
||||||
* Also note that it may be called before the master module is initialized!
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
|
||||||
/* Do computations that are needed before master selection phase.
|
|
||||||
* This function is used for full decompression.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
#ifdef IDCT_SCALING_SUPPORTED
|
|
||||||
int ci;
|
|
||||||
jpeg_component_info *compptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Prevent application from calling me at wrong times */
|
|
||||||
if (cinfo->global_state != DSTATE_READY)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
|
|
||||||
/* Compute core output image dimensions and DCT scaling choices. */
|
|
||||||
jpeg_core_output_dimensions(cinfo);
|
|
||||||
|
|
||||||
#ifdef IDCT_SCALING_SUPPORTED
|
|
||||||
|
|
||||||
/* In selecting the actual DCT scaling for each component, we try to
|
|
||||||
* scale up the chroma components via IDCT scaling rather than upsampling.
|
|
||||||
* This saves time if the upsampler gets to use 1:1 scaling.
|
|
||||||
* Note this code adapts subsampling ratios which are powers of 2.
|
|
||||||
*/
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
int ssize = 1;
|
|
||||||
while (cinfo->min_DCT_h_scaled_size * ssize <=
|
|
||||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
|
||||||
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
|
|
||||||
ssize = ssize * 2;
|
|
||||||
}
|
|
||||||
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
|
|
||||||
ssize = 1;
|
|
||||||
while (cinfo->min_DCT_v_scaled_size * ssize <=
|
|
||||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
|
||||||
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
|
|
||||||
ssize = ssize * 2;
|
|
||||||
}
|
|
||||||
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
|
|
||||||
|
|
||||||
/* We don't support IDCT ratios larger than 2. */
|
|
||||||
if (compptr->DCT_h_scaled_size > compptr->DCT_v_scaled_size * 2)
|
|
||||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
|
|
||||||
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
|
|
||||||
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Recompute downsampled dimensions of components;
|
|
||||||
* application needs to know these if using raw downsampled data.
|
|
||||||
*/
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Size in samples, after IDCT scaling */
|
|
||||||
compptr->downsampled_width = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_width *
|
|
||||||
(long) (compptr->h_samp_factor * compptr->DCT_h_scaled_size),
|
|
||||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
|
||||||
compptr->downsampled_height = (JDIMENSION)
|
|
||||||
jdiv_round_up((long) cinfo->image_height *
|
|
||||||
(long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size),
|
|
||||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* IDCT_SCALING_SUPPORTED */
|
|
||||||
|
|
||||||
/* Report number of components in selected colorspace. */
|
|
||||||
/* Probably this should be in the color conversion module... */
|
|
||||||
switch (cinfo->out_color_space) {
|
|
||||||
case JCS_GRAYSCALE:
|
|
||||||
cinfo->out_color_components = 1;
|
|
||||||
break;
|
|
||||||
case JCS_RGB:
|
|
||||||
case JCS_BG_RGB:
|
|
||||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
|
||||||
break;
|
|
||||||
case JCS_YCbCr:
|
|
||||||
case JCS_BG_YCC:
|
|
||||||
cinfo->out_color_components = 3;
|
|
||||||
break;
|
|
||||||
case JCS_CMYK:
|
|
||||||
case JCS_YCCK:
|
|
||||||
cinfo->out_color_components = 4;
|
|
||||||
break;
|
|
||||||
default: /* else must be same colorspace as in file */
|
|
||||||
cinfo->out_color_components = cinfo->num_components;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cinfo->output_components = (cinfo->quantize_colors ? 1 :
|
|
||||||
cinfo->out_color_components);
|
|
||||||
|
|
||||||
/* See if upsampler will want to emit more than one row at a time */
|
|
||||||
if (use_merged_upsample(cinfo))
|
|
||||||
cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
|
|
||||||
else
|
|
||||||
cinfo->rec_outbuf_height = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Several decompression processes need to range-limit values to the range
|
|
||||||
* 0..MAXJSAMPLE; the input value may fall somewhat outside this range
|
|
||||||
* due to noise introduced by quantization, roundoff error, etc. These
|
|
||||||
* processes are inner loops and need to be as fast as possible. On most
|
|
||||||
* machines, particularly CPUs with pipelines or instruction prefetch,
|
|
||||||
* a (subscript-check-less) C table lookup
|
|
||||||
* x = sample_range_limit[x];
|
|
||||||
* is faster than explicit tests
|
|
||||||
* if (x < 0) x = 0;
|
|
||||||
* else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
|
|
||||||
* These processes all use a common table prepared by the routine below.
|
|
||||||
*
|
|
||||||
* For most steps we can mathematically guarantee that the initial value
|
|
||||||
* of x is within 2*(MAXJSAMPLE+1) of the legal range, so a table running
|
|
||||||
* from -2*(MAXJSAMPLE+1) to 3*MAXJSAMPLE+2 is sufficient. But for the
|
|
||||||
* initial limiting step (just after the IDCT), a wildly out-of-range value
|
|
||||||
* is possible if the input data is corrupt. To avoid any chance of indexing
|
|
||||||
* off the end of memory and getting a bad-pointer trap, we perform the
|
|
||||||
* post-IDCT limiting thus:
|
|
||||||
* x = (sample_range_limit - SUBSET)[(x + CENTER) & MASK];
|
|
||||||
* where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
|
|
||||||
* samples. Under normal circumstances this is more than enough range and
|
|
||||||
* a correct output will be generated; with bogus input data the mask will
|
|
||||||
* cause wraparound, and we will safely generate a bogus-but-in-range output.
|
|
||||||
* For the post-IDCT step, we want to convert the data from signed to unsigned
|
|
||||||
* representation by adding CENTERJSAMPLE at the same time that we limit it.
|
|
||||||
* This is accomplished with SUBSET = CENTER - CENTERJSAMPLE.
|
|
||||||
*
|
|
||||||
* Note that the table is allocated in near data space on PCs; it's small
|
|
||||||
* enough and used often enough to justify this.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
prepare_range_limit_table (j_decompress_ptr cinfo)
|
|
||||||
/* Allocate and fill in the sample_range_limit table */
|
|
||||||
{
|
|
||||||
JSAMPLE * table;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
table = (JSAMPLE *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
|
|
||||||
JPOOL_IMAGE, (RANGE_CENTER * 2 + MAXJSAMPLE + 1) * SIZEOF(JSAMPLE));
|
|
||||||
/* First segment of range limit table: limit[x] = 0 for x < 0 */
|
|
||||||
MEMZERO(table, RANGE_CENTER * SIZEOF(JSAMPLE));
|
|
||||||
table += RANGE_CENTER; /* allow negative subscripts of table */
|
|
||||||
cinfo->sample_range_limit = table;
|
|
||||||
/* Main part of range limit table: limit[x] = x */
|
|
||||||
for (i = 0; i <= MAXJSAMPLE; i++)
|
|
||||||
table[i] = (JSAMPLE) i;
|
|
||||||
/* End of range limit table: limit[x] = MAXJSAMPLE for x > MAXJSAMPLE */
|
|
||||||
for (; i <= MAXJSAMPLE + RANGE_CENTER; i++)
|
|
||||||
table[i] = MAXJSAMPLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Master selection of decompression modules.
|
|
||||||
* This is done once at jpeg_start_decompress time. We determine
|
|
||||||
* which modules will be used and give them appropriate initialization calls.
|
|
||||||
* We also initialize the decompressor input side to begin consuming data.
|
|
||||||
*
|
|
||||||
* Since jpeg_read_header has finished, we know what is in the SOF
|
|
||||||
* and (first) SOS markers. We also have all the application parameter
|
|
||||||
* settings.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
master_selection (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_master_ptr master = (my_master_ptr) cinfo->master;
|
|
||||||
boolean use_c_buffer;
|
|
||||||
long samplesperrow;
|
|
||||||
JDIMENSION jd_samplesperrow;
|
|
||||||
|
|
||||||
/* For now, precision must match compiled-in value... */
|
|
||||||
if (cinfo->data_precision != BITS_IN_JSAMPLE)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
|
|
||||||
|
|
||||||
/* Initialize dimensions and other stuff */
|
|
||||||
jpeg_calc_output_dimensions(cinfo);
|
|
||||||
prepare_range_limit_table(cinfo);
|
|
||||||
|
|
||||||
/* Sanity check on image dimensions */
|
|
||||||
if (cinfo->output_height <= 0 || cinfo->output_width <= 0 ||
|
|
||||||
cinfo->out_color_components <= 0)
|
|
||||||
ERREXIT(cinfo, JERR_EMPTY_IMAGE);
|
|
||||||
|
|
||||||
/* Width of an output scanline must be representable as JDIMENSION. */
|
|
||||||
samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
|
|
||||||
jd_samplesperrow = (JDIMENSION) samplesperrow;
|
|
||||||
if ((long) jd_samplesperrow != samplesperrow)
|
|
||||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
|
||||||
|
|
||||||
/* Initialize my private state */
|
|
||||||
master->pass_number = 0;
|
|
||||||
master->using_merged_upsample = use_merged_upsample(cinfo);
|
|
||||||
|
|
||||||
/* Color quantizer selection */
|
|
||||||
master->quantizer_1pass = NULL;
|
|
||||||
master->quantizer_2pass = NULL;
|
|
||||||
/* No mode changes if not using buffered-image mode. */
|
|
||||||
if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
|
|
||||||
cinfo->enable_1pass_quant = FALSE;
|
|
||||||
cinfo->enable_external_quant = FALSE;
|
|
||||||
cinfo->enable_2pass_quant = FALSE;
|
|
||||||
}
|
|
||||||
if (cinfo->quantize_colors) {
|
|
||||||
if (cinfo->raw_data_out)
|
|
||||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
|
||||||
/* 2-pass quantizer only works in 3-component color space. */
|
|
||||||
if (cinfo->out_color_components != 3) {
|
|
||||||
cinfo->enable_1pass_quant = TRUE;
|
|
||||||
cinfo->enable_external_quant = FALSE;
|
|
||||||
cinfo->enable_2pass_quant = FALSE;
|
|
||||||
cinfo->colormap = NULL;
|
|
||||||
} else if (cinfo->colormap != NULL) {
|
|
||||||
cinfo->enable_external_quant = TRUE;
|
|
||||||
} else if (cinfo->two_pass_quantize) {
|
|
||||||
cinfo->enable_2pass_quant = TRUE;
|
|
||||||
} else {
|
|
||||||
cinfo->enable_1pass_quant = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cinfo->enable_1pass_quant) {
|
|
||||||
#ifdef QUANT_1PASS_SUPPORTED
|
|
||||||
jinit_1pass_quantizer(cinfo);
|
|
||||||
master->quantizer_1pass = cinfo->cquantize;
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We use the 2-pass code to map to external colormaps. */
|
|
||||||
if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
jinit_2pass_quantizer(cinfo);
|
|
||||||
master->quantizer_2pass = cinfo->cquantize;
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/* If both quantizers are initialized, the 2-pass one is left active;
|
|
||||||
* this is necessary for starting with quantization to an external map.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Post-processing: in particular, color conversion first */
|
|
||||||
if (! cinfo->raw_data_out) {
|
|
||||||
if (master->using_merged_upsample) {
|
|
||||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
|
||||||
jinit_merged_upsampler(cinfo); /* does color conversion too */
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
jinit_color_deconverter(cinfo);
|
|
||||||
jinit_upsampler(cinfo);
|
|
||||||
}
|
|
||||||
jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
|
|
||||||
}
|
|
||||||
/* Inverse DCT */
|
|
||||||
jinit_inverse_dct(cinfo);
|
|
||||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
|
||||||
if (cinfo->arith_code)
|
|
||||||
jinit_arith_decoder(cinfo);
|
|
||||||
else {
|
|
||||||
jinit_huff_decoder(cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize principal buffer controllers. */
|
|
||||||
use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
|
|
||||||
jinit_d_coef_controller(cinfo, use_c_buffer);
|
|
||||||
|
|
||||||
if (! cinfo->raw_data_out)
|
|
||||||
jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
|
|
||||||
|
|
||||||
/* We can now tell the memory manager to allocate virtual arrays. */
|
|
||||||
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
|
|
||||||
|
|
||||||
/* Initialize input side of decompressor to consume first scan. */
|
|
||||||
(*cinfo->inputctl->start_input_pass) (cinfo);
|
|
||||||
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
/* If jpeg_start_decompress will read the whole file, initialize
|
|
||||||
* progress monitoring appropriately. The input step is counted
|
|
||||||
* as one pass.
|
|
||||||
*/
|
|
||||||
if (cinfo->progress != NULL && ! cinfo->buffered_image &&
|
|
||||||
cinfo->inputctl->has_multiple_scans) {
|
|
||||||
int nscans;
|
|
||||||
/* Estimate number of scans to set pass_limit. */
|
|
||||||
if (cinfo->progressive_mode) {
|
|
||||||
/* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
|
|
||||||
nscans = 2 + 3 * cinfo->num_components;
|
|
||||||
} else {
|
|
||||||
/* For a nonprogressive multiscan file, estimate 1 scan per component. */
|
|
||||||
nscans = cinfo->num_components;
|
|
||||||
}
|
|
||||||
cinfo->progress->pass_counter = 0L;
|
|
||||||
cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
|
|
||||||
cinfo->progress->completed_passes = 0;
|
|
||||||
cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
|
|
||||||
/* Count the input pass as done */
|
|
||||||
master->pass_number++;
|
|
||||||
}
|
|
||||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Per-pass setup.
|
|
||||||
* This is called at the beginning of each output pass. We determine which
|
|
||||||
* modules will be active during this pass and give them appropriate
|
|
||||||
* start_pass calls. We also set is_dummy_pass to indicate whether this
|
|
||||||
* is a "real" output pass or a dummy pass for color quantization.
|
|
||||||
* (In the latter case, jdapistd.c will crank the pass to completion.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
prepare_for_output_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_master_ptr master = (my_master_ptr) cinfo->master;
|
|
||||||
|
|
||||||
if (master->pub.is_dummy_pass) {
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
/* Final pass of 2-pass quantization */
|
|
||||||
master->pub.is_dummy_pass = FALSE;
|
|
||||||
(*cinfo->cquantize->start_pass) (cinfo, FALSE);
|
|
||||||
(*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
|
|
||||||
(*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
#endif /* QUANT_2PASS_SUPPORTED */
|
|
||||||
} else {
|
|
||||||
if (cinfo->quantize_colors && cinfo->colormap == NULL) {
|
|
||||||
/* Select new quantization method */
|
|
||||||
if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
|
|
||||||
cinfo->cquantize = master->quantizer_2pass;
|
|
||||||
master->pub.is_dummy_pass = TRUE;
|
|
||||||
} else if (cinfo->enable_1pass_quant) {
|
|
||||||
cinfo->cquantize = master->quantizer_1pass;
|
|
||||||
} else {
|
|
||||||
ERREXIT(cinfo, JERR_MODE_CHANGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(*cinfo->idct->start_pass) (cinfo);
|
|
||||||
(*cinfo->coef->start_output_pass) (cinfo);
|
|
||||||
if (! cinfo->raw_data_out) {
|
|
||||||
if (! master->using_merged_upsample)
|
|
||||||
(*cinfo->cconvert->start_pass) (cinfo);
|
|
||||||
(*cinfo->upsample->start_pass) (cinfo);
|
|
||||||
if (cinfo->quantize_colors)
|
|
||||||
(*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
|
|
||||||
(*cinfo->post->start_pass) (cinfo,
|
|
||||||
(master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
|
|
||||||
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up progress monitor's pass info if present */
|
|
||||||
if (cinfo->progress != NULL) {
|
|
||||||
cinfo->progress->completed_passes = master->pass_number;
|
|
||||||
cinfo->progress->total_passes = master->pass_number +
|
|
||||||
(master->pub.is_dummy_pass ? 2 : 1);
|
|
||||||
/* In buffered-image mode, we assume one more output pass if EOI not
|
|
||||||
* yet reached, but no more passes if EOI has been reached.
|
|
||||||
*/
|
|
||||||
if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
|
|
||||||
cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish up at end of an output pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
finish_output_pass (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_master_ptr master = (my_master_ptr) cinfo->master;
|
|
||||||
|
|
||||||
if (cinfo->quantize_colors)
|
|
||||||
(*cinfo->cquantize->finish_pass) (cinfo);
|
|
||||||
master->pass_number++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef D_MULTISCAN_FILES_SUPPORTED
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch to a new external colormap between output passes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_new_colormap (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_master_ptr master = (my_master_ptr) cinfo->master;
|
|
||||||
|
|
||||||
/* Prevent application from calling me at wrong times */
|
|
||||||
if (cinfo->global_state != DSTATE_BUFIMAGE)
|
|
||||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
|
||||||
|
|
||||||
if (cinfo->quantize_colors && cinfo->enable_external_quant &&
|
|
||||||
cinfo->colormap != NULL) {
|
|
||||||
/* Select 2-pass quantizer for external colormap use */
|
|
||||||
cinfo->cquantize = master->quantizer_2pass;
|
|
||||||
/* Notify quantizer of colormap change */
|
|
||||||
(*cinfo->cquantize->new_color_map) (cinfo);
|
|
||||||
master->pub.is_dummy_pass = FALSE; /* just in case */
|
|
||||||
} else
|
|
||||||
ERREXIT(cinfo, JERR_MODE_CHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* D_MULTISCAN_FILES_SUPPORTED */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize master decompression control and select active modules.
|
|
||||||
* This is performed at the start of jpeg_start_decompress.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_master_decompress (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_master_ptr master;
|
|
||||||
|
|
||||||
master = (my_master_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_decomp_master));
|
|
||||||
cinfo->master = &master->pub;
|
|
||||||
master->pub.prepare_for_output_pass = prepare_for_output_pass;
|
|
||||||
master->pub.finish_output_pass = finish_output_pass;
|
|
||||||
|
|
||||||
master->pub.is_dummy_pass = FALSE;
|
|
||||||
|
|
||||||
master_selection(cinfo);
|
|
||||||
}
|
|
|
@ -1,451 +0,0 @@
|
||||||
/*
|
|
||||||
* jdmerge.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
|
||||||
* Modified 2013-2017 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 code for merged upsampling/color conversion.
|
|
||||||
*
|
|
||||||
* This file combines functions from jdsample.c and jdcolor.c;
|
|
||||||
* read those files first to understand what's going on.
|
|
||||||
*
|
|
||||||
* When the chroma components are to be upsampled by simple replication
|
|
||||||
* (ie, box filtering), we can save some work in color conversion by
|
|
||||||
* calculating all the output pixels corresponding to a pair of chroma
|
|
||||||
* samples at one time. In the conversion equations
|
|
||||||
* R = Y + K1 * Cr
|
|
||||||
* G = Y + K2 * Cb + K3 * Cr
|
|
||||||
* B = Y + K4 * Cb
|
|
||||||
* only the Y term varies among the group of pixels corresponding to a pair
|
|
||||||
* of chroma samples, so the rest of the terms can be calculated just once.
|
|
||||||
* At typical sampling ratios, this eliminates half or three-quarters of the
|
|
||||||
* multiplications needed for color conversion.
|
|
||||||
*
|
|
||||||
* This file currently provides implementations for the following cases:
|
|
||||||
* YCC => RGB color conversion only (YCbCr or BG_YCC).
|
|
||||||
* Sampling ratios of 2h1v or 2h2v.
|
|
||||||
* No scaling needed at upsample time.
|
|
||||||
* Corner-aligned (non-CCIR601) sampling alignment.
|
|
||||||
* Other special cases could be added, but in most applications these are
|
|
||||||
* the only common cases. (For uncommon cases we fall back on the more
|
|
||||||
* general code in jdsample.c and jdcolor.c.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
|
||||||
|
|
||||||
|
|
||||||
#if RANGE_BITS < 2
|
|
||||||
/* Deliberate syntax err */
|
|
||||||
Sorry, this code requires 2 or more range extension bits.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Private subobject */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_upsampler pub; /* public fields */
|
|
||||||
|
|
||||||
/* Pointer to routine to do actual upsampling/conversion of one row group */
|
|
||||||
JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
|
||||||
JSAMPARRAY output_buf));
|
|
||||||
|
|
||||||
/* Private state for YCC->RGB conversion */
|
|
||||||
int * Cr_r_tab; /* => table for Cr to R conversion */
|
|
||||||
int * Cb_b_tab; /* => table for Cb to B conversion */
|
|
||||||
INT32 * Cr_g_tab; /* => table for Cr to G conversion */
|
|
||||||
INT32 * Cb_g_tab; /* => table for Cb to G conversion */
|
|
||||||
|
|
||||||
/* For 2:1 vertical sampling, we produce two output rows at a time.
|
|
||||||
* We need a "spare" row buffer to hold the second output row if the
|
|
||||||
* application provides just a one-row buffer; we also use the spare
|
|
||||||
* to discard the dummy last row if the image height is odd.
|
|
||||||
*/
|
|
||||||
JSAMPROW spare_row;
|
|
||||||
boolean spare_full; /* T if spare buffer is occupied */
|
|
||||||
|
|
||||||
JDIMENSION out_row_width; /* samples per output row */
|
|
||||||
JDIMENSION rows_to_go; /* counts rows remaining in image */
|
|
||||||
} my_upsampler;
|
|
||||||
|
|
||||||
typedef my_upsampler * my_upsample_ptr;
|
|
||||||
|
|
||||||
#define SCALEBITS 16 /* speediest right-shift on some machines */
|
|
||||||
#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
|
|
||||||
#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion.
|
|
||||||
* This is taken directly from jdcolor.c; see that file for more info.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
build_ycc_rgb_table (j_decompress_ptr cinfo)
|
|
||||||
/* Normal case, sYCC */
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
int i;
|
|
||||||
INT32 x;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
upsample->Cr_r_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
upsample->Cb_b_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
upsample->Cr_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
upsample->Cb_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
|
|
||||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
|
||||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
|
||||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
|
||||||
/* Cr=>R value is nearest int to 1.402 * x */
|
|
||||||
upsample->Cr_r_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cb=>B value is nearest int to 1.772 * x */
|
|
||||||
upsample->Cb_b_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cr=>G value is scaled-up -0.714136286 * x */
|
|
||||||
upsample->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
|
|
||||||
/* Cb=>G value is scaled-up -0.344136286 * x */
|
|
||||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
|
||||||
upsample->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
|
|
||||||
/* Wide gamut case, bg-sYCC */
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
int i;
|
|
||||||
INT32 x;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
upsample->Cr_r_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
upsample->Cb_b_tab = (int *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(int));
|
|
||||||
upsample->Cr_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
upsample->Cb_g_tab = (INT32 *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(MAXJSAMPLE+1) * SIZEOF(INT32));
|
|
||||||
|
|
||||||
for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
|
|
||||||
/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
|
|
||||||
/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
|
|
||||||
/* Cr=>R value is nearest int to 2.804 * x */
|
|
||||||
upsample->Cr_r_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cb=>B value is nearest int to 3.544 * x */
|
|
||||||
upsample->Cb_b_tab[i] = (int)
|
|
||||||
RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
|
|
||||||
/* Cr=>G value is scaled-up -1.428272572 * x */
|
|
||||||
upsample->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
|
|
||||||
/* Cb=>G value is scaled-up -0.688272572 * x */
|
|
||||||
/* We also add in ONE_HALF so that need not do it in inner loop */
|
|
||||||
upsample->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for an upsampling pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass_merged_upsample (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
|
|
||||||
/* Mark the spare buffer empty */
|
|
||||||
upsample->spare_full = FALSE;
|
|
||||||
/* Initialize total-height counter for detecting bottom of image */
|
|
||||||
upsample->rows_to_go = cinfo->output_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Control routine to do upsampling (and color conversion).
|
|
||||||
*
|
|
||||||
* The control routine just handles the row buffering considerations.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
merged_2v_upsample (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
/* 2:1 vertical sampling case: may need a spare row. */
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
JSAMPROW work_ptrs[2];
|
|
||||||
JDIMENSION num_rows; /* number of rows returned to caller */
|
|
||||||
|
|
||||||
if (upsample->spare_full) {
|
|
||||||
/* If we have a spare row saved from a previous cycle, just return it. */
|
|
||||||
jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
|
|
||||||
1, upsample->out_row_width);
|
|
||||||
num_rows = 1;
|
|
||||||
upsample->spare_full = FALSE;
|
|
||||||
} else {
|
|
||||||
/* Figure number of rows to return to caller. */
|
|
||||||
num_rows = 2;
|
|
||||||
/* Not more than the distance to the end of the image. */
|
|
||||||
if (num_rows > upsample->rows_to_go)
|
|
||||||
num_rows = upsample->rows_to_go;
|
|
||||||
/* And not more than what the client can accept: */
|
|
||||||
out_rows_avail -= *out_row_ctr;
|
|
||||||
if (num_rows > out_rows_avail)
|
|
||||||
num_rows = out_rows_avail;
|
|
||||||
/* Create output pointer array for upsampler. */
|
|
||||||
work_ptrs[0] = output_buf[*out_row_ctr];
|
|
||||||
if (num_rows > 1) {
|
|
||||||
work_ptrs[1] = output_buf[*out_row_ctr + 1];
|
|
||||||
} else {
|
|
||||||
work_ptrs[1] = upsample->spare_row;
|
|
||||||
upsample->spare_full = TRUE;
|
|
||||||
}
|
|
||||||
/* Now do the upsampling. */
|
|
||||||
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjust counts */
|
|
||||||
*out_row_ctr += num_rows;
|
|
||||||
upsample->rows_to_go -= num_rows;
|
|
||||||
/* When the buffer is emptied, declare this input row group consumed */
|
|
||||||
if (! upsample->spare_full)
|
|
||||||
(*in_row_group_ctr)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
merged_1v_upsample (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
/* 1:1 vertical sampling case: much easier, never need a spare row. */
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
|
|
||||||
/* Just do the upsampling. */
|
|
||||||
(*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
|
|
||||||
output_buf + *out_row_ctr);
|
|
||||||
/* Adjust counts */
|
|
||||||
(*out_row_ctr)++;
|
|
||||||
(*in_row_group_ctr)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are the routines invoked by the control routines to do
|
|
||||||
* the actual upsampling/conversion. One row group is processed per call.
|
|
||||||
*
|
|
||||||
* Note: since we may be writing directly into application-supplied buffers,
|
|
||||||
* we have to be honest about the output width; we can't assume the buffer
|
|
||||||
* has been rounded up to an even width.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
h2v1_merged_upsample (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
|
||||||
JSAMPARRAY output_buf)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
register int y, cred, cgreen, cblue;
|
|
||||||
int cb, cr;
|
|
||||||
register JSAMPROW outptr;
|
|
||||||
JSAMPROW inptr0, inptr1, inptr2;
|
|
||||||
JDIMENSION col;
|
|
||||||
/* copy these pointers into registers if possible */
|
|
||||||
register JSAMPLE * range_limit = cinfo->sample_range_limit;
|
|
||||||
int * Crrtab = upsample->Cr_r_tab;
|
|
||||||
int * Cbbtab = upsample->Cb_b_tab;
|
|
||||||
INT32 * Crgtab = upsample->Cr_g_tab;
|
|
||||||
INT32 * Cbgtab = upsample->Cb_g_tab;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
inptr0 = input_buf[0][in_row_group_ctr];
|
|
||||||
inptr1 = input_buf[1][in_row_group_ctr];
|
|
||||||
inptr2 = input_buf[2][in_row_group_ctr];
|
|
||||||
outptr = output_buf[0];
|
|
||||||
/* Loop for each pair of output pixels */
|
|
||||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
|
||||||
/* Do the chroma part of the calculation */
|
|
||||||
cb = GETJSAMPLE(*inptr1++);
|
|
||||||
cr = GETJSAMPLE(*inptr2++);
|
|
||||||
cred = Crrtab[cr];
|
|
||||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
|
||||||
cblue = Cbbtab[cb];
|
|
||||||
/* Fetch 2 Y values and emit 2 pixels */
|
|
||||||
y = GETJSAMPLE(*inptr0++);
|
|
||||||
outptr[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
outptr += RGB_PIXELSIZE;
|
|
||||||
y = GETJSAMPLE(*inptr0++);
|
|
||||||
outptr[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
outptr += RGB_PIXELSIZE;
|
|
||||||
}
|
|
||||||
/* If image width is odd, do the last output column separately */
|
|
||||||
if (cinfo->output_width & 1) {
|
|
||||||
cb = GETJSAMPLE(*inptr1);
|
|
||||||
cr = GETJSAMPLE(*inptr2);
|
|
||||||
cred = Crrtab[cr];
|
|
||||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
|
||||||
cblue = Cbbtab[cb];
|
|
||||||
y = GETJSAMPLE(*inptr0);
|
|
||||||
outptr[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
h2v2_merged_upsample (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
|
|
||||||
JSAMPARRAY output_buf)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
register int y, cred, cgreen, cblue;
|
|
||||||
int cb, cr;
|
|
||||||
register JSAMPROW outptr0, outptr1;
|
|
||||||
JSAMPROW inptr00, inptr01, inptr1, inptr2;
|
|
||||||
JDIMENSION col;
|
|
||||||
/* copy these pointers into registers if possible */
|
|
||||||
register JSAMPLE * range_limit = cinfo->sample_range_limit;
|
|
||||||
int * Crrtab = upsample->Cr_r_tab;
|
|
||||||
int * Cbbtab = upsample->Cb_b_tab;
|
|
||||||
INT32 * Crgtab = upsample->Cr_g_tab;
|
|
||||||
INT32 * Cbgtab = upsample->Cb_g_tab;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
inptr00 = input_buf[0][in_row_group_ctr*2];
|
|
||||||
inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
|
|
||||||
inptr1 = input_buf[1][in_row_group_ctr];
|
|
||||||
inptr2 = input_buf[2][in_row_group_ctr];
|
|
||||||
outptr0 = output_buf[0];
|
|
||||||
outptr1 = output_buf[1];
|
|
||||||
/* Loop for each group of output pixels */
|
|
||||||
for (col = cinfo->output_width >> 1; col > 0; col--) {
|
|
||||||
/* Do the chroma part of the calculation */
|
|
||||||
cb = GETJSAMPLE(*inptr1++);
|
|
||||||
cr = GETJSAMPLE(*inptr2++);
|
|
||||||
cred = Crrtab[cr];
|
|
||||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
|
||||||
cblue = Cbbtab[cb];
|
|
||||||
/* Fetch 4 Y values and emit 4 pixels */
|
|
||||||
y = GETJSAMPLE(*inptr00++);
|
|
||||||
outptr0[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
outptr0 += RGB_PIXELSIZE;
|
|
||||||
y = GETJSAMPLE(*inptr00++);
|
|
||||||
outptr0[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
outptr0 += RGB_PIXELSIZE;
|
|
||||||
y = GETJSAMPLE(*inptr01++);
|
|
||||||
outptr1[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
outptr1 += RGB_PIXELSIZE;
|
|
||||||
y = GETJSAMPLE(*inptr01++);
|
|
||||||
outptr1[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
outptr1 += RGB_PIXELSIZE;
|
|
||||||
}
|
|
||||||
/* If image width is odd, do the last output column separately */
|
|
||||||
if (cinfo->output_width & 1) {
|
|
||||||
cb = GETJSAMPLE(*inptr1);
|
|
||||||
cr = GETJSAMPLE(*inptr2);
|
|
||||||
cred = Crrtab[cr];
|
|
||||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
|
||||||
cblue = Cbbtab[cb];
|
|
||||||
y = GETJSAMPLE(*inptr00);
|
|
||||||
outptr0[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr0[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr0[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
y = GETJSAMPLE(*inptr01);
|
|
||||||
outptr1[RGB_RED] = range_limit[y + cred];
|
|
||||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
|
||||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module initialization routine for merged upsampling/color conversion.
|
|
||||||
*
|
|
||||||
* NB: this is called under the conditions determined by use_merged_upsample()
|
|
||||||
* in jdmaster.c. That routine MUST correspond to the actual capabilities
|
|
||||||
* of this module; no safety checks are made here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_merged_upsampler (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample;
|
|
||||||
|
|
||||||
upsample = (my_upsample_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_upsampler));
|
|
||||||
cinfo->upsample = &upsample->pub;
|
|
||||||
upsample->pub.start_pass = start_pass_merged_upsample;
|
|
||||||
upsample->pub.need_context_rows = FALSE;
|
|
||||||
|
|
||||||
upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
|
|
||||||
|
|
||||||
if (cinfo->max_v_samp_factor == 2) {
|
|
||||||
upsample->pub.upsample = merged_2v_upsample;
|
|
||||||
upsample->upmethod = h2v2_merged_upsample;
|
|
||||||
/* Allocate a spare row buffer */
|
|
||||||
upsample->spare_row = (JSAMPROW)
|
|
||||||
(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
|
|
||||||
} else {
|
|
||||||
upsample->pub.upsample = merged_1v_upsample;
|
|
||||||
upsample->upmethod = h2v1_merged_upsample;
|
|
||||||
/* No spare row needed */
|
|
||||||
upsample->spare_row = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cinfo->jpeg_color_space == JCS_BG_YCC)
|
|
||||||
build_bg_ycc_rgb_table(cinfo);
|
|
||||||
else
|
|
||||||
build_ycc_rgb_table(cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* UPSAMPLE_MERGING_SUPPORTED */
|
|
|
@ -1,290 +0,0 @@
|
||||||
/*
|
|
||||||
* jdpostct.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains the decompression postprocessing controller.
|
|
||||||
* This controller manages the upsampling, color conversion, and color
|
|
||||||
* quantization/reduction steps; specifically, it controls the buffering
|
|
||||||
* between upsample/color conversion and color quantization/reduction.
|
|
||||||
*
|
|
||||||
* If no color quantization/reduction is required, then this module has no
|
|
||||||
* work to do, and it just hands off to the upsample/color conversion code.
|
|
||||||
* An integrated upsample/convert/quantize process would replace this module
|
|
||||||
* entirely.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Private buffer controller object */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_d_post_controller pub; /* public fields */
|
|
||||||
|
|
||||||
/* Color quantization source buffer: this holds output data from
|
|
||||||
* the upsample/color conversion step to be passed to the quantizer.
|
|
||||||
* For two-pass color quantization, we need a full-image buffer;
|
|
||||||
* for one-pass operation, a strip buffer is sufficient.
|
|
||||||
*/
|
|
||||||
jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
|
|
||||||
JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */
|
|
||||||
JDIMENSION strip_height; /* buffer size in rows */
|
|
||||||
/* for two-pass mode only: */
|
|
||||||
JDIMENSION starting_row; /* row # of first row in current strip */
|
|
||||||
JDIMENSION next_row; /* index of next row to fill/empty in strip */
|
|
||||||
} my_post_controller;
|
|
||||||
|
|
||||||
typedef my_post_controller * my_post_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
/* Forward declarations */
|
|
||||||
METHODDEF(void) post_process_1pass
|
|
||||||
JPP((j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail));
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
METHODDEF(void) post_process_prepass
|
|
||||||
JPP((j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail));
|
|
||||||
METHODDEF(void) post_process_2pass
|
|
||||||
JPP((j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for a processing pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
|
|
||||||
{
|
|
||||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
|
||||||
|
|
||||||
switch (pass_mode) {
|
|
||||||
case JBUF_PASS_THRU:
|
|
||||||
if (cinfo->quantize_colors) {
|
|
||||||
/* Single-pass processing with color quantization. */
|
|
||||||
post->pub.post_process_data = post_process_1pass;
|
|
||||||
/* We could be doing buffered-image output before starting a 2-pass
|
|
||||||
* color quantization; in that case, jinit_d_post_controller did not
|
|
||||||
* allocate a strip buffer. Use the virtual-array buffer as workspace.
|
|
||||||
*/
|
|
||||||
if (post->buffer == NULL) {
|
|
||||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
|
||||||
((j_common_ptr) cinfo, post->whole_image,
|
|
||||||
(JDIMENSION) 0, post->strip_height, TRUE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* For single-pass processing without color quantization,
|
|
||||||
* I have no work to do; just call the upsampler directly.
|
|
||||||
*/
|
|
||||||
post->pub.post_process_data = cinfo->upsample->upsample;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
case JBUF_SAVE_AND_PASS:
|
|
||||||
/* First pass of 2-pass quantization */
|
|
||||||
if (post->whole_image == NULL)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
|
||||||
post->pub.post_process_data = post_process_prepass;
|
|
||||||
break;
|
|
||||||
case JBUF_CRANK_DEST:
|
|
||||||
/* Second pass of 2-pass quantization */
|
|
||||||
if (post->whole_image == NULL)
|
|
||||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
|
||||||
post->pub.post_process_data = post_process_2pass;
|
|
||||||
break;
|
|
||||||
#endif /* QUANT_2PASS_SUPPORTED */
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
post->starting_row = post->next_row = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process some data in the one-pass (strip buffer) case.
|
|
||||||
* This is used for color precision reduction as well as one-pass quantization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
post_process_1pass (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
{
|
|
||||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
|
||||||
JDIMENSION num_rows, max_rows;
|
|
||||||
|
|
||||||
/* Fill the buffer, but not more than what we can dump out in one go. */
|
|
||||||
/* Note we rely on the upsampler to detect bottom of image. */
|
|
||||||
max_rows = out_rows_avail - *out_row_ctr;
|
|
||||||
if (max_rows > post->strip_height)
|
|
||||||
max_rows = post->strip_height;
|
|
||||||
num_rows = 0;
|
|
||||||
(*cinfo->upsample->upsample) (cinfo,
|
|
||||||
input_buf, in_row_group_ctr, in_row_groups_avail,
|
|
||||||
post->buffer, &num_rows, max_rows);
|
|
||||||
/* Quantize and emit data. */
|
|
||||||
(*cinfo->cquantize->color_quantize) (cinfo,
|
|
||||||
post->buffer, output_buf + *out_row_ctr, (int) num_rows);
|
|
||||||
*out_row_ctr += num_rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process some data in the first pass of 2-pass quantization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
post_process_prepass (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
{
|
|
||||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
|
||||||
JDIMENSION old_next_row, num_rows;
|
|
||||||
|
|
||||||
/* Reposition virtual buffer if at start of strip. */
|
|
||||||
if (post->next_row == 0) {
|
|
||||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
|
||||||
((j_common_ptr) cinfo, post->whole_image,
|
|
||||||
post->starting_row, post->strip_height, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Upsample some data (up to a strip height's worth). */
|
|
||||||
old_next_row = post->next_row;
|
|
||||||
(*cinfo->upsample->upsample) (cinfo,
|
|
||||||
input_buf, in_row_group_ctr, in_row_groups_avail,
|
|
||||||
post->buffer, &post->next_row, post->strip_height);
|
|
||||||
|
|
||||||
/* Allow quantizer to scan new data. No data is emitted, */
|
|
||||||
/* but we advance out_row_ctr so outer loop can tell when we're done. */
|
|
||||||
if (post->next_row > old_next_row) {
|
|
||||||
num_rows = post->next_row - old_next_row;
|
|
||||||
(*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
|
|
||||||
(JSAMPARRAY) NULL, (int) num_rows);
|
|
||||||
*out_row_ctr += num_rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance if we filled the strip. */
|
|
||||||
if (post->next_row >= post->strip_height) {
|
|
||||||
post->starting_row += post->strip_height;
|
|
||||||
post->next_row = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process some data in the second pass of 2-pass quantization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
post_process_2pass (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
{
|
|
||||||
my_post_ptr post = (my_post_ptr) cinfo->post;
|
|
||||||
JDIMENSION num_rows, max_rows;
|
|
||||||
|
|
||||||
/* Reposition virtual buffer if at start of strip. */
|
|
||||||
if (post->next_row == 0) {
|
|
||||||
post->buffer = (*cinfo->mem->access_virt_sarray)
|
|
||||||
((j_common_ptr) cinfo, post->whole_image,
|
|
||||||
post->starting_row, post->strip_height, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine number of rows to emit. */
|
|
||||||
num_rows = post->strip_height - post->next_row; /* available in strip */
|
|
||||||
max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
|
|
||||||
if (num_rows > max_rows)
|
|
||||||
num_rows = max_rows;
|
|
||||||
/* We have to check bottom of image here, can't depend on upsampler. */
|
|
||||||
max_rows = cinfo->output_height - post->starting_row;
|
|
||||||
if (num_rows > max_rows)
|
|
||||||
num_rows = max_rows;
|
|
||||||
|
|
||||||
/* Quantize and emit data. */
|
|
||||||
(*cinfo->cquantize->color_quantize) (cinfo,
|
|
||||||
post->buffer + post->next_row, output_buf + *out_row_ctr,
|
|
||||||
(int) num_rows);
|
|
||||||
*out_row_ctr += num_rows;
|
|
||||||
|
|
||||||
/* Advance if we filled the strip. */
|
|
||||||
post->next_row += num_rows;
|
|
||||||
if (post->next_row >= post->strip_height) {
|
|
||||||
post->starting_row += post->strip_height;
|
|
||||||
post->next_row = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* QUANT_2PASS_SUPPORTED */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize postprocessing controller.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
|
|
||||||
{
|
|
||||||
my_post_ptr post;
|
|
||||||
|
|
||||||
post = (my_post_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_post_controller));
|
|
||||||
cinfo->post = (struct jpeg_d_post_controller *) post;
|
|
||||||
post->pub.start_pass = start_pass_dpost;
|
|
||||||
post->whole_image = NULL; /* flag for no virtual arrays */
|
|
||||||
post->buffer = NULL; /* flag for no strip buffer */
|
|
||||||
|
|
||||||
/* Create the quantization buffer, if needed */
|
|
||||||
if (cinfo->quantize_colors) {
|
|
||||||
/* The buffer strip height is max_v_samp_factor, which is typically
|
|
||||||
* an efficient number of rows for upsampling to return.
|
|
||||||
* (In the presence of output rescaling, we might want to be smarter?)
|
|
||||||
*/
|
|
||||||
post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
|
|
||||||
if (need_full_buffer) {
|
|
||||||
/* Two-pass color quantization: need full-image storage. */
|
|
||||||
/* We round up the number of rows to a multiple of the strip height. */
|
|
||||||
#ifdef QUANT_2PASS_SUPPORTED
|
|
||||||
post->whole_image = (*cinfo->mem->request_virt_sarray)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
|
||||||
cinfo->output_width * cinfo->out_color_components,
|
|
||||||
(JDIMENSION) jround_up((long) cinfo->output_height,
|
|
||||||
(long) post->strip_height),
|
|
||||||
post->strip_height);
|
|
||||||
#else
|
|
||||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
|
||||||
#endif /* QUANT_2PASS_SUPPORTED */
|
|
||||||
} else {
|
|
||||||
/* One-pass color quantization: just make a strip buffer. */
|
|
||||||
post->buffer = (*cinfo->mem->alloc_sarray)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
cinfo->output_width * cinfo->out_color_components,
|
|
||||||
post->strip_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,358 +0,0 @@
|
||||||
/*
|
|
||||||
* jdsample.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
|
||||||
* Modified 2002-2015 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains upsampling routines.
|
|
||||||
*
|
|
||||||
* Upsampling input data is counted in "row groups". A row group
|
|
||||||
* is defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size)
|
|
||||||
* sample rows of each component. Upsampling will normally produce
|
|
||||||
* max_v_samp_factor pixel rows from each row group (but this could vary
|
|
||||||
* if the upsampler is applying a scale factor of its own).
|
|
||||||
*
|
|
||||||
* An excellent reference for image resampling is
|
|
||||||
* Digital Image Warping, George Wolberg, 1990.
|
|
||||||
* Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Pointer to routine to upsample a single component */
|
|
||||||
typedef JMETHOD(void, upsample1_ptr,
|
|
||||||
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
|
|
||||||
|
|
||||||
/* Private subobject */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_upsampler pub; /* public fields */
|
|
||||||
|
|
||||||
/* Color conversion buffer. When using separate upsampling and color
|
|
||||||
* conversion steps, this buffer holds one upsampled row group until it
|
|
||||||
* has been color converted and output.
|
|
||||||
* Note: we do not allocate any storage for component(s) which are full-size,
|
|
||||||
* ie do not need rescaling. The corresponding entry of color_buf[] is
|
|
||||||
* simply set to point to the input data array, thereby avoiding copying.
|
|
||||||
*/
|
|
||||||
JSAMPARRAY color_buf[MAX_COMPONENTS];
|
|
||||||
|
|
||||||
/* Per-component upsampling method pointers */
|
|
||||||
upsample1_ptr methods[MAX_COMPONENTS];
|
|
||||||
|
|
||||||
int next_row_out; /* counts rows emitted from color_buf */
|
|
||||||
JDIMENSION rows_to_go; /* counts rows remaining in image */
|
|
||||||
|
|
||||||
/* Height of an input row group for each component. */
|
|
||||||
int rowgroup_height[MAX_COMPONENTS];
|
|
||||||
|
|
||||||
/* These arrays save pixel expansion factors so that int_expand need not
|
|
||||||
* recompute them each time. They are unused for other upsampling methods.
|
|
||||||
*/
|
|
||||||
UINT8 h_expand[MAX_COMPONENTS];
|
|
||||||
UINT8 v_expand[MAX_COMPONENTS];
|
|
||||||
} my_upsampler;
|
|
||||||
|
|
||||||
typedef my_upsampler * my_upsample_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for an upsampling pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass_upsample (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
|
|
||||||
/* Mark the conversion buffer empty */
|
|
||||||
upsample->next_row_out = cinfo->max_v_samp_factor;
|
|
||||||
/* Initialize total-height counter for detecting bottom of image */
|
|
||||||
upsample->rows_to_go = cinfo->output_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Control routine to do upsampling (and color conversion).
|
|
||||||
*
|
|
||||||
* In this version we upsample each component independently.
|
|
||||||
* We upsample one row group into the conversion buffer, then apply
|
|
||||||
* color conversion a row at a time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
sep_upsample (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
int ci;
|
|
||||||
jpeg_component_info * compptr;
|
|
||||||
JDIMENSION num_rows;
|
|
||||||
|
|
||||||
/* Fill the conversion buffer, if it's empty */
|
|
||||||
if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Invoke per-component upsample method. Notice we pass a POINTER
|
|
||||||
* to color_buf[ci], so that fullsize_upsample can change it.
|
|
||||||
*/
|
|
||||||
(*upsample->methods[ci]) (cinfo, compptr,
|
|
||||||
input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
|
|
||||||
upsample->color_buf + ci);
|
|
||||||
}
|
|
||||||
upsample->next_row_out = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Color-convert and emit rows */
|
|
||||||
|
|
||||||
/* How many we have in the buffer: */
|
|
||||||
num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
|
|
||||||
/* Not more than the distance to the end of the image. Need this test
|
|
||||||
* in case the image height is not a multiple of max_v_samp_factor:
|
|
||||||
*/
|
|
||||||
if (num_rows > upsample->rows_to_go)
|
|
||||||
num_rows = upsample->rows_to_go;
|
|
||||||
/* And not more than what the client can accept: */
|
|
||||||
out_rows_avail -= *out_row_ctr;
|
|
||||||
if (num_rows > out_rows_avail)
|
|
||||||
num_rows = out_rows_avail;
|
|
||||||
|
|
||||||
(*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
|
|
||||||
(JDIMENSION) upsample->next_row_out,
|
|
||||||
output_buf + *out_row_ctr,
|
|
||||||
(int) num_rows);
|
|
||||||
|
|
||||||
/* Adjust counts */
|
|
||||||
*out_row_ctr += num_rows;
|
|
||||||
upsample->rows_to_go -= num_rows;
|
|
||||||
upsample->next_row_out += num_rows;
|
|
||||||
/* When the buffer is emptied, declare this input row group consumed */
|
|
||||||
if (upsample->next_row_out >= cinfo->max_v_samp_factor)
|
|
||||||
(*in_row_group_ctr)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are the routines invoked by sep_upsample to upsample pixel values
|
|
||||||
* of a single component. One row group is processed per call.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For full-size components, we just make color_buf[ci] point at the
|
|
||||||
* input buffer, and thus avoid copying any data. Note that this is
|
|
||||||
* safe only because sep_upsample doesn't declare the input row group
|
|
||||||
* "consumed" until we are done color converting and emitting it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
|
||||||
{
|
|
||||||
*output_data_ptr = input_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a no-op version used for "uninteresting" components.
|
|
||||||
* These components will not be referenced by color conversion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
|
||||||
{
|
|
||||||
*output_data_ptr = NULL; /* safety check */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This version handles any integral sampling ratios.
|
|
||||||
* This is not used for typical JPEG files, so it need not be fast.
|
|
||||||
* Nor, for that matter, is it particularly accurate: the algorithm is
|
|
||||||
* simple replication of the input pixel onto the corresponding output
|
|
||||||
* pixels. The hi-falutin sampling literature refers to this as a
|
|
||||||
* "box filter". A box filter tends to introduce visible artifacts,
|
|
||||||
* so if you are actually going to use 3:1 or 4:1 sampling ratios
|
|
||||||
* you would be well advised to improve this code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
|
|
||||||
JSAMPARRAY output_data = *output_data_ptr;
|
|
||||||
register JSAMPROW inptr, outptr;
|
|
||||||
register JSAMPLE invalue;
|
|
||||||
register int h;
|
|
||||||
JSAMPROW outend;
|
|
||||||
int h_expand, v_expand;
|
|
||||||
int inrow, outrow;
|
|
||||||
|
|
||||||
h_expand = upsample->h_expand[compptr->component_index];
|
|
||||||
v_expand = upsample->v_expand[compptr->component_index];
|
|
||||||
|
|
||||||
inrow = outrow = 0;
|
|
||||||
while (outrow < cinfo->max_v_samp_factor) {
|
|
||||||
/* Generate one output row with proper horizontal expansion */
|
|
||||||
inptr = input_data[inrow];
|
|
||||||
outptr = output_data[outrow];
|
|
||||||
outend = outptr + cinfo->output_width;
|
|
||||||
while (outptr < outend) {
|
|
||||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
|
||||||
for (h = h_expand; h > 0; h--) {
|
|
||||||
*outptr++ = invalue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Generate any additional output rows by duplicating the first one */
|
|
||||||
if (v_expand > 1) {
|
|
||||||
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
|
|
||||||
v_expand-1, cinfo->output_width);
|
|
||||||
}
|
|
||||||
inrow++;
|
|
||||||
outrow += v_expand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
|
|
||||||
* It's still a box filter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
|
||||||
{
|
|
||||||
JSAMPARRAY output_data = *output_data_ptr;
|
|
||||||
register JSAMPROW inptr, outptr;
|
|
||||||
register JSAMPLE invalue;
|
|
||||||
JSAMPROW outend;
|
|
||||||
int outrow;
|
|
||||||
|
|
||||||
for (outrow = 0; outrow < cinfo->max_v_samp_factor; outrow++) {
|
|
||||||
inptr = input_data[outrow];
|
|
||||||
outptr = output_data[outrow];
|
|
||||||
outend = outptr + cinfo->output_width;
|
|
||||||
while (outptr < outend) {
|
|
||||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
|
||||||
*outptr++ = invalue;
|
|
||||||
*outptr++ = invalue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
|
|
||||||
* It's still a box filter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
|
||||||
{
|
|
||||||
JSAMPARRAY output_data = *output_data_ptr;
|
|
||||||
register JSAMPROW inptr, outptr;
|
|
||||||
register JSAMPLE invalue;
|
|
||||||
JSAMPROW outend;
|
|
||||||
int inrow, outrow;
|
|
||||||
|
|
||||||
inrow = outrow = 0;
|
|
||||||
while (outrow < cinfo->max_v_samp_factor) {
|
|
||||||
inptr = input_data[inrow];
|
|
||||||
outptr = output_data[outrow];
|
|
||||||
outend = outptr + cinfo->output_width;
|
|
||||||
while (outptr < outend) {
|
|
||||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
|
||||||
*outptr++ = invalue;
|
|
||||||
*outptr++ = invalue;
|
|
||||||
}
|
|
||||||
jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
|
|
||||||
1, cinfo->output_width);
|
|
||||||
inrow++;
|
|
||||||
outrow += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module initialization routine for upsampling.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_upsampler (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_upsample_ptr upsample;
|
|
||||||
int ci;
|
|
||||||
jpeg_component_info * compptr;
|
|
||||||
int h_in_group, v_in_group, h_out_group, v_out_group;
|
|
||||||
|
|
||||||
upsample = (my_upsample_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_upsampler));
|
|
||||||
cinfo->upsample = &upsample->pub;
|
|
||||||
upsample->pub.start_pass = start_pass_upsample;
|
|
||||||
upsample->pub.upsample = sep_upsample;
|
|
||||||
upsample->pub.need_context_rows = FALSE; /* until we find out differently */
|
|
||||||
|
|
||||||
if (cinfo->CCIR601_sampling) /* this isn't supported */
|
|
||||||
ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
|
|
||||||
|
|
||||||
/* Verify we can handle the sampling factors, select per-component methods,
|
|
||||||
* and create storage as needed.
|
|
||||||
*/
|
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
|
||||||
ci++, compptr++) {
|
|
||||||
/* Compute size of an "input group" after IDCT scaling. This many samples
|
|
||||||
* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
|
|
||||||
*/
|
|
||||||
h_in_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
|
|
||||||
cinfo->min_DCT_h_scaled_size;
|
|
||||||
v_in_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
|
||||||
cinfo->min_DCT_v_scaled_size;
|
|
||||||
h_out_group = cinfo->max_h_samp_factor;
|
|
||||||
v_out_group = cinfo->max_v_samp_factor;
|
|
||||||
upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
|
|
||||||
if (! compptr->component_needed) {
|
|
||||||
/* Don't bother to upsample an uninteresting component. */
|
|
||||||
upsample->methods[ci] = noop_upsample;
|
|
||||||
continue; /* don't need to allocate buffer */
|
|
||||||
}
|
|
||||||
if (h_in_group == h_out_group && v_in_group == v_out_group) {
|
|
||||||
/* Fullsize components can be processed without any work. */
|
|
||||||
upsample->methods[ci] = fullsize_upsample;
|
|
||||||
continue; /* don't need to allocate buffer */
|
|
||||||
}
|
|
||||||
if (h_in_group * 2 == h_out_group && v_in_group == v_out_group) {
|
|
||||||
/* Special case for 2h1v upsampling */
|
|
||||||
upsample->methods[ci] = h2v1_upsample;
|
|
||||||
} else if (h_in_group * 2 == h_out_group &&
|
|
||||||
v_in_group * 2 == v_out_group) {
|
|
||||||
/* Special case for 2h2v upsampling */
|
|
||||||
upsample->methods[ci] = h2v2_upsample;
|
|
||||||
} else if ((h_out_group % h_in_group) == 0 &&
|
|
||||||
(v_out_group % v_in_group) == 0) {
|
|
||||||
/* Generic integral-factors upsampling method */
|
|
||||||
upsample->methods[ci] = int_upsample;
|
|
||||||
upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
|
|
||||||
upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
|
|
||||||
} else
|
|
||||||
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
|
|
||||||
upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(JDIMENSION) jround_up((long) cinfo->output_width,
|
|
||||||
(long) cinfo->max_h_samp_factor),
|
|
||||||
(JDIMENSION) cinfo->max_v_samp_factor);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,253 +0,0 @@
|
||||||
/*
|
|
||||||
* jerror.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
|
||||||
* Modified 2012-2015 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 simple error-reporting and trace-message routines.
|
|
||||||
* These are suitable for Unix-like systems and others where writing to
|
|
||||||
* stderr is the right thing to do. Many applications will want to replace
|
|
||||||
* some or all of these routines.
|
|
||||||
*
|
|
||||||
* If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
|
|
||||||
* you get a Windows-specific hack to display error messages in a dialog box.
|
|
||||||
* It ain't much, but it beats dropping error messages into the bit bucket,
|
|
||||||
* which is what happens to output to stderr under most Windows C compilers.
|
|
||||||
*
|
|
||||||
* These routines are used by both the compression and decompression code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_MESSAGEBOX
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
#include "jversion.h"
|
|
||||||
#include "jerror.h"
|
|
||||||
|
|
||||||
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
|
|
||||||
#define EXIT_FAILURE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the message string table.
|
|
||||||
* We do this from the master message list in jerror.h by re-reading
|
|
||||||
* jerror.h with a suitable definition for macro JMESSAGE.
|
|
||||||
* The message table is made an external symbol just in case any applications
|
|
||||||
* want to refer to it directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
|
||||||
#define jpeg_std_message_table jMsgTable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define JMESSAGE(code,string) string ,
|
|
||||||
|
|
||||||
const char * const jpeg_std_message_table[] = {
|
|
||||||
#include "jerror.h"
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Error exit handler: must not return to caller.
|
|
||||||
*
|
|
||||||
* Applications may override this if they want to get control back after
|
|
||||||
* an error. Typically one would longjmp somewhere instead of exiting.
|
|
||||||
* The setjmp buffer can be made a private field within an expanded error
|
|
||||||
* handler object. Note that the info needed to generate an error message
|
|
||||||
* is stored in the error object, so you can generate the message now or
|
|
||||||
* later, at your convenience.
|
|
||||||
* You should make sure that the JPEG object is cleaned up (with jpeg_abort
|
|
||||||
* or jpeg_destroy) at some point.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(noreturn_t)
|
|
||||||
error_exit (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* Always display the message */
|
|
||||||
(*cinfo->err->output_message) (cinfo);
|
|
||||||
|
|
||||||
/* Let the memory manager delete any temp files before we die */
|
|
||||||
jpeg_destroy(cinfo);
|
|
||||||
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Actual output of an error or trace message.
|
|
||||||
* Applications may override this method to send JPEG messages somewhere
|
|
||||||
* other than stderr.
|
|
||||||
*
|
|
||||||
* On Windows, printing to stderr is generally completely useless,
|
|
||||||
* so we provide optional code to produce an error-dialog popup.
|
|
||||||
* Most Windows applications will still prefer to override this routine,
|
|
||||||
* but if they don't, it'll do something at least marginally useful.
|
|
||||||
*
|
|
||||||
* NOTE: to use the library in an environment that doesn't support the
|
|
||||||
* C stdio library, you may have to delete the call to fprintf() entirely,
|
|
||||||
* not just not use this routine.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
output_message (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
char buffer[JMSG_LENGTH_MAX];
|
|
||||||
|
|
||||||
/* Create the message */
|
|
||||||
(*cinfo->err->format_message) (cinfo, buffer);
|
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_MESSAGEBOX
|
|
||||||
/* Display it in a message dialog box */
|
|
||||||
MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
|
|
||||||
MB_OK | MB_ICONERROR);
|
|
||||||
#else
|
|
||||||
/* Send it to stderr, adding a newline */
|
|
||||||
fprintf(stderr, "%s\n", buffer);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Decide whether to emit a trace or warning message.
|
|
||||||
* msg_level is one of:
|
|
||||||
* -1: recoverable corrupt-data warning, may want to abort.
|
|
||||||
* 0: important advisory messages (always display to user).
|
|
||||||
* 1: first level of tracing detail.
|
|
||||||
* 2,3,...: successively more detailed tracing messages.
|
|
||||||
* An application might override this method if it wanted to abort on warnings
|
|
||||||
* or change the policy about which messages to display.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
emit_message (j_common_ptr cinfo, int msg_level)
|
|
||||||
{
|
|
||||||
struct jpeg_error_mgr * err = cinfo->err;
|
|
||||||
|
|
||||||
if (msg_level < 0) {
|
|
||||||
/* It's a warning message. Since corrupt files may generate many warnings,
|
|
||||||
* the policy implemented here is to show only the first warning,
|
|
||||||
* unless trace_level >= 3.
|
|
||||||
*/
|
|
||||||
if (err->num_warnings == 0 || err->trace_level >= 3)
|
|
||||||
(*err->output_message) (cinfo);
|
|
||||||
/* Always count warnings in num_warnings. */
|
|
||||||
err->num_warnings++;
|
|
||||||
} else {
|
|
||||||
/* It's a trace message. Show it if trace_level >= msg_level. */
|
|
||||||
if (err->trace_level >= msg_level)
|
|
||||||
(*err->output_message) (cinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Format a message string for the most recent JPEG error or message.
|
|
||||||
* The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
|
|
||||||
* characters. Note that no '\n' character is added to the string.
|
|
||||||
* Few applications should need to override this method.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
format_message (j_common_ptr cinfo, char * buffer)
|
|
||||||
{
|
|
||||||
struct jpeg_error_mgr * err = cinfo->err;
|
|
||||||
int msg_code = err->msg_code;
|
|
||||||
const char * msgtext = NULL;
|
|
||||||
const char * msgptr;
|
|
||||||
char ch;
|
|
||||||
boolean isstring;
|
|
||||||
|
|
||||||
/* Look up message string in proper table */
|
|
||||||
if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
|
|
||||||
msgtext = err->jpeg_message_table[msg_code];
|
|
||||||
} else if (err->addon_message_table != NULL &&
|
|
||||||
msg_code >= err->first_addon_message &&
|
|
||||||
msg_code <= err->last_addon_message) {
|
|
||||||
msgtext = err->addon_message_table[msg_code - err->first_addon_message];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Defend against bogus message number */
|
|
||||||
if (msgtext == NULL) {
|
|
||||||
err->msg_parm.i[0] = msg_code;
|
|
||||||
msgtext = err->jpeg_message_table[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for string parameter, as indicated by %s in the message text */
|
|
||||||
isstring = FALSE;
|
|
||||||
msgptr = msgtext;
|
|
||||||
while ((ch = *msgptr++) != '\0') {
|
|
||||||
if (ch == '%') {
|
|
||||||
if (*msgptr == 's') isstring = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Format the message into the passed buffer */
|
|
||||||
if (isstring)
|
|
||||||
sprintf(buffer, msgtext, err->msg_parm.s);
|
|
||||||
else
|
|
||||||
sprintf(buffer, msgtext,
|
|
||||||
err->msg_parm.i[0], err->msg_parm.i[1],
|
|
||||||
err->msg_parm.i[2], err->msg_parm.i[3],
|
|
||||||
err->msg_parm.i[4], err->msg_parm.i[5],
|
|
||||||
err->msg_parm.i[6], err->msg_parm.i[7]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset error state variables at start of a new image.
|
|
||||||
* This is called during compression startup to reset trace/error
|
|
||||||
* processing to default state, without losing any application-specific
|
|
||||||
* method pointers. An application might possibly want to override
|
|
||||||
* this method if it has additional error processing state.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
reset_error_mgr (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
cinfo->err->num_warnings = 0;
|
|
||||||
/* trace_level is not reset since it is an application-supplied parameter */
|
|
||||||
cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill in the standard error-handling methods in a jpeg_error_mgr object.
|
|
||||||
* Typical call is:
|
|
||||||
* struct jpeg_compress_struct cinfo;
|
|
||||||
* struct jpeg_error_mgr err;
|
|
||||||
*
|
|
||||||
* cinfo.err = jpeg_std_error(&err);
|
|
||||||
* after which the application may override some of the methods.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(struct jpeg_error_mgr *)
|
|
||||||
jpeg_std_error (struct jpeg_error_mgr * err)
|
|
||||||
{
|
|
||||||
err->error_exit = error_exit;
|
|
||||||
err->emit_message = emit_message;
|
|
||||||
err->output_message = output_message;
|
|
||||||
err->format_message = format_message;
|
|
||||||
err->reset_error_mgr = reset_error_mgr;
|
|
||||||
|
|
||||||
err->trace_level = 0; /* default = no tracing */
|
|
||||||
err->num_warnings = 0; /* no warnings emitted yet */
|
|
||||||
err->msg_code = 0; /* may be useful as a flag for "no error" */
|
|
||||||
|
|
||||||
/* Initialize message table pointers */
|
|
||||||
err->jpeg_message_table = jpeg_std_message_table;
|
|
||||||
err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
|
|
||||||
|
|
||||||
err->addon_message_table = NULL;
|
|
||||||
err->first_addon_message = 0; /* for safety */
|
|
||||||
err->last_addon_message = 0;
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
|
@ -1,304 +0,0 @@
|
||||||
/*
|
|
||||||
* jerror.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
|
||||||
* Modified 1997-2012 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file defines the error and message codes for the JPEG library.
|
|
||||||
* Edit this file to add new codes, or to translate the message strings to
|
|
||||||
* some other language.
|
|
||||||
* A set of error-reporting macros are defined too. Some applications using
|
|
||||||
* the JPEG library may wish to include this file to get the error codes
|
|
||||||
* and/or the macros.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* To define the enum list of message codes, include this file without
|
|
||||||
* defining macro JMESSAGE. To create a message string table, include it
|
|
||||||
* again with a suitable JMESSAGE definition (see jerror.c for an example).
|
|
||||||
*/
|
|
||||||
#ifndef JMESSAGE
|
|
||||||
#ifndef JERROR_H
|
|
||||||
/* First time through, define the enum list */
|
|
||||||
#define JMAKE_ENUM_LIST
|
|
||||||
#else
|
|
||||||
/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
|
|
||||||
#define JMESSAGE(code,string)
|
|
||||||
#endif /* JERROR_H */
|
|
||||||
#endif /* JMESSAGE */
|
|
||||||
|
|
||||||
#ifdef JMAKE_ENUM_LIST
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
|
|
||||||
#define JMESSAGE(code,string) code ,
|
|
||||||
|
|
||||||
#endif /* JMAKE_ENUM_LIST */
|
|
||||||
|
|
||||||
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
|
|
||||||
|
|
||||||
/* For maintenance convenience, list is alphabetical by message code name */
|
|
||||||
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
|
|
||||||
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
|
|
||||||
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
|
|
||||||
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
|
|
||||||
JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
|
|
||||||
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
|
|
||||||
JMESSAGE(JERR_BAD_DCTSIZE, "DCT scaled block size %dx%d not supported")
|
|
||||||
JMESSAGE(JERR_BAD_DROP_SAMPLING,
|
|
||||||
"Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c")
|
|
||||||
JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
|
|
||||||
JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
|
|
||||||
JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
|
|
||||||
JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
|
|
||||||
JMESSAGE(JERR_BAD_LIB_VERSION,
|
|
||||||
"Wrong JPEG library version: library is %d, caller expects %d")
|
|
||||||
JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
|
|
||||||
JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
|
|
||||||
JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
|
|
||||||
JMESSAGE(JERR_BAD_PROGRESSION,
|
|
||||||
"Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
|
|
||||||
JMESSAGE(JERR_BAD_PROG_SCRIPT,
|
|
||||||
"Invalid progressive parameters at scan script entry %d")
|
|
||||||
JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
|
|
||||||
JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
|
|
||||||
JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
|
|
||||||
JMESSAGE(JERR_BAD_STRUCT_SIZE,
|
|
||||||
"JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
|
|
||||||
JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
|
|
||||||
JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
|
|
||||||
JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
|
|
||||||
JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
|
|
||||||
JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
|
|
||||||
JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
|
|
||||||
JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
|
|
||||||
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
|
|
||||||
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
|
|
||||||
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
|
|
||||||
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
|
|
||||||
JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
|
|
||||||
JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
|
|
||||||
JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
|
|
||||||
JMESSAGE(JERR_FILE_READ, "Input file read error")
|
|
||||||
JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
|
|
||||||
JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
|
|
||||||
JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
|
|
||||||
JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
|
|
||||||
JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
|
|
||||||
JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
|
|
||||||
JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
|
|
||||||
JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
|
|
||||||
"Cannot transcode due to multiple use of quantization table %d")
|
|
||||||
JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
|
|
||||||
JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
|
|
||||||
JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
|
|
||||||
JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
|
|
||||||
JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
|
|
||||||
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
|
|
||||||
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
|
|
||||||
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
|
|
||||||
JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
|
|
||||||
JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
|
|
||||||
JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
|
|
||||||
JMESSAGE(JERR_QUANT_COMPONENTS,
|
|
||||||
"Cannot quantize more than %d color components")
|
|
||||||
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
|
|
||||||
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
|
|
||||||
JMESSAGE(JERR_SOF_BEFORE, "Invalid JPEG file structure: %s before SOF")
|
|
||||||
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
|
|
||||||
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
|
|
||||||
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
|
|
||||||
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
|
|
||||||
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
|
|
||||||
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
|
|
||||||
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
|
|
||||||
JMESSAGE(JERR_TFILE_WRITE,
|
|
||||||
"Write failed on temporary file --- out of disk space?")
|
|
||||||
JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
|
|
||||||
JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
|
|
||||||
JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
|
|
||||||
JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
|
|
||||||
JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
|
|
||||||
JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
|
|
||||||
JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
|
|
||||||
JMESSAGE(JMSG_VERSION, JVERSION)
|
|
||||||
JMESSAGE(JTRC_16BIT_TABLES,
|
|
||||||
"Caution: quantization tables are too coarse for baseline JPEG")
|
|
||||||
JMESSAGE(JTRC_ADOBE,
|
|
||||||
"Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
|
|
||||||
JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
|
|
||||||
JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
|
|
||||||
JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
|
|
||||||
JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
|
|
||||||
JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
|
|
||||||
JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
|
|
||||||
JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
|
|
||||||
JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
|
|
||||||
JMESSAGE(JTRC_EOI, "End Of Image")
|
|
||||||
JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
|
|
||||||
JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
|
|
||||||
JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
|
|
||||||
"Warning: thumbnail image size does not match data length %u")
|
|
||||||
JMESSAGE(JTRC_JFIF_EXTENSION,
|
|
||||||
"JFIF extension marker: type 0x%02x, length %u")
|
|
||||||
JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
|
|
||||||
JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
|
|
||||||
JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
|
|
||||||
JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
|
|
||||||
JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
|
|
||||||
JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
|
|
||||||
JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
|
|
||||||
JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
|
|
||||||
JMESSAGE(JTRC_RST, "RST%d")
|
|
||||||
JMESSAGE(JTRC_SMOOTH_NOTIMPL,
|
|
||||||
"Smoothing not supported with nonstandard sampling ratios")
|
|
||||||
JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
|
|
||||||
JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
|
|
||||||
JMESSAGE(JTRC_SOI, "Start of Image")
|
|
||||||
JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
|
|
||||||
JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
|
|
||||||
JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
|
|
||||||
JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
|
|
||||||
JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
|
|
||||||
JMESSAGE(JTRC_THUMB_JPEG,
|
|
||||||
"JFIF extension marker: JPEG-compressed thumbnail image, length %u")
|
|
||||||
JMESSAGE(JTRC_THUMB_PALETTE,
|
|
||||||
"JFIF extension marker: palette thumbnail image, length %u")
|
|
||||||
JMESSAGE(JTRC_THUMB_RGB,
|
|
||||||
"JFIF extension marker: RGB thumbnail image, length %u")
|
|
||||||
JMESSAGE(JTRC_UNKNOWN_IDS,
|
|
||||||
"Unrecognized component IDs %d %d %d, assuming YCbCr")
|
|
||||||
JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
|
|
||||||
JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
|
|
||||||
JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
|
|
||||||
JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
|
|
||||||
JMESSAGE(JWRN_BOGUS_PROGRESSION,
|
|
||||||
"Inconsistent progression sequence for component %d coefficient %d")
|
|
||||||
JMESSAGE(JWRN_EXTRANEOUS_DATA,
|
|
||||||
"Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
|
|
||||||
JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
|
|
||||||
JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
|
|
||||||
JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
|
|
||||||
JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
|
|
||||||
JMESSAGE(JWRN_MUST_RESYNC,
|
|
||||||
"Corrupt JPEG data: found marker 0x%02x instead of RST%d")
|
|
||||||
JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
|
|
||||||
JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
|
|
||||||
|
|
||||||
#ifdef JMAKE_ENUM_LIST
|
|
||||||
|
|
||||||
JMSG_LASTMSGCODE
|
|
||||||
} J_MESSAGE_CODE;
|
|
||||||
|
|
||||||
#undef JMAKE_ENUM_LIST
|
|
||||||
#endif /* JMAKE_ENUM_LIST */
|
|
||||||
|
|
||||||
/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
|
|
||||||
#undef JMESSAGE
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef JERROR_H
|
|
||||||
#define JERROR_H
|
|
||||||
|
|
||||||
/* Macros to simplify using the error and trace message stuff */
|
|
||||||
/* The first parameter is either type of cinfo pointer */
|
|
||||||
|
|
||||||
/* Fatal errors (print message and exit) */
|
|
||||||
#define ERREXIT(cinfo,code) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT1(cinfo,code,p1) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT2(cinfo,code,p1,p2) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT3(cinfo,code,p1,p2,p3) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
|
||||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXIT6(cinfo,code,p1,p2,p3,p4,p5,p6) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
|
||||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
|
||||||
(cinfo)->err->msg_parm.i[4] = (p5), \
|
|
||||||
(cinfo)->err->msg_parm.i[5] = (p6), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
#define ERREXITS(cinfo,code,str) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
|
||||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
|
||||||
|
|
||||||
#define MAKESTMT(stuff) do { stuff } while (0)
|
|
||||||
|
|
||||||
/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
|
|
||||||
#define WARNMS(cinfo,code) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
|
||||||
#define WARNMS1(cinfo,code,p1) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
|
||||||
#define WARNMS2(cinfo,code,p1,p2) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
|
|
||||||
|
|
||||||
/* Informational/debugging messages */
|
|
||||||
#define TRACEMS(cinfo,lvl,code) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
#define TRACEMS1(cinfo,lvl,code,p1) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
#define TRACEMS2(cinfo,lvl,code,p1,p2) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
|
||||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
|
||||||
_mp[4] = (p5); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
|
|
||||||
MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
|
|
||||||
_mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
|
|
||||||
_mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
|
|
||||||
(cinfo)->err->msg_code = (code); \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
|
|
||||||
#define TRACEMSS(cinfo,lvl,code,str) \
|
|
||||||
((cinfo)->err->msg_code = (code), \
|
|
||||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
|
||||||
(*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
|
|
||||||
|
|
||||||
#endif /* JERROR_H */
|
|
|
@ -1,238 +0,0 @@
|
||||||
/*
|
|
||||||
* jidctflt.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
|
||||||
* Modified 2010-2017 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 a floating-point implementation of the
|
|
||||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
|
||||||
* must also perform dequantization of the input coefficients.
|
|
||||||
*
|
|
||||||
* This implementation should be more accurate than either of the integer
|
|
||||||
* IDCT implementations. However, it may not give the same results on all
|
|
||||||
* machines because of differences in roundoff behavior. Speed will depend
|
|
||||||
* on the hardware's floating point capacity.
|
|
||||||
*
|
|
||||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
|
||||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
|
||||||
* a time). Direct algorithms are also available, but they are much more
|
|
||||||
* complex and seem not to be any faster when reduced to code.
|
|
||||||
*
|
|
||||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
|
||||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
|
||||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
|
||||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
|
||||||
* is based directly on figure 4-8 in P&M.
|
|
||||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
|
||||||
* possible to arrange the computation so that many of the multiplies are
|
|
||||||
* simple scalings of the final outputs. These multiplies can then be
|
|
||||||
* folded into the multiplications or divisions by the JPEG quantization
|
|
||||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
|
||||||
* to be done in the DCT itself.
|
|
||||||
* The primary disadvantage of this method is that with a fixed-point
|
|
||||||
* implementation, accuracy is lost due to imprecise representation of the
|
|
||||||
* scaled quantization values. However, that problem does not arise if
|
|
||||||
* we use floating point arithmetic.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
|
||||||
|
|
||||||
#ifdef DCT_FLOAT_SUPPORTED
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This module is specialized to the case DCTSIZE = 8.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if DCTSIZE != 8
|
|
||||||
Sorry, this code only copes with 8x8 DCT blocks. /* deliberate syntax err */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
|
||||||
* entry; produce a float result.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
|
||||||
*
|
|
||||||
* cK represents cos(K*pi/16).
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
|
||||||
{
|
|
||||||
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
|
||||||
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
|
|
||||||
FAST_FLOAT z5, z10, z11, z12, z13;
|
|
||||||
JCOEFPTR inptr;
|
|
||||||
FLOAT_MULT_TYPE * quantptr;
|
|
||||||
FAST_FLOAT * wsptr;
|
|
||||||
JSAMPROW outptr;
|
|
||||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
|
||||||
int ctr;
|
|
||||||
FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
|
|
||||||
|
|
||||||
/* Pass 1: process columns from input, store into work array. */
|
|
||||||
|
|
||||||
inptr = coef_block;
|
|
||||||
quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
|
|
||||||
wsptr = workspace;
|
|
||||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
|
||||||
/* Due to quantization, we will usually find that many of the input
|
|
||||||
* coefficients are zero, especially the AC terms. We can exploit this
|
|
||||||
* by short-circuiting the IDCT calculation for any column in which all
|
|
||||||
* the AC terms are zero. In that case each output is equal to the
|
|
||||||
* DC coefficient (with scale factor as needed).
|
|
||||||
* With typical images and quantization tables, half or more of the
|
|
||||||
* column DCT calculations can be simplified this way.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
|
||||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
|
||||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
|
||||||
inptr[DCTSIZE*7] == 0) {
|
|
||||||
/* AC terms all zero */
|
|
||||||
FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
|
||||||
|
|
||||||
wsptr[DCTSIZE*0] = dcval;
|
|
||||||
wsptr[DCTSIZE*1] = dcval;
|
|
||||||
wsptr[DCTSIZE*2] = dcval;
|
|
||||||
wsptr[DCTSIZE*3] = dcval;
|
|
||||||
wsptr[DCTSIZE*4] = dcval;
|
|
||||||
wsptr[DCTSIZE*5] = dcval;
|
|
||||||
wsptr[DCTSIZE*6] = dcval;
|
|
||||||
wsptr[DCTSIZE*7] = dcval;
|
|
||||||
|
|
||||||
inptr++; /* advance pointers to next column */
|
|
||||||
quantptr++;
|
|
||||||
wsptr++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Even part */
|
|
||||||
|
|
||||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
|
||||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
|
||||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
|
||||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
|
||||||
|
|
||||||
tmp10 = tmp0 + tmp2; /* phase 3 */
|
|
||||||
tmp11 = tmp0 - tmp2;
|
|
||||||
|
|
||||||
tmp13 = tmp1 + tmp3; /* phases 5-3 */
|
|
||||||
tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
|
|
||||||
|
|
||||||
tmp0 = tmp10 + tmp13; /* phase 2 */
|
|
||||||
tmp3 = tmp10 - tmp13;
|
|
||||||
tmp1 = tmp11 + tmp12;
|
|
||||||
tmp2 = tmp11 - tmp12;
|
|
||||||
|
|
||||||
/* Odd part */
|
|
||||||
|
|
||||||
tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
|
||||||
tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
|
||||||
tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
|
||||||
tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
|
||||||
|
|
||||||
z13 = tmp6 + tmp5; /* phase 6 */
|
|
||||||
z10 = tmp6 - tmp5;
|
|
||||||
z11 = tmp4 + tmp7;
|
|
||||||
z12 = tmp4 - tmp7;
|
|
||||||
|
|
||||||
tmp7 = z11 + z13; /* phase 5 */
|
|
||||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
|
|
||||||
|
|
||||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
|
||||||
tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
|
|
||||||
tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
|
|
||||||
|
|
||||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
|
||||||
tmp5 = tmp11 - tmp6;
|
|
||||||
tmp4 = tmp10 - tmp5;
|
|
||||||
|
|
||||||
wsptr[DCTSIZE*0] = tmp0 + tmp7;
|
|
||||||
wsptr[DCTSIZE*7] = tmp0 - tmp7;
|
|
||||||
wsptr[DCTSIZE*1] = tmp1 + tmp6;
|
|
||||||
wsptr[DCTSIZE*6] = tmp1 - tmp6;
|
|
||||||
wsptr[DCTSIZE*2] = tmp2 + tmp5;
|
|
||||||
wsptr[DCTSIZE*5] = tmp2 - tmp5;
|
|
||||||
wsptr[DCTSIZE*3] = tmp3 + tmp4;
|
|
||||||
wsptr[DCTSIZE*4] = tmp3 - tmp4;
|
|
||||||
|
|
||||||
inptr++; /* advance pointers to next column */
|
|
||||||
quantptr++;
|
|
||||||
wsptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pass 2: process rows from work array, store into output array. */
|
|
||||||
|
|
||||||
wsptr = workspace;
|
|
||||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
|
||||||
outptr = output_buf[ctr] + output_col;
|
|
||||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
|
||||||
* However, the column calculation has created many nonzero AC terms, so
|
|
||||||
* the simplification applies less often (typically 5% to 10% of the time).
|
|
||||||
* And testing floats for zero is relatively expensive, so we don't bother.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Even part */
|
|
||||||
|
|
||||||
/* Prepare range-limit and float->int conversion */
|
|
||||||
z5 = wsptr[0] + (((FAST_FLOAT) RANGE_CENTER) + ((FAST_FLOAT) 0.5));
|
|
||||||
tmp10 = z5 + wsptr[4];
|
|
||||||
tmp11 = z5 - wsptr[4];
|
|
||||||
|
|
||||||
tmp13 = wsptr[2] + wsptr[6];
|
|
||||||
tmp12 = (wsptr[2] - wsptr[6]) *
|
|
||||||
((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
|
|
||||||
|
|
||||||
tmp0 = tmp10 + tmp13;
|
|
||||||
tmp3 = tmp10 - tmp13;
|
|
||||||
tmp1 = tmp11 + tmp12;
|
|
||||||
tmp2 = tmp11 - tmp12;
|
|
||||||
|
|
||||||
/* Odd part */
|
|
||||||
|
|
||||||
z13 = wsptr[5] + wsptr[3];
|
|
||||||
z10 = wsptr[5] - wsptr[3];
|
|
||||||
z11 = wsptr[1] + wsptr[7];
|
|
||||||
z12 = wsptr[1] - wsptr[7];
|
|
||||||
|
|
||||||
tmp7 = z11 + z13; /* phase 5 */
|
|
||||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
|
|
||||||
|
|
||||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
|
||||||
tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
|
|
||||||
tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
|
|
||||||
|
|
||||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
|
||||||
tmp5 = tmp11 - tmp6;
|
|
||||||
tmp4 = tmp10 - tmp5;
|
|
||||||
|
|
||||||
/* Final output stage: float->int conversion and range-limit */
|
|
||||||
|
|
||||||
outptr[0] = range_limit[(int) (tmp0 + tmp7) & RANGE_MASK];
|
|
||||||
outptr[7] = range_limit[(int) (tmp0 - tmp7) & RANGE_MASK];
|
|
||||||
outptr[1] = range_limit[(int) (tmp1 + tmp6) & RANGE_MASK];
|
|
||||||
outptr[6] = range_limit[(int) (tmp1 - tmp6) & RANGE_MASK];
|
|
||||||
outptr[2] = range_limit[(int) (tmp2 + tmp5) & RANGE_MASK];
|
|
||||||
outptr[5] = range_limit[(int) (tmp2 - tmp5) & RANGE_MASK];
|
|
||||||
outptr[3] = range_limit[(int) (tmp3 + tmp4) & RANGE_MASK];
|
|
||||||
outptr[4] = range_limit[(int) (tmp3 - tmp4) & RANGE_MASK];
|
|
||||||
|
|
||||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* DCT_FLOAT_SUPPORTED */
|
|
|
@ -1,351 +0,0 @@
|
||||||
/*
|
|
||||||
* jidctfst.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
|
||||||
* Modified 2015-2017 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 a fast, not so accurate integer implementation of the
|
|
||||||
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
|
|
||||||
* must also perform dequantization of the input coefficients.
|
|
||||||
*
|
|
||||||
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
|
|
||||||
* on each row (or vice versa, but it's more convenient to emit a row at
|
|
||||||
* a time). Direct algorithms are also available, but they are much more
|
|
||||||
* complex and seem not to be any faster when reduced to code.
|
|
||||||
*
|
|
||||||
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
|
|
||||||
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
|
|
||||||
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
|
|
||||||
* JPEG textbook (see REFERENCES section in file README). The following code
|
|
||||||
* is based directly on figure 4-8 in P&M.
|
|
||||||
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
|
|
||||||
* possible to arrange the computation so that many of the multiplies are
|
|
||||||
* simple scalings of the final outputs. These multiplies can then be
|
|
||||||
* folded into the multiplications or divisions by the JPEG quantization
|
|
||||||
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
|
|
||||||
* to be done in the DCT itself.
|
|
||||||
* The primary disadvantage of this method is that with fixed-point math,
|
|
||||||
* accuracy is lost due to imprecise representation of the scaled
|
|
||||||
* quantization values. The smaller the quantization table entry, the less
|
|
||||||
* precise the scaled value, so this implementation does worse with high-
|
|
||||||
* quality-setting files than with low-quality ones.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
|
||||||
|
|
||||||
#ifdef DCT_IFAST_SUPPORTED
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This module is specialized to the case DCTSIZE = 8.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if DCTSIZE != 8
|
|
||||||
Sorry, this code only copes with 8x8 DCT blocks. /* deliberate syntax err */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Scaling decisions are generally the same as in the LL&M algorithm;
|
|
||||||
* see jidctint.c for more details. However, we choose to descale
|
|
||||||
* (right shift) multiplication products as soon as they are formed,
|
|
||||||
* rather than carrying additional fractional bits into subsequent additions.
|
|
||||||
* This compromises accuracy slightly, but it lets us save a few shifts.
|
|
||||||
* More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
|
|
||||||
* everywhere except in the multiplications proper; this saves a good deal
|
|
||||||
* of work on 16-bit-int machines.
|
|
||||||
*
|
|
||||||
* The dequantized coefficients are not integers because the AA&N scaling
|
|
||||||
* factors have been incorporated. We represent them scaled up by PASS1_BITS,
|
|
||||||
* so that the first and second IDCT rounds have the same input scaling.
|
|
||||||
* For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
|
|
||||||
* avoid a descaling shift; this compromises accuracy rather drastically
|
|
||||||
* for small quantization table entries, but it saves a lot of shifts.
|
|
||||||
* For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
|
|
||||||
* so we use a much larger scaling factor to preserve accuracy.
|
|
||||||
*
|
|
||||||
* A final compromise is to represent the multiplicative constants to only
|
|
||||||
* 8 fractional bits, rather than 13. This saves some shifting work on some
|
|
||||||
* machines, and may also reduce the cost of multiplication (since there
|
|
||||||
* are fewer one-bits in the constants).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
#define CONST_BITS 8
|
|
||||||
#define PASS1_BITS 2
|
|
||||||
#else
|
|
||||||
#define CONST_BITS 8
|
|
||||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
|
||||||
* causing a lot of useless floating-point operations at run time.
|
|
||||||
* To get around this we use the following pre-calculated constants.
|
|
||||||
* If you change CONST_BITS you may want to add appropriate values.
|
|
||||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if CONST_BITS == 8
|
|
||||||
#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
|
|
||||||
#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
|
|
||||||
#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
|
|
||||||
#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
|
|
||||||
#else
|
|
||||||
#define FIX_1_082392200 FIX(1.082392200)
|
|
||||||
#define FIX_1_414213562 FIX(1.414213562)
|
|
||||||
#define FIX_1_847759065 FIX(1.847759065)
|
|
||||||
#define FIX_2_613125930 FIX(2.613125930)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* We can gain a little more speed, with a further compromise in accuracy,
|
|
||||||
* by omitting the addition in a descaling shift. This yields an incorrectly
|
|
||||||
* rounded result half the time...
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef USE_ACCURATE_ROUNDING
|
|
||||||
#undef DESCALE
|
|
||||||
#define DESCALE(x,n) RIGHT_SHIFT(x, n)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Multiply a DCTELEM variable by an INT32 constant, and immediately
|
|
||||||
* descale to yield a DCTELEM result.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
|
|
||||||
|
|
||||||
|
|
||||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
|
||||||
* entry; produce a DCTELEM result. For 8-bit data a 16x16->16
|
|
||||||
* multiplication will do. For 12-bit data, the multiplier table is
|
|
||||||
* declared INT32, so a 32-bit multiply will be used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
|
|
||||||
#else
|
|
||||||
#define DEQUANTIZE(coef,quantval) \
|
|
||||||
DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform dequantization and inverse DCT on one block of coefficients.
|
|
||||||
*
|
|
||||||
* cK represents cos(K*pi/16).
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
|
||||||
{
|
|
||||||
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
|
||||||
DCTELEM tmp10, tmp11, tmp12, tmp13;
|
|
||||||
DCTELEM z5, z10, z11, z12, z13;
|
|
||||||
JCOEFPTR inptr;
|
|
||||||
IFAST_MULT_TYPE * quantptr;
|
|
||||||
int * wsptr;
|
|
||||||
JSAMPROW outptr;
|
|
||||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
|
||||||
int ctr;
|
|
||||||
int workspace[DCTSIZE2]; /* buffers data between passes */
|
|
||||||
SHIFT_TEMPS /* for DESCALE */
|
|
||||||
ISHIFT_TEMPS /* for IRIGHT_SHIFT */
|
|
||||||
|
|
||||||
/* Pass 1: process columns from input, store into work array. */
|
|
||||||
|
|
||||||
inptr = coef_block;
|
|
||||||
quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
|
|
||||||
wsptr = workspace;
|
|
||||||
for (ctr = DCTSIZE; ctr > 0; ctr--) {
|
|
||||||
/* Due to quantization, we will usually find that many of the input
|
|
||||||
* coefficients are zero, especially the AC terms. We can exploit this
|
|
||||||
* by short-circuiting the IDCT calculation for any column in which all
|
|
||||||
* the AC terms are zero. In that case each output is equal to the
|
|
||||||
* DC coefficient (with scale factor as needed).
|
|
||||||
* With typical images and quantization tables, half or more of the
|
|
||||||
* column DCT calculations can be simplified this way.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
|
||||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
|
|
||||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
|
|
||||||
inptr[DCTSIZE*7] == 0) {
|
|
||||||
/* AC terms all zero */
|
|
||||||
int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
|
||||||
|
|
||||||
wsptr[DCTSIZE*0] = dcval;
|
|
||||||
wsptr[DCTSIZE*1] = dcval;
|
|
||||||
wsptr[DCTSIZE*2] = dcval;
|
|
||||||
wsptr[DCTSIZE*3] = dcval;
|
|
||||||
wsptr[DCTSIZE*4] = dcval;
|
|
||||||
wsptr[DCTSIZE*5] = dcval;
|
|
||||||
wsptr[DCTSIZE*6] = dcval;
|
|
||||||
wsptr[DCTSIZE*7] = dcval;
|
|
||||||
|
|
||||||
inptr++; /* advance pointers to next column */
|
|
||||||
quantptr++;
|
|
||||||
wsptr++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Even part */
|
|
||||||
|
|
||||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
|
||||||
tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
|
||||||
tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
|
|
||||||
tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
|
||||||
|
|
||||||
tmp10 = tmp0 + tmp2; /* phase 3 */
|
|
||||||
tmp11 = tmp0 - tmp2;
|
|
||||||
|
|
||||||
tmp13 = tmp1 + tmp3; /* phases 5-3 */
|
|
||||||
tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
|
|
||||||
|
|
||||||
tmp0 = tmp10 + tmp13; /* phase 2 */
|
|
||||||
tmp3 = tmp10 - tmp13;
|
|
||||||
tmp1 = tmp11 + tmp12;
|
|
||||||
tmp2 = tmp11 - tmp12;
|
|
||||||
|
|
||||||
/* Odd part */
|
|
||||||
|
|
||||||
tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
|
||||||
tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
|
||||||
tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
|
||||||
tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
|
||||||
|
|
||||||
z13 = tmp6 + tmp5; /* phase 6 */
|
|
||||||
z10 = tmp6 - tmp5;
|
|
||||||
z11 = tmp4 + tmp7;
|
|
||||||
z12 = tmp4 - tmp7;
|
|
||||||
|
|
||||||
tmp7 = z11 + z13; /* phase 5 */
|
|
||||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
|
|
||||||
|
|
||||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
|
|
||||||
tmp10 = z5 - MULTIPLY(z12, FIX_1_082392200); /* 2*(c2-c6) */
|
|
||||||
tmp12 = z5 - MULTIPLY(z10, FIX_2_613125930); /* 2*(c2+c6) */
|
|
||||||
|
|
||||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
|
||||||
tmp5 = tmp11 - tmp6;
|
|
||||||
tmp4 = tmp10 - tmp5;
|
|
||||||
|
|
||||||
wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
|
|
||||||
wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
|
|
||||||
wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
|
|
||||||
wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
|
|
||||||
wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
|
|
||||||
wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
|
|
||||||
wsptr[DCTSIZE*3] = (int) (tmp3 + tmp4);
|
|
||||||
wsptr[DCTSIZE*4] = (int) (tmp3 - tmp4);
|
|
||||||
|
|
||||||
inptr++; /* advance pointers to next column */
|
|
||||||
quantptr++;
|
|
||||||
wsptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pass 2: process rows from work array, store into output array.
|
|
||||||
* Note that we must descale the results by a factor of 8 == 2**3,
|
|
||||||
* and also undo the PASS1_BITS scaling.
|
|
||||||
*/
|
|
||||||
|
|
||||||
wsptr = workspace;
|
|
||||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
|
||||||
outptr = output_buf[ctr] + output_col;
|
|
||||||
|
|
||||||
/* Add range center and fudge factor for final descale and range-limit. */
|
|
||||||
z5 = (DCTELEM) wsptr[0] +
|
|
||||||
((((DCTELEM) RANGE_CENTER) << (PASS1_BITS+3)) +
|
|
||||||
(1 << (PASS1_BITS+2)));
|
|
||||||
|
|
||||||
/* Rows of zeroes can be exploited in the same way as we did with columns.
|
|
||||||
* However, the column calculation has created many nonzero AC terms, so
|
|
||||||
* the simplification applies less often (typically 5% to 10% of the time).
|
|
||||||
* On machines with very fast multiplication, it's possible that the
|
|
||||||
* test takes more time than it's worth. In that case this section
|
|
||||||
* may be commented out.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NO_ZERO_ROW_TEST
|
|
||||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
|
|
||||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
|
||||||
/* AC terms all zero */
|
|
||||||
JSAMPLE dcval = range_limit[(int) IRIGHT_SHIFT(z5, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
|
|
||||||
outptr[0] = dcval;
|
|
||||||
outptr[1] = dcval;
|
|
||||||
outptr[2] = dcval;
|
|
||||||
outptr[3] = dcval;
|
|
||||||
outptr[4] = dcval;
|
|
||||||
outptr[5] = dcval;
|
|
||||||
outptr[6] = dcval;
|
|
||||||
outptr[7] = dcval;
|
|
||||||
|
|
||||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Even part */
|
|
||||||
|
|
||||||
tmp10 = z5 + (DCTELEM) wsptr[4];
|
|
||||||
tmp11 = z5 - (DCTELEM) wsptr[4];
|
|
||||||
|
|
||||||
tmp13 = (DCTELEM) wsptr[2] + (DCTELEM) wsptr[6];
|
|
||||||
tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6],
|
|
||||||
FIX_1_414213562) - tmp13; /* 2*c4 */
|
|
||||||
|
|
||||||
tmp0 = tmp10 + tmp13;
|
|
||||||
tmp3 = tmp10 - tmp13;
|
|
||||||
tmp1 = tmp11 + tmp12;
|
|
||||||
tmp2 = tmp11 - tmp12;
|
|
||||||
|
|
||||||
/* Odd part */
|
|
||||||
|
|
||||||
z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
|
|
||||||
z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
|
|
||||||
z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
|
|
||||||
z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
|
|
||||||
|
|
||||||
tmp7 = z11 + z13; /* phase 5 */
|
|
||||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
|
|
||||||
|
|
||||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
|
|
||||||
tmp10 = z5 - MULTIPLY(z12, FIX_1_082392200); /* 2*(c2-c6) */
|
|
||||||
tmp12 = z5 - MULTIPLY(z10, FIX_2_613125930); /* 2*(c2+c6) */
|
|
||||||
|
|
||||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
|
||||||
tmp5 = tmp11 - tmp6;
|
|
||||||
tmp4 = tmp10 - tmp5;
|
|
||||||
|
|
||||||
/* Final output stage: scale down by a factor of 8 and range-limit */
|
|
||||||
|
|
||||||
outptr[0] = range_limit[(int) IRIGHT_SHIFT(tmp0 + tmp7, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
outptr[7] = range_limit[(int) IRIGHT_SHIFT(tmp0 - tmp7, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
outptr[1] = range_limit[(int) IRIGHT_SHIFT(tmp1 + tmp6, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
outptr[6] = range_limit[(int) IRIGHT_SHIFT(tmp1 - tmp6, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
outptr[2] = range_limit[(int) IRIGHT_SHIFT(tmp2 + tmp5, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
outptr[5] = range_limit[(int) IRIGHT_SHIFT(tmp2 - tmp5, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
outptr[3] = range_limit[(int) IRIGHT_SHIFT(tmp3 + tmp4, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
outptr[4] = range_limit[(int) IRIGHT_SHIFT(tmp3 - tmp4, PASS1_BITS+3)
|
|
||||||
& RANGE_MASK];
|
|
||||||
|
|
||||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* DCT_IFAST_SUPPORTED */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
* jinclude.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1994, Thomas G. Lane.
|
|
||||||
* Modified 2017 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 exists to provide a single place to fix any problems with
|
|
||||||
* including the wrong system include files. (Common problems are taken
|
|
||||||
* care of by the standard jconfig symbols, but on really weird systems
|
|
||||||
* you may have to edit this file.)
|
|
||||||
*
|
|
||||||
* NOTE: this file is NOT intended to be included by applications using the
|
|
||||||
* JPEG library. Most applications need only include jpeglib.h.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Include auto-config file to find out which system include files we need. */
|
|
||||||
|
|
||||||
#include "jconfig.h" /* auto configuration options */
|
|
||||||
#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need the NULL macro and size_t typedef.
|
|
||||||
* On an ANSI-conforming system it is sufficient to include <stddef.h>.
|
|
||||||
* Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
|
|
||||||
* pull in <sys/types.h> as well.
|
|
||||||
* Note that the core JPEG library does not require <stdio.h>;
|
|
||||||
* only the default error handler and data source/destination modules do.
|
|
||||||
* But we must pull it in because of the references to FILE in jpeglib.h.
|
|
||||||
* You can remove those references if you want to compile without <stdio.h>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_STDDEF_H
|
|
||||||
#include <stddef.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDLIB_H
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NEED_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We need memory copying and zeroing functions, plus strncpy().
|
|
||||||
* ANSI and System V implementations declare these in <string.h>.
|
|
||||||
* BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
|
|
||||||
* Some systems may declare memset and memcpy in <memory.h>.
|
|
||||||
*
|
|
||||||
* NOTE: we assume the size parameters to these functions are of type size_t.
|
|
||||||
* Change the casts in these macros if not!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef NEED_BSD_STRINGS
|
|
||||||
|
|
||||||
#include <strings.h>
|
|
||||||
#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
|
|
||||||
#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
|
|
||||||
|
|
||||||
#else /* not BSD, assume ANSI/SysV string lib */
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
|
|
||||||
#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In ANSI C, and indeed any rational implementation, size_t is also the
|
|
||||||
* type returned by sizeof(). However, it seems there are some irrational
|
|
||||||
* implementations out there, in which sizeof() returns an int even though
|
|
||||||
* size_t is defined as long or unsigned long. To ensure consistent results
|
|
||||||
* we always use this SIZEOF() macro in place of using sizeof() directly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SIZEOF(object) ((size_t) sizeof(object))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The modules that use fread() and fwrite() always invoke them through
|
|
||||||
* these macros. On some systems you may need to twiddle the argument casts.
|
|
||||||
* CAUTION: argument order is different from underlying functions!
|
|
||||||
*
|
|
||||||
* Furthermore, macros are provided for fflush() and ferror() in order
|
|
||||||
* to facilitate adaption by applications using an own FILE class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JFREAD(file,buf,sizeofbuf) \
|
|
||||||
((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
|
||||||
#define JFWRITE(file,buf,sizeofbuf) \
|
|
||||||
((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
|
|
||||||
#define JFFLUSH(file) fflush(file)
|
|
||||||
#define JFERROR(file) ferror(file)
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* jmemansi.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1992-1996, Thomas G. Lane.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file provides a simple generic implementation of the system-
|
|
||||||
* dependent portion of the JPEG memory manager. This implementation
|
|
||||||
* assumes that you have the ANSI-standard library routine tmpfile().
|
|
||||||
* Also, the problem of determining the amount of memory available
|
|
||||||
* is shoved onto the user.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
|
||||||
|
|
||||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
|
||||||
extern void * malloc JPP((size_t size));
|
|
||||||
extern void free JPP((void *ptr));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
|
|
||||||
#define SEEK_SET 0 /* if not, assume 0 is correct */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Memory allocation and freeing are controlled by the regular library
|
|
||||||
* routines malloc() and free().
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void *)
|
|
||||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
|
||||||
{
|
|
||||||
return (void *) malloc(sizeofobject);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
|
||||||
{
|
|
||||||
free(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "Large" objects are treated the same as "small" ones.
|
|
||||||
* NB: although we include FAR keywords in the routine declarations,
|
|
||||||
* this file won't actually work in 80x86 small/medium model; at least,
|
|
||||||
* you probably won't be able to process useful-size images in only 64KB.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void FAR *)
|
|
||||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
|
||||||
{
|
|
||||||
return (void FAR *) malloc(sizeofobject);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
|
||||||
{
|
|
||||||
free(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This routine computes the total memory space available for allocation.
|
|
||||||
* It's impossible to do this in a portable way; our current solution is
|
|
||||||
* to make the user tell us (with a default value set at compile time).
|
|
||||||
* If you can actually get the available space, it's a good idea to subtract
|
|
||||||
* a slop factor of 5% or so.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
|
|
||||||
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GLOBAL(long)
|
|
||||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
|
||||||
long max_bytes_needed, long already_allocated)
|
|
||||||
{
|
|
||||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Backing store (temporary file) management.
|
|
||||||
* Backing store objects are only used when the value returned by
|
|
||||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
|
||||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
|
||||||
void FAR * buffer_address,
|
|
||||||
long file_offset, long byte_count)
|
|
||||||
{
|
|
||||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
|
||||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
|
||||||
if (JFREAD(info->temp_file, buffer_address, byte_count)
|
|
||||||
!= (size_t) byte_count)
|
|
||||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
|
||||||
void FAR * buffer_address,
|
|
||||||
long file_offset, long byte_count)
|
|
||||||
{
|
|
||||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
|
||||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
|
||||||
if (JFWRITE(info->temp_file, buffer_address, byte_count)
|
|
||||||
!= (size_t) byte_count)
|
|
||||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
|
|
||||||
{
|
|
||||||
fclose(info->temp_file);
|
|
||||||
/* Since this implementation uses tmpfile() to create the file,
|
|
||||||
* no explicit file deletion is needed.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initial opening of a backing-store object.
|
|
||||||
*
|
|
||||||
* This version uses tmpfile(), which constructs a suitable file name
|
|
||||||
* behind the scenes. We don't have to use info->temp_name[] at all;
|
|
||||||
* indeed, we can't even find out the actual name of the temp file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
|
||||||
long total_bytes_needed)
|
|
||||||
{
|
|
||||||
if ((info->temp_file = tmpfile()) == NULL)
|
|
||||||
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
|
|
||||||
info->read_backing_store = read_backing_store;
|
|
||||||
info->write_backing_store = write_backing_store;
|
|
||||||
info->close_backing_store = close_backing_store;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These routines take care of any system-dependent initialization and
|
|
||||||
* cleanup required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(long)
|
|
||||||
jpeg_mem_init (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
|
|
||||||
}
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jpeg_mem_term (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* no work */
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,198 +0,0 @@
|
||||||
/*
|
|
||||||
* jmemsys.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1992-1997, Thomas G. Lane.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This include file defines the interface between the system-independent
|
|
||||||
* and system-dependent portions of the JPEG memory manager. No other
|
|
||||||
* modules need include it. (The system-independent portion is jmemmgr.c;
|
|
||||||
* there are several different versions of the system-dependent portion.)
|
|
||||||
*
|
|
||||||
* This file works as-is for the system-dependent memory managers supplied
|
|
||||||
* in the IJG distribution. You may need to modify it if you write a
|
|
||||||
* custom memory manager. If system-dependent changes are needed in
|
|
||||||
* this file, the best method is to #ifdef them based on a configuration
|
|
||||||
* symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
|
|
||||||
* and USE_MAC_MEMMGR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
|
||||||
|
|
||||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
|
||||||
#define jpeg_get_small jGetSmall
|
|
||||||
#define jpeg_free_small jFreeSmall
|
|
||||||
#define jpeg_get_large jGetLarge
|
|
||||||
#define jpeg_free_large jFreeLarge
|
|
||||||
#define jpeg_mem_available jMemAvail
|
|
||||||
#define jpeg_open_backing_store jOpenBackStore
|
|
||||||
#define jpeg_mem_init jMemInit
|
|
||||||
#define jpeg_mem_term jMemTerm
|
|
||||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These two functions are used to allocate and release small chunks of
|
|
||||||
* memory. (Typically the total amount requested through jpeg_get_small is
|
|
||||||
* no more than 20K or so; this will be requested in chunks of a few K each.)
|
|
||||||
* Behavior should be the same as for the standard library functions malloc
|
|
||||||
* and free; in particular, jpeg_get_small must return NULL on failure.
|
|
||||||
* On most systems, these ARE malloc and free. jpeg_free_small is passed the
|
|
||||||
* size of the object being freed, just in case it's needed.
|
|
||||||
* On an 80x86 machine using small-data memory model, these manage near heap.
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
|
|
||||||
EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
|
|
||||||
size_t sizeofobject));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These two functions are used to allocate and release large chunks of
|
|
||||||
* memory (up to the total free space designated by jpeg_mem_available).
|
|
||||||
* The interface is the same as above, except that on an 80x86 machine,
|
|
||||||
* far pointers are used. On most other machines these are identical to
|
|
||||||
* the jpeg_get/free_small routines; but we keep them separate anyway,
|
|
||||||
* in case a different allocation strategy is desirable for large chunks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
|
|
||||||
size_t sizeofobject));
|
|
||||||
EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
|
|
||||||
size_t sizeofobject));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
|
|
||||||
* be requested in a single call to jpeg_get_large (and jpeg_get_small for that
|
|
||||||
* matter, but that case should never come into play). This macro is needed
|
|
||||||
* to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
|
|
||||||
* On those machines, we expect that jconfig.h will provide a proper value.
|
|
||||||
* On machines with 32-bit flat address spaces, any large constant may be used.
|
|
||||||
*
|
|
||||||
* NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
|
|
||||||
* size_t and will be a multiple of sizeof(align_type).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */
|
|
||||||
#define MAX_ALLOC_CHUNK 1000000000L
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This routine computes the total space still available for allocation by
|
|
||||||
* jpeg_get_large. If more space than this is needed, backing store will be
|
|
||||||
* used. NOTE: any memory already allocated must not be counted.
|
|
||||||
*
|
|
||||||
* There is a minimum space requirement, corresponding to the minimum
|
|
||||||
* feasible buffer sizes; jmemmgr.c will request that much space even if
|
|
||||||
* jpeg_mem_available returns zero. The maximum space needed, enough to hold
|
|
||||||
* all working storage in memory, is also passed in case it is useful.
|
|
||||||
* Finally, the total space already allocated is passed. If no better
|
|
||||||
* method is available, cinfo->mem->max_memory_to_use - already_allocated
|
|
||||||
* is often a suitable calculation.
|
|
||||||
*
|
|
||||||
* It is OK for jpeg_mem_available to underestimate the space available
|
|
||||||
* (that'll just lead to more backing-store access than is really necessary).
|
|
||||||
* However, an overestimate will lead to failure. Hence it's wise to subtract
|
|
||||||
* a slop factor from the true available space. 5% should be enough.
|
|
||||||
*
|
|
||||||
* On machines with lots of virtual memory, any large constant may be returned.
|
|
||||||
* Conversely, zero may be returned to always use the minimum amount of memory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
|
|
||||||
long min_bytes_needed,
|
|
||||||
long max_bytes_needed,
|
|
||||||
long already_allocated));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This structure holds whatever state is needed to access a single
|
|
||||||
* backing-store object. The read/write/close method pointers are called
|
|
||||||
* by jmemmgr.c to manipulate the backing-store object; all other fields
|
|
||||||
* are private to the system-dependent backing store routines.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
|
|
||||||
|
|
||||||
typedef unsigned short XMSH; /* type of extended-memory handles */
|
|
||||||
typedef unsigned short EMSH; /* type of expanded-memory handles */
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
short file_handle; /* DOS file handle if it's a temp file */
|
|
||||||
XMSH xms_handle; /* handle if it's a chunk of XMS */
|
|
||||||
EMSH ems_handle; /* handle if it's a chunk of EMS */
|
|
||||||
} handle_union;
|
|
||||||
|
|
||||||
#endif /* USE_MSDOS_MEMMGR */
|
|
||||||
|
|
||||||
#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
|
|
||||||
#include <Files.h>
|
|
||||||
#endif /* USE_MAC_MEMMGR */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct backing_store_struct * backing_store_ptr;
|
|
||||||
|
|
||||||
typedef struct backing_store_struct {
|
|
||||||
/* Methods for reading/writing/closing this backing-store object */
|
|
||||||
JMETHOD(void, read_backing_store, (j_common_ptr cinfo,
|
|
||||||
backing_store_ptr info,
|
|
||||||
void FAR * buffer_address,
|
|
||||||
long file_offset, long byte_count));
|
|
||||||
JMETHOD(void, write_backing_store, (j_common_ptr cinfo,
|
|
||||||
backing_store_ptr info,
|
|
||||||
void FAR * buffer_address,
|
|
||||||
long file_offset, long byte_count));
|
|
||||||
JMETHOD(void, close_backing_store, (j_common_ptr cinfo,
|
|
||||||
backing_store_ptr info));
|
|
||||||
|
|
||||||
/* Private fields for system-dependent backing-store management */
|
|
||||||
#ifdef USE_MSDOS_MEMMGR
|
|
||||||
/* For the MS-DOS manager (jmemdos.c), we need: */
|
|
||||||
handle_union handle; /* reference to backing-store storage object */
|
|
||||||
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
|
|
||||||
#else
|
|
||||||
#ifdef USE_MAC_MEMMGR
|
|
||||||
/* For the Mac manager (jmemmac.c), we need: */
|
|
||||||
short temp_file; /* file reference number to temp file */
|
|
||||||
FSSpec tempSpec; /* the FSSpec for the temp file */
|
|
||||||
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
|
|
||||||
#else
|
|
||||||
/* For a typical implementation with temp files, we need: */
|
|
||||||
FILE * temp_file; /* stdio reference to temp file */
|
|
||||||
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
} backing_store_info;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initial opening of a backing-store object. This must fill in the
|
|
||||||
* read/write/close pointers in the object. The read/write routines
|
|
||||||
* may take an error exit if the specified maximum file size is exceeded.
|
|
||||||
* (If jpeg_mem_available always returns a large value, this routine can
|
|
||||||
* just take an error exit.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
|
|
||||||
backing_store_ptr info,
|
|
||||||
long total_bytes_needed));
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These routines take care of any system-dependent initialization and
|
|
||||||
* cleanup required. jpeg_mem_init will be called before anything is
|
|
||||||
* allocated (and, therefore, nothing in cinfo is of use except the error
|
|
||||||
* manager pointer). It should return a suitable default value for
|
|
||||||
* max_memory_to_use; this may subsequently be overridden by the surrounding
|
|
||||||
* application. (Note that max_memory_to_use is only important if
|
|
||||||
* jpeg_mem_available chooses to consult it ... no one else will.)
|
|
||||||
* jpeg_mem_term may assume that all requested memory has been freed and that
|
|
||||||
* all opened backing-store objects have been closed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
|
|
||||||
EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
|
|
|
@ -1,446 +0,0 @@
|
||||||
/*
|
|
||||||
* jmorecfg.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
|
||||||
* Modified 1997-2013 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 additional configuration options that customize the
|
|
||||||
* JPEG software for special applications or support machine-dependent
|
|
||||||
* optimizations. Most users will not need to touch this file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define BITS_IN_JSAMPLE as either
|
|
||||||
* 8 for 8-bit sample values (the usual setting)
|
|
||||||
* 9 for 9-bit sample values
|
|
||||||
* 10 for 10-bit sample values
|
|
||||||
* 11 for 11-bit sample values
|
|
||||||
* 12 for 12-bit sample values
|
|
||||||
* Only 8, 9, 10, 11, and 12 bits sample data precision are supported for
|
|
||||||
* full-feature DCT processing. Further depths up to 16-bit may be added
|
|
||||||
* later for the lossless modes of operation.
|
|
||||||
* Run-time selection and conversion of data precision will be added later
|
|
||||||
* and are currently not supported, sorry.
|
|
||||||
* Exception: The transcoding part (jpegtran) supports all settings in a
|
|
||||||
* single instance, since it operates on the level of DCT coefficients and
|
|
||||||
* not sample values. The DCT coefficients are of the same type (16 bits)
|
|
||||||
* in all cases (see below).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BITS_IN_JSAMPLE 8 /* use 8, 9, 10, 11, or 12 */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Maximum number of components (color channels) allowed in JPEG image.
|
|
||||||
* To meet the letter of the JPEG spec, set this to 255. However, darn
|
|
||||||
* few applications need more than 4 channels (maybe 5 for CMYK + alpha
|
|
||||||
* mask). We recommend 10 as a reasonable compromise; use 4 if you are
|
|
||||||
* really short on memory. (Each allowed component costs a hundred or so
|
|
||||||
* bytes of storage, whether actually used in an image or not.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MAX_COMPONENTS 10 /* maximum number of image components */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Basic data types.
|
|
||||||
* You may need to change these if you have a machine with unusual data
|
|
||||||
* type sizes; for example, "char" not 8 bits, "short" not 16 bits,
|
|
||||||
* or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
|
|
||||||
* but it had better be at least 16.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Representation of a single sample (pixel element value).
|
|
||||||
* We frequently allocate large arrays of these, so it's important to keep
|
|
||||||
* them small. But if you have memory to burn and access to char or short
|
|
||||||
* arrays is very slow on your hardware, you might want to change these.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
/* JSAMPLE should be the smallest type that will hold the values 0..255.
|
|
||||||
* You can use a signed char by having GETJSAMPLE mask it with 0xFF.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_CHAR
|
|
||||||
|
|
||||||
typedef unsigned char JSAMPLE;
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
|
|
||||||
#else /* not HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
typedef char JSAMPLE;
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
#else
|
|
||||||
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
|
|
||||||
#endif /* CHAR_IS_UNSIGNED */
|
|
||||||
|
|
||||||
#endif /* HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
#define MAXJSAMPLE 255
|
|
||||||
#define CENTERJSAMPLE 128
|
|
||||||
|
|
||||||
#endif /* BITS_IN_JSAMPLE == 8 */
|
|
||||||
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 9
|
|
||||||
/* JSAMPLE should be the smallest type that will hold the values 0..511.
|
|
||||||
* On nearly all machines "short" will do nicely.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef short JSAMPLE;
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
|
|
||||||
#define MAXJSAMPLE 511
|
|
||||||
#define CENTERJSAMPLE 256
|
|
||||||
|
|
||||||
#endif /* BITS_IN_JSAMPLE == 9 */
|
|
||||||
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 10
|
|
||||||
/* JSAMPLE should be the smallest type that will hold the values 0..1023.
|
|
||||||
* On nearly all machines "short" will do nicely.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef short JSAMPLE;
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
|
|
||||||
#define MAXJSAMPLE 1023
|
|
||||||
#define CENTERJSAMPLE 512
|
|
||||||
|
|
||||||
#endif /* BITS_IN_JSAMPLE == 10 */
|
|
||||||
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 11
|
|
||||||
/* JSAMPLE should be the smallest type that will hold the values 0..2047.
|
|
||||||
* On nearly all machines "short" will do nicely.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef short JSAMPLE;
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
|
|
||||||
#define MAXJSAMPLE 2047
|
|
||||||
#define CENTERJSAMPLE 1024
|
|
||||||
|
|
||||||
#endif /* BITS_IN_JSAMPLE == 11 */
|
|
||||||
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 12
|
|
||||||
/* JSAMPLE should be the smallest type that will hold the values 0..4095.
|
|
||||||
* On nearly all machines "short" will do nicely.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef short JSAMPLE;
|
|
||||||
#define GETJSAMPLE(value) ((int) (value))
|
|
||||||
|
|
||||||
#define MAXJSAMPLE 4095
|
|
||||||
#define CENTERJSAMPLE 2048
|
|
||||||
|
|
||||||
#endif /* BITS_IN_JSAMPLE == 12 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Representation of a DCT frequency coefficient.
|
|
||||||
* This should be a signed value of at least 16 bits; "short" is usually OK.
|
|
||||||
* Again, we allocate large arrays of these, but you can change to int
|
|
||||||
* if you have memory to burn and "short" is really slow.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef short JCOEF;
|
|
||||||
|
|
||||||
|
|
||||||
/* Compressed datastreams are represented as arrays of JOCTET.
|
|
||||||
* These must be EXACTLY 8 bits wide, at least once they are written to
|
|
||||||
* external storage. Note that when using the stdio data source/destination
|
|
||||||
* managers, this is also the data type passed to fread/fwrite.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_CHAR
|
|
||||||
|
|
||||||
typedef unsigned char JOCTET;
|
|
||||||
#define GETJOCTET(value) (value)
|
|
||||||
|
|
||||||
#else /* not HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
typedef char JOCTET;
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
|
||||||
#define GETJOCTET(value) (value)
|
|
||||||
#else
|
|
||||||
#define GETJOCTET(value) ((value) & 0xFF)
|
|
||||||
#endif /* CHAR_IS_UNSIGNED */
|
|
||||||
|
|
||||||
#endif /* HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
|
|
||||||
/* These typedefs are used for various table entries and so forth.
|
|
||||||
* They must be at least as wide as specified; but making them too big
|
|
||||||
* won't cost a huge amount of memory, so we don't provide special
|
|
||||||
* extraction code like we did for JSAMPLE. (In other words, these
|
|
||||||
* typedefs live at a different point on the speed/space tradeoff curve.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* UINT8 must hold at least the values 0..255. */
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_CHAR
|
|
||||||
typedef unsigned char UINT8;
|
|
||||||
#else /* not HAVE_UNSIGNED_CHAR */
|
|
||||||
#ifdef CHAR_IS_UNSIGNED
|
|
||||||
typedef char UINT8;
|
|
||||||
#else /* not CHAR_IS_UNSIGNED */
|
|
||||||
typedef short UINT8;
|
|
||||||
#endif /* CHAR_IS_UNSIGNED */
|
|
||||||
#endif /* HAVE_UNSIGNED_CHAR */
|
|
||||||
|
|
||||||
/* UINT16 must hold at least the values 0..65535. */
|
|
||||||
|
|
||||||
#ifdef HAVE_UNSIGNED_SHORT
|
|
||||||
typedef unsigned short UINT16;
|
|
||||||
#else /* not HAVE_UNSIGNED_SHORT */
|
|
||||||
typedef unsigned int UINT16;
|
|
||||||
#endif /* HAVE_UNSIGNED_SHORT */
|
|
||||||
|
|
||||||
/* INT16 must hold at least the values -32768..32767. */
|
|
||||||
|
|
||||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
|
|
||||||
typedef short INT16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* INT32 must hold at least signed 32-bit values. */
|
|
||||||
|
|
||||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
|
|
||||||
#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */
|
|
||||||
#ifndef _BASETSD_H /* MinGW is slightly different */
|
|
||||||
#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */
|
|
||||||
typedef long INT32;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Datatype used for image dimensions. The JPEG standard only supports
|
|
||||||
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
|
||||||
* "unsigned int" is sufficient on all machines. However, if you need to
|
|
||||||
* handle larger images and you don't mind deviating from the spec, you
|
|
||||||
* can change this datatype.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef unsigned int JDIMENSION;
|
|
||||||
|
|
||||||
#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
|
|
||||||
|
|
||||||
|
|
||||||
/* These macros are used in all function definitions and extern declarations.
|
|
||||||
* You could modify them if you need to change function linkage conventions;
|
|
||||||
* in particular, you'll need to do that to make the library a Windows DLL.
|
|
||||||
* Another application is to make all functions global for use with debuggers
|
|
||||||
* or code profilers that require it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* a function called through method pointers: */
|
|
||||||
#define METHODDEF(type) static type
|
|
||||||
/* a function used only in its module: */
|
|
||||||
#define LOCAL(type) static type
|
|
||||||
/* a function referenced thru EXTERNs: */
|
|
||||||
#define GLOBAL(type) type
|
|
||||||
/* a reference to a GLOBAL function: */
|
|
||||||
#define EXTERN(type) extern type
|
|
||||||
|
|
||||||
|
|
||||||
/* This macro is used to declare a "method", that is, a function pointer.
|
|
||||||
* We want to supply prototype parameters if the compiler can cope.
|
|
||||||
* Note that the arglist parameter must be parenthesized!
|
|
||||||
* Again, you can customize this if you need special linkage keywords.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_PROTOTYPES
|
|
||||||
#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
|
|
||||||
#else
|
|
||||||
#define JMETHOD(type,methodname,arglist) type (*methodname) ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* The noreturn type identifier is used to declare functions
|
|
||||||
* which cannot return.
|
|
||||||
* Compilers can thus create more optimized code and perform
|
|
||||||
* better checks for warnings and errors.
|
|
||||||
* Static analyzer tools can make improved inferences about
|
|
||||||
* execution paths and are prevented from giving false alerts.
|
|
||||||
*
|
|
||||||
* Unfortunately, the proposed specifications of corresponding
|
|
||||||
* extensions in the Dec 2011 ISO C standard revision (C11),
|
|
||||||
* GCC, MSVC, etc. are not viable.
|
|
||||||
* Thus we introduce a user defined type to declare noreturn
|
|
||||||
* functions at least for clarity. A proper compiler would
|
|
||||||
* have a suitable noreturn type to match in place of void.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HAVE_NORETURN_T
|
|
||||||
typedef void noreturn_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Here is the pseudo-keyword for declaring pointers that must be "far"
|
|
||||||
* on 80x86 machines. Most of the specialized coding for 80x86 is handled
|
|
||||||
* by just saying "FAR *" where such a pointer is needed. In a few places
|
|
||||||
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FAR
|
|
||||||
#ifdef NEED_FAR_POINTERS
|
|
||||||
#define FAR far
|
|
||||||
#else
|
|
||||||
#define FAR
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
|
|
||||||
* in standard header files. Or you may have conflicts with application-
|
|
||||||
* specific header files that you want to include together with these files.
|
|
||||||
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HAVE_BOOLEAN
|
|
||||||
#if defined FALSE || defined TRUE || defined QGLOBAL_H
|
|
||||||
/* Qt3 defines FALSE and TRUE as "const" variables in qglobal.h */
|
|
||||||
typedef int boolean;
|
|
||||||
#ifndef FALSE /* in case these macros already exist */
|
|
||||||
#define FALSE 0 /* values of boolean */
|
|
||||||
#endif
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE 1
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
typedef enum { FALSE = 0, TRUE = 1 } boolean;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The remaining options affect code selection within the JPEG library,
|
|
||||||
* but they don't need to be visible to most applications using the library.
|
|
||||||
* To minimize application namespace pollution, the symbols won't be
|
|
||||||
* defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef JPEG_INTERNALS
|
|
||||||
#define JPEG_INTERNAL_OPTIONS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JPEG_INTERNAL_OPTIONS
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These defines indicate whether to include various optional functions.
|
|
||||||
* Undefining some of these symbols will produce a smaller but less capable
|
|
||||||
* library. Note that you can leave certain source files out of the
|
|
||||||
* compilation/linking process if you've #undef'd the corresponding symbols.
|
|
||||||
* (You may HAVE to do that if your compiler doesn't like null source files.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Capability options common to encoder and decoder: */
|
|
||||||
|
|
||||||
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
|
|
||||||
#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
|
|
||||||
#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
|
|
||||||
|
|
||||||
/* Encoder capability options: */
|
|
||||||
|
|
||||||
#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
|
||||||
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
|
||||||
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
|
||||||
#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/
|
|
||||||
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
|
|
||||||
/* Note: if you selected more than 8-bit data precision, it is dangerous to
|
|
||||||
* turn off ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only
|
|
||||||
* good for 8-bit precision, so arithmetic coding is recommended for higher
|
|
||||||
* precision. The Huffman encoder normally uses entropy optimization to
|
|
||||||
* compute usable tables for higher precision. Otherwise, you'll have to
|
|
||||||
* supply different default Huffman tables.
|
|
||||||
* The exact same statements apply for progressive JPEG: the default tables
|
|
||||||
* don't work for progressive mode. (This may get fixed, however.)
|
|
||||||
*/
|
|
||||||
#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
|
|
||||||
|
|
||||||
/* Decoder capability options: */
|
|
||||||
|
|
||||||
#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
|
||||||
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
|
||||||
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
|
||||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/
|
|
||||||
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
|
|
||||||
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
|
|
||||||
#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
|
|
||||||
#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
|
|
||||||
#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
|
|
||||||
#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
|
|
||||||
|
|
||||||
/* more capability options later, no doubt */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ordering of RGB data in scanlines passed to or from the application.
|
|
||||||
* If your application wants to deal with data in the order B,G,R, just
|
|
||||||
* change these macros. You can also deal with formats such as R,G,B,X
|
|
||||||
* (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
|
|
||||||
* the offsets will also change the order in which colormap data is organized.
|
|
||||||
* RESTRICTIONS:
|
|
||||||
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
|
|
||||||
* 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
|
|
||||||
* is not 3 (they don't understand about dummy color components!). So you
|
|
||||||
* can't use color quantization if you change that value.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
|
|
||||||
#define RGB_GREEN 1 /* Offset of Green */
|
|
||||||
#define RGB_BLUE 2 /* Offset of Blue */
|
|
||||||
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
|
|
||||||
|
|
||||||
|
|
||||||
/* Definitions for speed-related optimizations. */
|
|
||||||
|
|
||||||
|
|
||||||
/* If your compiler supports inline functions, define INLINE
|
|
||||||
* as the inline keyword; otherwise define it as empty.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INLINE
|
|
||||||
#ifdef __GNUC__ /* for instance, GNU C knows about inline */
|
|
||||||
#define INLINE __inline__
|
|
||||||
#endif
|
|
||||||
#ifndef INLINE
|
|
||||||
#define INLINE /* default is to define it as empty */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
|
|
||||||
* two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
|
|
||||||
* as short on such a machine. MULTIPLIER must be at least 16 bits wide.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MULTIPLIER
|
|
||||||
#define MULTIPLIER int /* type for fastest integer multiply */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* FAST_FLOAT should be either float or double, whichever is done faster
|
|
||||||
* by your compiler. (Note that this type is only used in the floating point
|
|
||||||
* DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
|
|
||||||
* Typically, float is faster in ANSI C compilers, while double is faster in
|
|
||||||
* pre-ANSI compilers (because they insist on converting to double anyway).
|
|
||||||
* The code below therefore chooses float if we have ANSI-style prototypes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FAST_FLOAT
|
|
||||||
#ifdef HAVE_PROTOTYPES
|
|
||||||
#define FAST_FLOAT float
|
|
||||||
#else
|
|
||||||
#define FAST_FLOAT double
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* JPEG_INTERNAL_OPTIONS */
|
|
|
@ -1,439 +0,0 @@
|
||||||
/*
|
|
||||||
* jpegint.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
|
||||||
* Modified 1997-2017 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 provides common declarations for the various JPEG modules.
|
|
||||||
* These declarations are considered internal to the JPEG library; most
|
|
||||||
* applications using the library shouldn't need to include this file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Declarations for both compression & decompression */
|
|
||||||
|
|
||||||
typedef enum { /* Operating modes for buffer controllers */
|
|
||||||
JBUF_PASS_THRU, /* Plain stripwise operation */
|
|
||||||
/* Remaining modes require a full-image buffer to have been created */
|
|
||||||
JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
|
|
||||||
JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
|
|
||||||
JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
|
|
||||||
} J_BUF_MODE;
|
|
||||||
|
|
||||||
/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
|
|
||||||
#define CSTATE_START 100 /* after create_compress */
|
|
||||||
#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */
|
|
||||||
#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */
|
|
||||||
#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */
|
|
||||||
#define DSTATE_START 200 /* after create_decompress */
|
|
||||||
#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */
|
|
||||||
#define DSTATE_READY 202 /* found SOS, ready for start_decompress */
|
|
||||||
#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/
|
|
||||||
#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */
|
|
||||||
#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */
|
|
||||||
#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */
|
|
||||||
#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */
|
|
||||||
#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */
|
|
||||||
#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */
|
|
||||||
#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */
|
|
||||||
|
|
||||||
|
|
||||||
/* Declarations for compression modules */
|
|
||||||
|
|
||||||
/* Master control module */
|
|
||||||
struct jpeg_comp_master {
|
|
||||||
JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, pass_startup, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
|
|
||||||
|
|
||||||
/* State variables made visible to other modules */
|
|
||||||
boolean call_pass_startup; /* True if pass_startup must be called */
|
|
||||||
boolean is_last_pass; /* True during last pass */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Main buffer control (downsampled-data buffer) */
|
|
||||||
struct jpeg_c_main_controller {
|
|
||||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
|
||||||
JMETHOD(void, process_data, (j_compress_ptr cinfo,
|
|
||||||
JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
|
|
||||||
JDIMENSION in_rows_avail));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Compression preprocessing (downsampling input buffer control) */
|
|
||||||
struct jpeg_c_prep_controller {
|
|
||||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
|
||||||
JMETHOD(void, pre_process_data, (j_compress_ptr cinfo,
|
|
||||||
JSAMPARRAY input_buf,
|
|
||||||
JDIMENSION *in_row_ctr,
|
|
||||||
JDIMENSION in_rows_avail,
|
|
||||||
JSAMPIMAGE output_buf,
|
|
||||||
JDIMENSION *out_row_group_ctr,
|
|
||||||
JDIMENSION out_row_groups_avail));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Coefficient buffer control */
|
|
||||||
struct jpeg_c_coef_controller {
|
|
||||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
|
|
||||||
JMETHOD(boolean, compress_data, (j_compress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Colorspace conversion */
|
|
||||||
struct jpeg_color_converter {
|
|
||||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, color_convert, (j_compress_ptr cinfo,
|
|
||||||
JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
|
|
||||||
JDIMENSION output_row, int num_rows));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Downsampling */
|
|
||||||
struct jpeg_downsampler {
|
|
||||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, downsample, (j_compress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION in_row_index,
|
|
||||||
JSAMPIMAGE output_buf,
|
|
||||||
JDIMENSION out_row_group_index));
|
|
||||||
|
|
||||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Forward DCT (also controls coefficient quantization) */
|
|
||||||
typedef JMETHOD(void, forward_DCT_ptr,
|
|
||||||
(j_compress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
|
||||||
JDIMENSION start_row, JDIMENSION start_col,
|
|
||||||
JDIMENSION num_blocks));
|
|
||||||
|
|
||||||
struct jpeg_forward_dct {
|
|
||||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo));
|
|
||||||
/* It is useful to allow each component to have a separate FDCT method. */
|
|
||||||
forward_DCT_ptr forward_DCT[MAX_COMPONENTS];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Entropy encoding */
|
|
||||||
struct jpeg_entropy_encoder {
|
|
||||||
JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
|
|
||||||
JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
|
|
||||||
JMETHOD(void, finish_pass, (j_compress_ptr cinfo));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Marker writing */
|
|
||||||
struct jpeg_marker_writer {
|
|
||||||
JMETHOD(void, write_file_header, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, write_frame_header, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, write_scan_header, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo));
|
|
||||||
JMETHOD(void, write_tables_only, (j_compress_ptr cinfo));
|
|
||||||
/* These routines are exported to allow insertion of extra markers */
|
|
||||||
/* Probably only COM and APPn markers should be written this way */
|
|
||||||
JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
|
|
||||||
unsigned int datalen));
|
|
||||||
JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Declarations for decompression modules */
|
|
||||||
|
|
||||||
/* Master control module */
|
|
||||||
struct jpeg_decomp_master {
|
|
||||||
JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
|
|
||||||
|
|
||||||
/* State variables made visible to other modules */
|
|
||||||
boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Input control module */
|
|
||||||
struct jpeg_input_controller {
|
|
||||||
JMETHOD(int, consume_input, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
|
|
||||||
|
|
||||||
/* State variables made visible to other modules */
|
|
||||||
boolean has_multiple_scans; /* True if file has multiple scans */
|
|
||||||
boolean eoi_reached; /* True when EOI has been consumed */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Main buffer control (downsampled-data buffer) */
|
|
||||||
struct jpeg_d_main_controller {
|
|
||||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
|
|
||||||
JMETHOD(void, process_data, (j_decompress_ptr cinfo,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Coefficient buffer control */
|
|
||||||
struct jpeg_d_coef_controller {
|
|
||||||
JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(int, consume_data, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(int, decompress_data, (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE output_buf));
|
|
||||||
/* Pointer to array of coefficient virtual arrays, or NULL if none */
|
|
||||||
jvirt_barray_ptr *coef_arrays;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Decompression postprocessing (color quantization buffer control) */
|
|
||||||
struct jpeg_d_post_controller {
|
|
||||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
|
|
||||||
JMETHOD(void, post_process_data, (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf,
|
|
||||||
JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf,
|
|
||||||
JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Marker reading & parsing */
|
|
||||||
struct jpeg_marker_reader {
|
|
||||||
JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
|
|
||||||
/* Read markers until SOS or EOI.
|
|
||||||
* Returns same codes as are defined for jpeg_consume_input:
|
|
||||||
* JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
|
|
||||||
*/
|
|
||||||
JMETHOD(int, read_markers, (j_decompress_ptr cinfo));
|
|
||||||
/* Read a restart marker --- exported for use by entropy decoder only */
|
|
||||||
jpeg_marker_parser_method read_restart_marker;
|
|
||||||
|
|
||||||
/* State of marker reader --- nominally internal, but applications
|
|
||||||
* supplying COM or APPn handlers might like to know the state.
|
|
||||||
*/
|
|
||||||
boolean saw_SOI; /* found SOI? */
|
|
||||||
boolean saw_SOF; /* found SOF? */
|
|
||||||
int next_restart_num; /* next restart number expected (0-7) */
|
|
||||||
unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Entropy decoding */
|
|
||||||
struct jpeg_entropy_decoder {
|
|
||||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKROW *MCU_data));
|
|
||||||
JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Inverse DCT (also performs dequantization) */
|
|
||||||
typedef JMETHOD(void, inverse_DCT_method_ptr,
|
|
||||||
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
|
||||||
JCOEFPTR coef_block,
|
|
||||||
JSAMPARRAY output_buf, JDIMENSION output_col));
|
|
||||||
|
|
||||||
struct jpeg_inverse_dct {
|
|
||||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
|
||||||
/* It is useful to allow each component to have a separate IDCT method. */
|
|
||||||
inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Upsampling (note that upsampler must also call color converter) */
|
|
||||||
struct jpeg_upsampler {
|
|
||||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, upsample, (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf,
|
|
||||||
JDIMENSION *in_row_group_ctr,
|
|
||||||
JDIMENSION in_row_groups_avail,
|
|
||||||
JSAMPARRAY output_buf,
|
|
||||||
JDIMENSION *out_row_ctr,
|
|
||||||
JDIMENSION out_rows_avail));
|
|
||||||
|
|
||||||
boolean need_context_rows; /* TRUE if need rows above & below */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Colorspace conversion */
|
|
||||||
struct jpeg_color_deconverter {
|
|
||||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
|
|
||||||
JSAMPIMAGE input_buf, JDIMENSION input_row,
|
|
||||||
JSAMPARRAY output_buf, int num_rows));
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Color quantization or color precision reduction */
|
|
||||||
struct jpeg_color_quantizer {
|
|
||||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
|
|
||||||
JMETHOD(void, color_quantize, (j_decompress_ptr cinfo,
|
|
||||||
JSAMPARRAY input_buf, JSAMPARRAY output_buf,
|
|
||||||
int num_rows));
|
|
||||||
JMETHOD(void, finish_pass, (j_decompress_ptr cinfo));
|
|
||||||
JMETHOD(void, new_color_map, (j_decompress_ptr cinfo));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Definition of range extension bits for decompression processes.
|
|
||||||
* See the comments with prepare_range_limit_table (in jdmaster.c)
|
|
||||||
* for more info.
|
|
||||||
* The recommended default value for normal applications is 2.
|
|
||||||
* Applications with special requirements may use a different value.
|
|
||||||
* For example, Ghostscript wants to use 3 for proper handling of
|
|
||||||
* wacky images with oversize coefficient values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RANGE_BITS 2
|
|
||||||
#define RANGE_CENTER (CENTERJSAMPLE << RANGE_BITS)
|
|
||||||
|
|
||||||
|
|
||||||
/* Miscellaneous useful macros */
|
|
||||||
|
|
||||||
#undef MAX
|
|
||||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
|
||||||
#undef MIN
|
|
||||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
||||||
|
|
||||||
|
|
||||||
/* We assume that right shift corresponds to signed division by 2 with
|
|
||||||
* rounding towards minus infinity. This is correct for typical "arithmetic
|
|
||||||
* shift" instructions that shift in copies of the sign bit. But some
|
|
||||||
* C compilers implement >> with an unsigned shift. For these machines you
|
|
||||||
* must define RIGHT_SHIFT_IS_UNSIGNED.
|
|
||||||
* RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
|
|
||||||
* It is only applied with constant shift counts. SHIFT_TEMPS must be
|
|
||||||
* included in the variables of any routine using RIGHT_SHIFT.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
|
||||||
#define SHIFT_TEMPS INT32 shift_temp;
|
|
||||||
#define RIGHT_SHIFT(x,shft) \
|
|
||||||
((shift_temp = (x)) < 0 ? \
|
|
||||||
(shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
|
|
||||||
(shift_temp >> (shft)))
|
|
||||||
#else
|
|
||||||
#define SHIFT_TEMPS
|
|
||||||
#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
|
||||||
|
|
||||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
|
||||||
#define jinit_compress_master jICompress
|
|
||||||
#define jinit_c_master_control jICMaster
|
|
||||||
#define jinit_c_main_controller jICMainC
|
|
||||||
#define jinit_c_prep_controller jICPrepC
|
|
||||||
#define jinit_c_coef_controller jICCoefC
|
|
||||||
#define jinit_color_converter jICColor
|
|
||||||
#define jinit_downsampler jIDownsampler
|
|
||||||
#define jinit_forward_dct jIFDCT
|
|
||||||
#define jinit_huff_encoder jIHEncoder
|
|
||||||
#define jinit_arith_encoder jIAEncoder
|
|
||||||
#define jinit_marker_writer jIMWriter
|
|
||||||
#define jinit_master_decompress jIDMaster
|
|
||||||
#define jinit_d_main_controller jIDMainC
|
|
||||||
#define jinit_d_coef_controller jIDCoefC
|
|
||||||
#define jinit_d_post_controller jIDPostC
|
|
||||||
#define jinit_input_controller jIInCtlr
|
|
||||||
#define jinit_marker_reader jIMReader
|
|
||||||
#define jinit_huff_decoder jIHDecoder
|
|
||||||
#define jinit_arith_decoder jIADecoder
|
|
||||||
#define jinit_inverse_dct jIIDCT
|
|
||||||
#define jinit_upsampler jIUpsampler
|
|
||||||
#define jinit_color_deconverter jIDColor
|
|
||||||
#define jinit_1pass_quantizer jI1Quant
|
|
||||||
#define jinit_2pass_quantizer jI2Quant
|
|
||||||
#define jinit_merged_upsampler jIMUpsampler
|
|
||||||
#define jinit_memory_mgr jIMemMgr
|
|
||||||
#define jdiv_round_up jDivRound
|
|
||||||
#define jround_up jRound
|
|
||||||
#define jzero_far jZeroFar
|
|
||||||
#define jcopy_sample_rows jCopySamples
|
|
||||||
#define jcopy_block_row jCopyBlocks
|
|
||||||
#define jpeg_zigzag_order jZIGTable
|
|
||||||
#define jpeg_natural_order jZAGTable
|
|
||||||
#define jpeg_natural_order7 jZAG7Table
|
|
||||||
#define jpeg_natural_order6 jZAG6Table
|
|
||||||
#define jpeg_natural_order5 jZAG5Table
|
|
||||||
#define jpeg_natural_order4 jZAG4Table
|
|
||||||
#define jpeg_natural_order3 jZAG3Table
|
|
||||||
#define jpeg_natural_order2 jZAG2Table
|
|
||||||
#define jpeg_aritab jAriTab
|
|
||||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
|
||||||
|
|
||||||
|
|
||||||
/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
|
|
||||||
* and coefficient-block arrays. This won't work on 80x86 because the arrays
|
|
||||||
* are FAR and we're assuming a small-pointer memory model. However, some
|
|
||||||
* DOS compilers provide far-pointer versions of memcpy() and memset() even
|
|
||||||
* in the small-model libraries. These will be used if USE_FMEM is defined.
|
|
||||||
* Otherwise, the routines in jutils.c do it the hard way.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */
|
|
||||||
#define FMEMZERO(target,size) MEMZERO(target,size)
|
|
||||||
#else /* 80x86 case */
|
|
||||||
#ifdef USE_FMEM
|
|
||||||
#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
|
|
||||||
#else
|
|
||||||
EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
|
|
||||||
#define FMEMZERO(target,size) jzero_far(target, size)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Compression module initialization routines */
|
|
||||||
EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
|
|
||||||
boolean transcode_only));
|
|
||||||
EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
|
|
||||||
boolean need_full_buffer));
|
|
||||||
EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
|
|
||||||
boolean need_full_buffer));
|
|
||||||
EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
|
|
||||||
boolean need_full_buffer));
|
|
||||||
EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_arith_encoder JPP((j_compress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
|
|
||||||
/* Decompression module initialization routines */
|
|
||||||
EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
|
|
||||||
boolean need_full_buffer));
|
|
||||||
EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
|
|
||||||
boolean need_full_buffer));
|
|
||||||
EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
|
|
||||||
boolean need_full_buffer));
|
|
||||||
EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_arith_decoder JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
|
|
||||||
EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
|
|
||||||
/* Memory manager initialization */
|
|
||||||
EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
|
|
||||||
|
|
||||||
/* Utility routines in jutils.c */
|
|
||||||
EXTERN(long) jdiv_round_up JPP((long a, long b));
|
|
||||||
EXTERN(long) jround_up JPP((long a, long b));
|
|
||||||
EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
|
|
||||||
JSAMPARRAY output_array, int dest_row,
|
|
||||||
int num_rows, JDIMENSION num_cols));
|
|
||||||
EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
|
|
||||||
JDIMENSION num_blocks));
|
|
||||||
/* Constant tables in jutils.c */
|
|
||||||
#if 0 /* This table is not actually needed in v6a */
|
|
||||||
extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
|
|
||||||
#endif
|
|
||||||
extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
|
|
||||||
extern const int jpeg_natural_order7[]; /* zz to natural order for 7x7 block */
|
|
||||||
extern const int jpeg_natural_order6[]; /* zz to natural order for 6x6 block */
|
|
||||||
extern const int jpeg_natural_order5[]; /* zz to natural order for 5x5 block */
|
|
||||||
extern const int jpeg_natural_order4[]; /* zz to natural order for 4x4 block */
|
|
||||||
extern const int jpeg_natural_order3[]; /* zz to natural order for 3x3 block */
|
|
||||||
extern const int jpeg_natural_order2[]; /* zz to natural order for 2x2 block */
|
|
||||||
|
|
||||||
/* Arithmetic coding probability estimation tables in jaricom.c */
|
|
||||||
extern const INT32 jpeg_aritab[];
|
|
||||||
|
|
||||||
/* Suppress undefined-structure complaints if necessary. */
|
|
||||||
|
|
||||||
#ifdef INCOMPLETE_TYPES_BROKEN
|
|
||||||
#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */
|
|
||||||
struct jvirt_sarray_control { long dummy; };
|
|
||||||
struct jvirt_barray_control { long dummy; };
|
|
||||||
#endif
|
|
||||||
#endif /* INCOMPLETE_TYPES_BROKEN */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,857 +0,0 @@
|
||||||
/*
|
|
||||||
* jquant1.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
|
||||||
* Modified 2011 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains 1-pass color quantization (color mapping) routines.
|
|
||||||
* These routines provide mapping to a fixed color map using equally spaced
|
|
||||||
* color values. Optional Floyd-Steinberg or ordered dithering is available.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
#ifdef QUANT_1PASS_SUPPORTED
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The main purpose of 1-pass quantization is to provide a fast, if not very
|
|
||||||
* high quality, colormapped output capability. A 2-pass quantizer usually
|
|
||||||
* gives better visual quality; however, for quantized grayscale output this
|
|
||||||
* quantizer is perfectly adequate. Dithering is highly recommended with this
|
|
||||||
* quantizer, though you can turn it off if you really want to.
|
|
||||||
*
|
|
||||||
* In 1-pass quantization the colormap must be chosen in advance of seeing the
|
|
||||||
* image. We use a map consisting of all combinations of Ncolors[i] color
|
|
||||||
* values for the i'th component. The Ncolors[] values are chosen so that
|
|
||||||
* their product, the total number of colors, is no more than that requested.
|
|
||||||
* (In most cases, the product will be somewhat less.)
|
|
||||||
*
|
|
||||||
* Since the colormap is orthogonal, the representative value for each color
|
|
||||||
* component can be determined without considering the other components;
|
|
||||||
* then these indexes can be combined into a colormap index by a standard
|
|
||||||
* N-dimensional-array-subscript calculation. Most of the arithmetic involved
|
|
||||||
* can be precalculated and stored in the lookup table colorindex[].
|
|
||||||
* colorindex[i][j] maps pixel value j in component i to the nearest
|
|
||||||
* representative value (grid plane) for that component; this index is
|
|
||||||
* multiplied by the array stride for component i, so that the
|
|
||||||
* index of the colormap entry closest to a given pixel value is just
|
|
||||||
* sum( colorindex[component-number][pixel-component-value] )
|
|
||||||
* Aside from being fast, this scheme allows for variable spacing between
|
|
||||||
* representative values with no additional lookup cost.
|
|
||||||
*
|
|
||||||
* If gamma correction has been applied in color conversion, it might be wise
|
|
||||||
* to adjust the color grid spacing so that the representative colors are
|
|
||||||
* equidistant in linear space. At this writing, gamma correction is not
|
|
||||||
* implemented by jdcolor, so nothing is done here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Declarations for ordered dithering.
|
|
||||||
*
|
|
||||||
* We use a standard 16x16 ordered dither array. The basic concept of ordered
|
|
||||||
* dithering is described in many references, for instance Dale Schumacher's
|
|
||||||
* chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
|
|
||||||
* In place of Schumacher's comparisons against a "threshold" value, we add a
|
|
||||||
* "dither" value to the input pixel and then round the result to the nearest
|
|
||||||
* output value. The dither value is equivalent to (0.5 - threshold) times
|
|
||||||
* the distance between output values. For ordered dithering, we assume that
|
|
||||||
* the output colors are equally spaced; if not, results will probably be
|
|
||||||
* worse, since the dither may be too much or too little at a given point.
|
|
||||||
*
|
|
||||||
* The normal calculation would be to form pixel value + dither, range-limit
|
|
||||||
* this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
|
|
||||||
* We can skip the separate range-limiting step by extending the colorindex
|
|
||||||
* table in both directions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ODITHER_SIZE 16 /* dimension of dither matrix */
|
|
||||||
/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
|
|
||||||
#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */
|
|
||||||
#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */
|
|
||||||
|
|
||||||
typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
|
|
||||||
typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
|
|
||||||
|
|
||||||
static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
|
|
||||||
/* Bayer's order-4 dither array. Generated by the code given in
|
|
||||||
* Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
|
|
||||||
* The values in this array must range from 0 to ODITHER_CELLS-1.
|
|
||||||
*/
|
|
||||||
{ 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
|
|
||||||
{ 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
|
|
||||||
{ 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
|
|
||||||
{ 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
|
|
||||||
{ 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
|
|
||||||
{ 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
|
|
||||||
{ 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
|
|
||||||
{ 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
|
|
||||||
{ 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
|
|
||||||
{ 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
|
|
||||||
{ 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
|
|
||||||
{ 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
|
|
||||||
{ 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
|
|
||||||
{ 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
|
|
||||||
{ 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
|
|
||||||
{ 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Declarations for Floyd-Steinberg dithering.
|
|
||||||
*
|
|
||||||
* Errors are accumulated into the array fserrors[], at a resolution of
|
|
||||||
* 1/16th of a pixel count. The error at a given pixel is propagated
|
|
||||||
* to its not-yet-processed neighbors using the standard F-S fractions,
|
|
||||||
* ... (here) 7/16
|
|
||||||
* 3/16 5/16 1/16
|
|
||||||
* We work left-to-right on even rows, right-to-left on odd rows.
|
|
||||||
*
|
|
||||||
* We can get away with a single array (holding one row's worth of errors)
|
|
||||||
* by using it to store the current row's errors at pixel columns not yet
|
|
||||||
* processed, but the next row's errors at columns already processed. We
|
|
||||||
* need only a few extra variables to hold the errors immediately around the
|
|
||||||
* current column. (If we are lucky, those variables are in registers, but
|
|
||||||
* even if not, they're probably cheaper to access than array elements are.)
|
|
||||||
*
|
|
||||||
* The fserrors[] array is indexed [component#][position].
|
|
||||||
* We provide (#columns + 2) entries per component; the extra entry at each
|
|
||||||
* end saves us from special-casing the first and last pixels.
|
|
||||||
*
|
|
||||||
* Note: on a wide image, we might not have enough room in a PC's near data
|
|
||||||
* segment to hold the error array; so it is allocated with alloc_large.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if BITS_IN_JSAMPLE == 8
|
|
||||||
typedef INT16 FSERROR; /* 16 bits should be enough */
|
|
||||||
typedef int LOCFSERROR; /* use 'int' for calculation temps */
|
|
||||||
#else
|
|
||||||
typedef INT32 FSERROR; /* may need more than 16 bits */
|
|
||||||
typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
|
|
||||||
|
|
||||||
|
|
||||||
/* Private subobject */
|
|
||||||
|
|
||||||
#define MAX_Q_COMPS 4 /* max components I can handle */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_color_quantizer pub; /* public fields */
|
|
||||||
|
|
||||||
/* Initially allocated colormap is saved here */
|
|
||||||
JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
|
|
||||||
int sv_actual; /* number of entries in use */
|
|
||||||
|
|
||||||
JSAMPARRAY colorindex; /* Precomputed mapping for speed */
|
|
||||||
/* colorindex[i][j] = index of color closest to pixel value j in component i,
|
|
||||||
* premultiplied as described above. Since colormap indexes must fit into
|
|
||||||
* JSAMPLEs, the entries of this array will too.
|
|
||||||
*/
|
|
||||||
boolean is_padded; /* is the colorindex padded for odither? */
|
|
||||||
|
|
||||||
int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */
|
|
||||||
|
|
||||||
/* Variables for ordered dithering */
|
|
||||||
int row_index; /* cur row's vertical index in dither matrix */
|
|
||||||
ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */
|
|
||||||
|
|
||||||
/* Variables for Floyd-Steinberg dithering */
|
|
||||||
FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */
|
|
||||||
boolean on_odd_row; /* flag to remember which row we are on */
|
|
||||||
} my_cquantizer;
|
|
||||||
|
|
||||||
typedef my_cquantizer * my_cquantize_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Policy-making subroutines for create_colormap and create_colorindex.
|
|
||||||
* These routines determine the colormap to be used. The rest of the module
|
|
||||||
* only assumes that the colormap is orthogonal.
|
|
||||||
*
|
|
||||||
* * select_ncolors decides how to divvy up the available colors
|
|
||||||
* among the components.
|
|
||||||
* * output_value defines the set of representative values for a component.
|
|
||||||
* * largest_input_value defines the mapping from input values to
|
|
||||||
* representative values for a component.
|
|
||||||
* Note that the latter two routines may impose different policies for
|
|
||||||
* different components, though this is not currently done.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(int)
|
|
||||||
select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
|
|
||||||
/* Determine allocation of desired colors to components, */
|
|
||||||
/* and fill in Ncolors[] array to indicate choice. */
|
|
||||||
/* Return value is total number of colors (product of Ncolors[] values). */
|
|
||||||
{
|
|
||||||
int nc = cinfo->out_color_components; /* number of color components */
|
|
||||||
int max_colors = cinfo->desired_number_of_colors;
|
|
||||||
int total_colors, iroot, i, j;
|
|
||||||
boolean changed;
|
|
||||||
long temp;
|
|
||||||
static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
|
|
||||||
|
|
||||||
/* We can allocate at least the nc'th root of max_colors per component. */
|
|
||||||
/* Compute floor(nc'th root of max_colors). */
|
|
||||||
iroot = 1;
|
|
||||||
do {
|
|
||||||
iroot++;
|
|
||||||
temp = iroot; /* set temp = iroot ** nc */
|
|
||||||
for (i = 1; i < nc; i++)
|
|
||||||
temp *= iroot;
|
|
||||||
} while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
|
|
||||||
iroot--; /* now iroot = floor(root) */
|
|
||||||
|
|
||||||
/* Must have at least 2 color values per component */
|
|
||||||
if (iroot < 2)
|
|
||||||
ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp);
|
|
||||||
|
|
||||||
/* Initialize to iroot color values for each component */
|
|
||||||
total_colors = 1;
|
|
||||||
for (i = 0; i < nc; i++) {
|
|
||||||
Ncolors[i] = iroot;
|
|
||||||
total_colors *= iroot;
|
|
||||||
}
|
|
||||||
/* We may be able to increment the count for one or more components without
|
|
||||||
* exceeding max_colors, though we know not all can be incremented.
|
|
||||||
* Sometimes, the first component can be incremented more than once!
|
|
||||||
* (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
|
|
||||||
* In RGB colorspace, try to increment G first, then R, then B.
|
|
||||||
*/
|
|
||||||
do {
|
|
||||||
changed = FALSE;
|
|
||||||
for (i = 0; i < nc; i++) {
|
|
||||||
j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
|
|
||||||
/* calculate new total_colors if Ncolors[j] is incremented */
|
|
||||||
temp = total_colors / Ncolors[j];
|
|
||||||
temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */
|
|
||||||
if (temp > (long) max_colors)
|
|
||||||
break; /* won't fit, done with this pass */
|
|
||||||
Ncolors[j]++; /* OK, apply the increment */
|
|
||||||
total_colors = (int) temp;
|
|
||||||
changed = TRUE;
|
|
||||||
}
|
|
||||||
} while (changed);
|
|
||||||
|
|
||||||
return total_colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(int)
|
|
||||||
output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
|
|
||||||
/* Return j'th output value, where j will range from 0 to maxj */
|
|
||||||
/* The output values must fall in 0..MAXJSAMPLE in increasing order */
|
|
||||||
{
|
|
||||||
/* We always provide values 0 and MAXJSAMPLE for each component;
|
|
||||||
* any additional values are equally spaced between these limits.
|
|
||||||
* (Forcing the upper and lower values to the limits ensures that
|
|
||||||
* dithering can't produce a color outside the selected gamut.)
|
|
||||||
*/
|
|
||||||
return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOCAL(int)
|
|
||||||
largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
|
|
||||||
/* Return largest input value that should map to j'th output value */
|
|
||||||
/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
|
|
||||||
{
|
|
||||||
/* Breakpoints are halfway between values returned by output_value */
|
|
||||||
return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the colormap.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
create_colormap (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
JSAMPARRAY colormap; /* Created colormap */
|
|
||||||
int total_colors; /* Number of distinct output colors */
|
|
||||||
int i,j,k, nci, blksize, blkdist, ptr, val;
|
|
||||||
|
|
||||||
/* Select number of colors for each component */
|
|
||||||
total_colors = select_ncolors(cinfo, cquantize->Ncolors);
|
|
||||||
|
|
||||||
/* Report selected color counts */
|
|
||||||
if (cinfo->out_color_components == 3)
|
|
||||||
TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS,
|
|
||||||
total_colors, cquantize->Ncolors[0],
|
|
||||||
cquantize->Ncolors[1], cquantize->Ncolors[2]);
|
|
||||||
else
|
|
||||||
TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors);
|
|
||||||
|
|
||||||
/* Allocate and fill in the colormap. */
|
|
||||||
/* The colors are ordered in the map in standard row-major order, */
|
|
||||||
/* i.e. rightmost (highest-indexed) color changes most rapidly. */
|
|
||||||
|
|
||||||
colormap = (*cinfo->mem->alloc_sarray)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
|
|
||||||
|
|
||||||
/* blksize is number of adjacent repeated entries for a component */
|
|
||||||
/* blkdist is distance between groups of identical entries for a component */
|
|
||||||
blkdist = total_colors;
|
|
||||||
|
|
||||||
for (i = 0; i < cinfo->out_color_components; i++) {
|
|
||||||
/* fill in colormap entries for i'th color component */
|
|
||||||
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
|
|
||||||
blksize = blkdist / nci;
|
|
||||||
for (j = 0; j < nci; j++) {
|
|
||||||
/* Compute j'th output value (out of nci) for component */
|
|
||||||
val = output_value(cinfo, i, j, nci-1);
|
|
||||||
/* Fill in all colormap entries that have this value of this component */
|
|
||||||
for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
|
|
||||||
/* fill in blksize entries beginning at ptr */
|
|
||||||
for (k = 0; k < blksize; k++)
|
|
||||||
colormap[i][ptr+k] = (JSAMPLE) val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
blkdist = blksize; /* blksize of this color is blkdist of next */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save the colormap in private storage,
|
|
||||||
* where it will survive color quantization mode changes.
|
|
||||||
*/
|
|
||||||
cquantize->sv_colormap = colormap;
|
|
||||||
cquantize->sv_actual = total_colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the color index table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
create_colorindex (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
JSAMPROW indexptr;
|
|
||||||
int i,j,k, nci, blksize, val, pad;
|
|
||||||
|
|
||||||
/* For ordered dither, we pad the color index tables by MAXJSAMPLE in
|
|
||||||
* each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
|
|
||||||
* This is not necessary in the other dithering modes. However, we
|
|
||||||
* flag whether it was done in case user changes dithering mode.
|
|
||||||
*/
|
|
||||||
if (cinfo->dither_mode == JDITHER_ORDERED) {
|
|
||||||
pad = MAXJSAMPLE*2;
|
|
||||||
cquantize->is_padded = TRUE;
|
|
||||||
} else {
|
|
||||||
pad = 0;
|
|
||||||
cquantize->is_padded = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cquantize->colorindex = (*cinfo->mem->alloc_sarray)
|
|
||||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
(JDIMENSION) (MAXJSAMPLE+1 + pad),
|
|
||||||
(JDIMENSION) cinfo->out_color_components);
|
|
||||||
|
|
||||||
/* blksize is number of adjacent repeated entries for a component */
|
|
||||||
blksize = cquantize->sv_actual;
|
|
||||||
|
|
||||||
for (i = 0; i < cinfo->out_color_components; i++) {
|
|
||||||
/* fill in colorindex entries for i'th color component */
|
|
||||||
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
|
|
||||||
blksize = blksize / nci;
|
|
||||||
|
|
||||||
/* adjust colorindex pointers to provide padding at negative indexes. */
|
|
||||||
if (pad)
|
|
||||||
cquantize->colorindex[i] += MAXJSAMPLE;
|
|
||||||
|
|
||||||
/* in loop, val = index of current output value, */
|
|
||||||
/* and k = largest j that maps to current val */
|
|
||||||
indexptr = cquantize->colorindex[i];
|
|
||||||
val = 0;
|
|
||||||
k = largest_input_value(cinfo, i, 0, nci-1);
|
|
||||||
for (j = 0; j <= MAXJSAMPLE; j++) {
|
|
||||||
while (j > k) /* advance val if past boundary */
|
|
||||||
k = largest_input_value(cinfo, i, ++val, nci-1);
|
|
||||||
/* premultiply so that no multiplication needed in main processing */
|
|
||||||
indexptr[j] = (JSAMPLE) (val * blksize);
|
|
||||||
}
|
|
||||||
/* Pad at both ends if necessary */
|
|
||||||
if (pad)
|
|
||||||
for (j = 1; j <= MAXJSAMPLE; j++) {
|
|
||||||
indexptr[-j] = indexptr[0];
|
|
||||||
indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create an ordered-dither array for a component having ncolors
|
|
||||||
* distinct output values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(ODITHER_MATRIX_PTR)
|
|
||||||
make_odither_array (j_decompress_ptr cinfo, int ncolors)
|
|
||||||
{
|
|
||||||
ODITHER_MATRIX_PTR odither;
|
|
||||||
int j,k;
|
|
||||||
INT32 num,den;
|
|
||||||
|
|
||||||
odither = (ODITHER_MATRIX_PTR)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(ODITHER_MATRIX));
|
|
||||||
/* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
|
|
||||||
* Hence the dither value for the matrix cell with fill order f
|
|
||||||
* (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
|
|
||||||
* On 16-bit-int machine, be careful to avoid overflow.
|
|
||||||
*/
|
|
||||||
den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
|
|
||||||
for (j = 0; j < ODITHER_SIZE; j++) {
|
|
||||||
for (k = 0; k < ODITHER_SIZE; k++) {
|
|
||||||
num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
|
|
||||||
* MAXJSAMPLE;
|
|
||||||
/* Ensure round towards zero despite C's lack of consistency
|
|
||||||
* about rounding negative values in integer division...
|
|
||||||
*/
|
|
||||||
odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return odither;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the ordered-dither tables.
|
|
||||||
* Components having the same number of representative colors may
|
|
||||||
* share a dither table.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
create_odither_tables (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
ODITHER_MATRIX_PTR odither;
|
|
||||||
int i, j, nci;
|
|
||||||
|
|
||||||
for (i = 0; i < cinfo->out_color_components; i++) {
|
|
||||||
nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
|
|
||||||
odither = NULL; /* search for matching prior component */
|
|
||||||
for (j = 0; j < i; j++) {
|
|
||||||
if (nci == cquantize->Ncolors[j]) {
|
|
||||||
odither = cquantize->odither[j];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (odither == NULL) /* need a new table? */
|
|
||||||
odither = make_odither_array(cinfo, nci);
|
|
||||||
cquantize->odither[i] = odither;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map some rows of pixels to the output colormapped representation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
/* General case, no dithering */
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
JSAMPARRAY colorindex = cquantize->colorindex;
|
|
||||||
register int pixcode, ci;
|
|
||||||
register JSAMPROW ptrin, ptrout;
|
|
||||||
int row;
|
|
||||||
JDIMENSION col;
|
|
||||||
JDIMENSION width = cinfo->output_width;
|
|
||||||
register int nc = cinfo->out_color_components;
|
|
||||||
|
|
||||||
for (row = 0; row < num_rows; row++) {
|
|
||||||
ptrin = input_buf[row];
|
|
||||||
ptrout = output_buf[row];
|
|
||||||
for (col = width; col > 0; col--) {
|
|
||||||
pixcode = 0;
|
|
||||||
for (ci = 0; ci < nc; ci++) {
|
|
||||||
pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
|
|
||||||
}
|
|
||||||
*ptrout++ = (JSAMPLE) pixcode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
/* Fast path for out_color_components==3, no dithering */
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
register int pixcode;
|
|
||||||
register JSAMPROW ptrin, ptrout;
|
|
||||||
JSAMPROW colorindex0 = cquantize->colorindex[0];
|
|
||||||
JSAMPROW colorindex1 = cquantize->colorindex[1];
|
|
||||||
JSAMPROW colorindex2 = cquantize->colorindex[2];
|
|
||||||
int row;
|
|
||||||
JDIMENSION col;
|
|
||||||
JDIMENSION width = cinfo->output_width;
|
|
||||||
|
|
||||||
for (row = 0; row < num_rows; row++) {
|
|
||||||
ptrin = input_buf[row];
|
|
||||||
ptrout = output_buf[row];
|
|
||||||
for (col = width; col > 0; col--) {
|
|
||||||
pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
|
|
||||||
pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
|
|
||||||
pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
|
|
||||||
*ptrout++ = (JSAMPLE) pixcode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
/* General case, with ordered dithering */
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
register JSAMPROW input_ptr;
|
|
||||||
register JSAMPROW output_ptr;
|
|
||||||
JSAMPROW colorindex_ci;
|
|
||||||
int * dither; /* points to active row of dither matrix */
|
|
||||||
int row_index, col_index; /* current indexes into dither matrix */
|
|
||||||
int nc = cinfo->out_color_components;
|
|
||||||
int ci;
|
|
||||||
int row;
|
|
||||||
JDIMENSION col;
|
|
||||||
JDIMENSION width = cinfo->output_width;
|
|
||||||
|
|
||||||
for (row = 0; row < num_rows; row++) {
|
|
||||||
/* Initialize output values to 0 so can process components separately */
|
|
||||||
FMEMZERO((void FAR *) output_buf[row],
|
|
||||||
(size_t) (width * SIZEOF(JSAMPLE)));
|
|
||||||
row_index = cquantize->row_index;
|
|
||||||
for (ci = 0; ci < nc; ci++) {
|
|
||||||
input_ptr = input_buf[row] + ci;
|
|
||||||
output_ptr = output_buf[row];
|
|
||||||
colorindex_ci = cquantize->colorindex[ci];
|
|
||||||
dither = cquantize->odither[ci][row_index];
|
|
||||||
col_index = 0;
|
|
||||||
|
|
||||||
for (col = width; col > 0; col--) {
|
|
||||||
/* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
|
|
||||||
* select output value, accumulate into output code for this pixel.
|
|
||||||
* Range-limiting need not be done explicitly, as we have extended
|
|
||||||
* the colorindex table to produce the right answers for out-of-range
|
|
||||||
* inputs. The maximum dither is +- MAXJSAMPLE; this sets the
|
|
||||||
* required amount of padding.
|
|
||||||
*/
|
|
||||||
*output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
|
|
||||||
input_ptr += nc;
|
|
||||||
output_ptr++;
|
|
||||||
col_index = (col_index + 1) & ODITHER_MASK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Advance row index for next row */
|
|
||||||
row_index = (row_index + 1) & ODITHER_MASK;
|
|
||||||
cquantize->row_index = row_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
/* Fast path for out_color_components==3, with ordered dithering */
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
register int pixcode;
|
|
||||||
register JSAMPROW input_ptr;
|
|
||||||
register JSAMPROW output_ptr;
|
|
||||||
JSAMPROW colorindex0 = cquantize->colorindex[0];
|
|
||||||
JSAMPROW colorindex1 = cquantize->colorindex[1];
|
|
||||||
JSAMPROW colorindex2 = cquantize->colorindex[2];
|
|
||||||
int * dither0; /* points to active row of dither matrix */
|
|
||||||
int * dither1;
|
|
||||||
int * dither2;
|
|
||||||
int row_index, col_index; /* current indexes into dither matrix */
|
|
||||||
int row;
|
|
||||||
JDIMENSION col;
|
|
||||||
JDIMENSION width = cinfo->output_width;
|
|
||||||
|
|
||||||
for (row = 0; row < num_rows; row++) {
|
|
||||||
row_index = cquantize->row_index;
|
|
||||||
input_ptr = input_buf[row];
|
|
||||||
output_ptr = output_buf[row];
|
|
||||||
dither0 = cquantize->odither[0][row_index];
|
|
||||||
dither1 = cquantize->odither[1][row_index];
|
|
||||||
dither2 = cquantize->odither[2][row_index];
|
|
||||||
col_index = 0;
|
|
||||||
|
|
||||||
for (col = width; col > 0; col--) {
|
|
||||||
pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) +
|
|
||||||
dither0[col_index]]);
|
|
||||||
pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) +
|
|
||||||
dither1[col_index]]);
|
|
||||||
pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) +
|
|
||||||
dither2[col_index]]);
|
|
||||||
*output_ptr++ = (JSAMPLE) pixcode;
|
|
||||||
col_index = (col_index + 1) & ODITHER_MASK;
|
|
||||||
}
|
|
||||||
row_index = (row_index + 1) & ODITHER_MASK;
|
|
||||||
cquantize->row_index = row_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
|
|
||||||
JSAMPARRAY output_buf, int num_rows)
|
|
||||||
/* General case, with Floyd-Steinberg dithering */
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
register LOCFSERROR cur; /* current error or pixel value */
|
|
||||||
LOCFSERROR belowerr; /* error for pixel below cur */
|
|
||||||
LOCFSERROR bpreverr; /* error for below/prev col */
|
|
||||||
LOCFSERROR bnexterr; /* error for below/next col */
|
|
||||||
LOCFSERROR delta;
|
|
||||||
register FSERRPTR errorptr; /* => fserrors[] at column before current */
|
|
||||||
register JSAMPROW input_ptr;
|
|
||||||
register JSAMPROW output_ptr;
|
|
||||||
JSAMPROW colorindex_ci;
|
|
||||||
JSAMPROW colormap_ci;
|
|
||||||
int pixcode;
|
|
||||||
int nc = cinfo->out_color_components;
|
|
||||||
int dir; /* 1 for left-to-right, -1 for right-to-left */
|
|
||||||
int dirnc; /* dir * nc */
|
|
||||||
int ci;
|
|
||||||
int row;
|
|
||||||
JDIMENSION col;
|
|
||||||
JDIMENSION width = cinfo->output_width;
|
|
||||||
JSAMPLE *range_limit = cinfo->sample_range_limit;
|
|
||||||
SHIFT_TEMPS
|
|
||||||
|
|
||||||
for (row = 0; row < num_rows; row++) {
|
|
||||||
/* Initialize output values to 0 so can process components separately */
|
|
||||||
FMEMZERO((void FAR *) output_buf[row],
|
|
||||||
(size_t) (width * SIZEOF(JSAMPLE)));
|
|
||||||
for (ci = 0; ci < nc; ci++) {
|
|
||||||
input_ptr = input_buf[row] + ci;
|
|
||||||
output_ptr = output_buf[row];
|
|
||||||
if (cquantize->on_odd_row) {
|
|
||||||
/* work right to left in this row */
|
|
||||||
input_ptr += (width-1) * nc; /* so point to rightmost pixel */
|
|
||||||
output_ptr += width-1;
|
|
||||||
dir = -1;
|
|
||||||
dirnc = -nc;
|
|
||||||
errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
|
|
||||||
} else {
|
|
||||||
/* work left to right in this row */
|
|
||||||
dir = 1;
|
|
||||||
dirnc = nc;
|
|
||||||
errorptr = cquantize->fserrors[ci]; /* => entry before first column */
|
|
||||||
}
|
|
||||||
colorindex_ci = cquantize->colorindex[ci];
|
|
||||||
colormap_ci = cquantize->sv_colormap[ci];
|
|
||||||
/* Preset error values: no error propagated to first pixel from left */
|
|
||||||
cur = 0;
|
|
||||||
/* and no error propagated to row below yet */
|
|
||||||
belowerr = bpreverr = 0;
|
|
||||||
|
|
||||||
for (col = width; col > 0; col--) {
|
|
||||||
/* cur holds the error propagated from the previous pixel on the
|
|
||||||
* current line. Add the error propagated from the previous line
|
|
||||||
* to form the complete error correction term for this pixel, and
|
|
||||||
* round the error term (which is expressed * 16) to an integer.
|
|
||||||
* RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
|
|
||||||
* for either sign of the error value.
|
|
||||||
* Note: errorptr points to *previous* column's array entry.
|
|
||||||
*/
|
|
||||||
cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
|
|
||||||
/* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
|
|
||||||
* The maximum error is +- MAXJSAMPLE; this sets the required size
|
|
||||||
* of the range_limit array.
|
|
||||||
*/
|
|
||||||
cur += GETJSAMPLE(*input_ptr);
|
|
||||||
cur = GETJSAMPLE(range_limit[cur]);
|
|
||||||
/* Select output value, accumulate into output code for this pixel */
|
|
||||||
pixcode = GETJSAMPLE(colorindex_ci[cur]);
|
|
||||||
*output_ptr += (JSAMPLE) pixcode;
|
|
||||||
/* Compute actual representation error at this pixel */
|
|
||||||
/* Note: we can do this even though we don't have the final */
|
|
||||||
/* pixel code, because the colormap is orthogonal. */
|
|
||||||
cur -= GETJSAMPLE(colormap_ci[pixcode]);
|
|
||||||
/* Compute error fractions to be propagated to adjacent pixels.
|
|
||||||
* Add these into the running sums, and simultaneously shift the
|
|
||||||
* next-line error sums left by 1 column.
|
|
||||||
*/
|
|
||||||
bnexterr = cur;
|
|
||||||
delta = cur * 2;
|
|
||||||
cur += delta; /* form error * 3 */
|
|
||||||
errorptr[0] = (FSERROR) (bpreverr + cur);
|
|
||||||
cur += delta; /* form error * 5 */
|
|
||||||
bpreverr = belowerr + cur;
|
|
||||||
belowerr = bnexterr;
|
|
||||||
cur += delta; /* form error * 7 */
|
|
||||||
/* At this point cur contains the 7/16 error value to be propagated
|
|
||||||
* to the next pixel on the current line, and all the errors for the
|
|
||||||
* next line have been shifted over. We are therefore ready to move on.
|
|
||||||
*/
|
|
||||||
input_ptr += dirnc; /* advance input ptr to next column */
|
|
||||||
output_ptr += dir; /* advance output ptr to next column */
|
|
||||||
errorptr += dir; /* advance errorptr to current column */
|
|
||||||
}
|
|
||||||
/* Post-loop cleanup: we must unload the final error value into the
|
|
||||||
* final fserrors[] entry. Note we need not unload belowerr because
|
|
||||||
* it is for the dummy column before or after the actual array.
|
|
||||||
*/
|
|
||||||
errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
|
|
||||||
}
|
|
||||||
cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate workspace for Floyd-Steinberg errors.
|
|
||||||
*/
|
|
||||||
|
|
||||||
LOCAL(void)
|
|
||||||
alloc_fs_workspace (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
size_t arraysize;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
|
|
||||||
for (i = 0; i < cinfo->out_color_components; i++) {
|
|
||||||
cquantize->fserrors[i] = (FSERRPTR)
|
|
||||||
(*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize for one-pass color quantization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
|
|
||||||
size_t arraysize;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Install my colormap. */
|
|
||||||
cinfo->colormap = cquantize->sv_colormap;
|
|
||||||
cinfo->actual_number_of_colors = cquantize->sv_actual;
|
|
||||||
|
|
||||||
/* Initialize for desired dithering mode. */
|
|
||||||
switch (cinfo->dither_mode) {
|
|
||||||
case JDITHER_NONE:
|
|
||||||
if (cinfo->out_color_components == 3)
|
|
||||||
cquantize->pub.color_quantize = color_quantize3;
|
|
||||||
else
|
|
||||||
cquantize->pub.color_quantize = color_quantize;
|
|
||||||
break;
|
|
||||||
case JDITHER_ORDERED:
|
|
||||||
if (cinfo->out_color_components == 3)
|
|
||||||
cquantize->pub.color_quantize = quantize3_ord_dither;
|
|
||||||
else
|
|
||||||
cquantize->pub.color_quantize = quantize_ord_dither;
|
|
||||||
cquantize->row_index = 0; /* initialize state for ordered dither */
|
|
||||||
/* If user changed to ordered dither from another mode,
|
|
||||||
* we must recreate the color index table with padding.
|
|
||||||
* This will cost extra space, but probably isn't very likely.
|
|
||||||
*/
|
|
||||||
if (! cquantize->is_padded)
|
|
||||||
create_colorindex(cinfo);
|
|
||||||
/* Create ordered-dither tables if we didn't already. */
|
|
||||||
if (cquantize->odither[0] == NULL)
|
|
||||||
create_odither_tables(cinfo);
|
|
||||||
break;
|
|
||||||
case JDITHER_FS:
|
|
||||||
cquantize->pub.color_quantize = quantize_fs_dither;
|
|
||||||
cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
|
|
||||||
/* Allocate Floyd-Steinberg workspace if didn't already. */
|
|
||||||
if (cquantize->fserrors[0] == NULL)
|
|
||||||
alloc_fs_workspace(cinfo);
|
|
||||||
/* Initialize the propagated errors to zero. */
|
|
||||||
arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
|
|
||||||
for (i = 0; i < cinfo->out_color_components; i++)
|
|
||||||
FMEMZERO((void FAR *) cquantize->fserrors[i], arraysize);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish up at the end of the pass.
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
finish_pass_1_quant (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
/* no work in 1-pass case */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch to a new external colormap between output passes.
|
|
||||||
* Shouldn't get to this module!
|
|
||||||
*/
|
|
||||||
|
|
||||||
METHODDEF(void)
|
|
||||||
new_color_map_1_quant (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
ERREXIT(cinfo, JERR_MODE_CHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Module initialization routine for 1-pass color quantization.
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jinit_1pass_quantizer (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_cquantize_ptr cquantize;
|
|
||||||
|
|
||||||
cquantize = (my_cquantize_ptr)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
SIZEOF(my_cquantizer));
|
|
||||||
cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
|
|
||||||
cquantize->pub.start_pass = start_pass_1_quant;
|
|
||||||
cquantize->pub.finish_pass = finish_pass_1_quant;
|
|
||||||
cquantize->pub.new_color_map = new_color_map_1_quant;
|
|
||||||
cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
|
|
||||||
cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */
|
|
||||||
|
|
||||||
/* Make sure my internal arrays won't overflow */
|
|
||||||
if (cinfo->out_color_components > MAX_Q_COMPS)
|
|
||||||
ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS);
|
|
||||||
/* Make sure colormap indexes can be represented by JSAMPLEs */
|
|
||||||
if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
|
|
||||||
ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1);
|
|
||||||
|
|
||||||
/* Create the colormap and color index table. */
|
|
||||||
create_colormap(cinfo);
|
|
||||||
create_colorindex(cinfo);
|
|
||||||
|
|
||||||
/* Allocate Floyd-Steinberg workspace now if requested.
|
|
||||||
* We do this now since it is FAR storage and may affect the memory
|
|
||||||
* manager's space calculations. If the user changes to FS dither
|
|
||||||
* mode in a later pass, we will allocate the space then, and will
|
|
||||||
* possibly overrun the max_memory_to_use setting.
|
|
||||||
*/
|
|
||||||
if (cinfo->dither_mode == JDITHER_FS)
|
|
||||||
alloc_fs_workspace(cinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* QUANT_1PASS_SUPPORTED */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,227 +0,0 @@
|
||||||
/*
|
|
||||||
* jutils.c
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
|
||||||
* Modified 2009-2011 by Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains tables and miscellaneous utility routines needed
|
|
||||||
* for both compression and decompression.
|
|
||||||
* Note we prefix all global names with "j" to minimize conflicts with
|
|
||||||
* a surrounding application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JPEG_INTERNALS
|
|
||||||
#include "jinclude.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
|
|
||||||
* of a DCT block read in natural order (left to right, top to bottom).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if 0 /* This table is not actually needed in v6a */
|
|
||||||
|
|
||||||
const int jpeg_zigzag_order[DCTSIZE2] = {
|
|
||||||
0, 1, 5, 6, 14, 15, 27, 28,
|
|
||||||
2, 4, 7, 13, 16, 26, 29, 42,
|
|
||||||
3, 8, 12, 17, 25, 30, 41, 43,
|
|
||||||
9, 11, 18, 24, 31, 40, 44, 53,
|
|
||||||
10, 19, 23, 32, 39, 45, 52, 54,
|
|
||||||
20, 22, 33, 38, 46, 51, 55, 60,
|
|
||||||
21, 34, 37, 47, 50, 56, 59, 61,
|
|
||||||
35, 36, 48, 49, 57, 58, 62, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* jpeg_natural_order[i] is the natural-order position of the i'th element
|
|
||||||
* of zigzag order.
|
|
||||||
*
|
|
||||||
* When reading corrupted data, the Huffman decoders could attempt
|
|
||||||
* to reference an entry beyond the end of this array (if the decoded
|
|
||||||
* zero run length reaches past the end of the block). To prevent
|
|
||||||
* wild stores without adding an inner-loop test, we put some extra
|
|
||||||
* "63"s after the real entries. This will cause the extra coefficient
|
|
||||||
* to be stored in location 63 of the block, not somewhere random.
|
|
||||||
* The worst case would be a run-length of 15, which means we need 16
|
|
||||||
* fake entries.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const int jpeg_natural_order[DCTSIZE2+16] = {
|
|
||||||
0, 1, 8, 16, 9, 2, 3, 10,
|
|
||||||
17, 24, 32, 25, 18, 11, 4, 5,
|
|
||||||
12, 19, 26, 33, 40, 48, 41, 34,
|
|
||||||
27, 20, 13, 6, 7, 14, 21, 28,
|
|
||||||
35, 42, 49, 56, 57, 50, 43, 36,
|
|
||||||
29, 22, 15, 23, 30, 37, 44, 51,
|
|
||||||
58, 59, 52, 45, 38, 31, 39, 46,
|
|
||||||
53, 60, 61, 54, 47, 55, 62, 63,
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
const int jpeg_natural_order7[7*7+16] = {
|
|
||||||
0, 1, 8, 16, 9, 2, 3, 10,
|
|
||||||
17, 24, 32, 25, 18, 11, 4, 5,
|
|
||||||
12, 19, 26, 33, 40, 48, 41, 34,
|
|
||||||
27, 20, 13, 6, 14, 21, 28, 35,
|
|
||||||
42, 49, 50, 43, 36, 29, 22, 30,
|
|
||||||
37, 44, 51, 52, 45, 38, 46, 53,
|
|
||||||
54,
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
const int jpeg_natural_order6[6*6+16] = {
|
|
||||||
0, 1, 8, 16, 9, 2, 3, 10,
|
|
||||||
17, 24, 32, 25, 18, 11, 4, 5,
|
|
||||||
12, 19, 26, 33, 40, 41, 34, 27,
|
|
||||||
20, 13, 21, 28, 35, 42, 43, 36,
|
|
||||||
29, 37, 44, 45,
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
const int jpeg_natural_order5[5*5+16] = {
|
|
||||||
0, 1, 8, 16, 9, 2, 3, 10,
|
|
||||||
17, 24, 32, 25, 18, 11, 4, 12,
|
|
||||||
19, 26, 33, 34, 27, 20, 28, 35,
|
|
||||||
36,
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
const int jpeg_natural_order4[4*4+16] = {
|
|
||||||
0, 1, 8, 16, 9, 2, 3, 10,
|
|
||||||
17, 24, 25, 18, 11, 19, 26, 27,
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
const int jpeg_natural_order3[3*3+16] = {
|
|
||||||
0, 1, 8, 16, 9, 2, 10, 17,
|
|
||||||
18,
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
const int jpeg_natural_order2[2*2+16] = {
|
|
||||||
0, 1, 8, 9,
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
|
|
||||||
63, 63, 63, 63, 63, 63, 63, 63
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Arithmetic utilities
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLOBAL(long)
|
|
||||||
jdiv_round_up (long a, long b)
|
|
||||||
/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
|
|
||||||
/* Assumes a >= 0, b > 0 */
|
|
||||||
{
|
|
||||||
return (a + b - 1L) / b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLOBAL(long)
|
|
||||||
jround_up (long a, long b)
|
|
||||||
/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
|
|
||||||
/* Assumes a >= 0, b > 0 */
|
|
||||||
{
|
|
||||||
a += b - 1L;
|
|
||||||
return a - (a % b);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
|
|
||||||
* and coefficient-block arrays. This won't work on 80x86 because the arrays
|
|
||||||
* are FAR and we're assuming a small-pointer memory model. However, some
|
|
||||||
* DOS compilers provide far-pointer versions of memcpy() and memset() even
|
|
||||||
* in the small-model libraries. These will be used if USE_FMEM is defined.
|
|
||||||
* Otherwise, the routines below do it the hard way. (The performance cost
|
|
||||||
* is not all that great, because these routines aren't very heavily used.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */
|
|
||||||
#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
|
|
||||||
#else /* 80x86 case, define if we can */
|
|
||||||
#ifdef USE_FMEM
|
|
||||||
#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
|
|
||||||
#else
|
|
||||||
/* This function is for use by the FMEMZERO macro defined in jpegint.h.
|
|
||||||
* Do not call this function directly, use the FMEMZERO macro instead.
|
|
||||||
*/
|
|
||||||
GLOBAL(void)
|
|
||||||
jzero_far (void FAR * target, size_t bytestozero)
|
|
||||||
/* Zero out a chunk of FAR memory. */
|
|
||||||
/* This might be sample-array data, block-array data, or alloc_large data. */
|
|
||||||
{
|
|
||||||
register char FAR * ptr = (char FAR *) target;
|
|
||||||
register size_t count;
|
|
||||||
|
|
||||||
for (count = bytestozero; count > 0; count--) {
|
|
||||||
*ptr++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
|
|
||||||
JSAMPARRAY output_array, int dest_row,
|
|
||||||
int num_rows, JDIMENSION num_cols)
|
|
||||||
/* Copy some rows of samples from one place to another.
|
|
||||||
* num_rows rows are copied from input_array[source_row++]
|
|
||||||
* to output_array[dest_row++]; these areas may overlap for duplication.
|
|
||||||
* The source and destination arrays must be at least as wide as num_cols.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
register JSAMPROW inptr, outptr;
|
|
||||||
#ifdef FMEMCOPY
|
|
||||||
register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
|
|
||||||
#else
|
|
||||||
register JDIMENSION count;
|
|
||||||
#endif
|
|
||||||
register int row;
|
|
||||||
|
|
||||||
input_array += source_row;
|
|
||||||
output_array += dest_row;
|
|
||||||
|
|
||||||
for (row = num_rows; row > 0; row--) {
|
|
||||||
inptr = *input_array++;
|
|
||||||
outptr = *output_array++;
|
|
||||||
#ifdef FMEMCOPY
|
|
||||||
FMEMCOPY(outptr, inptr, count);
|
|
||||||
#else
|
|
||||||
for (count = num_cols; count > 0; count--)
|
|
||||||
*outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLOBAL(void)
|
|
||||||
jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
|
|
||||||
JDIMENSION num_blocks)
|
|
||||||
/* Copy a row of coefficient blocks from one place to another. */
|
|
||||||
{
|
|
||||||
#ifdef FMEMCOPY
|
|
||||||
FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
|
|
||||||
#else
|
|
||||||
register JCOEFPTR inptr, outptr;
|
|
||||||
register long count;
|
|
||||||
|
|
||||||
inptr = (JCOEFPTR) input_row;
|
|
||||||
outptr = (JCOEFPTR) output_row;
|
|
||||||
for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
|
|
||||||
*outptr++ = *inptr++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
/*
|
|
||||||
* jversion.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding.
|
|
||||||
* This file is part of the Independent JPEG Group's software.
|
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
|
||||||
*
|
|
||||||
* This file contains software version identification.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define JVERSION "9c 14-Jan-2018"
|
|
||||||
|
|
||||||
#define JCOPYRIGHT "Copyright (C) 2018, Thomas G. Lane, Guido Vollbeding"
|
|
|
@ -319,7 +319,7 @@ add_custom_target( revision_check ALL
|
||||||
|
|
||||||
# required libraries
|
# required libraries
|
||||||
|
|
||||||
set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}")
|
set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}")
|
||||||
if (HAVE_VULKAN)
|
if (HAVE_VULKAN)
|
||||||
list( APPEND PROJECT_LIBRARIES "zvulkan" )
|
list( APPEND PROJECT_LIBRARIES "zvulkan" )
|
||||||
endif()
|
endif()
|
||||||
|
@ -387,7 +387,7 @@ if (TARGET WebP::webp)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}")
|
include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}")
|
||||||
|
|
||||||
if( ${HAVE_VM_JIT} )
|
if( ${HAVE_VM_JIT} )
|
||||||
add_definitions( -DHAVE_VM_JIT )
|
add_definitions( -DHAVE_VM_JIT )
|
||||||
|
@ -1021,7 +1021,6 @@ set (PCH_SOURCES
|
||||||
common/textures/formats/flattexture.cpp
|
common/textures/formats/flattexture.cpp
|
||||||
common/textures/formats/fontchars.cpp
|
common/textures/formats/fontchars.cpp
|
||||||
common/textures/formats/imgztexture.cpp
|
common/textures/formats/imgztexture.cpp
|
||||||
common/textures/formats/jpegtexture.cpp
|
|
||||||
common/textures/formats/md5check.cpp
|
common/textures/formats/md5check.cpp
|
||||||
common/textures/formats/multipatchtexture.cpp
|
common/textures/formats/multipatchtexture.cpp
|
||||||
common/textures/formats/patchtexture.cpp
|
common/textures/formats/patchtexture.cpp
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "gl_renderstate.h"
|
#include "gl_renderstate.h"
|
||||||
#include "gl_samplers.h"
|
#include "gl_samplers.h"
|
||||||
#include "gl_hwtexture.h"
|
#include "gl_hwtexture.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
namespace OpenGLRenderer
|
namespace OpenGLRenderer
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,487 +0,0 @@
|
||||||
/*
|
|
||||||
** jpegtexture.cpp
|
|
||||||
** Texture class for JPEG images
|
|
||||||
**
|
|
||||||
**---------------------------------------------------------------------------
|
|
||||||
** Copyright 2005-2016 Randy Heit
|
|
||||||
** Copyright 2005-2019 Christoph Oelckers
|
|
||||||
** All rights reserved.
|
|
||||||
**
|
|
||||||
** Redistribution and use in source and binary forms, with or without
|
|
||||||
** modification, are permitted provided that the following conditions
|
|
||||||
** are met:
|
|
||||||
**
|
|
||||||
** 1. Redistributions of source code must retain the above copyright
|
|
||||||
** notice, this list of conditions and the following disclaimer.
|
|
||||||
** 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
** notice, this list of conditions and the following disclaimer in the
|
|
||||||
** documentation and/or other materials provided with the distribution.
|
|
||||||
** 3. The name of the author may not be used to endorse or promote products
|
|
||||||
** derived from this software without specific prior written permission.
|
|
||||||
**
|
|
||||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
**---------------------------------------------------------------------------
|
|
||||||
**
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <jpeglib.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "files.h"
|
|
||||||
#include "filesystem.h"
|
|
||||||
#include "printf.h"
|
|
||||||
#include "bitmap.h"
|
|
||||||
#include "imagehelpers.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "m_swap.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct FLumpSourceMgr : public jpeg_source_mgr
|
|
||||||
{
|
|
||||||
FileReader *Lump;
|
|
||||||
JOCTET Buffer[4096];
|
|
||||||
bool StartOfFile;
|
|
||||||
|
|
||||||
FLumpSourceMgr (FileReader *lump, j_decompress_ptr cinfo);
|
|
||||||
static void InitSource (j_decompress_ptr cinfo);
|
|
||||||
static boolean FillInputBuffer (j_decompress_ptr cinfo);
|
|
||||||
static void SkipInputData (j_decompress_ptr cinfo, long num_bytes);
|
|
||||||
static void TermSource (j_decompress_ptr cinfo);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FLumpSourceMgr::InitSource (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
((FLumpSourceMgr *)(cinfo->src))->StartOfFile = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
boolean FLumpSourceMgr::FillInputBuffer (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src);
|
|
||||||
auto nbytes = me->Lump->Read (me->Buffer, sizeof(me->Buffer));
|
|
||||||
|
|
||||||
if (nbytes <= 0)
|
|
||||||
{
|
|
||||||
me->Buffer[0] = (JOCTET)0xFF;
|
|
||||||
me->Buffer[1] = (JOCTET)JPEG_EOI;
|
|
||||||
nbytes = 2;
|
|
||||||
}
|
|
||||||
me->next_input_byte = me->Buffer;
|
|
||||||
me->bytes_in_buffer = nbytes;
|
|
||||||
me->StartOfFile = false;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FLumpSourceMgr::SkipInputData (j_decompress_ptr cinfo, long num_bytes)
|
|
||||||
{
|
|
||||||
FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src);
|
|
||||||
if (num_bytes <= (long)me->bytes_in_buffer)
|
|
||||||
{
|
|
||||||
me->bytes_in_buffer -= num_bytes;
|
|
||||||
me->next_input_byte += num_bytes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
num_bytes -= (long)me->bytes_in_buffer;
|
|
||||||
me->Lump->Seek (num_bytes, FileReader::SeekCur);
|
|
||||||
FillInputBuffer (cinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FLumpSourceMgr::TermSource (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FLumpSourceMgr::FLumpSourceMgr (FileReader *lump, j_decompress_ptr cinfo)
|
|
||||||
: Lump (lump)
|
|
||||||
{
|
|
||||||
cinfo->src = this;
|
|
||||||
init_source = InitSource;
|
|
||||||
fill_input_buffer = FillInputBuffer;
|
|
||||||
skip_input_data = SkipInputData;
|
|
||||||
resync_to_restart = jpeg_resync_to_restart;
|
|
||||||
term_source = TermSource;
|
|
||||||
bytes_in_buffer = 0;
|
|
||||||
next_input_byte = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void JPEG_ErrorExit (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
(*cinfo->err->output_message) (cinfo);
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void JPEG_OutputMessage (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
char buffer[JMSG_LENGTH_MAX];
|
|
||||||
|
|
||||||
(*cinfo->err->format_message) (cinfo, buffer);
|
|
||||||
Printf (TEXTCOLOR_ORANGE "JPEG failure: %s\n", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// A JPEG texture
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
class FJPEGTexture : public FImageSource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FJPEGTexture (int lumpnum, int width, int height);
|
|
||||||
|
|
||||||
int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override;
|
|
||||||
PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FImageSource *JPEGImage_TryCreate(FileReader & data, int lumpnum)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32_t dw;
|
|
||||||
uint16_t w[2];
|
|
||||||
uint8_t b[4];
|
|
||||||
} first4bytes;
|
|
||||||
|
|
||||||
data.Seek(0, FileReader::SeekSet);
|
|
||||||
if (data.Read(&first4bytes, 4) < 4) return NULL;
|
|
||||||
|
|
||||||
if (first4bytes.b[0] != 0xFF || first4bytes.b[1] != 0xD8 || first4bytes.b[2] != 0xFF)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// Find the SOFn marker to extract the image dimensions,
|
|
||||||
// where n is 0, 1, or 2 (other types are unsupported).
|
|
||||||
while ((unsigned)first4bytes.b[3] - 0xC0 >= 3)
|
|
||||||
{
|
|
||||||
if (data.Read (first4bytes.w, 2) != 2)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
data.Seek (BigShort(first4bytes.w[0]) - 2, FileReader::SeekCur);
|
|
||||||
if (data.Read (first4bytes.b + 2, 2) != 2 || first4bytes.b[2] != 0xFF)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.Read (first4bytes.b, 3) != 3)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (BigShort (first4bytes.w[0]) < 5)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (data.Read (first4bytes.b, 4) != 4)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return new FJPEGTexture (lumpnum, BigShort(first4bytes.w[1]), BigShort(first4bytes.w[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height)
|
|
||||||
: FImageSource(lumpnum)
|
|
||||||
{
|
|
||||||
bMasked = false;
|
|
||||||
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion, int frame)
|
|
||||||
{
|
|
||||||
auto lump = fileSystem.OpenFileReader (SourceLump);
|
|
||||||
JSAMPLE *buff = NULL;
|
|
||||||
|
|
||||||
jpeg_decompress_struct cinfo;
|
|
||||||
jpeg_error_mgr jerr;
|
|
||||||
|
|
||||||
PalettedPixels Pixels(Width * Height);
|
|
||||||
memset (Pixels.Data(), 0xBA, Width * Height);
|
|
||||||
|
|
||||||
cinfo.err = jpeg_std_error(&jerr);
|
|
||||||
cinfo.err->output_message = JPEG_OutputMessage;
|
|
||||||
cinfo.err->error_exit = JPEG_ErrorExit;
|
|
||||||
jpeg_create_decompress(&cinfo);
|
|
||||||
|
|
||||||
FLumpSourceMgr sourcemgr(&lump, &cinfo);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
bool doalpha = conversion == luminance;
|
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
|
||||||
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
|
|
||||||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
|
|
||||||
(cinfo.out_color_space == JCS_YCCK && cinfo.num_components == 4) ||
|
|
||||||
(cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) ||
|
|
||||||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
|
|
||||||
{
|
|
||||||
Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
jpeg_start_decompress(&cinfo);
|
|
||||||
|
|
||||||
int y = 0;
|
|
||||||
buff = new uint8_t[cinfo.output_width * cinfo.output_components];
|
|
||||||
|
|
||||||
while (cinfo.output_scanline < cinfo.output_height)
|
|
||||||
{
|
|
||||||
jpeg_read_scanlines(&cinfo, &buff, 1);
|
|
||||||
uint8_t *in = buff;
|
|
||||||
uint8_t *out = Pixels.Data() + y;
|
|
||||||
switch (cinfo.out_color_space)
|
|
||||||
{
|
|
||||||
case JCS_RGB:
|
|
||||||
for (int x = Width; x > 0; --x)
|
|
||||||
{
|
|
||||||
*out = ImageHelpers::RGBToPalette(doalpha, in[0], in[1], in[2]);
|
|
||||||
out += Height;
|
|
||||||
in += 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_GRAYSCALE:
|
|
||||||
{
|
|
||||||
auto remap = ImageHelpers::GetRemap(doalpha, true);
|
|
||||||
for (int x = Width; x > 0; --x)
|
|
||||||
{
|
|
||||||
*out = remap[in[0]];
|
|
||||||
out += Height;
|
|
||||||
in += 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JCS_CMYK:
|
|
||||||
// What are you doing using a CMYK image? :)
|
|
||||||
for (int x = Width; x > 0; --x)
|
|
||||||
{
|
|
||||||
// To be precise, these calculations should use 255, but
|
|
||||||
// 256 is much faster and virtually indistinguishable.
|
|
||||||
int r = in[3] - (((256 - in[0])*in[3]) >> 8);
|
|
||||||
int g = in[3] - (((256 - in[1])*in[3]) >> 8);
|
|
||||||
int b = in[3] - (((256 - in[2])*in[3]) >> 8);
|
|
||||||
*out = ImageHelpers::RGBToPalette(doalpha, r, g, b);
|
|
||||||
out += Height;
|
|
||||||
in += 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_YCbCr:
|
|
||||||
// Probably useless but since I had the formula available...
|
|
||||||
for (int x = Width; x > 0; --x)
|
|
||||||
{
|
|
||||||
double Y = in[0], Cb = in[1], Cr = in[2];
|
|
||||||
int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255);
|
|
||||||
int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255);
|
|
||||||
int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255);
|
|
||||||
*out = ImageHelpers::RGBToPalette(doalpha, r, g, b);
|
|
||||||
out += Height;
|
|
||||||
in += 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_YCCK:
|
|
||||||
// Probably useless but since I had the formula available...
|
|
||||||
for (int x = Width; x > 0; --x)
|
|
||||||
{
|
|
||||||
double Y = in[0], Cb = in[1], Cr = in[2];
|
|
||||||
int K = in[3];
|
|
||||||
int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255);
|
|
||||||
int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255);
|
|
||||||
int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255);
|
|
||||||
r = r - ((r * K) >> 8);
|
|
||||||
g = g - ((g * K) >> 8);
|
|
||||||
b = b - ((b * K) >> 8);
|
|
||||||
*out = ImageHelpers::RGBToPalette(doalpha, r, g, b);
|
|
||||||
out += Height;
|
|
||||||
in += 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// The other colorspaces were considered above and discarded,
|
|
||||||
// but GCC will complain without a default for them here.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (int)
|
|
||||||
{
|
|
||||||
Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str());
|
|
||||||
}
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
if (buff != NULL)
|
|
||||||
{
|
|
||||||
delete[] buff;
|
|
||||||
}
|
|
||||||
return Pixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// FJPEGTexture::CopyPixels
|
|
||||||
//
|
|
||||||
// Preserves the full color information (unlike software mode)
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion, int frame)
|
|
||||||
{
|
|
||||||
PalEntry pe[256];
|
|
||||||
|
|
||||||
auto lump = fileSystem.OpenFileReader (SourceLump);
|
|
||||||
|
|
||||||
jpeg_decompress_struct cinfo;
|
|
||||||
jpeg_error_mgr jerr;
|
|
||||||
|
|
||||||
cinfo.err = jpeg_std_error(&jerr);
|
|
||||||
cinfo.err->output_message = JPEG_OutputMessage;
|
|
||||||
cinfo.err->error_exit = JPEG_ErrorExit;
|
|
||||||
jpeg_create_decompress(&cinfo);
|
|
||||||
|
|
||||||
FLumpSourceMgr sourcemgr(&lump, &cinfo);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
jpeg_read_header(&cinfo, TRUE);
|
|
||||||
|
|
||||||
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
|
|
||||||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
|
|
||||||
(cinfo.out_color_space == JCS_YCCK && cinfo.num_components == 4) ||
|
|
||||||
(cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) ||
|
|
||||||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
|
|
||||||
{
|
|
||||||
Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
jpeg_start_decompress(&cinfo);
|
|
||||||
|
|
||||||
int yc = 0;
|
|
||||||
TArray<uint8_t> buff(cinfo.output_height * cinfo.output_width * cinfo.output_components, true);
|
|
||||||
|
|
||||||
while (cinfo.output_scanline < cinfo.output_height)
|
|
||||||
{
|
|
||||||
uint8_t * ptr = buff.Data() + cinfo.output_width * cinfo.output_components * yc;
|
|
||||||
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
|
||||||
yc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (cinfo.out_color_space)
|
|
||||||
{
|
|
||||||
case JCS_RGB:
|
|
||||||
bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height,
|
|
||||||
3, cinfo.output_width * cinfo.output_components, 0, CF_RGB);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_GRAYSCALE:
|
|
||||||
for (int i = 0; i < 256; i++) pe[i] = PalEntry(255, i, i, i); // default to a gray map
|
|
||||||
bmp->CopyPixelData(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height,
|
|
||||||
1, cinfo.output_width, 0, pe);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_CMYK:
|
|
||||||
bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height,
|
|
||||||
4, cinfo.output_width * cinfo.output_components, 0, CF_CMYK);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_YCCK:
|
|
||||||
bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height,
|
|
||||||
4, cinfo.output_width * cinfo.output_components, 0, CF_YCCK);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JCS_YCbCr:
|
|
||||||
bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height,
|
|
||||||
4, cinfo.output_width * cinfo.output_components, 0, CF_YCbCr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (int)
|
|
||||||
{
|
|
||||||
Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str());
|
|
||||||
}
|
|
||||||
jpeg_destroy_decompress(&cinfo);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -36,9 +36,8 @@
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#define STBI_NO_STDIO
|
#define STBI_NO_STDIO
|
||||||
// Undefine formats we do not want to support here.
|
// Undefine formats we do not want to support here.
|
||||||
#define STBI_NO_JPEG
|
|
||||||
//#define STBI_NO_PNG we need PNG for 16 bit channel images. Regular ones still use our own, more flexible decoder.
|
//#define STBI_NO_PNG we need PNG for 16 bit channel images. Regular ones still use our own, more flexible decoder.
|
||||||
#define STBI_NO_TGA
|
#define STBI_NO_TGA // we could use that but our own loader has better palette support.
|
||||||
#define STBI_NO_PSD
|
#define STBI_NO_PSD
|
||||||
#define STBI_NO_HDR
|
#define STBI_NO_HDR
|
||||||
#define STBI_NO_PNM
|
#define STBI_NO_PNM
|
||||||
|
|
|
@ -325,7 +325,6 @@ struct TexCreateInfo
|
||||||
|
|
||||||
FImageSource *IMGZImage_TryCreate(FileReader &, int lumpnum);
|
FImageSource *IMGZImage_TryCreate(FileReader &, int lumpnum);
|
||||||
FImageSource *PNGImage_TryCreate(FileReader &, int lumpnum);
|
FImageSource *PNGImage_TryCreate(FileReader &, int lumpnum);
|
||||||
FImageSource *JPEGImage_TryCreate(FileReader &, int lumpnum);
|
|
||||||
FImageSource *DDSImage_TryCreate(FileReader &, int lumpnum);
|
FImageSource *DDSImage_TryCreate(FileReader &, int lumpnum);
|
||||||
FImageSource *PCXImage_TryCreate(FileReader &, int lumpnum);
|
FImageSource *PCXImage_TryCreate(FileReader &, int lumpnum);
|
||||||
FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum);
|
FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum);
|
||||||
|
@ -348,7 +347,6 @@ FImageSource * FImageSource::GetImage(int lumpnum, bool isflat)
|
||||||
static TexCreateInfo CreateInfo[] = {
|
static TexCreateInfo CreateInfo[] = {
|
||||||
{ IMGZImage_TryCreate, false },
|
{ IMGZImage_TryCreate, false },
|
||||||
{ PNGImage_TryCreate, false },
|
{ PNGImage_TryCreate, false },
|
||||||
{ JPEGImage_TryCreate, false },
|
|
||||||
{ DDSImage_TryCreate, false },
|
{ DDSImage_TryCreate, false },
|
||||||
{ PCXImage_TryCreate, false },
|
{ PCXImage_TryCreate, false },
|
||||||
{ StbImage_TryCreate, false },
|
{ StbImage_TryCreate, false },
|
||||||
|
|
|
@ -31,10 +31,6 @@
|
||||||
"name": "zlib",
|
"name": "zlib",
|
||||||
"platform": "!windows | (windows & static & staticcrt)"
|
"platform": "!windows | (windows & static & staticcrt)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "libjpeg-turbo",
|
|
||||||
"platform": "!windows | (windows & static & staticcrt)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "bzip2",
|
"name": "bzip2",
|
||||||
"platform": "!windows | (windows & static & staticcrt)"
|
"platform": "!windows | (windows & static & staticcrt)"
|
||||||
|
|
Loading…
Reference in a new issue