Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c39ec149e8 | ||
|
|
a4ecaacde6 | ||
|
|
f18f81b7e2 | ||
|
|
989630f70c | ||
|
|
5996a25e2f | ||
|
|
1e247ac854 | ||
|
|
5ead57a34a | ||
|
|
489583f516 | ||
|
|
bc79e0680a | ||
|
|
a8b67c4fbb | ||
|
|
9ba2f5ed36 | ||
|
|
36a4ccccd3 | ||
|
|
cc7150e281 | ||
|
|
88aeed428f | ||
|
|
4a6b730364 | ||
|
|
bd543f030e | ||
|
|
2cbeb8abd9 |
326
BUILDING.txt
326
BUILDING.txt
@@ -1,326 +0,0 @@
|
||||
*******************************************************************************
|
||||
** Building on Unix Platforms, Cygwin, and MinGW
|
||||
*******************************************************************************
|
||||
|
||||
==================
|
||||
Build Requirements
|
||||
==================
|
||||
|
||||
-- autoconf 2.56 or later
|
||||
* If using MinGW, this can be obtained by installing the MSYS DTK
|
||||
|
||||
-- automake 1.7 or later
|
||||
* If using MinGW, this can be obtained by installing the MSYS DTK
|
||||
|
||||
-- libtool 1.4 or later
|
||||
* If using MinGW, this can be obtained by installing the MSYS DTK
|
||||
|
||||
-- NASM
|
||||
* 0.98 or later is required for a 32-bit build
|
||||
* NASM 2.05 or later is required for a 64-bit build
|
||||
* NASM 2.07 or later is required for a 64-bit build on OS/X (10.6 "Snow
|
||||
Leopard" or later.) This can be obtained from MacPorts
|
||||
(http://www.macports.org/).
|
||||
|
||||
The NASM 2.05 RPMs do not work on older Linux systems, such as Enterprise
|
||||
Linux 4. On such systems, you can easily build and install NASM 2.05
|
||||
from the source RPM by executing the following as root:
|
||||
|
||||
ARCH=`uname -m`
|
||||
wget http://www.nasm.us/pub/nasm/releasebuilds/2.05.01/nasm-2.05.01-1.src.rpm
|
||||
rpmbuild --rebuild nasm-2.05.01-1.src.rpm
|
||||
rpm -Uvh /usr/src/redhat/RPMS/$ARCH/nasm-2.05.01-1.$ARCH.rpm
|
||||
|
||||
NOTE: NASM build will fail if texinfo is not installed.
|
||||
|
||||
-- GCC v4.1 or later recommended for best performance
|
||||
|
||||
======================
|
||||
Building libjpeg-turbo
|
||||
======================
|
||||
|
||||
The following procedure will build libjpeg-turbo on Linux, 32-bit OS X, and
|
||||
Solaris/x86 systems (on Solaris, this generates a 32-bit library. See below
|
||||
for 64-bit build instructions.)
|
||||
|
||||
cd libjpeg-turbo
|
||||
autoreconf -fiv
|
||||
sh ./configure
|
||||
make
|
||||
|
||||
NOTE: Running autoreconf is only necessary if building libjpeg-turbo from the
|
||||
SVN repository.
|
||||
|
||||
This will generate the following files under .libs/
|
||||
|
||||
libjpeg.a
|
||||
Static link library for libjpeg-turbo
|
||||
|
||||
libjpeg.so.62.0.0 (Linux, Solaris)
|
||||
libjpeg.62.dylib (OS X)
|
||||
libjpeg-62.dll (MinGW)
|
||||
cygjpeg-62.dll (Cygwin)
|
||||
Shared library for libjpeg-turbo
|
||||
|
||||
libjpeg.so (Linux, Solaris)
|
||||
libjpeg.dylib (OS X)
|
||||
libjpeg.dll.a (Cygwin, MinGW)
|
||||
Development stub for libjpeg-turbo shared library
|
||||
|
||||
libturbojpeg.a
|
||||
Static link library for TurboJPEG/OSS
|
||||
|
||||
libturbojpeg.so (Linux, Solaris)
|
||||
libturbojpeg.dylib (OS X)
|
||||
Shared library and development stub for TurboJPEG/OSS
|
||||
|
||||
libturbojpeg.dll (MinGW)
|
||||
cygturbojpeg.dll (Cygwin)
|
||||
Shared library for TurboJPEG/OSS
|
||||
|
||||
libturbojpeg.dll.a (Cygwin, MinGW)
|
||||
Development stub for TurboJPEG/OSS shared library
|
||||
|
||||
========================
|
||||
Installing libjpeg-turbo
|
||||
========================
|
||||
|
||||
If you intend to install these libraries and the associated header files, then
|
||||
replace 'make' in the instructions above with
|
||||
|
||||
make install prefix={base dir} libdir={library directory}
|
||||
|
||||
For example,
|
||||
|
||||
make install prefix=/usr/local libdir=/usr/local/lib64
|
||||
|
||||
will install the header files in /usr/local/include and the library files in
|
||||
/usr/local/lib64. If 'prefix' and 'libdir' are not specified, then the default
|
||||
is to install the header files in /opt/libjpeg-turbo/include and the library
|
||||
files in /opt/libjpeg-turbo/lib.
|
||||
|
||||
NOTE: You can specify a prefix of /usr and a libdir of, for instance,
|
||||
/usr/lib64 to overwrite the system's version of libjpeg. If you do this,
|
||||
however, then be sure to BACK UP YOUR SYSTEM'S INSTALLATION OF LIBJPEG before
|
||||
overwriting it. It is recommended that you instead install libjpeg-turbo into
|
||||
a non-system directory and manipulate the LD_LIBRARY_PATH or create sym links
|
||||
to force applications to use libjpeg-turbo instead of libjpeg. See
|
||||
README-turbo.txt for more information.
|
||||
|
||||
=============
|
||||
Build Recipes
|
||||
=============
|
||||
|
||||
32-bit Library Build on 64-bit Linux
|
||||
------------------------------------
|
||||
|
||||
Add
|
||||
|
||||
--host i686-pc-linux-gnu CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32'
|
||||
|
||||
to the configure command line.
|
||||
|
||||
|
||||
64-bit Library Build on 64-bit OS/X
|
||||
-----------------------------------
|
||||
|
||||
Add
|
||||
|
||||
--host x86_64-apple-darwin10.0.0 NASM=/opt/local/bin/nasm
|
||||
|
||||
to the configure command line. NASM 2.07 or later from MacPorts must be
|
||||
installed.
|
||||
|
||||
|
||||
32-bit Library Build on 64-bit OS/X
|
||||
-----------------------------------
|
||||
|
||||
Add
|
||||
|
||||
CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS=-m32
|
||||
|
||||
to the configure command line.
|
||||
|
||||
|
||||
32-bit Backward-Compatible Library Build on 64-bit OS/X
|
||||
-------------------------------------------------------
|
||||
|
||||
Add
|
||||
|
||||
CFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
|
||||
-mmacosx-version-min=10.4 -O3 -m32' \
|
||||
CXXFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
|
||||
-mmacosx-version-min=10.4 -O3 -m32' \
|
||||
LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.4u.sdk \
|
||||
-mmacosx-version-min=10.4 -m32'
|
||||
|
||||
to the configure command line. The OS X 10.4 SDK must be installed.
|
||||
|
||||
|
||||
64-bit Library Build on 64-bit Solaris
|
||||
--------------------------------------
|
||||
|
||||
Add
|
||||
|
||||
--host x86_64-pc-solaris CFLAGS='-O3 -m64' CXXFLAGS='-O3 -m64' LDFLAGS=-m64
|
||||
|
||||
to the configure command line.
|
||||
|
||||
|
||||
64-bit Library Build on 64-bit FreeBSD
|
||||
--------------------------------------
|
||||
|
||||
Add
|
||||
|
||||
--host x86_64-unknown-freebsd
|
||||
|
||||
to the configure command line. NASM 2.07 or later from FreeBSD ports must be
|
||||
installed.
|
||||
|
||||
|
||||
32-bit Library Build on 64-bit FreeBSD
|
||||
--------------------------------------
|
||||
|
||||
Add
|
||||
|
||||
--host i386-unknown-freebsd CC='gcc -B /usr/lib32' CXX='g++ -B/usr/lib32' \
|
||||
CFLAGS='-O3 -m32' CXXFLAGS='-O3 -m32' LDFLAGS='-B/usr/lib32'
|
||||
|
||||
to the configure command line. NASM 2.07 or later from FreeBSD ports must be
|
||||
installed.
|
||||
|
||||
|
||||
MinGW Build on Cygwin
|
||||
---------------------
|
||||
|
||||
Add
|
||||
|
||||
--host mingw32
|
||||
|
||||
to the configure command line. This will produce libraries which do not
|
||||
depend on cygwin1.dll or other Cygwin DLL's.
|
||||
|
||||
|
||||
Sun Studio
|
||||
----------
|
||||
|
||||
Add
|
||||
|
||||
CC=cc CXX=CC
|
||||
|
||||
to the configure command line. libjpeg-turbo will automatically be built with
|
||||
the maximum optimization level (-xO5) unless you override CFLAGS and CXXFLAGS.
|
||||
|
||||
To build a 64-bit version of libjpeg-turbo using Sun Studio, add
|
||||
|
||||
--host x86_64-pc-solaris CC=cc CXX=CC CFLAGS='-xO5 -m64' \
|
||||
CXXFLAGS='-xO5 -m64' LDFLAGS=-m64
|
||||
|
||||
to the configure command line.
|
||||
|
||||
|
||||
*******************************************************************************
|
||||
** Building on Windows (Visual C++)
|
||||
*******************************************************************************
|
||||
|
||||
==================
|
||||
Build Requirements
|
||||
==================
|
||||
|
||||
-- GNU Make v3.7 or later
|
||||
* Can be found in MSYS (http://www.mingw.org/download.shtml) or
|
||||
Cygwin (http://www.cygwin.com/)
|
||||
|
||||
-- Windows SDK for Windows Server 2008 and .NET Framework 3.5 (or a later
|
||||
version)
|
||||
|
||||
http://msdn.microsoft.com/en-us/windows/dd146047.aspx
|
||||
|
||||
* The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
|
||||
everything necessary to build libjpeg-turbo. If you do not already have
|
||||
Visual C++ installed, then this is the recommended solution. Also tested
|
||||
with Microsoft Visual C++ 2008 Express Edition (both are free downloads.)
|
||||
* Add the compiler and SDK binary directories (for instance,
|
||||
c:\Program Files\Microsoft Visual Studio 9.0\VC\BIN;
|
||||
c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;
|
||||
c:\Program Files\Microsoft SDKs\Windows\v6.1\bin)
|
||||
to the system or user PATH environment variable prior to building
|
||||
libjpeg-turbo.
|
||||
* Add the compiler and SDK include directories (for instance,
|
||||
c:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE;
|
||||
c:\Program Files\Microsoft SDKs\Windows\v6.1\include)
|
||||
to the system or user INCLUDE environment variable prior to building
|
||||
libjpeg-turbo.
|
||||
* Add the compiler library directory (for instance,
|
||||
c:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;
|
||||
c:\Program Files\Microsoft SDKs\Windows\v6.1\lib)
|
||||
to the system or user LIB environment variable prior to building
|
||||
libjpeg-turbo.
|
||||
|
||||
-- NASM (http://www.nasm.us/) 0.98 or later
|
||||
|
||||
======================
|
||||
Building libjpeg-turbo
|
||||
======================
|
||||
|
||||
cd libjpeg-turbo
|
||||
make -f win/Makefile
|
||||
|
||||
This will generate the following files under libjpeg-turbo\windows\:
|
||||
|
||||
jpeg-static.lib Static link library for libjpeg-turbo
|
||||
jpeg62.dll Shared library for libjpeg-turbo
|
||||
jpeg.lib Development stub for libjpeg-turbo shared library
|
||||
turbojpeg-static.lib Static link library for TurboJPEG/OSS
|
||||
turbojpeg.dll Shared library for TurboJPEG/OSS
|
||||
turbojpeg.lib Development stub for TurboJPEG/OSS shared library
|
||||
|
||||
If a 64-bit Windows platform is detected, then the build system will attempt
|
||||
to build a 64-bit version of libjpeg-turbo. You can override this by running
|
||||
|
||||
make -f win/Makefile WIN64=no
|
||||
|
||||
|
||||
*******************************************************************************
|
||||
** Creating Release Packages
|
||||
*******************************************************************************
|
||||
|
||||
The following commands can be used to create various types of release packages:
|
||||
|
||||
make rpm
|
||||
|
||||
Create RedHat-style binary RPM package. Requires RPM v4 or later.
|
||||
|
||||
make srpm
|
||||
|
||||
This runs 'make dist' to create a pristine source tarball, then creates a
|
||||
RedHat-style source RPM package from the tarball. Requires RPM v4 or later.
|
||||
|
||||
make deb
|
||||
|
||||
Create Debian-style binary package. Requires dpkg.
|
||||
|
||||
make dmg
|
||||
|
||||
Create Macintosh package/disk image. This requires the PackageMaker
|
||||
application, which must be installed in /Developer/Applications/Utilities.
|
||||
|
||||
make udmg
|
||||
|
||||
On 64-bit OS X (10.6 "Snow Leopard" or later), this creates a version of the
|
||||
Macintosh package/disk image which contains universal i386/x86-64 binaries.
|
||||
The 32-bit fork of these binaries is backward compatible with OS X 10.4 and
|
||||
later, whereas the 64-bit fork is compatible with OS X 10.6 and later. OS X
|
||||
10.4 compatibility SDK required.
|
||||
|
||||
make nsi
|
||||
|
||||
When using MinGW, this creates a Win32 installer for the GCC version of the
|
||||
libjpeg-turbo SDK. This requires the Nullsoft Install System
|
||||
(http://nsis.sourceforge.net/.) makensis.exe should be in your PATH.
|
||||
|
||||
make -f win/Makefile nsi
|
||||
|
||||
This creates a Win32 installer for the Visual C++ version of the
|
||||
libjpeg-turbo SDK. This requires the Nullsoft Install System
|
||||
(http://nsis.sourceforge.net/.) makensis.exe should be in your PATH.
|
||||
@@ -1,15 +0,0 @@
|
||||
Significant changes since 0.0.91
|
||||
================================
|
||||
|
||||
[1] Fixed x86-64 build on FreeBSD systems
|
||||
|
||||
[2] Added support for Windows 64-bit systems
|
||||
|
||||
|
||||
Significant changes since 0.0.90
|
||||
================================
|
||||
|
||||
[1] Added documentation to .deb packages
|
||||
|
||||
[2] 2968313: Fixed data corruption issues when decompressing large JPEG images
|
||||
and/or using buffered I/O with the libjpeg-turbo decompressor
|
||||
504
LGPL.txt
504
LGPL.txt
@@ -1,504 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
53
LICENSE.txt
53
LICENSE.txt
@@ -1,53 +0,0 @@
|
||||
wxWindows Library Licence, Version 3.1
|
||||
======================================
|
||||
|
||||
Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this licence document, but changing it is not allowed.
|
||||
|
||||
WXWINDOWS LIBRARY LICENCE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Library General Public Licence as published by
|
||||
the Free Software Foundation; either version 2 of the Licence, or (at
|
||||
your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
|
||||
General Public Licence for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public Licence
|
||||
along with this software, usually in a file named COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA.
|
||||
|
||||
EXCEPTION NOTICE
|
||||
|
||||
1. As a special exception, the copyright holders of this library give
|
||||
permission for additional uses of the text contained in this release of
|
||||
the library as licenced under the wxWindows Library Licence, applying
|
||||
either version 3.1 of the Licence, or (at your option) any later version of
|
||||
the Licence as published by the copyright holders of version
|
||||
3.1 of the Licence document.
|
||||
|
||||
2. The exception is that you may use, copy, link, modify and distribute
|
||||
under your own terms, binary object code versions of works based
|
||||
on the Library.
|
||||
|
||||
3. If you copy code from files distributed under the terms of the GNU
|
||||
General Public Licence or the GNU Library General Public Licence into a
|
||||
copy of this library, as this licence permits, the exception does not
|
||||
apply to the code that you add in this way. To avoid misleading anyone as
|
||||
to the status of such modified files, you must delete this exception
|
||||
notice from such code and/or adjust the licensing conditions notice
|
||||
accordingly.
|
||||
|
||||
4. If you write modifications of your own for this library, it is your
|
||||
choice whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, you must delete the exception notice from such
|
||||
code and/or adjust the licensing conditions notice accordingly.
|
||||
|
||||
|
||||
281
Makefile.am
281
Makefile.am
@@ -1,177 +1,134 @@
|
||||
lib_LTLIBRARIES = libjpeg.la libturbojpeg.la
|
||||
libjpeg_la_LDFLAGS = -version-number 62:0:0 -no-undefined
|
||||
libturbojpeg_la_LDFLAGS = -avoid-version -no-undefined
|
||||
include_HEADERS = jerror.h jmorecfg.h jpeglib.h turbojpeg.h
|
||||
nodist_include_HEADERS = jconfig.h
|
||||
## Process this file with automake to produce Makefile.in
|
||||
#
|
||||
# Automake Makefile for the JPEG library
|
||||
#
|
||||
# This file is written by Bob Friesenhahn, Guido Vollbeding
|
||||
#
|
||||
|
||||
HDRS = jchuff.h jdct.h jdhuff.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
|
||||
jpegint.h jpeglib.h jversion.h jsimd.h jsimddct.h
|
||||
# Sources to build library
|
||||
LIBSOURCES = jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c \
|
||||
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
|
||||
jcomapi.c jcparam.c jcprepct.c jcsample.c jctrans.c jdapimin.c \
|
||||
jdapistd.c jdarith.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
|
||||
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
|
||||
jdmerge.c jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c \
|
||||
jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jquant1.c \
|
||||
jquant2.c jutils.c jmemmgr.c @MEMORYMGR@.c
|
||||
|
||||
libjpeg_la_SOURCES = $(HDRS) jcapimin.c jcapistd.c jccoefct.c jccolor.c \
|
||||
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
|
||||
jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
|
||||
jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
|
||||
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
|
||||
jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
|
||||
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
|
||||
jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c
|
||||
# System dependent sources
|
||||
SYSDEPSOURCES = jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
|
||||
|
||||
libturbojpeg_la_SOURCES = $(libjpeg_la_SOURCES) turbojpegl.c turbojpeg.h \
|
||||
turbojpeg-mapfile
|
||||
|
||||
if VERSION_SCRIPT
|
||||
|
||||
libturbojpeg_la_LDFLAGS += $(VERSION_SCRIPT_FLAG)$(srcdir)/turbojpeg-mapfile
|
||||
|
||||
endif
|
||||
|
||||
if WITH_SIMD
|
||||
|
||||
SUBDIRS = simd
|
||||
libjpeg_la_LIBADD = simd/libsimd.la
|
||||
libturbojpeg_la_LIBADD = simd/libsimd.la
|
||||
|
||||
else
|
||||
|
||||
libjpeg_la_SOURCES += jsimd_none.c
|
||||
|
||||
endif
|
||||
|
||||
TSTHDRS = rrutil.h rrtimer.h
|
||||
|
||||
noinst_PROGRAMS = jpgtest jpegut cjpeg djpeg jpegtran rdjpgcom wrjpgcom
|
||||
|
||||
jpgtest_SOURCES = $(TSTHDRS) jpgtest.cxx bmp.h bmp.c
|
||||
|
||||
jpgtest_LDADD = libturbojpeg.la
|
||||
|
||||
jpegut_SOURCES = $(TSTHDRS) jpegut.c bmp.h bmp.c
|
||||
|
||||
jpegut_LDADD = libturbojpeg.la
|
||||
|
||||
cjpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c cjpeg.c rdbmp.c rdgif.c \
|
||||
rdppm.c rdswitch.c rdtarga.c
|
||||
|
||||
cjpeg_LDADD = libjpeg.la
|
||||
|
||||
cjpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
|
||||
-DTARGA_SUPPORTED
|
||||
|
||||
djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
|
||||
wrbmp.c wrgif.c wrppm.c wrtarga.c
|
||||
|
||||
djpeg_LDADD = libjpeg.la
|
||||
|
||||
djpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
|
||||
-DTARGA_SUPPORTED
|
||||
|
||||
jpegtran_SOURCES = jpegtran.c rdswitch.c cdjpeg.c transupp.c transupp.h
|
||||
|
||||
jpegtran_LDADD = libjpeg.la
|
||||
|
||||
rdjpgcom_SOURCES = rdjpgcom.c
|
||||
|
||||
rdjpgcom_LDADD = libjpeg.la
|
||||
|
||||
wrjpgcom_SOURCES = wrjpgcom.c
|
||||
|
||||
wrjpgcom_LDADD = libjpeg.la
|
||||
# Headers which are installed to support the library
|
||||
INSTINCLUDES = jerror.h jmorecfg.h jpeglib.h
|
||||
|
||||
# Headers which are not installed
|
||||
OTHERINCLUDES = cderror.h cdjpeg.h jdct.h jinclude.h jmemsys.h jpegint.h \
|
||||
jversion.h transupp.h
|
||||
|
||||
# Manual pages (Automake uses 'MANS' for itself)
|
||||
DISTMANS= cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1
|
||||
|
||||
DOCS= README install.doc usage.doc wizard.doc example.c libjpeg.doc \
|
||||
structure.doc coderules.doc filelist.doc jconfig.doc change.log \
|
||||
README-turbo.txt rdrle.c wrrle.c LICENSE.txt LGPL.txt BUILDING.txt \
|
||||
ChangeLog.txt
|
||||
# Other documentation files
|
||||
DOCS= README install.txt usage.txt wizard.txt example.c libjpeg.txt \
|
||||
structure.txt coderules.txt filelist.txt change.log
|
||||
|
||||
TESTFILES= testorig.jpg testorig.ppm testimg.bmp testimgflt.jpg \
|
||||
testimgfst.jpg testimgint.jpg testimgp.jpg testimgfst.ppm testimgint.ppm
|
||||
# Makefiles for various systems
|
||||
MKFILES= configure Makefile.in makefile.ansi makefile.unix makefile.bcc \
|
||||
makefile.mc6 makefile.dj makefile.wat makefile.vc makejdsw.vc6 \
|
||||
makeadsw.vc6 makejdep.vc6 makejdsp.vc6 makejmak.vc6 makecdep.vc6 \
|
||||
makecdsp.vc6 makecmak.vc6 makeddep.vc6 makeddsp.vc6 makedmak.vc6 \
|
||||
maketdep.vc6 maketdsp.vc6 maketmak.vc6 makerdep.vc6 makerdsp.vc6 \
|
||||
makermak.vc6 makewdep.vc6 makewdsp.vc6 makewmak.vc6 makejsln.v10 \
|
||||
makeasln.v10 makejvcx.v10 makejfil.v10 makecvcx.v10 makecfil.v10 \
|
||||
makedvcx.v10 makedfil.v10 maketvcx.v10 maketfil.v10 makervcx.v10 \
|
||||
makerfil.v10 makewvcx.v10 makewfil.v10 makeproj.mac makcjpeg.st \
|
||||
makdjpeg.st makljpeg.st maktjpeg.st makefile.manx makefile.sas \
|
||||
makefile.mms makefile.vms makvms.opt
|
||||
|
||||
EXTRA_DIST = win release $(DOCS) $(DISTMANS) $(TESTFILES)
|
||||
# Configuration files
|
||||
CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
|
||||
jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
|
||||
jconfig.vms
|
||||
|
||||
dist-hook:
|
||||
rm -rf `find $(distdir) -name .svn`
|
||||
# Support scripts for configure
|
||||
CONFIGUREFILES= config.guess config.sub install-sh ltmain.sh depcomp missing
|
||||
|
||||
# Miscellaneous support files
|
||||
OTHERFILES= jconfig.txt ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm \
|
||||
libjpeg.map
|
||||
|
||||
test: testclean cjpeg djpeg jpegtran jpegut
|
||||
./jpegut
|
||||
./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testorig.ppm
|
||||
./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm
|
||||
./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm
|
||||
cmp $(srcdir)/testimgint.jpg testoutint.jpg
|
||||
cmp $(srcdir)/testimgfst.jpg testoutfst.jpg
|
||||
cmp $(srcdir)/testimgflt.jpg testoutflt.jpg
|
||||
./djpeg -dct int -fast -ppm -outfile testoutint.ppm $(srcdir)/testorig.jpg
|
||||
./djpeg -dct fast -ppm -outfile testoutfst.ppm $(srcdir)/testorig.jpg
|
||||
./djpeg -dct float -ppm -outfile testoutflt.ppm $(srcdir)/testorig.jpg
|
||||
cmp $(srcdir)/testimgint.ppm testoutint.ppm
|
||||
cmp $(srcdir)/testimgfst.ppm testoutfst.ppm
|
||||
cmp $(srcdir)/testorig.ppm testoutflt.ppm
|
||||
# Test support files
|
||||
TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
|
||||
testimgp.jpg
|
||||
|
||||
# libtool libraries to build
|
||||
lib_LTLIBRARIES = libjpeg.la
|
||||
|
||||
# Library sources for libjpeg.la
|
||||
libjpeg_la_SOURCES = $(LIBSOURCES)
|
||||
|
||||
# LDFLAGS for libjpeg.la
|
||||
libjpeg_la_LDFLAGS = -no-undefined \
|
||||
-version-info $(JPEG_LIB_VERSION)
|
||||
|
||||
if HAVE_LD_VERSION_SCRIPT
|
||||
libjpeg_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libjpeg.map
|
||||
endif
|
||||
|
||||
# Executables to build
|
||||
bin_PROGRAMS = cjpeg djpeg jpegtran rdjpgcom wrjpgcom
|
||||
|
||||
# Executable sources & libs
|
||||
cjpeg_SOURCES = cjpeg.c rdppm.c rdgif.c rdtarga.c rdrle.c rdbmp.c \
|
||||
rdswitch.c cdjpeg.c
|
||||
cjpeg_LDADD = libjpeg.la
|
||||
djpeg_SOURCES = djpeg.c wrppm.c wrgif.c wrtarga.c wrrle.c wrbmp.c \
|
||||
rdcolmap.c cdjpeg.c
|
||||
djpeg_LDADD = libjpeg.la
|
||||
jpegtran_SOURCES = jpegtran.c rdswitch.c cdjpeg.c transupp.c
|
||||
jpegtran_LDADD = libjpeg.la
|
||||
rdjpgcom_SOURCES = rdjpgcom.c
|
||||
wrjpgcom_SOURCES = wrjpgcom.c
|
||||
|
||||
# Manual pages to install
|
||||
man_MANS = $(DISTMANS)
|
||||
|
||||
# Headers to install
|
||||
include_HEADERS = $(INSTINCLUDES)
|
||||
|
||||
# Other distributed headers
|
||||
noinst_HEADERS = $(OTHERINCLUDES)
|
||||
|
||||
# Other distributed files
|
||||
EXTRA_DIST = $(DOCS) $(DISTMANS) $(MKFILES) $(CONFIGFILES) $(SYSDEPSOURCES) \
|
||||
$(OTHERFILES) $(TESTFILES)
|
||||
|
||||
# Files to be cleaned
|
||||
CLEANFILES = testout.ppm testout.bmp testout.jpg testoutp.ppm testoutp.jpg \
|
||||
testoutt.jpg
|
||||
|
||||
# Install jconfig.h
|
||||
install-data-local:
|
||||
$(mkinstalldirs) $(DESTDIR)$(includedir)
|
||||
$(INSTALL_HEADER) jconfig.h $(DESTDIR)$(includedir)/jconfig.h
|
||||
|
||||
# Uninstall jconfig.h
|
||||
uninstall-local:
|
||||
rm -f $(DESTDIR)$(includedir)/jconfig.h
|
||||
|
||||
# Run tests
|
||||
test: check-local
|
||||
check-local:
|
||||
rm -f testout*
|
||||
./djpeg -dct int -ppm -outfile testout.ppm $(srcdir)/testorig.jpg
|
||||
./djpeg -dct int -bmp -colors 256 -outfile testout.bmp $(srcdir)/testorig.jpg
|
||||
./cjpeg -dct int -outfile testout.jpg $(srcdir)/testimg.ppm
|
||||
./djpeg -dct int -ppm -outfile testoutp.ppm $(srcdir)/testprog.jpg
|
||||
./cjpeg -dct int -progressive -opt -outfile testoutp.jpg $(srcdir)/testimg.ppm
|
||||
./jpegtran -outfile testoutt.jpg $(srcdir)/testprog.jpg
|
||||
cmp $(srcdir)/testimg.ppm testout.ppm
|
||||
cmp $(srcdir)/testimg.bmp testout.bmp
|
||||
./cjpeg -dct int -progressive -outfile testoutp.jpg $(srcdir)/testorig.ppm
|
||||
cmp $(srcdir)/testimg.jpg testout.jpg
|
||||
cmp $(srcdir)/testimg.ppm testoutp.ppm
|
||||
cmp $(srcdir)/testimgp.jpg testoutp.jpg
|
||||
./jpegtran -outfile testoutt.jpg testoutp.jpg
|
||||
cmp $(srcdir)/testimgint.jpg testoutt.jpg
|
||||
|
||||
testclean:
|
||||
$(RM) testout*
|
||||
$(RM) *_GRAYQ[0-9]*.bmp
|
||||
$(RM) *_GRAYQ[0-9]*.ppm
|
||||
$(RM) *_GRAYQ[0-9]*.jpg
|
||||
$(RM) *_420Q[0-9]*.bmp
|
||||
$(RM) *_420Q[0-9]*.ppm
|
||||
$(RM) *_420Q[0-9]*.jpg
|
||||
$(RM) *_422Q[0-9]*.bmp
|
||||
$(RM) *_422Q[0-9]*.ppm
|
||||
$(RM) *_422Q[0-9]*.jpg
|
||||
$(RM) *_444Q[0-9]*.bmp
|
||||
$(RM) *_444Q[0-9]*.ppm
|
||||
$(RM) *_444Q[0-9]*.jpg
|
||||
|
||||
rpm: all
|
||||
sh $(srcdir)/release/makerpm ${PACKAGE_NAME} ${VERSION} ${BUILD} \
|
||||
${RPMARCH} ${srcdir}
|
||||
|
||||
srpm: dist-gzip
|
||||
sh $(srcdir)/release/makesrpm ${PACKAGE_NAME} ${VERSION} ${BUILD} ${srcdir}
|
||||
|
||||
deb: all
|
||||
sh $(srcdir)/release/makedpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
|
||||
${DEBARCH} ${srcdir}
|
||||
|
||||
if X86_64
|
||||
|
||||
udmg: all
|
||||
sh $(srcdir)/release/makemacpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
|
||||
${srcdir} universal
|
||||
|
||||
endif
|
||||
|
||||
dmg: all
|
||||
sh $(srcdir)/release/makemacpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} ${srcdir}
|
||||
|
||||
if X86_64
|
||||
|
||||
sunpkg: all
|
||||
sh $(srcdir)/release/makesunpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
|
||||
${DEBARCH} ${srcdir} $(CC) $(CXX) combined
|
||||
|
||||
nsi: all
|
||||
makensis -nocd -DVERSION=$(VERSION) -DAPPNAME=libjpeg-turbo-gcc64 \
|
||||
-DWLIBDIR=.libs -DWSRCDIR=$(srcdir) -DWBLDDIR=. -DWHDRDIR=. -DWIN64 \
|
||||
-DPLATFORM="GCC 64-bit" -DGCC $(srcdir)/release/libjpeg-turbo.nsi
|
||||
|
||||
else
|
||||
|
||||
sunpkg: all
|
||||
sh $(srcdir)/release/makesunpkg ${PACKAGE_NAME} ${VERSION} ${BUILD} \
|
||||
${DEBARCH} ${srcdir} $(CC) $(CXX)
|
||||
|
||||
nsi: all
|
||||
makensis -nocd -DVERSION=$(VERSION) -DAPPNAME=libjpeg-turbo-gcc \
|
||||
-DWLIBDIR=.libs -DWSRCDIR=$(srcdir) -DWBLDDIR=. -DWHDRDIR=. \
|
||||
-DPLATFORM="GCC" -DGCC $(srcdir)/release/libjpeg-turbo.nsi
|
||||
|
||||
endif
|
||||
cmp $(srcdir)/testorig.jpg testoutt.jpg
|
||||
|
||||
1092
Makefile.in
Normal file
1092
Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
284
README
284
README
@@ -1,29 +1,17 @@
|
||||
libjpeg-turbo note: This is the legacy document from the original libjpeg v6b
|
||||
release, which is included for reference. The Internet addresses given below
|
||||
are likely non-functional. For more information about the libjpeg project,
|
||||
please see http://www.ijg.org. For more information about libjpeg-turbo,
|
||||
please see http://libjpeg-turbo.virtualgl.org.
|
||||
|
||||
|
||||
The Independent JPEG Group's JPEG software
|
||||
==========================================
|
||||
|
||||
README for release 6b of 27-Mar-1998
|
||||
README for release 8c of 16-Jan-2011
|
||||
====================================
|
||||
|
||||
This distribution contains the sixth public release of the Independent JPEG
|
||||
This distribution contains the eighth public release of the Independent JPEG
|
||||
Group's free JPEG software. You are welcome to redistribute this software and
|
||||
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
|
||||
|
||||
Serious users of this software (particularly those incorporating it into
|
||||
larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
|
||||
our electronic mailing list. Mailing list members are notified of updates
|
||||
and have a chance to participate in technical discussions, etc.
|
||||
|
||||
This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
|
||||
Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
|
||||
Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
|
||||
Group.
|
||||
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 official ISO JPEG standards committee.
|
||||
|
||||
@@ -37,27 +25,27 @@ OVERVIEW General description of JPEG and the IJG software.
|
||||
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
|
||||
REFERENCES Where to learn more about JPEG.
|
||||
ARCHIVE LOCATIONS Where to find newer versions of this software.
|
||||
RELATED SOFTWARE Other stuff you should get.
|
||||
ACKNOWLEDGMENTS Special thanks.
|
||||
FILE FORMAT WARS Software *not* to get.
|
||||
TO DO Plans for future IJG releases.
|
||||
|
||||
Other documentation files in the distribution are:
|
||||
|
||||
User documentation:
|
||||
install.doc How to configure and install the IJG software.
|
||||
usage.doc Usage instructions for cjpeg, djpeg, jpegtran,
|
||||
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.doc).
|
||||
wizard.doc Advanced usage instructions for JPEG wizards only.
|
||||
*.1 Unix-style man pages for programs (same info as usage.txt).
|
||||
wizard.txt Advanced usage instructions for JPEG wizards only.
|
||||
change.log Version-to-version change highlights.
|
||||
Programmer and internal documentation:
|
||||
libjpeg.doc How to use the JPEG library in your own programs.
|
||||
libjpeg.txt How to use the JPEG library in your own programs.
|
||||
example.c Sample code for calling the JPEG library.
|
||||
structure.doc Overview of the JPEG library's internal structure.
|
||||
filelist.doc Road map of IJG files.
|
||||
coderules.doc Coding style rules --- please read if you contribute code.
|
||||
structure.txt Overview of the JPEG library's internal structure.
|
||||
filelist.txt Road map of IJG files.
|
||||
coderules.txt Coding style rules --- please read if you contribute code.
|
||||
|
||||
Please read at least the files install.doc and usage.doc. Useful information
|
||||
Please read at least the files install.txt and usage.txt. Some information
|
||||
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
|
||||
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
|
||||
|
||||
@@ -69,24 +57,15 @@ the order listed) before diving into the code.
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
This package contains C software to implement JPEG image compression and
|
||||
decompression. JPEG (pronounced "jay-peg") is a standardized compression
|
||||
method for full-color and gray-scale images. JPEG is intended for compressing
|
||||
"real-world" scenes; line drawings, cartoons and other non-realistic images
|
||||
are not its strong suit. JPEG is lossy, meaning that the output image is not
|
||||
exactly identical to the input image. Hence you must not use JPEG if you
|
||||
have to have identical output bits. However, on typical photographic images,
|
||||
very good compression levels can be obtained with no visible change, and
|
||||
remarkably high compression levels are possible if you can tolerate a
|
||||
low-quality image. For more details, see the references, or just experiment
|
||||
with various compression settings.
|
||||
This package contains C software to implement JPEG image encoding, decoding,
|
||||
and transcoding. JPEG (pronounced "jay-peg") is a standardized compression
|
||||
method for full-color and gray-scale images.
|
||||
|
||||
This software implements JPEG baseline, extended-sequential, and progressive
|
||||
compression processes. Provision is made for supporting all variants of these
|
||||
processes, although some uncommon parameter settings aren't implemented yet.
|
||||
For legal reasons, we are not distributing code for the arithmetic-coding
|
||||
variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting
|
||||
the hierarchical or lossless processes defined in the standard.
|
||||
We 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
|
||||
@@ -98,10 +77,11 @@ 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.
|
||||
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,
|
||||
@@ -134,7 +114,7 @@ with respect to this software, its quality, accuracy, merchantability, or
|
||||
fitness for a particular purpose. This software is provided "AS IS", and you,
|
||||
its user, assume the entire risk as to its quality and accuracy.
|
||||
|
||||
This software is copyright (C) 1991-1998, Thomas G. Lane.
|
||||
This software is copyright (C) 1991-2011, Thomas G. Lane, Guido Vollbeding.
|
||||
All Rights Reserved except as specified below.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
@@ -177,17 +157,8 @@ the foregoing paragraphs do.
|
||||
The Unix configuration script "configure" was produced with GNU Autoconf.
|
||||
It is copyright by the Free Software Foundation but is freely distributable.
|
||||
The same holds for its supporting scripts (config.guess, config.sub,
|
||||
ltconfig, ltmain.sh). Another support script, install-sh, is copyright
|
||||
by M.I.T. but is also freely distributable.
|
||||
|
||||
It appears that the arithmetic coding option of the JPEG spec is covered by
|
||||
patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
|
||||
legally be used without obtaining one or more licenses. For this reason,
|
||||
support for arithmetic coding has been removed from the free JPEG software.
|
||||
(Since arithmetic coding provides only a marginal gain over the unpatented
|
||||
Huffman mode, it is unlikely that very many implementations will support it.)
|
||||
So far as we are aware, there are no patent restrictions on the remaining
|
||||
code.
|
||||
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, GIF reading support has
|
||||
@@ -205,7 +176,7 @@ We are required to state that
|
||||
REFERENCES
|
||||
==========
|
||||
|
||||
We highly recommend reading one or more of these references before trying to
|
||||
We recommend reading one or more of these references before trying to
|
||||
understand the innards of the JPEG software.
|
||||
|
||||
The best short technical introduction to the JPEG compression algorithm is
|
||||
@@ -214,7 +185,7 @@ The best short technical introduction to the JPEG compression algorithm is
|
||||
(Adjacent articles in that issue discuss MPEG motion picture compression,
|
||||
applications of JPEG, and related topics.) If you don't have the CACM issue
|
||||
handy, a PostScript file containing a revised version of Wallace's article is
|
||||
available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually
|
||||
available at http://www.ijg.org/files/wallace.ps.gz. The file (actually
|
||||
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
|
||||
omits the sample images that appeared in CACM, but it includes corrections
|
||||
and some added material. Note: the Wallace article is copyright ACM and IEEE,
|
||||
@@ -229,82 +200,65 @@ code but don't know much about data compression in general. The book's JPEG
|
||||
sample code is far from industrial-strength, but when you are ready to look
|
||||
at a full implementation, you've got one here...
|
||||
|
||||
The best full description of JPEG is the textbook "JPEG Still Image Data
|
||||
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
|
||||
by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
|
||||
The book includes the complete text of the ISO JPEG standards (DIS 10918-1
|
||||
and draft DIS 10918-2). This is by far the most complete exposition of JPEG
|
||||
in existence, and we highly recommend it.
|
||||
The best currently available description of JPEG is the textbook "JPEG Still
|
||||
Image Data Compression Standard" by William B. Pennebaker and Joan L.
|
||||
Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1.
|
||||
Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG
|
||||
standards (DIS 10918-1 and draft DIS 10918-2).
|
||||
Although this is by far the most detailed and comprehensive exposition of
|
||||
JPEG publicly available, we point out that it is still missing an explanation
|
||||
of the most essential properties and algorithms of the underlying DCT
|
||||
technology.
|
||||
If you think that you know about DCT-based JPEG after reading this book,
|
||||
then you are in delusion. The real fundamentals and corresponding potential
|
||||
of DCT-based JPEG are not publicly known so far, and that is the reason for
|
||||
all the mistaken developments taking place in the image coding domain.
|
||||
|
||||
The JPEG standard itself is not available electronically; you must order a
|
||||
paper copy through ISO or ITU. (Unless you feel a need to own a certified
|
||||
official copy, we recommend buying the Pennebaker and Mitchell book instead;
|
||||
it's much cheaper and includes a great deal of useful explanatory material.)
|
||||
In the USA, copies of the standard may be ordered from ANSI Sales at (212)
|
||||
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
|
||||
doesn't take credit card orders, but Global does.) It's not cheap: as of
|
||||
1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
|
||||
shipping/handling. The standard is divided into two parts, Part 1 being the
|
||||
actual specification, while Part 2 covers compliance testing methods. Part 1
|
||||
is titled "Digital Compression and Coding of Continuous-tone Still Images,
|
||||
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.
|
||||
|
||||
Some extensions to the original JPEG standard are defined in JPEG Part 3,
|
||||
a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG
|
||||
currently does not support any Part 3 extensions.
|
||||
IJG JPEG 8 introduces an implementation of the JPEG SmartScale extension
|
||||
which is specified in 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 the document is Revision 3.
|
||||
|
||||
The JPEG standard does not specify all details of an interchangeable file
|
||||
format. For the omitted details we follow the "JFIF" conventions, revision
|
||||
1.02. A copy of the JFIF spec is available from:
|
||||
Literature Department
|
||||
C-Cube Microsystems, Inc.
|
||||
1778 McCarthy Blvd.
|
||||
Milpitas, CA 95035
|
||||
phone (408) 944-6300, fax (408) 944-6314
|
||||
A PostScript version of this document is available by FTP at
|
||||
ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text
|
||||
version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
|
||||
the figures.
|
||||
1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report
|
||||
and thus received a formal publication status. It is available as a free
|
||||
download in PDF format from
|
||||
http://www.ecma-international.org/publications/techreports/E-TR-098.htm.
|
||||
A PostScript version of the JFIF document is available at
|
||||
http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at
|
||||
http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures.
|
||||
|
||||
The TIFF 6.0 file format specification can be obtained by FTP from
|
||||
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
|
||||
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
|
||||
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
|
||||
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
|
||||
(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or
|
||||
from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision
|
||||
(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. libtiff is available
|
||||
from ftp://ftp.sgi.com/graphics/tiff/.
|
||||
uses our library to implement TIFF/JPEG per the Note.
|
||||
|
||||
|
||||
ARCHIVE LOCATIONS
|
||||
=================
|
||||
|
||||
The "official" archive site for this software is ftp.uu.net (Internet
|
||||
address 192.48.96.9). The most recent released version can always be found
|
||||
there in directory graphics/jpeg. This particular version will be archived
|
||||
as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have
|
||||
direct Internet access, UUNET's archives are also available via UUCP; contact
|
||||
help@uunet.uu.net for information on retrieving files that way.
|
||||
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.v8c.tar.gz, and in Windows-compatible
|
||||
"zip" archive format as http://www.ijg.org/files/jpegsr8c.zip.
|
||||
|
||||
Numerous Internet sites maintain copies of the UUNET files. However, only
|
||||
ftp.uu.net is guaranteed to have the latest official version.
|
||||
|
||||
You can also obtain this software in DOS-compatible "zip" archive format from
|
||||
the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
|
||||
on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
|
||||
"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net
|
||||
release.
|
||||
|
||||
The JPEG FAQ (Frequently Asked Questions) article is a useful source of
|
||||
general information about JPEG. It is updated constantly and therefore is
|
||||
not included in this distribution. The FAQ is posted every two weeks to
|
||||
Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
|
||||
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/.
|
||||
@@ -314,79 +268,59 @@ with body
|
||||
send usenet/news.answers/jpeg-faq/part2
|
||||
|
||||
|
||||
RELATED SOFTWARE
|
||||
================
|
||||
ACKNOWLEDGMENTS
|
||||
===============
|
||||
|
||||
Numerous viewing and image manipulation programs now support JPEG. (Quite a
|
||||
few of them use this library to do so.) The JPEG FAQ described above lists
|
||||
some of the more popular free and shareware viewers, and tells where to
|
||||
obtain them on Internet.
|
||||
Thank to Juergen Bruder for providing me with a copy of the common DCT
|
||||
algorithm article, only to find out that I had come to the same result
|
||||
in a more direct and comprehensible way with a more generative approach.
|
||||
|
||||
If you are on a Unix machine, we highly recommend Jef Poskanzer's free
|
||||
PBMPLUS software, which provides many useful operations on PPM-format image
|
||||
files. In particular, it can convert PPM images to and from a wide range of
|
||||
other formats, thus making cjpeg/djpeg considerably more useful. The latest
|
||||
version is distributed by the NetPBM group, and is available from numerous
|
||||
sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
|
||||
Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
|
||||
you are likely to have difficulty making it work on any non-Unix machine.
|
||||
Thank to Istvan Sebestyen and Joan L. Mitchell for inviting me to the
|
||||
ITU JPEG (Study Group 16) meeting in Geneva, Switzerland.
|
||||
|
||||
A different free JPEG implementation, written by the PVRG group at Stanford,
|
||||
is available from ftp://havefun.stanford.edu/pub/jpeg/. This program
|
||||
is designed for research and experimentation rather than production use;
|
||||
it is slower, harder to use, and less portable than the IJG code, but it
|
||||
is easier to read and modify. Also, the PVRG code supports lossless JPEG,
|
||||
which we do not. (On the other hand, it doesn't do progressive JPEG.)
|
||||
Thank to Thomas Wiegand and Gary Sullivan for inviting me to the
|
||||
Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland.
|
||||
|
||||
Thank to John Korejwa and Massimo Ballerini for inviting me to
|
||||
fruitful consultations in Boston, MA and Milan, Italy.
|
||||
|
||||
Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther
|
||||
Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel
|
||||
for corresponding business development.
|
||||
|
||||
Thank to Nico Zschach and Dirk Stelling of the technical support team
|
||||
at the Digital Images company in Halle for providing me with extra
|
||||
equipment for configuration tests.
|
||||
|
||||
Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful
|
||||
communication about JPEG configuration in Sigma Photo Pro software.
|
||||
|
||||
Thank to Andrew Finkenstadt for hosting the ijg.org site.
|
||||
|
||||
Last but not least special thank to Thomas G. Lane for the original
|
||||
design and development of this singular software package.
|
||||
|
||||
|
||||
FILE FORMAT WARS
|
||||
================
|
||||
|
||||
Some JPEG programs produce files that are not compatible with our library.
|
||||
The root of the problem is that the ISO JPEG committee failed to specify a
|
||||
concrete file format. Some vendors "filled in the blanks" on their own,
|
||||
creating proprietary formats that no one else could read. (For example, none
|
||||
of the early commercial JPEG implementations for the Macintosh were able to
|
||||
exchange compressed files.)
|
||||
|
||||
The file format we have adopted is called JFIF (see REFERENCES). This format
|
||||
has been agreed to by a number of major commercial JPEG vendors, and it has
|
||||
become the de facto standard. JFIF is a minimal or "low end" representation.
|
||||
We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
|
||||
Technical Note #2) for "high end" applications that need to record a lot of
|
||||
additional data about an image. TIFF/JPEG is fairly new and not yet widely
|
||||
supported, unfortunately.
|
||||
|
||||
The upcoming JPEG Part 3 standard defines a file format called SPIFF.
|
||||
SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
|
||||
be able to read the most common variant of SPIFF. SPIFF has some technical
|
||||
advantages over JFIF, but its major claim to fame is simply that it is an
|
||||
official standard rather than an informal one. At this point it is unclear
|
||||
whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
|
||||
standard. IJG intends to support SPIFF once the standard is frozen, but we
|
||||
have not decided whether it should become our default output format or not.
|
||||
(In any case, our decoder will remain capable of reading JFIF indefinitely.)
|
||||
|
||||
Various proprietary file formats incorporating JPEG compression also exist.
|
||||
We have little or no sympathy for the existence of these formats. Indeed,
|
||||
The ISO JPEG standards committee actually promotes different formats like
|
||||
"JPEG 2000" or "JPEG XR" which are incompatible with original DCT-based
|
||||
JPEG and which are based on faulty technologies. IJG therefore does not
|
||||
and will not support such momentary mistakes (see REFERENCES).
|
||||
We have little or no sympathy for the promotion of these formats. Indeed,
|
||||
one of the original reasons for developing this free software was to help
|
||||
force convergence on common, open format standards for JPEG files. Don't
|
||||
use a proprietary file format!
|
||||
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.)
|
||||
|
||||
|
||||
TO DO
|
||||
=====
|
||||
|
||||
The major thrust for v7 will probably be improvement of visual quality.
|
||||
The current method for scaling the quantization tables is known not to be
|
||||
very good at low Q values. We also intend to investigate block boundary
|
||||
smoothing, "poor man's variable quantization", and other means of improving
|
||||
quality-vs-file-size performance without sacrificing compatibility.
|
||||
Version 8 is the first release of a new generation JPEG standard
|
||||
to overcome the limitations of the original JPEG specification.
|
||||
More features are being prepared for coming releases...
|
||||
|
||||
In future versions, we are considering supporting some of the upcoming JPEG
|
||||
Part 3 extensions --- principally, variable quantization and the SPIFF file
|
||||
format.
|
||||
|
||||
As always, speeding things up is of great interest.
|
||||
|
||||
Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
|
||||
Please send bug reports, offers of help, etc. to jpeg-info@uc.ag.
|
||||
|
||||
201
README-turbo.txt
201
README-turbo.txt
@@ -1,201 +0,0 @@
|
||||
*******************************************************************************
|
||||
** Background
|
||||
*******************************************************************************
|
||||
|
||||
libjpeg-turbo is a high-speed version of libjpeg for x86 and x86-64 processors
|
||||
which uses SIMD instructions (MMX, SSE2, etc.) to accelerate baseline JPEG
|
||||
compression and decompression. libjpeg-turbo is generally 2-4x as fast
|
||||
as the unmodified version of libjpeg, all else being equal.
|
||||
|
||||
libjpeg-turbo was originally based on libjpeg/SIMD by Miyasaka Masaru, but
|
||||
the TigerVNC and VirtualGL projects made numerous enhancements to the codec,
|
||||
including improved support for Mac OS X, 64-bit support, support for 32-bit
|
||||
and big endian pixel formats, accelerated Huffman encoding/decoding, and
|
||||
various bug fixes. The goal was to produce a fully open source codec that
|
||||
could replace the partially closed source TurboJPEG/IPP codec used by VirtualGL
|
||||
and TurboVNC. libjpeg-turbo generally performs in the range of 80-120% of
|
||||
TurboJPEG/IPP. It is faster in some areas but slower in others.
|
||||
|
||||
It was decided to split libjpeg-turbo into a separate SDK so that other
|
||||
projects could take advantage of this technology. The libjpeg-turbo shared
|
||||
libraries can be used as drop-in replacements for libjpeg on most systems.
|
||||
|
||||
|
||||
*******************************************************************************
|
||||
** License
|
||||
*******************************************************************************
|
||||
|
||||
Some of the optimizations to the Huffman encoder/decoder were borrowed from
|
||||
VirtualGL, and thus the libjpeg-turbo distribution, as a whole, falls under the
|
||||
wxWindows Library Licence, Version 3.1. A copy of this license can be found in
|
||||
this directory under LICENSE.txt. The wxWindows Library License is based on
|
||||
the LGPL but includes provisions which allow the Library to be statically
|
||||
linked into proprietary libraries and applications without requiring the
|
||||
resulting binaries to be distributed under the terms of the LGPL.
|
||||
|
||||
The rest of the source code, apart from these modifications, falls under a less
|
||||
restrictive, BSD-style license (see README.)
|
||||
|
||||
|
||||
*******************************************************************************
|
||||
** Using libjpeg-turbo
|
||||
*******************************************************************************
|
||||
|
||||
=============================
|
||||
Replacing libjpeg at Run Time
|
||||
=============================
|
||||
|
||||
If a Unix application is dynamically linked with libjpeg, then you can replace
|
||||
libjpeg with libjpeg-turbo at run time by manipulating the LD_LIBRARY_PATH.
|
||||
For instance:
|
||||
|
||||
[Using libjpeg]
|
||||
> time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
|
||||
real 0m0.392s
|
||||
user 0m0.074s
|
||||
sys 0m0.020s
|
||||
|
||||
[Using libjpeg-turbo]
|
||||
> export LD_LIBRARY_PATH=/opt/libjpeg-turbo/{lib}:$LD_LIBRARY_PATH
|
||||
> time cjpeg <vgl_5674_0098.ppm >vgl_5674_0098.jpg
|
||||
real 0m0.109s
|
||||
user 0m0.029s
|
||||
sys 0m0.010s
|
||||
|
||||
NOTE: {lib} can be lib, lib32, lib64, or lib/amd64, depending on the O/S and
|
||||
architecture.
|
||||
|
||||
System administrators can also replace the libjpeg sym links in /usr/{lib} with
|
||||
links to the libjpeg dynamic library located in /opt/libjpeg-turbo/{lib}. This
|
||||
will effectively accelerate every dynamically linked libjpeg application on the
|
||||
system.
|
||||
|
||||
The Windows distribution of the libjpeg-turbo SDK installs jpeg62.dll into
|
||||
c:\libjpeg-turbo\bin, and the PATH environment variable can be modified such
|
||||
that this directory is searched before any others that might contain
|
||||
jpeg62.dll. However, if jpeg62.dll also exists in an application's install
|
||||
directory, then Windows will load the application's version of it first. Thus,
|
||||
if an application ships with jpeg62.dll, then back up the application's version
|
||||
of jpeg62.dll and copy c:\libjpeg-turbo\bin\jpeg62.dll into the application's
|
||||
install directory to accelerate it.
|
||||
|
||||
The version of jpeg62.dll distributed in the libjpeg-turbo SDK requires the
|
||||
Visual C++ 2008 C run time DLL (msvcr90.dll). This library ships with more
|
||||
recent versions of Windows, but users of older versions can obtain it from the
|
||||
Visual C++ 2008 Redistributable Package, which is available as a free download
|
||||
from Microsoft's web site.
|
||||
|
||||
NOTE: Features of libjpeg which require passing a C run time structure, such
|
||||
as a file handle, from an application to libjpeg will probably not work with
|
||||
the distributed version of jpeg62.dll unless the application is also built to
|
||||
use the Visual C++ 2008 C run time DLL. In particular, this affects
|
||||
jpeg_stdio_dest() and jpeg_stdio_src().
|
||||
|
||||
Mac applications typically embed their own copies of libjpeg.62.dylib inside
|
||||
the (hidden) application bundle, so it is not possible to globally replace
|
||||
libjpeg on OS X systems. If an application uses a shared library version of
|
||||
libjpeg, then it may be possible to replace the application's version of it.
|
||||
This would generally involve copying libjpeg.62.dylib into the appropriate
|
||||
place in the application bundle and using install_name_tool to repoint the
|
||||
dylib to the new directory. This requires an advanced knowledge of OS X and
|
||||
would not survive an upgrade or a re-install of the application. Thus, it is
|
||||
not recommended for most users.
|
||||
|
||||
=======================
|
||||
Replacing TurboJPEG/IPP
|
||||
=======================
|
||||
|
||||
libjpeg-turbo is a drop-in replacement for the TurboJPEG/IPP SDK used by
|
||||
VirtualGL 2.1.x (and prior) and TurboVNC. libjpeg-turbo contains a wrapper
|
||||
library (TurboJPEG/OSS) that emulates the TurboJPEG API using libjpeg-turbo
|
||||
instead of the closed source Intel Performance Primitives. You can replace the
|
||||
TurboJPEG/IPP package on Linux systems with the libjpeg-turbo package in order
|
||||
to make existing releases of VirtualGL 2.1.x and TurboVNC use the new codec at
|
||||
run time. Note that the 64-bit libjpeg-turbo packages contain only 64-bit
|
||||
binaries, whereas the TurboJPEG/IPP 64-bit packages contain both 64-bit and
|
||||
32-bit binaries. Thus, to replace a TurboJPEG/IPP 64-bit package, install
|
||||
both the 64-bit and 32-bit versions of libjpeg-turbo.
|
||||
|
||||
You can also build the VirtualGL 2.1.x and TurboVNC source code with
|
||||
the libjpeg-turbo SDK instead of TurboJPEG/IPP. It should work identically.
|
||||
libjpeg-turbo also includes static library versions of TurboJPEG/OSS, which
|
||||
are used to build VirtualGL 2.2 and later.
|
||||
|
||||
========================================
|
||||
Using libjpeg-turbo in Your Own Programs
|
||||
========================================
|
||||
|
||||
For the most part, libjpeg-turbo should work identically to libjpeg, so in
|
||||
most cases, an application can be built against libjpeg and then run against
|
||||
libjpeg-turbo. On Unix systems, you can build against libjpeg-turbo instead
|
||||
of libjpeg by setting
|
||||
|
||||
CPATH=/opt/libjpeg-turbo/include
|
||||
and
|
||||
LIBRARY_PATH=/opt/libjpeg-turbo/{lib}
|
||||
|
||||
({lib} = lib, lib32, lib64, or lib/amd64, as appropriate.)
|
||||
|
||||
If using Cygwin, then set
|
||||
|
||||
CPATH=/cygdrive/c/libjpeg-turbo-gcc[64]/include
|
||||
and
|
||||
LIBRARY_PATH=/cygdrive/c/libjpeg-turbo-gcc[64]/lib
|
||||
|
||||
If using MinGW, then set
|
||||
|
||||
CPATH=/c/libjpeg-turbo-gcc[64]/include
|
||||
and
|
||||
LIBRARY_PATH=/c/libjpeg-turbo-gcc[64]/lib
|
||||
|
||||
Building against libjpeg-turbo is useful, for instance, if you want to build an
|
||||
application that leverages the libjpeg-turbo colorspace extensions (see below.)
|
||||
On Linux and Solaris systems, you would still need to manipulate the
|
||||
LD_LIBRARY_PATH or sym links appropriately to use libjpeg-turbo at run time.
|
||||
On such systems, you can pass -R /opt/libjpeg-turbo/{lib} to the linker to
|
||||
force the use of libjpeg-turbo at run time rather than libjpeg (also useful if
|
||||
you want to leverage the colorspace extensions), or you can link against the
|
||||
libjpeg-turbo static library.
|
||||
|
||||
To force a Linux, Solaris, or MinGW application to link against the static
|
||||
version of libjpeg-turbo, you can use the following linker options:
|
||||
|
||||
-Wl,-Bstatic -ljpeg -Wl,-Bdynamic
|
||||
|
||||
On OS X, simply add /opt/libjpeg-turbo/{lib}/libjpeg.a to the linker command
|
||||
line (this also works on Linux and Solaris.)
|
||||
|
||||
To build Visual C++ applications using libjpeg-turbo, add
|
||||
c:\libjpeg-turbo[64]\include to your system or user INCLUDE environment
|
||||
variable and c:\libjpeg-turbo[64]\lib to your system or user LIB environment
|
||||
variable, and then link against either jpeg.lib (to use jpeg62.dll) or
|
||||
jpeg-static.lib (to use the static version of libjpeg-turbo.)
|
||||
|
||||
=====================
|
||||
Colorspace Extensions
|
||||
=====================
|
||||
|
||||
libjpeg-turbo includes extensions which allow JPEG images to be compressed
|
||||
directly from (and decompressed directly to) buffers which use BGR, BGRA,
|
||||
RGBA, ABGR, and ARGB pixel ordering. This is implemented with six new
|
||||
colorspace constants:
|
||||
|
||||
JCS_EXT_RGB /* red/green/blue */
|
||||
JCS_EXT_RGBX /* red/green/blue/x */
|
||||
JCS_EXT_BGR /* blue/green/red */
|
||||
JCS_EXT_BGRX /* blue/green/red/x */
|
||||
JCS_EXT_XBGR /* x/blue/green/red */
|
||||
JCS_EXT_XRGB /* x/red/green/blue */
|
||||
|
||||
Setting cinfo.in_color_space (compression) or cinfo.out_color_space
|
||||
(decompression) to one of these values will cause libjpeg-turbo to read the
|
||||
red, green, and blue values from (or write them to) the appropriate position in
|
||||
the pixel when YUV conversion is performed.
|
||||
|
||||
Your application can check for the existence of these extensions at compile
|
||||
time with:
|
||||
|
||||
#ifdef JCS_EXTENSIONS
|
||||
|
||||
At run time, attempting to use these extensions with a version of libjpeg
|
||||
that doesn't support them will result in a "Bogus input colorspace" error.
|
||||
136
acinclude.m4
136
acinclude.m4
@@ -1,136 +0,0 @@
|
||||
# AC_PROG_NASM
|
||||
# --------------------------
|
||||
# Check that NASM exists and determine flags
|
||||
AC_DEFUN([AC_PROG_NASM],[
|
||||
|
||||
AC_CHECK_PROGS(NASM, [nasm nasmw])
|
||||
test -z "$NASM" && AC_MSG_ERROR([no nasm (Netwide Assembler) found])
|
||||
|
||||
AC_MSG_CHECKING([for object file format of host system])
|
||||
case "$host_os" in
|
||||
cygwin* | mingw* | pw32* | interix*)
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
objfmt='Win64-COFF'
|
||||
;;
|
||||
*)
|
||||
objfmt='Win32-COFF'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
msdosdjgpp* | go32*)
|
||||
objfmt='COFF'
|
||||
;;
|
||||
os2-emx*) # not tested
|
||||
objfmt='MSOMF' # obj
|
||||
;;
|
||||
linux*coff* | linux*oldld*)
|
||||
objfmt='COFF' # ???
|
||||
;;
|
||||
linux*aout*)
|
||||
objfmt='a.out'
|
||||
;;
|
||||
linux*)
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
objfmt='ELF64'
|
||||
;;
|
||||
*)
|
||||
objfmt='ELF'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
freebsd* | netbsd* | openbsd*)
|
||||
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
|
||||
objfmt='BSD-a.out'
|
||||
else
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
objfmt='ELF64'
|
||||
;;
|
||||
*)
|
||||
objfmt='ELF'
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
solaris* | sunos* | sysv* | sco*)
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
objfmt='ELF64'
|
||||
;;
|
||||
*)
|
||||
objfmt='ELF'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
darwin* | rhapsody* | nextstep* | openstep* | macos*)
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
objfmt='Mach-O64'
|
||||
;;
|
||||
*)
|
||||
objfmt='Mach-O'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
objfmt='ELF ?'
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_RESULT([$objfmt])
|
||||
if test "$objfmt" = 'ELF ?'; then
|
||||
objfmt='ELF'
|
||||
AC_MSG_WARN([unexpected host system. assumed that the format is $objfmt.])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for object file format specifier (NAFLAGS) ])
|
||||
case "$objfmt" in
|
||||
MSOMF) NAFLAGS='-fobj -DOBJ32';;
|
||||
Win32-COFF) NAFLAGS='-fwin32 -DWIN32';;
|
||||
Win64-COFF) NAFLAGS='-fwin64 -DWIN64 -D__x86_64__';;
|
||||
COFF) NAFLAGS='-fcoff -DCOFF';;
|
||||
a.out) NAFLAGS='-faout -DAOUT';;
|
||||
BSD-a.out) NAFLAGS='-faoutb -DAOUT';;
|
||||
ELF) NAFLAGS='-felf -DELF';;
|
||||
ELF64) NAFLAGS='-felf64 -DELF -D__x86_64__';;
|
||||
RDF) NAFLAGS='-frdf -DRDF';;
|
||||
Mach-O) NAFLAGS='-fmacho -DMACHO';;
|
||||
Mach-O64) NAFLAGS='-fmacho64 -DMACHO -D__x86_64__';;
|
||||
esac
|
||||
AC_MSG_RESULT([$NAFLAGS])
|
||||
AC_SUBST([NAFLAGS])
|
||||
|
||||
AC_MSG_CHECKING([whether the assembler ($NASM $NAFLAGS) works])
|
||||
cat > conftest.asm <<EOF
|
||||
[%line __oline__ "configure"
|
||||
section .text
|
||||
global _main,main
|
||||
_main:
|
||||
main: xor eax,eax
|
||||
ret
|
||||
]EOF
|
||||
try_nasm='$NASM $NAFLAGS -o conftest.o conftest.asm'
|
||||
if AC_TRY_EVAL(try_nasm) && test -s conftest.o; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
echo "configure: failed program was:" >&AC_FD_CC
|
||||
cat conftest.asm >&AC_FD_CC
|
||||
rm -rf conftest*
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([installation or configuration problem: assembler cannot create object files.])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether the linker accepts assembler output])
|
||||
try_nasm='${CC-cc} -o conftest${ac_exeext} $LDFLAGS conftest.o $LIBS 1>&AC_FD_CC'
|
||||
if AC_TRY_EVAL(try_nasm) && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
rm -rf conftest*
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([configuration problem: maybe object file format mismatch.])
|
||||
fi
|
||||
|
||||
])
|
||||
9471
aclocal.m4
vendored
Normal file
9471
aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
36
ansi2knr.1
Normal file
36
ansi2knr.1
Normal file
@@ -0,0 +1,36 @@
|
||||
.TH ANSI2KNR 1 "19 Jan 1996"
|
||||
.SH NAME
|
||||
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
|
||||
.SH SYNOPSIS
|
||||
.I ansi2knr
|
||||
[--varargs] input_file [output_file]
|
||||
.SH DESCRIPTION
|
||||
If no output_file is supplied, output goes to stdout.
|
||||
.br
|
||||
There are no error messages.
|
||||
.sp
|
||||
.I ansi2knr
|
||||
recognizes function definitions by seeing a non-keyword identifier at the left
|
||||
margin, followed by a left parenthesis, with a right parenthesis as the last
|
||||
character on the line, and with a left brace as the first token on the
|
||||
following line (ignoring possible intervening comments). It will recognize a
|
||||
multi-line header provided that no intervening line ends with a left or right
|
||||
brace or a semicolon. These algorithms ignore whitespace and comments, except
|
||||
that the function name must be the first thing on the line.
|
||||
.sp
|
||||
The following constructs will confuse it:
|
||||
.br
|
||||
- Any other construct that starts at the left margin and follows the
|
||||
above syntax (such as a macro or function call).
|
||||
.br
|
||||
- Some macros that tinker with the syntax of the function header.
|
||||
.sp
|
||||
The --varargs switch is obsolete, and is recognized only for
|
||||
backwards compatibility. The present version of
|
||||
.I ansi2knr
|
||||
will always attempt to convert a ... argument to va_alist and va_dcl.
|
||||
.SH AUTHOR
|
||||
L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
|
||||
continues to maintain the current version; most of the code in the current
|
||||
version is his work. ansi2knr also includes contributions by Francois
|
||||
Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.
|
||||
739
ansi2knr.c
Normal file
739
ansi2knr.c
Normal file
@@ -0,0 +1,739 @@
|
||||
/* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. */
|
||||
|
||||
/*$Id: ansi2knr.c,v 1.14 2003/09/06 05:36:56 eggert Exp $*/
|
||||
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
|
||||
|
||||
/*
|
||||
ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY. No author or distributor accepts responsibility to anyone for the
|
||||
consequences of using it or for whether it serves any particular purpose or
|
||||
works at all, unless he says so in writing. Refer to the GNU General Public
|
||||
License (the "GPL") for full details.
|
||||
|
||||
Everyone is granted permission to copy, modify and redistribute ansi2knr,
|
||||
but only under the conditions described in the GPL. A copy of this license
|
||||
is supposed to have been given to you along with ansi2knr so you can know
|
||||
your rights and responsibilities. It should be in a file named COPYLEFT,
|
||||
or, if there is no file named COPYLEFT, a file named COPYING. Among other
|
||||
things, the copyright notice and this notice must be preserved on all
|
||||
copies.
|
||||
|
||||
We explicitly state here what we believe is already implied by the GPL: if
|
||||
the ansi2knr program is distributed as a separate set of sources and a
|
||||
separate executable file which are aggregated on a storage medium together
|
||||
with another program, this in itself does not bring the other program under
|
||||
the GPL, nor does the mere fact that such a program or the procedures for
|
||||
constructing it invoke the ansi2knr executable bring any other part of the
|
||||
program under the GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Usage:
|
||||
ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]
|
||||
* --filename provides the file name for the #line directive in the output,
|
||||
* overriding input_file (if present).
|
||||
* If no input_file is supplied, input is read from stdin.
|
||||
* If no output_file is supplied, output goes to stdout.
|
||||
* There are no error messages.
|
||||
*
|
||||
* ansi2knr recognizes function definitions by seeing a non-keyword
|
||||
* identifier at the left margin, followed by a left parenthesis, with a
|
||||
* right parenthesis as the last character on the line, and with a left
|
||||
* brace as the first token on the following line (ignoring possible
|
||||
* intervening comments and/or preprocessor directives), except that a line
|
||||
* consisting of only
|
||||
* identifier1(identifier2)
|
||||
* will not be considered a function definition unless identifier2 is
|
||||
* the word "void", and a line consisting of
|
||||
* identifier1(identifier2, <<arbitrary>>)
|
||||
* will not be considered a function definition.
|
||||
* ansi2knr will recognize a multi-line header provided that no intervening
|
||||
* line ends with a left or right brace or a semicolon. These algorithms
|
||||
* ignore whitespace, comments, and preprocessor directives, except that
|
||||
* the function name must be the first thing on the line. The following
|
||||
* constructs will confuse it:
|
||||
* - Any other construct that starts at the left margin and
|
||||
* follows the above syntax (such as a macro or function call).
|
||||
* - Some macros that tinker with the syntax of function headers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The original and principal author of ansi2knr is L. Peter Deutsch
|
||||
* <ghost@aladdin.com>. Other authors are noted in the change history
|
||||
* that follows (in reverse chronological order):
|
||||
|
||||
lpd 2000-04-12 backs out Eggert's changes because of bugs:
|
||||
- concatlits didn't declare the type of its bufend argument;
|
||||
- concatlits didn't recognize when it was inside a comment;
|
||||
- scanstring could scan backward past the beginning of the string; when
|
||||
- the check for \ + newline in scanstring was unnecessary.
|
||||
|
||||
2000-03-05 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
Add support for concatenated string literals.
|
||||
* ansi2knr.c (concatlits): New decl.
|
||||
(main): Invoke concatlits to concatenate string literals.
|
||||
(scanstring): Handle backslash-newline correctly. Work with
|
||||
character constants. Fix bug when scanning backwards through
|
||||
backslash-quote. Check for unterminated strings.
|
||||
(convert1): Parse character constants, too.
|
||||
(appendline, concatlits): New functions.
|
||||
* ansi2knr.1: Document this.
|
||||
|
||||
lpd 1999-08-17 added code to allow preprocessor directives
|
||||
wherever comments are allowed
|
||||
lpd 1999-04-12 added minor fixes from Pavel Roskin
|
||||
<pavel_roskin@geocities.com> for clean compilation with
|
||||
gcc -W -Wall
|
||||
lpd 1999-03-22 added hack to recognize lines consisting of
|
||||
identifier1(identifier2, xxx) as *not* being procedures
|
||||
lpd 1999-02-03 made indentation of preprocessor commands consistent
|
||||
lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
|
||||
endless loop; quoted strings within an argument list
|
||||
confused the parser
|
||||
lpd 1999-01-24 added a check for write errors on the output,
|
||||
suggested by Jim Meyering <meyering@ascend.com>
|
||||
lpd 1998-11-09 added further hack to recognize identifier(void)
|
||||
as being a procedure
|
||||
lpd 1998-10-23 added hack to recognize lines consisting of
|
||||
identifier1(identifier2) as *not* being procedures
|
||||
lpd 1997-12-08 made input_file optional; only closes input and/or
|
||||
output file if not stdin or stdout respectively; prints
|
||||
usage message on stderr rather than stdout; adds
|
||||
--filename switch (changes suggested by
|
||||
<ceder@lysator.liu.se>)
|
||||
lpd 1996-01-21 added code to cope with not HAVE_CONFIG_H and with
|
||||
compilers that don't understand void, as suggested by
|
||||
Tom Lane
|
||||
lpd 1996-01-15 changed to require that the first non-comment token
|
||||
on the line following a function header be a left brace,
|
||||
to reduce sensitivity to macros, as suggested by Tom Lane
|
||||
<tgl@sss.pgh.pa.us>
|
||||
lpd 1995-06-22 removed #ifndefs whose sole purpose was to define
|
||||
undefined preprocessor symbols as 0; changed all #ifdefs
|
||||
for configuration symbols to #ifs
|
||||
lpd 1995-04-05 changed copyright notice to make it clear that
|
||||
including ansi2knr in a program does not bring the entire
|
||||
program under the GPL
|
||||
lpd 1994-12-18 added conditionals for systems where ctype macros
|
||||
don't handle 8-bit characters properly, suggested by
|
||||
Francois Pinard <pinard@iro.umontreal.ca>;
|
||||
removed --varargs switch (this is now the default)
|
||||
lpd 1994-10-10 removed CONFIG_BROKETS conditional
|
||||
lpd 1994-07-16 added some conditionals to help GNU `configure',
|
||||
suggested by Francois Pinard <pinard@iro.umontreal.ca>;
|
||||
properly erase prototype args in function parameters,
|
||||
contributed by Jim Avera <jima@netcom.com>;
|
||||
correct error in writeblanks (it shouldn't erase EOLs)
|
||||
lpd 1989-xx-xx original version
|
||||
*/
|
||||
|
||||
/* Most of the conditionals here are to make ansi2knr work with */
|
||||
/* or without the GNU configure machinery. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
|
||||
/*
|
||||
For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
|
||||
This will define HAVE_CONFIG_H and so, activate the following lines.
|
||||
*/
|
||||
|
||||
# if STDC_HEADERS || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# else
|
||||
# include <strings.h>
|
||||
# endif
|
||||
|
||||
#else /* not HAVE_CONFIG_H */
|
||||
|
||||
/* Otherwise do it the hard way */
|
||||
|
||||
# ifdef BSD
|
||||
# include <strings.h>
|
||||
# else
|
||||
# ifdef VMS
|
||||
extern int strlen(), strncmp();
|
||||
# else
|
||||
# include <string.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif /* not HAVE_CONFIG_H */
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
/*
|
||||
malloc and free should be declared in stdlib.h,
|
||||
but if you've got a K&R compiler, they probably aren't.
|
||||
*/
|
||||
# ifdef MSDOS
|
||||
# include <malloc.h>
|
||||
# else
|
||||
# ifdef VMS
|
||||
extern char *malloc();
|
||||
extern void free();
|
||||
# else
|
||||
extern char *malloc();
|
||||
extern int free();
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Define NULL (for *very* old compilers). */
|
||||
#ifndef NULL
|
||||
# define NULL (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The ctype macros don't always handle 8-bit characters correctly.
|
||||
* Compensate for this here.
|
||||
*/
|
||||
#ifdef isascii
|
||||
# undef HAVE_ISASCII /* just in case */
|
||||
# define HAVE_ISASCII 1
|
||||
#else
|
||||
#endif
|
||||
#if STDC_HEADERS || !HAVE_ISASCII
|
||||
# define is_ascii(c) 1
|
||||
#else
|
||||
# define is_ascii(c) isascii(c)
|
||||
#endif
|
||||
|
||||
#define is_space(c) (is_ascii(c) && isspace(c))
|
||||
#define is_alpha(c) (is_ascii(c) && isalpha(c))
|
||||
#define is_alnum(c) (is_ascii(c) && isalnum(c))
|
||||
|
||||
/* Scanning macros */
|
||||
#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
|
||||
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
|
||||
|
||||
/* Forward references */
|
||||
char *ppdirforward();
|
||||
char *ppdirbackward();
|
||||
char *skipspace();
|
||||
char *scanstring();
|
||||
int writeblanks();
|
||||
int test1();
|
||||
int convert1();
|
||||
|
||||
/* The main program */
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{ FILE *in = stdin;
|
||||
FILE *out = stdout;
|
||||
char *filename = 0;
|
||||
char *program_name = argv[0];
|
||||
char *output_name = 0;
|
||||
#define bufsize 5000 /* arbitrary size */
|
||||
char *buf;
|
||||
char *line;
|
||||
char *more;
|
||||
char *usage =
|
||||
"Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
|
||||
/*
|
||||
* In previous versions, ansi2knr recognized a --varargs switch.
|
||||
* If this switch was supplied, ansi2knr would attempt to convert
|
||||
* a ... argument to va_alist and va_dcl; if this switch was not
|
||||
* supplied, ansi2knr would simply drop any such arguments.
|
||||
* Now, ansi2knr always does this conversion, and we only
|
||||
* check for this switch for backward compatibility.
|
||||
*/
|
||||
int convert_varargs = 1;
|
||||
int output_error;
|
||||
|
||||
while ( argc > 1 && argv[1][0] == '-' ) {
|
||||
if ( !strcmp(argv[1], "--varargs") ) {
|
||||
convert_varargs = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
continue;
|
||||
}
|
||||
if ( !strcmp(argv[1], "--filename") && argc > 2 ) {
|
||||
filename = argv[2];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
|
||||
argv[1]);
|
||||
fprintf(stderr, usage);
|
||||
exit(1);
|
||||
}
|
||||
switch ( argc )
|
||||
{
|
||||
default:
|
||||
fprintf(stderr, usage);
|
||||
exit(0);
|
||||
case 3:
|
||||
output_name = argv[2];
|
||||
out = fopen(output_name, "w");
|
||||
if ( out == NULL ) {
|
||||
fprintf(stderr, "%s: Cannot open output file %s\n",
|
||||
program_name, output_name);
|
||||
exit(1);
|
||||
}
|
||||
/* falls through */
|
||||
case 2:
|
||||
in = fopen(argv[1], "r");
|
||||
if ( in == NULL ) {
|
||||
fprintf(stderr, "%s: Cannot open input file %s\n",
|
||||
program_name, argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
if ( filename == 0 )
|
||||
filename = argv[1];
|
||||
/* falls through */
|
||||
case 1:
|
||||
break;
|
||||
}
|
||||
if ( filename )
|
||||
fprintf(out, "#line 1 \"%s\"\n", filename);
|
||||
buf = malloc(bufsize);
|
||||
if ( buf == NULL )
|
||||
{
|
||||
fprintf(stderr, "Unable to allocate read buffer!\n");
|
||||
exit(1);
|
||||
}
|
||||
line = buf;
|
||||
while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
|
||||
{
|
||||
test: line += strlen(line);
|
||||
switch ( test1(buf) )
|
||||
{
|
||||
case 2: /* a function header */
|
||||
convert1(buf, out, 1, convert_varargs);
|
||||
break;
|
||||
case 1: /* a function */
|
||||
/* Check for a { at the start of the next line. */
|
||||
more = ++line;
|
||||
f: if ( line >= buf + (bufsize - 1) ) /* overflow check */
|
||||
goto wl;
|
||||
if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
|
||||
goto wl;
|
||||
switch ( *skipspace(ppdirforward(more), 1) )
|
||||
{
|
||||
case '{':
|
||||
/* Definitely a function header. */
|
||||
convert1(buf, out, 0, convert_varargs);
|
||||
fputs(more, out);
|
||||
break;
|
||||
case 0:
|
||||
/* The next line was blank or a comment: */
|
||||
/* keep scanning for a non-comment. */
|
||||
line += strlen(line);
|
||||
goto f;
|
||||
default:
|
||||
/* buf isn't a function header, but */
|
||||
/* more might be. */
|
||||
fputs(buf, out);
|
||||
strcpy(buf, more);
|
||||
line = buf;
|
||||
goto test;
|
||||
}
|
||||
break;
|
||||
case -1: /* maybe the start of a function */
|
||||
if ( line != buf + (bufsize - 1) ) /* overflow check */
|
||||
continue;
|
||||
/* falls through */
|
||||
default: /* not a function */
|
||||
wl: fputs(buf, out);
|
||||
break;
|
||||
}
|
||||
line = buf;
|
||||
}
|
||||
if ( line != buf )
|
||||
fputs(buf, out);
|
||||
free(buf);
|
||||
if ( output_name ) {
|
||||
output_error = ferror(out);
|
||||
output_error |= fclose(out);
|
||||
} else { /* out == stdout */
|
||||
fflush(out);
|
||||
output_error = ferror(out);
|
||||
}
|
||||
if ( output_error ) {
|
||||
fprintf(stderr, "%s: error writing to %s\n", program_name,
|
||||
(output_name ? output_name : "stdout"));
|
||||
exit(1);
|
||||
}
|
||||
if ( in != stdin )
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip forward or backward over one or more preprocessor directives.
|
||||
*/
|
||||
char *
|
||||
ppdirforward(p)
|
||||
char *p;
|
||||
{
|
||||
for (; *p == '#'; ++p) {
|
||||
for (; *p != '\r' && *p != '\n'; ++p)
|
||||
if (*p == 0)
|
||||
return p;
|
||||
if (*p == '\r' && p[1] == '\n')
|
||||
++p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
char *
|
||||
ppdirbackward(p, limit)
|
||||
char *p;
|
||||
char *limit;
|
||||
{
|
||||
char *np = p;
|
||||
|
||||
for (;; p = --np) {
|
||||
if (*np == '\n' && np[-1] == '\r')
|
||||
--np;
|
||||
for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np)
|
||||
if (np[-1] == 0)
|
||||
return np;
|
||||
if (*np != '#')
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over whitespace, comments, and preprocessor directives,
|
||||
* in either direction.
|
||||
*/
|
||||
char *
|
||||
skipspace(p, dir)
|
||||
char *p;
|
||||
int dir; /* 1 for forward, -1 for backward */
|
||||
{
|
||||
for ( ; ; ) {
|
||||
while ( is_space(*p) )
|
||||
p += dir;
|
||||
if ( !(*p == '/' && p[dir] == '*') )
|
||||
break;
|
||||
p += dir; p += dir;
|
||||
while ( !(*p == '*' && p[dir] == '/') ) {
|
||||
if ( *p == 0 )
|
||||
return p; /* multi-line comment?? */
|
||||
p += dir;
|
||||
}
|
||||
p += dir; p += dir;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Scan over a quoted string, in either direction. */
|
||||
char *
|
||||
scanstring(p, dir)
|
||||
char *p;
|
||||
int dir;
|
||||
{
|
||||
for (p += dir; ; p += dir)
|
||||
if (*p == '"' && p[-dir] != '\\')
|
||||
return p + dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write blanks over part of a string.
|
||||
* Don't overwrite end-of-line characters.
|
||||
*/
|
||||
int
|
||||
writeblanks(start, end)
|
||||
char *start;
|
||||
char *end;
|
||||
{ char *p;
|
||||
for ( p = start; p < end; p++ )
|
||||
if ( *p != '\r' && *p != '\n' )
|
||||
*p = ' ';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether the string in buf is a function definition.
|
||||
* The string may contain and/or end with a newline.
|
||||
* Return as follows:
|
||||
* 0 - definitely not a function definition;
|
||||
* 1 - definitely a function definition;
|
||||
* 2 - definitely a function prototype (NOT USED);
|
||||
* -1 - may be the beginning of a function definition,
|
||||
* append another line and look again.
|
||||
* The reason we don't attempt to convert function prototypes is that
|
||||
* Ghostscript's declaration-generating macros look too much like
|
||||
* prototypes, and confuse the algorithms.
|
||||
*/
|
||||
int
|
||||
test1(buf)
|
||||
char *buf;
|
||||
{ char *p = buf;
|
||||
char *bend;
|
||||
char *endfn;
|
||||
int contin;
|
||||
|
||||
if ( !isidfirstchar(*p) )
|
||||
return 0; /* no name at left margin */
|
||||
bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1);
|
||||
switch ( *bend )
|
||||
{
|
||||
case ';': contin = 0 /*2*/; break;
|
||||
case ')': contin = 1; break;
|
||||
case '{': return 0; /* not a function */
|
||||
case '}': return 0; /* not a function */
|
||||
default: contin = -1;
|
||||
}
|
||||
while ( isidchar(*p) )
|
||||
p++;
|
||||
endfn = p;
|
||||
p = skipspace(p, 1);
|
||||
if ( *p++ != '(' )
|
||||
return 0; /* not a function */
|
||||
p = skipspace(p, 1);
|
||||
if ( *p == ')' )
|
||||
return 0; /* no parameters */
|
||||
/* Check that the apparent function name isn't a keyword. */
|
||||
/* We only need to check for keywords that could be followed */
|
||||
/* by a left parenthesis (which, unfortunately, is most of them). */
|
||||
{ static char *words[] =
|
||||
{ "asm", "auto", "case", "char", "const", "double",
|
||||
"extern", "float", "for", "if", "int", "long",
|
||||
"register", "return", "short", "signed", "sizeof",
|
||||
"static", "switch", "typedef", "unsigned",
|
||||
"void", "volatile", "while", 0
|
||||
};
|
||||
char **key = words;
|
||||
char *kp;
|
||||
unsigned len = endfn - buf;
|
||||
|
||||
while ( (kp = *key) != 0 )
|
||||
{ if ( strlen(kp) == len && !strncmp(kp, buf, len) )
|
||||
return 0; /* name is a keyword */
|
||||
key++;
|
||||
}
|
||||
}
|
||||
{
|
||||
char *id = p;
|
||||
int len;
|
||||
/*
|
||||
* Check for identifier1(identifier2) and not
|
||||
* identifier1(void), or identifier1(identifier2, xxxx).
|
||||
*/
|
||||
|
||||
while ( isidchar(*p) )
|
||||
p++;
|
||||
len = p - id;
|
||||
p = skipspace(p, 1);
|
||||
if (*p == ',' ||
|
||||
(*p == ')' && (len != 4 || strncmp(id, "void", 4)))
|
||||
)
|
||||
return 0; /* not a function */
|
||||
}
|
||||
/*
|
||||
* If the last significant character was a ), we need to count
|
||||
* parentheses, because it might be part of a formal parameter
|
||||
* that is a procedure.
|
||||
*/
|
||||
if (contin > 0) {
|
||||
int level = 0;
|
||||
|
||||
for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
|
||||
level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
|
||||
if (level > 0)
|
||||
contin = -1;
|
||||
}
|
||||
return contin;
|
||||
}
|
||||
|
||||
/* Convert a recognized function definition or header to K&R syntax. */
|
||||
int
|
||||
convert1(buf, out, header, convert_varargs)
|
||||
char *buf;
|
||||
FILE *out;
|
||||
int header; /* Boolean */
|
||||
int convert_varargs; /* Boolean */
|
||||
{ char *endfn;
|
||||
char *p;
|
||||
/*
|
||||
* The breaks table contains pointers to the beginning and end
|
||||
* of each argument.
|
||||
*/
|
||||
char **breaks;
|
||||
unsigned num_breaks = 2; /* for testing */
|
||||
char **btop;
|
||||
char **bp;
|
||||
char **ap;
|
||||
char *vararg = 0;
|
||||
|
||||
/* Pre-ANSI implementations don't agree on whether strchr */
|
||||
/* is called strchr or index, so we open-code it here. */
|
||||
for ( endfn = buf; *(endfn++) != '('; )
|
||||
;
|
||||
top: p = endfn;
|
||||
breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
|
||||
if ( breaks == NULL )
|
||||
{ /* Couldn't allocate break table, give up */
|
||||
fprintf(stderr, "Unable to allocate break table!\n");
|
||||
fputs(buf, out);
|
||||
return -1;
|
||||
}
|
||||
btop = breaks + num_breaks * 2 - 2;
|
||||
bp = breaks;
|
||||
/* Parse the argument list */
|
||||
do
|
||||
{ int level = 0;
|
||||
char *lp = NULL;
|
||||
char *rp = NULL;
|
||||
char *end = NULL;
|
||||
|
||||
if ( bp >= btop )
|
||||
{ /* Filled up break table. */
|
||||
/* Allocate a bigger one and start over. */
|
||||
free((char *)breaks);
|
||||
num_breaks <<= 1;
|
||||
goto top;
|
||||
}
|
||||
*bp++ = p;
|
||||
/* Find the end of the argument */
|
||||
for ( ; end == NULL; p++ )
|
||||
{ switch(*p)
|
||||
{
|
||||
case ',':
|
||||
if ( !level ) end = p;
|
||||
break;
|
||||
case '(':
|
||||
if ( !level ) lp = p;
|
||||
level++;
|
||||
break;
|
||||
case ')':
|
||||
if ( --level < 0 ) end = p;
|
||||
else rp = p;
|
||||
break;
|
||||
case '/':
|
||||
if (p[1] == '*')
|
||||
p = skipspace(p, 1) - 1;
|
||||
break;
|
||||
case '"':
|
||||
p = scanstring(p, 1) - 1;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
/* Erase any embedded prototype parameters. */
|
||||
if ( lp && rp )
|
||||
writeblanks(lp + 1, rp);
|
||||
p--; /* back up over terminator */
|
||||
/* Find the name being declared. */
|
||||
/* This is complicated because of procedure and */
|
||||
/* array modifiers. */
|
||||
for ( ; ; )
|
||||
{ p = skipspace(p - 1, -1);
|
||||
switch ( *p )
|
||||
{
|
||||
case ']': /* skip array dimension(s) */
|
||||
case ')': /* skip procedure args OR name */
|
||||
{ int level = 1;
|
||||
while ( level )
|
||||
switch ( *--p )
|
||||
{
|
||||
case ']': case ')':
|
||||
level++;
|
||||
break;
|
||||
case '[': case '(':
|
||||
level--;
|
||||
break;
|
||||
case '/':
|
||||
if (p > buf && p[-1] == '*')
|
||||
p = skipspace(p, -1) + 1;
|
||||
break;
|
||||
case '"':
|
||||
p = scanstring(p, -1) + 1;
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
|
||||
{ /* We found the name being declared */
|
||||
while ( !isidfirstchar(*p) )
|
||||
p = skipspace(p, 1) + 1;
|
||||
goto found;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
|
||||
{ if ( convert_varargs )
|
||||
{ *bp++ = "va_alist";
|
||||
vararg = p-2;
|
||||
}
|
||||
else
|
||||
{ p++;
|
||||
if ( bp == breaks + 1 ) /* sole argument */
|
||||
writeblanks(breaks[0], p);
|
||||
else
|
||||
writeblanks(bp[-1] - 1, p);
|
||||
bp--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ while ( isidchar(*p) ) p--;
|
||||
*bp++ = p+1;
|
||||
}
|
||||
p = end;
|
||||
}
|
||||
while ( *p++ == ',' );
|
||||
*bp = p;
|
||||
/* Make a special check for 'void' arglist */
|
||||
if ( bp == breaks+2 )
|
||||
{ p = skipspace(breaks[0], 1);
|
||||
if ( !strncmp(p, "void", 4) )
|
||||
{ p = skipspace(p+4, 1);
|
||||
if ( p == breaks[2] - 1 )
|
||||
{ bp = breaks; /* yup, pretend arglist is empty */
|
||||
writeblanks(breaks[0], p + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Put out the function name and left parenthesis. */
|
||||
p = buf;
|
||||
while ( p != endfn ) putc(*p, out), p++;
|
||||
/* Put out the declaration. */
|
||||
if ( header )
|
||||
{ fputs(");", out);
|
||||
for ( p = breaks[0]; *p; p++ )
|
||||
if ( *p == '\r' || *p == '\n' )
|
||||
putc(*p, out);
|
||||
}
|
||||
else
|
||||
{ for ( ap = breaks+1; ap < bp; ap += 2 )
|
||||
{ p = *ap;
|
||||
while ( isidchar(*p) )
|
||||
putc(*p, out), p++;
|
||||
if ( ap < bp - 1 )
|
||||
fputs(", ", out);
|
||||
}
|
||||
fputs(") ", out);
|
||||
/* Put out the argument declarations */
|
||||
for ( ap = breaks+2; ap <= bp; ap += 2 )
|
||||
(*ap)[-1] = ';';
|
||||
if ( vararg != 0 )
|
||||
{ *vararg = 0;
|
||||
fputs(breaks[0], out); /* any prior args */
|
||||
fputs("va_dcl", out); /* the final arg */
|
||||
fputs(bp[0], out);
|
||||
}
|
||||
else
|
||||
fputs(breaks[0], out);
|
||||
}
|
||||
free((char *)breaks);
|
||||
return 0;
|
||||
}
|
||||
370
bmp.c
370
bmp.c
@@ -1,370 +0,0 @@
|
||||
/* Copyright (C)2004 Landmark Graphics Corporation
|
||||
* Copyright (C)2005 Sun Microsystems, Inc.
|
||||
*
|
||||
* This library is free software and may be redistributed and/or modified under
|
||||
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
|
||||
* any later version. The full license is in the LICENSE.txt file included
|
||||
* with this distribution.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* wxWindows Library License for more details.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "./rrutil.h"
|
||||
#include "./bmp.h"
|
||||
|
||||
#ifndef BI_BITFIELDS
|
||||
#define BI_BITFIELDS 3L
|
||||
#endif
|
||||
#ifndef BI_RGB
|
||||
#define BI_RGB 0L
|
||||
#endif
|
||||
|
||||
#define BMPHDRSIZE 54
|
||||
typedef struct _bmphdr
|
||||
{
|
||||
unsigned short bfType;
|
||||
unsigned int bfSize;
|
||||
unsigned short bfReserved1, bfReserved2;
|
||||
unsigned int bfOffBits;
|
||||
|
||||
unsigned int biSize;
|
||||
int biWidth, biHeight;
|
||||
unsigned short biPlanes, biBitCount;
|
||||
unsigned int biCompression, biSizeImage;
|
||||
int biXPelsPerMeter, biYPelsPerMeter;
|
||||
unsigned int biClrUsed, biClrImportant;
|
||||
} bmphdr;
|
||||
|
||||
static const char *__bmperr="No error";
|
||||
|
||||
static const int ps[BMPPIXELFORMATS]={3, 4, 3, 4, 4, 4};
|
||||
static const int roffset[BMPPIXELFORMATS]={0, 0, 2, 2, 3, 1};
|
||||
static const int goffset[BMPPIXELFORMATS]={1, 1, 1, 1, 2, 2};
|
||||
static const int boffset[BMPPIXELFORMATS]={2, 2, 0, 0, 1, 3};
|
||||
|
||||
#define _throw(m) {__bmperr=m; retcode=-1; goto finally;}
|
||||
#define _unix(f) {if((f)==-1) _throw(strerror(errno));}
|
||||
#define _catch(f) {if((f)==-1) {retcode=-1; goto finally;}}
|
||||
|
||||
#define readme(fd, addr, size) \
|
||||
if((bytesread=read(fd, addr, (size)))==-1) _throw(strerror(errno)); \
|
||||
if(bytesread!=(size)) _throw("Read error");
|
||||
|
||||
void pixelconvert(unsigned char *srcbuf, enum BMPPIXELFORMAT srcformat,
|
||||
int srcpitch, unsigned char *dstbuf, enum BMPPIXELFORMAT dstformat, int dstpitch,
|
||||
int w, int h, int flip)
|
||||
{
|
||||
unsigned char *srcptr, *srcptr0, *dstptr, *dstptr0;
|
||||
int i, j;
|
||||
|
||||
srcptr=flip? &srcbuf[srcpitch*(h-1)]:srcbuf;
|
||||
for(j=0, dstptr=dstbuf; j<h; j++,
|
||||
srcptr+=flip? -srcpitch:srcpitch, dstptr+=dstpitch)
|
||||
{
|
||||
for(i=0, srcptr0=srcptr, dstptr0=dstptr; i<w; i++,
|
||||
srcptr0+=ps[srcformat], dstptr0+=ps[dstformat])
|
||||
{
|
||||
dstptr0[roffset[dstformat]]=srcptr0[roffset[srcformat]];
|
||||
dstptr0[goffset[dstformat]]=srcptr0[goffset[srcformat]];
|
||||
dstptr0[boffset[dstformat]]=srcptr0[boffset[srcformat]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int loadppm(int *fd, unsigned char **buf, int *w, int *h,
|
||||
enum BMPPIXELFORMAT f, int align, int dstbottomup, int ascii)
|
||||
{
|
||||
FILE *fs=NULL; int retcode=0, scalefactor, dstpitch;
|
||||
unsigned char *tempbuf=NULL; char temps[255], temps2[255];
|
||||
int numread=0, totalread=0, pixel[3], i, j;
|
||||
|
||||
if((fs=fdopen(*fd, "r"))==NULL) _throw(strerror(errno));
|
||||
|
||||
do
|
||||
{
|
||||
if(!fgets(temps, 255, fs)) _throw("Read error");
|
||||
if(strlen(temps)==0 || temps[0]=='\n') continue;
|
||||
if(sscanf(temps, "%s", temps2)==1 && temps2[1]=='#') continue;
|
||||
switch(totalread)
|
||||
{
|
||||
case 0:
|
||||
if((numread=sscanf(temps, "%d %d %d", w, h, &scalefactor))==EOF)
|
||||
_throw("Read error");
|
||||
break;
|
||||
case 1:
|
||||
if((numread=sscanf(temps, "%d %d", h, &scalefactor))==EOF)
|
||||
_throw("Read error");
|
||||
break;
|
||||
case 2:
|
||||
if((numread=sscanf(temps, "%d", &scalefactor))==EOF)
|
||||
_throw("Read error");
|
||||
break;
|
||||
}
|
||||
totalread+=numread;
|
||||
} while(totalread<3);
|
||||
if((*w)<1 || (*h)<1 || scalefactor<1) _throw("Corrupt PPM header");
|
||||
|
||||
dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1));
|
||||
if((*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL)
|
||||
_throw("Memory allocation error");
|
||||
if(ascii)
|
||||
{
|
||||
for(j=0; j<*h; j++)
|
||||
{
|
||||
for(i=0; i<*w; i++)
|
||||
{
|
||||
if(fscanf(fs, "%d%d%d", &pixel[0], &pixel[1], &pixel[2])!=3)
|
||||
_throw("Read error");
|
||||
(*buf)[j*dstpitch+i*ps[f]+roffset[f]]=(unsigned char)(pixel[0]*255/scalefactor);
|
||||
(*buf)[j*dstpitch+i*ps[f]+goffset[f]]=(unsigned char)(pixel[1]*255/scalefactor);
|
||||
(*buf)[j*dstpitch+i*ps[f]+boffset[f]]=(unsigned char)(pixel[2]*255/scalefactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(scalefactor!=255)
|
||||
_throw("Binary PPMs must have 8-bit components");
|
||||
if((tempbuf=(unsigned char *)malloc((*w)*(*h)*3))==NULL)
|
||||
_throw("Memory allocation error");
|
||||
if(fread(tempbuf, (*w)*(*h)*3, 1, fs)!=1) _throw("Read error");
|
||||
pixelconvert(tempbuf, BMP_RGB, (*w)*3, *buf, f, dstpitch, *w, *h, dstbottomup);
|
||||
}
|
||||
|
||||
finally:
|
||||
if(fs) {fclose(fs); *fd=-1;}
|
||||
if(tempbuf) free(tempbuf);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
int loadbmp(char *filename, unsigned char **buf, int *w, int *h,
|
||||
enum BMPPIXELFORMAT f, int align, int dstbottomup)
|
||||
{
|
||||
int fd=-1, bytesread, srcpitch, srcbottomup=1, srcps, dstpitch,
|
||||
retcode=0;
|
||||
unsigned char *tempbuf=NULL;
|
||||
bmphdr bh; int flags=O_RDONLY;
|
||||
|
||||
dstbottomup=dstbottomup? 1:0;
|
||||
#ifdef _WIN32
|
||||
flags|=O_BINARY;
|
||||
#endif
|
||||
if(!filename || !buf || !w || !h || f<0 || f>BMPPIXELFORMATS-1 || align<1)
|
||||
_throw("invalid argument to loadbmp()");
|
||||
if((align&(align-1))!=0)
|
||||
_throw("Alignment must be a power of 2");
|
||||
_unix(fd=open(filename, flags));
|
||||
|
||||
readme(fd, &bh.bfType, sizeof(unsigned short));
|
||||
if(!littleendian()) bh.bfType=byteswap16(bh.bfType);
|
||||
|
||||
if(bh.bfType==0x3650)
|
||||
{
|
||||
_catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 0));
|
||||
goto finally;
|
||||
}
|
||||
if(bh.bfType==0x3350)
|
||||
{
|
||||
_catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 1));
|
||||
goto finally;
|
||||
}
|
||||
|
||||
readme(fd, &bh.bfSize, sizeof(unsigned int));
|
||||
readme(fd, &bh.bfReserved1, sizeof(unsigned short));
|
||||
readme(fd, &bh.bfReserved2, sizeof(unsigned short));
|
||||
readme(fd, &bh.bfOffBits, sizeof(unsigned int));
|
||||
readme(fd, &bh.biSize, sizeof(unsigned int));
|
||||
readme(fd, &bh.biWidth, sizeof(int));
|
||||
readme(fd, &bh.biHeight, sizeof(int));
|
||||
readme(fd, &bh.biPlanes, sizeof(unsigned short));
|
||||
readme(fd, &bh.biBitCount, sizeof(unsigned short));
|
||||
readme(fd, &bh.biCompression, sizeof(unsigned int));
|
||||
readme(fd, &bh.biSizeImage, sizeof(unsigned int));
|
||||
readme(fd, &bh.biXPelsPerMeter, sizeof(int));
|
||||
readme(fd, &bh.biYPelsPerMeter, sizeof(int));
|
||||
readme(fd, &bh.biClrUsed, sizeof(unsigned int));
|
||||
readme(fd, &bh.biClrImportant, sizeof(unsigned int));
|
||||
|
||||
if(!littleendian())
|
||||
{
|
||||
bh.bfSize=byteswap(bh.bfSize);
|
||||
bh.bfOffBits=byteswap(bh.bfOffBits);
|
||||
bh.biSize=byteswap(bh.biSize);
|
||||
bh.biWidth=byteswap(bh.biWidth);
|
||||
bh.biHeight=byteswap(bh.biHeight);
|
||||
bh.biPlanes=byteswap16(bh.biPlanes);
|
||||
bh.biBitCount=byteswap16(bh.biBitCount);
|
||||
bh.biCompression=byteswap(bh.biCompression);
|
||||
bh.biSizeImage=byteswap(bh.biSizeImage);
|
||||
bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter);
|
||||
bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter);
|
||||
bh.biClrUsed=byteswap(bh.biClrUsed);
|
||||
bh.biClrImportant=byteswap(bh.biClrImportant);
|
||||
}
|
||||
|
||||
if(bh.bfType!=0x4d42 || bh.bfOffBits<BMPHDRSIZE
|
||||
|| bh.biWidth<1 || bh.biHeight==0)
|
||||
_throw("Corrupt bitmap header");
|
||||
if((bh.biBitCount!=24 && bh.biBitCount!=32) || bh.biCompression!=BI_RGB)
|
||||
_throw("Only uncompessed RGB bitmaps are supported");
|
||||
|
||||
*w=bh.biWidth; *h=bh.biHeight; srcps=bh.biBitCount/8;
|
||||
if(*h<0) {*h=-(*h); srcbottomup=0;}
|
||||
srcpitch=(((*w)*srcps)+3)&(~3);
|
||||
dstpitch=(((*w)*ps[f])+(align-1))&(~(align-1));
|
||||
|
||||
if(srcpitch*(*h)+bh.bfOffBits!=bh.bfSize) _throw("Corrupt bitmap header");
|
||||
if((tempbuf=(unsigned char *)malloc(srcpitch*(*h)))==NULL
|
||||
|| (*buf=(unsigned char *)malloc(dstpitch*(*h)))==NULL)
|
||||
_throw("Memory allocation error");
|
||||
if(lseek(fd, (long)bh.bfOffBits, SEEK_SET)!=(long)bh.bfOffBits)
|
||||
_throw(strerror(errno));
|
||||
_unix(bytesread=read(fd, tempbuf, srcpitch*(*h)));
|
||||
if(bytesread!=srcpitch*(*h)) _throw("Read error");
|
||||
|
||||
pixelconvert(tempbuf, BMP_BGR, srcpitch, *buf, f, dstpitch, *w, *h,
|
||||
srcbottomup!=dstbottomup);
|
||||
|
||||
finally:
|
||||
if(tempbuf) free(tempbuf);
|
||||
if(fd!=-1) close(fd);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
#define writeme(fd, addr, size) \
|
||||
if((byteswritten=write(fd, addr, (size)))==-1) _throw(strerror(errno)); \
|
||||
if(byteswritten!=(size)) _throw("Write error");
|
||||
|
||||
int saveppm(char *filename, unsigned char *buf, int w, int h,
|
||||
enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup)
|
||||
{
|
||||
FILE *fs=NULL; int retcode=0;
|
||||
unsigned char *tempbuf=NULL;
|
||||
|
||||
if((fs=fopen(filename, "wb"))==NULL) _throw(strerror(errno));
|
||||
if(fprintf(fs, "P6\n")<1) _throw("Write error");
|
||||
if(fprintf(fs, "%d %d\n", w, h)<1) _throw("Write error");
|
||||
if(fprintf(fs, "255\n")<1) _throw("Write error");
|
||||
|
||||
if((tempbuf=(unsigned char *)malloc(w*h*3))==NULL)
|
||||
_throw("Memory allocation error");
|
||||
|
||||
pixelconvert(buf, f, srcpitch, tempbuf, BMP_RGB, w*3, w, h,
|
||||
srcbottomup);
|
||||
|
||||
if((fwrite(tempbuf, w*h*3, 1, fs))!=1) _throw("Write error");
|
||||
|
||||
finally:
|
||||
if(tempbuf) free(tempbuf);
|
||||
if(fs) fclose(fs);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int savebmp(char *filename, unsigned char *buf, int w, int h,
|
||||
enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup)
|
||||
{
|
||||
int fd=-1, byteswritten, dstpitch, retcode=0;
|
||||
int flags=O_RDWR|O_CREAT|O_TRUNC;
|
||||
unsigned char *tempbuf=NULL; char *temp;
|
||||
bmphdr bh; int mode;
|
||||
|
||||
#ifdef _WIN32
|
||||
flags|=O_BINARY; mode=_S_IREAD|_S_IWRITE;
|
||||
#else
|
||||
mode=S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
|
||||
#endif
|
||||
if(!filename || !buf || w<1 || h<1 || f<0 || f>BMPPIXELFORMATS-1 || srcpitch<0)
|
||||
_throw("bad argument to savebmp()");
|
||||
|
||||
if(srcpitch==0) srcpitch=w*ps[f];
|
||||
|
||||
if((temp=strrchr(filename, '.'))!=NULL)
|
||||
{
|
||||
if(!stricmp(temp, ".ppm"))
|
||||
return saveppm(filename, buf, w, h, f, srcpitch, srcbottomup);
|
||||
}
|
||||
|
||||
_unix(fd=open(filename, flags, mode));
|
||||
dstpitch=((w*3)+3)&(~3);
|
||||
|
||||
bh.bfType=0x4d42;
|
||||
bh.bfSize=BMPHDRSIZE+dstpitch*h;
|
||||
bh.bfReserved1=0; bh.bfReserved2=0;
|
||||
bh.bfOffBits=BMPHDRSIZE;
|
||||
bh.biSize=40;
|
||||
bh.biWidth=w; bh.biHeight=h;
|
||||
bh.biPlanes=0; bh.biBitCount=24;
|
||||
bh.biCompression=BI_RGB; bh.biSizeImage=0;
|
||||
bh.biXPelsPerMeter=0; bh.biYPelsPerMeter=0;
|
||||
bh.biClrUsed=0; bh.biClrImportant=0;
|
||||
|
||||
if(!littleendian())
|
||||
{
|
||||
bh.bfType=byteswap16(bh.bfType);
|
||||
bh.bfSize=byteswap(bh.bfSize);
|
||||
bh.bfOffBits=byteswap(bh.bfOffBits);
|
||||
bh.biSize=byteswap(bh.biSize);
|
||||
bh.biWidth=byteswap(bh.biWidth);
|
||||
bh.biHeight=byteswap(bh.biHeight);
|
||||
bh.biPlanes=byteswap16(bh.biPlanes);
|
||||
bh.biBitCount=byteswap16(bh.biBitCount);
|
||||
bh.biCompression=byteswap(bh.biCompression);
|
||||
bh.biSizeImage=byteswap(bh.biSizeImage);
|
||||
bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter);
|
||||
bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter);
|
||||
bh.biClrUsed=byteswap(bh.biClrUsed);
|
||||
bh.biClrImportant=byteswap(bh.biClrImportant);
|
||||
}
|
||||
|
||||
writeme(fd, &bh.bfType, sizeof(unsigned short));
|
||||
writeme(fd, &bh.bfSize, sizeof(unsigned int));
|
||||
writeme(fd, &bh.bfReserved1, sizeof(unsigned short));
|
||||
writeme(fd, &bh.bfReserved2, sizeof(unsigned short));
|
||||
writeme(fd, &bh.bfOffBits, sizeof(unsigned int));
|
||||
writeme(fd, &bh.biSize, sizeof(unsigned int));
|
||||
writeme(fd, &bh.biWidth, sizeof(int));
|
||||
writeme(fd, &bh.biHeight, sizeof(int));
|
||||
writeme(fd, &bh.biPlanes, sizeof(unsigned short));
|
||||
writeme(fd, &bh.biBitCount, sizeof(unsigned short));
|
||||
writeme(fd, &bh.biCompression, sizeof(unsigned int));
|
||||
writeme(fd, &bh.biSizeImage, sizeof(unsigned int));
|
||||
writeme(fd, &bh.biXPelsPerMeter, sizeof(int));
|
||||
writeme(fd, &bh.biYPelsPerMeter, sizeof(int));
|
||||
writeme(fd, &bh.biClrUsed, sizeof(unsigned int));
|
||||
writeme(fd, &bh.biClrImportant, sizeof(unsigned int));
|
||||
|
||||
if((tempbuf=(unsigned char *)malloc(dstpitch*h))==NULL)
|
||||
_throw("Memory allocation error");
|
||||
|
||||
pixelconvert(buf, f, srcpitch, tempbuf, BMP_BGR, dstpitch, w, h,
|
||||
!srcbottomup);
|
||||
|
||||
if((byteswritten=write(fd, tempbuf, dstpitch*h))!=dstpitch*h)
|
||||
_throw(strerror(errno));
|
||||
|
||||
finally:
|
||||
if(tempbuf) free(tempbuf);
|
||||
if(fd!=-1) close(fd);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
const char *bmpgeterr(void)
|
||||
{
|
||||
return __bmperr;
|
||||
}
|
||||
48
bmp.h
48
bmp.h
@@ -1,48 +0,0 @@
|
||||
/* Copyright (C)2004 Landmark Graphics Corporation
|
||||
* Copyright (C)2005 Sun Microsystems, Inc.
|
||||
*
|
||||
* This library is free software and may be redistributed and/or modified under
|
||||
* the terms of the wxWindows Library License, Version 3.1 or (at your option)
|
||||
* any later version. The full license is in the LICENSE.txt file included
|
||||
* with this distribution.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* wxWindows Library License for more details.
|
||||
*/
|
||||
|
||||
// This provides rudimentary facilities for loading and saving true color
|
||||
// BMP and PPM files
|
||||
|
||||
#ifndef __BMP_H__
|
||||
#define __BMP_H__
|
||||
|
||||
#define BMPPIXELFORMATS 6
|
||||
enum BMPPIXELFORMAT {BMP_RGB=0, BMP_RGBA, BMP_BGR, BMP_BGRA, BMP_ABGR, BMP_ARGB};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This will load a Windows bitmap from a file and return a buffer with the
|
||||
// specified pixel format, scanline alignment, and orientation. The width and
|
||||
// height are returned in w and h.
|
||||
|
||||
int loadbmp(char *filename, unsigned char **buf, int *w, int *h,
|
||||
enum BMPPIXELFORMAT f, int align, int dstbottomup);
|
||||
|
||||
// This will save a buffer with the specified pixel format, pitch, orientation,
|
||||
// width, and height as a 24-bit Windows bitmap or PPM (the filename determines
|
||||
// which format to use)
|
||||
|
||||
int savebmp(char *filename, unsigned char *buf, int w, int h,
|
||||
enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup);
|
||||
|
||||
const char *bmpgeterr(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
* cderror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Modified 2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -45,6 +46,7 @@ JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length")
|
||||
JMESSAGE(JERR_BMP_BADPLANES, "Invalid BMP file: biPlanes not equal to 1")
|
||||
JMESSAGE(JERR_BMP_COLORSPACE, "BMP output must be grayscale or RGB")
|
||||
JMESSAGE(JERR_BMP_COMPRESSED, "Sorry, compressed BMPs not yet supported")
|
||||
JMESSAGE(JERR_BMP_EMPTY, "Empty BMP image")
|
||||
JMESSAGE(JERR_BMP_NOT, "Not a BMP file - does not start with BM")
|
||||
JMESSAGE(JTRC_BMP, "%ux%u 24-bit BMP image")
|
||||
JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image")
|
||||
|
||||
5
cdjpeg.h
5
cdjpeg.h
@@ -104,6 +104,7 @@ typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
|
||||
#define jinit_write_targa jIWrTarga
|
||||
#define read_quant_tables RdQTables
|
||||
#define read_scan_script RdScnScript
|
||||
#define set_quality_ratings SetQRates
|
||||
#define set_quant_slots SetQSlots
|
||||
#define set_sample_factors SetSFacts
|
||||
#define read_color_map RdCMap
|
||||
@@ -131,8 +132,10 @@ EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo));
|
||||
/* cjpeg support routines (in rdswitch.c) */
|
||||
|
||||
EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
|
||||
int scale_factor, boolean force_baseline));
|
||||
boolean force_baseline));
|
||||
EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
|
||||
EXTERN(boolean) set_quality_ratings JPP((j_compress_ptr cinfo, char *arg,
|
||||
boolean force_baseline));
|
||||
EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
|
||||
EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
|
||||
|
||||
|
||||
109
change.log
109
change.log
@@ -1,6 +1,115 @@
|
||||
CHANGE LOG for Independent JPEG Group's JPEG software
|
||||
|
||||
|
||||
Version 8c 16-Jan-2011
|
||||
-----------------------
|
||||
|
||||
Add option to compression library and cjpeg (-block N) to use
|
||||
different DCT block size.
|
||||
All N from 1 to 16 are possible. Default is 8 (baseline format).
|
||||
Larger values produce higher compression,
|
||||
smaller values produce higher quality.
|
||||
SmartScale capable decoder (introduced with IJG JPEG 8) required.
|
||||
|
||||
|
||||
Version 8b 16-May-2010
|
||||
-----------------------
|
||||
|
||||
Repair problem in new memory source manager with corrupt JPEG data.
|
||||
Thank to Ted Campbell and Samuel Chun for the report.
|
||||
|
||||
Repair problem in Makefile.am test target.
|
||||
Thank to anonymous user for the report.
|
||||
|
||||
Support MinGW installation with automatic configure.
|
||||
Thank to Volker Grabsch for the suggestion.
|
||||
|
||||
|
||||
Version 8a 28-Feb-2010
|
||||
-----------------------
|
||||
|
||||
Writing tables-only datastreams via jpeg_write_tables works again.
|
||||
|
||||
Support 32-bit BMPs (RGB image with Alpha channel) for read in cjpeg.
|
||||
Thank to Brett Blackham for the suggestion.
|
||||
|
||||
Improve accuracy in floating point IDCT calculation.
|
||||
Thank to Robert Hooke for the hint.
|
||||
|
||||
|
||||
Version 8 10-Jan-2010
|
||||
----------------------
|
||||
|
||||
jpegtran now supports the same -scale option as djpeg for "lossless" resize.
|
||||
An implementation of the JPEG SmartScale extension is required for this
|
||||
feature. A (draft) specification of the JPEG SmartScale extension is
|
||||
available as a contributed document at ITU and ISO. Revision 2 or later
|
||||
of the document is required (latest document version is Revision 3).
|
||||
The SmartScale extension will enable more features beside lossless resize
|
||||
in future implementations, as described in the document (new compression
|
||||
options).
|
||||
|
||||
Add sanity check in BMP reader module to avoid cjpeg crash for empty input
|
||||
image (thank to Isaev Ildar of ISP RAS, Moscow, RU for reporting this error).
|
||||
|
||||
Add data source and destination managers for read from and write to
|
||||
memory buffers. New API functions jpeg_mem_src and jpeg_mem_dest.
|
||||
Thank to Roberto Boni from Italy for the suggestion.
|
||||
|
||||
|
||||
Version 7 27-Jun-2009
|
||||
----------------------
|
||||
|
||||
New scaled DCTs implemented.
|
||||
djpeg now supports scalings N/8 with all N from 1 to 16.
|
||||
cjpeg now supports scalings 8/N with all N from 1 to 16.
|
||||
Scaled DCTs with size larger than 8 are now also used for resolving the
|
||||
common 2x2 chroma subsampling case without additional spatial resampling.
|
||||
Separate spatial resampling for those kind of files is now only necessary
|
||||
for N>8 scaling cases.
|
||||
Furthermore, separate scaled DCT functions are provided for direct resolving
|
||||
of the common asymmetric subsampling cases (2x1 and 1x2) without additional
|
||||
spatial resampling.
|
||||
|
||||
cjpeg -quality option has been extended for support of separate quality
|
||||
settings for luminance and chrominance (or in general, for every provided
|
||||
quantization table slot).
|
||||
New API function jpeg_default_qtables() and q_scale_factor array in library.
|
||||
|
||||
Added -nosmooth option to cjpeg, complementary to djpeg.
|
||||
New variable "do_fancy_downsampling" in library, complement to fancy
|
||||
upsampling. Fancy upsampling now uses direct DCT scaling with sizes
|
||||
larger than 8. The old method is not reversible and has been removed.
|
||||
|
||||
Support arithmetic entropy encoding and decoding.
|
||||
Added files jaricom.c, jcarith.c, jdarith.c.
|
||||
|
||||
Straighten the file structure:
|
||||
Removed files jidctred.c, jcphuff.c, jchuff.h, jdphuff.c, jdhuff.h.
|
||||
|
||||
jpegtran has a new "lossless" cropping feature.
|
||||
|
||||
Implement -perfect option in jpegtran, new API function
|
||||
jtransform_perfect_transform() in transupp. (DP 204_perfect.dpatch)
|
||||
|
||||
Better error messages for jpegtran fopen failure.
|
||||
(DP 203_jpegtran_errmsg.dpatch)
|
||||
|
||||
Fix byte order issue with 16bit PPM/PGM files in rdppm.c/wrppm.c:
|
||||
according to Netpbm, the de facto standard implementation of the PNM formats,
|
||||
the most significant byte is first. (DP 203_rdppm.dpatch)
|
||||
|
||||
Add -raw option to rdjpgcom not to mangle the output.
|
||||
(DP 205_rdjpgcom_raw.dpatch)
|
||||
|
||||
Make rdjpgcom locale aware. (DP 201_rdjpgcom_locale.dpatch)
|
||||
|
||||
Add extern "C" to jpeglib.h.
|
||||
This avoids the need to put extern "C" { ... } around #include "jpeglib.h"
|
||||
in your C++ application. Defining the symbol DONT_USE_EXTERN_C in the
|
||||
configuration prevents this. (DP 202_jpeglib.h_c++.dpatch)
|
||||
|
||||
|
||||
Version 6b 27-Mar-1998
|
||||
-----------------------
|
||||
|
||||
|
||||
71
cjpeg.1
71
cjpeg.1
@@ -1,4 +1,4 @@
|
||||
.TH CJPEG 1 "20 March 1998"
|
||||
.TH CJPEG 1 "14 November 2010"
|
||||
.SH NAME
|
||||
cjpeg \- compress an image file to a JPEG file
|
||||
.SH SYNOPSIS
|
||||
@@ -36,7 +36,7 @@ though for brevity these are not mentioned below.
|
||||
.PP
|
||||
The basic switches are:
|
||||
.TP
|
||||
.BI \-quality " N"
|
||||
.BI \-quality " N[,...]"
|
||||
Scale quantization tables to adjust image quality. Quality is 0 (worst) to
|
||||
100 (best); default is 75. (See below for more info.)
|
||||
.TP
|
||||
@@ -62,6 +62,13 @@ decompression are unaffected by
|
||||
.B \-progressive
|
||||
Create progressive JPEG file (see below).
|
||||
.TP
|
||||
.BI \-scale " M/N"
|
||||
Scale the output image by a factor M/N. Currently supported scale factors are
|
||||
M/N with all N from 1 to 16, where M is the destination DCT size, which is 8
|
||||
by default (see
|
||||
.BI \-block " N"
|
||||
switch below).
|
||||
.TP
|
||||
.B \-targa
|
||||
Input file is Targa format. Targa files that contain an "identification"
|
||||
field will not be automatically recognized by
|
||||
@@ -109,6 +116,34 @@ other JPEG programs may be unable to decode the resulting file. Use
|
||||
if you need to ensure compatibility at low quality values.)
|
||||
.PP
|
||||
The
|
||||
.B \-quality
|
||||
option has been extended in IJG version 7 for support of separate quality
|
||||
settings for luminance and chrominance (or in general, for every provided
|
||||
quantization table slot). This feature is useful for high-quality
|
||||
applications which cannot accept the damage of color data by coarse
|
||||
subsampling settings. You can now easily reduce the color data amount more
|
||||
smoothly with finer control without separate subsampling. The resulting file
|
||||
is fully compliant with standard JPEG decoders.
|
||||
Note that the
|
||||
.B \-quality
|
||||
ratings refer to the quantization table slots, and that the last value is
|
||||
replicated if there are more q-table slots than parameters. The default
|
||||
q-table slots are 0 for luminance and 1 for chrominance with default tables as
|
||||
given in the JPEG standard. This is compatible with the old behaviour in case
|
||||
that only one parameter is given, which is then used for both luminance and
|
||||
chrominance (slots 0 and 1). More or custom quantization tables can be set
|
||||
with
|
||||
.B \-qtables
|
||||
and assigned to components with
|
||||
.B \-qslots
|
||||
parameter (see the "wizard" switches below).
|
||||
.B Caution:
|
||||
You must explicitly add
|
||||
.BI \-sample " 1x1"
|
||||
for efficient separate color
|
||||
quality selection, since the default value used by library is 2x2!
|
||||
.PP
|
||||
The
|
||||
.B \-progressive
|
||||
switch creates a "progressive JPEG" file. In this type of JPEG file, the data
|
||||
is stored in multiple scans of increasing quality. If the file is being
|
||||
@@ -117,12 +152,20 @@ scan to display a low-quality image very quickly, and can then improve the
|
||||
display with each subsequent scan. The final image is exactly equivalent to a
|
||||
standard JPEG file of the same quality setting, and the total file size is
|
||||
about the same --- often a little smaller.
|
||||
.B Caution:
|
||||
progressive JPEG is not yet widely implemented, so many decoders will be
|
||||
unable to view a progressive JPEG file at all.
|
||||
.PP
|
||||
Switches for advanced users:
|
||||
.TP
|
||||
.BI \-block " N"
|
||||
Set DCT block size. All N from 1 to 16 are possible.
|
||||
Default is 8 (baseline format).
|
||||
Larger values produce higher compression,
|
||||
smaller values produce higher quality
|
||||
(exact DCT stage possible with 1 or 2; with the default quality of 75 and
|
||||
default Luminance qtable the DCT+Quantization stage is lossless for N=1).
|
||||
CAUTION: An implementation of the JPEG SmartScale extension is required for
|
||||
this feature. SmartScale enabled JPEG is not yet widely implemented, so
|
||||
many decoders will be unable to view a SmartScale extended JPEG file at all.
|
||||
.TP
|
||||
.B \-dct int
|
||||
Use integer DCT method (default).
|
||||
.TP
|
||||
@@ -137,6 +180,9 @@ note that results of the floating-point method may vary slightly across
|
||||
machines, while the integer methods should give the same results everywhere.
|
||||
The fast integer method is much less accurate than the other two.
|
||||
.TP
|
||||
.B \-nosmooth
|
||||
Don't use high-quality downsampling.
|
||||
.TP
|
||||
.BI \-restart " N"
|
||||
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
|
||||
attached to the number.
|
||||
@@ -187,6 +233,12 @@ visibly blur the image, however.
|
||||
.PP
|
||||
Switches for wizards:
|
||||
.TP
|
||||
.B \-arithmetic
|
||||
Use arithmetic coding.
|
||||
.B Caution:
|
||||
arithmetic coded JPEG is not yet widely implemented, so many decoders will be
|
||||
unable to view an arithmetic coded JPEG file at all.
|
||||
.TP
|
||||
.B \-baseline
|
||||
Force baseline-compatible quantization tables to be generated. This clamps
|
||||
quantization values to 8 bits even at low quality settings. (This switch is
|
||||
@@ -211,7 +263,7 @@ Use the scan script given in the specified text file.
|
||||
.PP
|
||||
The "wizard" switches are intended for experimentation with JPEG. If you
|
||||
don't know what you are doing, \fBdon't use them\fR. These switches are
|
||||
documented further in the file wizard.doc.
|
||||
documented further in the file wizard.txt.
|
||||
.SH EXAMPLES
|
||||
.LP
|
||||
This example compresses the PPM file foo.ppm with a quality factor of
|
||||
@@ -276,11 +328,8 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
|
||||
.SH AUTHOR
|
||||
Independent JPEG Group
|
||||
.SH BUGS
|
||||
Arithmetic coding is not supported for legal reasons.
|
||||
.PP
|
||||
GIF input files are no longer supported, to avoid the Unisys LZW patent.
|
||||
Use a Unisys-licensed program if you need to read a GIF file. (Conversion
|
||||
of GIF files to JPEG is usually a bad idea anyway.)
|
||||
(Conversion of GIF files to JPEG is usually a bad idea anyway.)
|
||||
.PP
|
||||
Not all variants of BMP and Targa file formats are supported.
|
||||
.PP
|
||||
@@ -288,5 +337,3 @@ The
|
||||
.B \-targa
|
||||
switch is not a bug, it's a feature. (It would be a bug if the Targa format
|
||||
designers had not been clueless.)
|
||||
.PP
|
||||
Still not as fast as we'd like.
|
||||
|
||||
69
cjpeg.c
69
cjpeg.c
@@ -2,6 +2,7 @@
|
||||
* cjpeg.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -149,7 +150,7 @@ usage (void)
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "Switches (names may be abbreviated):\n");
|
||||
fprintf(stderr, " -quality N Compression quality (0..100; 5-95 is useful range)\n");
|
||||
fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is useful range)\n");
|
||||
fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
|
||||
@@ -157,10 +158,16 @@ usage (void)
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
fprintf(stderr, " -progressive Create progressive JPEG file\n");
|
||||
#endif
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
fprintf(stderr, " -scale M/N Scale image by fraction M/N, eg, 1/2\n");
|
||||
#endif
|
||||
#ifdef TARGA_SUPPORTED
|
||||
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
|
||||
#endif
|
||||
fprintf(stderr, "Switches for advanced users:\n");
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
fprintf(stderr, " -block N DCT block size (1..16; default is 8)\n");
|
||||
#endif
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
fprintf(stderr, " -dct int Use integer DCT method%s\n",
|
||||
(JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
|
||||
@@ -173,6 +180,7 @@ usage (void)
|
||||
fprintf(stderr, " -dct float Use floating-point DCT method%s\n",
|
||||
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
|
||||
#endif
|
||||
fprintf(stderr, " -nosmooth Don't use high-quality downsampling\n");
|
||||
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
|
||||
#ifdef INPUT_SMOOTHING_SUPPORTED
|
||||
fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
|
||||
@@ -209,21 +217,16 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
||||
{
|
||||
int argn;
|
||||
char * arg;
|
||||
int quality; /* -quality parameter */
|
||||
int q_scale_factor; /* scaling percentage for -qtables */
|
||||
boolean force_baseline;
|
||||
boolean simple_progressive;
|
||||
char * qualityarg = NULL; /* saves -quality parm if any */
|
||||
char * qtablefile = NULL; /* saves -qtables filename if any */
|
||||
char * qslotsarg = NULL; /* saves -qslots parm if any */
|
||||
char * samplearg = NULL; /* saves -sample parm if any */
|
||||
char * scansarg = NULL; /* saves -scans parm if any */
|
||||
|
||||
/* Set up default JPEG parameters. */
|
||||
/* Note that default -quality level need not, and does not,
|
||||
* match the default scaling for an explicit -qtables argument.
|
||||
*/
|
||||
quality = 75; /* default -quality value */
|
||||
q_scale_factor = 100; /* default to no scaling for -qtables */
|
||||
|
||||
force_baseline = FALSE; /* by default, allow 16-bit quantizers */
|
||||
simple_progressive = FALSE;
|
||||
is_targa = FALSE;
|
||||
@@ -254,10 +257,30 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
|
||||
} else if (keymatch(arg, "baseline", 1)) {
|
||||
} else if (keymatch(arg, "baseline", 2)) {
|
||||
/* Force baseline-compatible output (8-bit quantizer values). */
|
||||
force_baseline = TRUE;
|
||||
|
||||
} else if (keymatch(arg, "block", 2)) {
|
||||
/* Set DCT block size. */
|
||||
#if defined(DCT_SCALING_SUPPORTED) && defined(JPEG_LIB_VERSION_MAJOR) && \
|
||||
(JPEG_LIB_VERSION_MAJOR > 8 || (JPEG_LIB_VERSION_MAJOR == 8 && \
|
||||
defined(JPEG_LIB_VERSION_MINOR) && JPEG_LIB_VERSION_MINOR >= 3))
|
||||
int val;
|
||||
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
usage();
|
||||
if (sscanf(argv[argn], "%d", &val) != 1)
|
||||
usage();
|
||||
if (val < 1 || val > 16)
|
||||
usage();
|
||||
cinfo->block_size = val;
|
||||
#else
|
||||
fprintf(stderr, "%s: sorry, block size setting not supported\n",
|
||||
progname);
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
|
||||
} else if (keymatch(arg, "dct", 2)) {
|
||||
/* Select DCT algorithm. */
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
@@ -300,6 +323,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
||||
lval *= 1000L;
|
||||
cinfo->mem->max_memory_to_use = lval * 1000L;
|
||||
|
||||
} else if (keymatch(arg, "nosmooth", 3)) {
|
||||
/* Suppress fancy downsampling */
|
||||
cinfo->do_fancy_downsampling = FALSE;
|
||||
|
||||
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
|
||||
/* Enable entropy parm optimization. */
|
||||
#ifdef ENTROPY_OPT_SUPPORTED
|
||||
@@ -328,13 +355,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
||||
#endif
|
||||
|
||||
} else if (keymatch(arg, "quality", 1)) {
|
||||
/* Quality factor (quantization table scaling factor). */
|
||||
/* Quality ratings (quantization table scaling factors). */
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
usage();
|
||||
if (sscanf(argv[argn], "%d", &quality) != 1)
|
||||
usage();
|
||||
/* Change scale factor in case -qtables is present. */
|
||||
q_scale_factor = jpeg_quality_scaling(quality);
|
||||
qualityarg = argv[argn];
|
||||
|
||||
} else if (keymatch(arg, "qslots", 2)) {
|
||||
/* Quantization table slot numbers. */
|
||||
@@ -382,7 +406,15 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
||||
* default sampling factors.
|
||||
*/
|
||||
|
||||
} else if (keymatch(arg, "scans", 2)) {
|
||||
} else if (keymatch(arg, "scale", 4)) {
|
||||
/* Scale the image by a fraction M/N. */
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
usage();
|
||||
if (sscanf(argv[argn], "%d/%d",
|
||||
&cinfo->scale_num, &cinfo->scale_denom) != 2)
|
||||
usage();
|
||||
|
||||
} else if (keymatch(arg, "scans", 4)) {
|
||||
/* Set scan script. */
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
@@ -422,11 +454,12 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
||||
|
||||
/* Set quantization tables for selected quality. */
|
||||
/* Some or all may be overridden if -qtables is present. */
|
||||
jpeg_set_quality(cinfo, quality, force_baseline);
|
||||
if (qualityarg != NULL) /* process -quality if it was present */
|
||||
if (! set_quality_ratings(cinfo, qualityarg, force_baseline))
|
||||
usage();
|
||||
|
||||
if (qtablefile != NULL) /* process -qtables if it was present */
|
||||
if (! read_quant_tables(cinfo, qtablefile,
|
||||
q_scale_factor, force_baseline))
|
||||
if (! read_quant_tables(cinfo, qtablefile, force_baseline))
|
||||
usage();
|
||||
|
||||
if (qslotsarg != NULL) /* process -qslots if it was present */
|
||||
|
||||
402
ckconfig.c
Normal file
402
ckconfig.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* ckconfig.c
|
||||
*
|
||||
* Copyright (C) 1991-1994, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is intended to help you determine how to configure the JPEG
|
||||
* software for installation on a particular system. The idea is to try to
|
||||
* compile and execute this program. If your compiler fails to compile the
|
||||
* program, make changes as indicated in the comments below. Once you can
|
||||
* compile the program, run it, and it will produce a "jconfig.h" file for
|
||||
* your system.
|
||||
*
|
||||
* As a general rule, each time you try to compile this program,
|
||||
* pay attention only to the *first* error message you get from the compiler.
|
||||
* Many C compilers will issue lots of spurious error messages once they
|
||||
* have gotten confused. Go to the line indicated in the first error message,
|
||||
* and read the comments preceding that line to see what to change.
|
||||
*
|
||||
* Almost all of the edits you may need to make to this program consist of
|
||||
* changing a line that reads "#define SOME_SYMBOL" to "#undef SOME_SYMBOL",
|
||||
* or vice versa. This is called defining or undefining that symbol.
|
||||
*/
|
||||
|
||||
|
||||
/* First we must see if your system has the include files we need.
|
||||
* We start out with the assumption that your system has all the ANSI-standard
|
||||
* include files. If you get any error trying to include one of these files,
|
||||
* undefine the corresponding HAVE_xxx symbol.
|
||||
*/
|
||||
|
||||
#define HAVE_STDDEF_H /* replace 'define' by 'undef' if error here */
|
||||
#ifdef HAVE_STDDEF_H /* next line will be skipped if you undef... */
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
#define HAVE_STDLIB_H /* same thing for stdlib.h */
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* If you ain't got this, you ain't got C. */
|
||||
|
||||
/* We have to see if your string functions are defined by
|
||||
* strings.h (old BSD convention) or string.h (everybody else).
|
||||
* We try the non-BSD convention first; define NEED_BSD_STRINGS
|
||||
* if the compiler says it can't find string.h.
|
||||
*/
|
||||
|
||||
#undef NEED_BSD_STRINGS
|
||||
|
||||
#ifdef NEED_BSD_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* On some systems (especially older Unix machines), type size_t is
|
||||
* defined only in the include file <sys/types.h>. If you get a failure
|
||||
* on the size_t test below, try defining NEED_SYS_TYPES_H.
|
||||
*/
|
||||
|
||||
#undef NEED_SYS_TYPES_H /* start by assuming we don't need it */
|
||||
#ifdef NEED_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Usually type size_t is defined in one of the include files we've included
|
||||
* above. If not, you'll get an error on the "typedef size_t my_size_t;" line.
|
||||
* In that case, first try defining NEED_SYS_TYPES_H just above.
|
||||
* If that doesn't work, you'll have to search through your system library
|
||||
* to figure out which include file defines "size_t". Look for a line that
|
||||
* says "typedef something-or-other size_t;". Then, change the line below
|
||||
* that says "#include <someincludefile.h>" to instead include the file
|
||||
* you found size_t in, and define NEED_SPECIAL_INCLUDE. If you can't find
|
||||
* type size_t anywhere, try replacing "#include <someincludefile.h>" with
|
||||
* "typedef unsigned int size_t;".
|
||||
*/
|
||||
|
||||
#undef NEED_SPECIAL_INCLUDE /* assume we DON'T need it, for starters */
|
||||
|
||||
#ifdef NEED_SPECIAL_INCLUDE
|
||||
#include <someincludefile.h>
|
||||
#endif
|
||||
|
||||
typedef size_t my_size_t; /* The payoff: do we have size_t now? */
|
||||
|
||||
|
||||
/* The next question is whether your compiler supports ANSI-style function
|
||||
* prototypes. You need to know this in order to choose between using
|
||||
* makefile.ansi and using makefile.unix.
|
||||
* The #define line below is set to assume you have ANSI function prototypes.
|
||||
* If you get an error in this group of lines, undefine HAVE_PROTOTYPES.
|
||||
*/
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
int testfunction (int arg1, int * arg2); /* check prototypes */
|
||||
|
||||
struct methods_struct { /* check method-pointer declarations */
|
||||
int (*error_exit) (char *msgtext);
|
||||
int (*trace_message) (char *msgtext);
|
||||
int (*another_method) (void);
|
||||
};
|
||||
|
||||
int testfunction (int arg1, int * arg2) /* check definitions */
|
||||
{
|
||||
return arg2[arg1];
|
||||
}
|
||||
|
||||
int test2function (void) /* check void arg list */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Now we want to find out if your compiler knows what "unsigned char" means.
|
||||
* If you get an error on the "unsigned char un_char;" line,
|
||||
* then undefine HAVE_UNSIGNED_CHAR.
|
||||
*/
|
||||
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
unsigned char un_char;
|
||||
#endif
|
||||
|
||||
|
||||
/* Now we want to find out if your compiler knows what "unsigned short" means.
|
||||
* If you get an error on the "unsigned short un_short;" line,
|
||||
* then undefine HAVE_UNSIGNED_SHORT.
|
||||
*/
|
||||
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
|
||||
#ifdef HAVE_UNSIGNED_SHORT
|
||||
unsigned short un_short;
|
||||
#endif
|
||||
|
||||
|
||||
/* Now we want to find out if your compiler understands type "void".
|
||||
* If you get an error anywhere in here, undefine HAVE_VOID.
|
||||
*/
|
||||
|
||||
#define HAVE_VOID
|
||||
|
||||
#ifdef HAVE_VOID
|
||||
/* Caution: a C++ compiler will insist on complete prototypes */
|
||||
typedef void * void_ptr; /* check void * */
|
||||
#ifdef HAVE_PROTOTYPES /* check ptr to function returning void */
|
||||
typedef void (*void_func) (int a, int b);
|
||||
#else
|
||||
typedef void (*void_func) ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROTOTYPES /* check void function result */
|
||||
void test3function (void_ptr arg1, void_func arg2)
|
||||
#else
|
||||
void test3function (arg1, arg2)
|
||||
void_ptr arg1;
|
||||
void_func arg2;
|
||||
#endif
|
||||
{
|
||||
char * locptr = (char *) arg1; /* check casting to and from void * */
|
||||
arg1 = (void *) locptr;
|
||||
(*arg2) (1, 2); /* check call of fcn returning void */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Now we want to find out if your compiler knows what "const" means.
|
||||
* If you get an error here, undefine HAVE_CONST.
|
||||
*/
|
||||
|
||||
#define HAVE_CONST
|
||||
|
||||
#ifdef HAVE_CONST
|
||||
static const int carray[3] = {1, 2, 3};
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
int test4function (const int arg1)
|
||||
#else
|
||||
int test4function (arg1)
|
||||
const int arg1;
|
||||
#endif
|
||||
{
|
||||
return carray[arg1];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* If you get an error or warning about this structure definition,
|
||||
* define INCOMPLETE_TYPES_BROKEN.
|
||||
*/
|
||||
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifndef INCOMPLETE_TYPES_BROKEN
|
||||
typedef struct undefined_structure * undef_struct_ptr;
|
||||
#endif
|
||||
|
||||
|
||||
/* If you get an error about duplicate names,
|
||||
* define NEED_SHORT_EXTERNAL_NAMES.
|
||||
*/
|
||||
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
|
||||
#ifndef NEED_SHORT_EXTERNAL_NAMES
|
||||
|
||||
int possibly_duplicate_function ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int possibly_dupli_function ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* OK, that's it. You should not have to change anything beyond this
|
||||
* point in order to compile and execute this program. (You might get
|
||||
* some warnings, but you can ignore them.)
|
||||
* When you run the program, it will make a couple more tests that it
|
||||
* can do automatically, and then it will create jconfig.h and print out
|
||||
* any additional suggestions it has.
|
||||
************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
int is_char_signed (int arg)
|
||||
#else
|
||||
int is_char_signed (arg)
|
||||
int arg;
|
||||
#endif
|
||||
{
|
||||
if (arg == 189) { /* expected result for unsigned char */
|
||||
return 0; /* type char is unsigned */
|
||||
}
|
||||
else if (arg != -67) { /* expected result for signed char */
|
||||
printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n");
|
||||
printf("I fear the JPEG software will not work at all.\n\n");
|
||||
}
|
||||
return 1; /* assume char is signed otherwise */
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
int is_shifting_signed (long arg)
|
||||
#else
|
||||
int is_shifting_signed (arg)
|
||||
long arg;
|
||||
#endif
|
||||
/* See whether right-shift on a long is signed or not. */
|
||||
{
|
||||
long res = arg >> 4;
|
||||
|
||||
if (res == -0x7F7E80CL) { /* expected result for signed shift */
|
||||
return 1; /* right shift is signed */
|
||||
}
|
||||
/* see if unsigned-shift hack will fix it. */
|
||||
/* we can't just test exact value since it depends on width of long... */
|
||||
res |= (~0L) << (32-4);
|
||||
if (res == -0x7F7E80CL) { /* expected result now? */
|
||||
return 0; /* right shift is unsigned */
|
||||
}
|
||||
printf("Right shift isn't acting as I expect it to.\n");
|
||||
printf("I fear the JPEG software will not work at all.\n\n");
|
||||
return 0; /* try it with unsigned anyway */
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
int main (int argc, char ** argv)
|
||||
#else
|
||||
int main (argc, argv)
|
||||
int argc;
|
||||
char ** argv;
|
||||
#endif
|
||||
{
|
||||
char signed_char_check = (char) (-67);
|
||||
FILE *outfile;
|
||||
|
||||
/* Attempt to write jconfig.h */
|
||||
if ((outfile = fopen("jconfig.h", "w")) == NULL) {
|
||||
printf("Failed to write jconfig.h\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Write out all the info */
|
||||
fprintf(outfile, "/* jconfig.h --- generated by ckconfig.c */\n");
|
||||
fprintf(outfile, "/* see jconfig.txt for explanations */\n\n");
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
fprintf(outfile, "#define HAVE_PROTOTYPES\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef HAVE_PROTOTYPES\n");
|
||||
#endif
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
fprintf(outfile, "#define HAVE_UNSIGNED_CHAR\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef HAVE_UNSIGNED_CHAR\n");
|
||||
#endif
|
||||
#ifdef HAVE_UNSIGNED_SHORT
|
||||
fprintf(outfile, "#define HAVE_UNSIGNED_SHORT\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef HAVE_UNSIGNED_SHORT\n");
|
||||
#endif
|
||||
#ifdef HAVE_VOID
|
||||
fprintf(outfile, "/* #define void char */\n");
|
||||
#else
|
||||
fprintf(outfile, "#define void char\n");
|
||||
#endif
|
||||
#ifdef HAVE_CONST
|
||||
fprintf(outfile, "/* #define const */\n");
|
||||
#else
|
||||
fprintf(outfile, "#define const\n");
|
||||
#endif
|
||||
if (is_char_signed((int) signed_char_check))
|
||||
fprintf(outfile, "#undef CHAR_IS_UNSIGNED\n");
|
||||
else
|
||||
fprintf(outfile, "#define CHAR_IS_UNSIGNED\n");
|
||||
#ifdef HAVE_STDDEF_H
|
||||
fprintf(outfile, "#define HAVE_STDDEF_H\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef HAVE_STDDEF_H\n");
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
fprintf(outfile, "#define HAVE_STDLIB_H\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef HAVE_STDLIB_H\n");
|
||||
#endif
|
||||
#ifdef NEED_BSD_STRINGS
|
||||
fprintf(outfile, "#define NEED_BSD_STRINGS\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef NEED_BSD_STRINGS\n");
|
||||
#endif
|
||||
#ifdef NEED_SYS_TYPES_H
|
||||
fprintf(outfile, "#define NEED_SYS_TYPES_H\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef NEED_SYS_TYPES_H\n");
|
||||
#endif
|
||||
fprintf(outfile, "#undef NEED_FAR_POINTERS\n");
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
fprintf(outfile, "#define NEED_SHORT_EXTERNAL_NAMES\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef NEED_SHORT_EXTERNAL_NAMES\n");
|
||||
#endif
|
||||
#ifdef INCOMPLETE_TYPES_BROKEN
|
||||
fprintf(outfile, "#define INCOMPLETE_TYPES_BROKEN\n");
|
||||
#else
|
||||
fprintf(outfile, "#undef INCOMPLETE_TYPES_BROKEN\n");
|
||||
#endif
|
||||
fprintf(outfile, "\n#ifdef JPEG_INTERNALS\n\n");
|
||||
if (is_shifting_signed(-0x7F7E80B1L))
|
||||
fprintf(outfile, "#undef RIGHT_SHIFT_IS_UNSIGNED\n");
|
||||
else
|
||||
fprintf(outfile, "#define RIGHT_SHIFT_IS_UNSIGNED\n");
|
||||
fprintf(outfile, "\n#endif /* JPEG_INTERNALS */\n");
|
||||
fprintf(outfile, "\n#ifdef JPEG_CJPEG_DJPEG\n\n");
|
||||
fprintf(outfile, "#define BMP_SUPPORTED /* BMP image file format */\n");
|
||||
fprintf(outfile, "#define GIF_SUPPORTED /* GIF image file format */\n");
|
||||
fprintf(outfile, "#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */\n");
|
||||
fprintf(outfile, "#undef RLE_SUPPORTED /* Utah RLE image file format */\n");
|
||||
fprintf(outfile, "#define TARGA_SUPPORTED /* Targa image file format */\n\n");
|
||||
fprintf(outfile, "#undef TWO_FILE_COMMANDLINE /* You may need this on non-Unix systems */\n");
|
||||
fprintf(outfile, "#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */\n");
|
||||
fprintf(outfile, "#undef DONT_USE_B_MODE\n");
|
||||
fprintf(outfile, "/* #define PROGRESS_REPORT */ /* optional */\n");
|
||||
fprintf(outfile, "\n#endif /* JPEG_CJPEG_DJPEG */\n");
|
||||
|
||||
/* Close the jconfig.h file */
|
||||
fclose(outfile);
|
||||
|
||||
/* User report */
|
||||
printf("Configuration check for Independent JPEG Group's software done.\n");
|
||||
printf("\nI have written the jconfig.h file for you.\n\n");
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
printf("You should use makefile.ansi as the starting point for your Makefile.\n");
|
||||
#else
|
||||
printf("You should use makefile.unix as the starting point for your Makefile.\n");
|
||||
#endif
|
||||
|
||||
#ifdef NEED_SPECIAL_INCLUDE
|
||||
printf("\nYou'll need to change jconfig.h to include the system include file\n");
|
||||
printf("that you found type size_t in, or add a direct definition of type\n");
|
||||
printf("size_t if that's what you used. Just add it to the end.\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ should be in the common data structures.
|
||||
|
||||
4. Don't use static variables except for read-only constant tables. Variables
|
||||
that should be private to a module can be placed into private structures (see
|
||||
the system architecture document, structure.doc).
|
||||
the system architecture document, structure.txt).
|
||||
|
||||
5. Source file names should begin with "j" for files that are part of the
|
||||
library proper; source files that are not part of the library, such as cjpeg.c
|
||||
1501
config.guess
vendored
Executable file
1501
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1705
config.sub
vendored
Executable file
1705
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
444
configure.ac
444
configure.ac
@@ -1,184 +1,318 @@
|
||||
# -*- Autoconf -*-
|
||||
# IJG auto-configuration source file.
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.56])
|
||||
AC_INIT([libjpeg-turbo], [0.0.93])
|
||||
BUILD=`date +%Y%m%d`
|
||||
#
|
||||
# Configure script for IJG libjpeg
|
||||
#
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
|
||||
AC_PREFIX_DEFAULT(/opt/libjpeg-turbo)
|
||||
AC_INIT([libjpeg], [8.3.0])
|
||||
|
||||
# Always build with prototypes
|
||||
AC_DEFINE([HAVE_PROTOTYPES], 1, [Define if your compiler supports prototypes])
|
||||
# Don't use undefined types
|
||||
AC_DEFINE([INCOMPLETE_TYPES_BROKEN], 1, [Define if you want use complete types])
|
||||
# Directory where autotools helper scripts lives.
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
|
||||
# Checks for programs.
|
||||
SAVED_CFLAGS=${CFLAGS}
|
||||
SAVED_CXXFLAGS=${CXXFLAGS}
|
||||
AC_PROG_CPP
|
||||
# Generate configuration headers.
|
||||
AC_CONFIG_HEADERS([jconfig.h:jconfig.cfg])
|
||||
|
||||
# Hack: disable autoheader so that it doesn't overwrite our cfg template.
|
||||
AUTOHEADER="echo autoheader ignored"
|
||||
|
||||
# Check system type
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
# Initialize Automake
|
||||
# Don't require all the GNU mandated files
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror ansi2knr no-dist foreign])
|
||||
|
||||
# Make --enable-silent-rules the default.
|
||||
# To get verbose build output you may configure
|
||||
# with --disable-silent-rules or use "make V=1".
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
# This is required when using the de-ANSI-fication feature.
|
||||
AM_C_PROTOTYPES
|
||||
|
||||
# Add configure option --enable-maintainer-mode which enables
|
||||
# dependency checking and generation useful to package maintainers.
|
||||
# This is made an option to avoid confusing end users.
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
# Check for programs
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC_STDC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_LN_S
|
||||
|
||||
AC_MSG_CHECKING([whether the linker supports version scripts])
|
||||
VERSION_SCRIPT=no
|
||||
LDVER=`$LD --help </dev/null 2>&1 | grep "\-\-version-script"`
|
||||
if test "$LDVER"; then
|
||||
VERSION_SCRIPT=yes
|
||||
VERSION_SCRIPT_FLAG=-Wl,--version-script,
|
||||
AC_MSG_RESULT(yes)
|
||||
# Check if LD supports linker scripts,
|
||||
# and define automake conditional HAVE_LD_VERSION_SCRIPT if so.
|
||||
AC_ARG_ENABLE([ld-version-script],
|
||||
AS_HELP_STRING([--enable-ld-version-script],
|
||||
[enable linker version script (default is enabled when possible)]),
|
||||
[have_ld_version_script=$enableval], [])
|
||||
if test -z "$have_ld_version_script"; then
|
||||
AC_MSG_CHECKING([if LD -Wl,--version-script works])
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
|
||||
cat > conftest.map <<EOF
|
||||
VERS_1 {
|
||||
global: sym;
|
||||
};
|
||||
|
||||
VERS_2 {
|
||||
global: sym;
|
||||
} VERS_1;
|
||||
EOF
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
|
||||
[have_ld_version_script=yes], [have_ld_version_script=no])
|
||||
rm -f conftest.map
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
AC_MSG_RESULT($have_ld_version_script)
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
|
||||
|
||||
# See if compiler supports prototypes.
|
||||
AC_MSG_CHECKING(for function prototypes)
|
||||
AC_CACHE_VAL(ijg_cv_have_prototypes,
|
||||
[AC_TRY_COMPILE([
|
||||
int testfunction (int arg1, int * arg2); /* check prototypes */
|
||||
struct methods_struct { /* check method-pointer declarations */
|
||||
int (*error_exit) (char *msgtext);
|
||||
int (*trace_message) (char *msgtext);
|
||||
int (*another_method) (void);
|
||||
};
|
||||
int testfunction (int arg1, int * arg2) /* check definitions */
|
||||
{ return arg2[arg1]; }
|
||||
int test2function (void) /* check void arg list */
|
||||
{ return 0; }
|
||||
], [ ], ijg_cv_have_prototypes=yes, ijg_cv_have_prototypes=no)])
|
||||
AC_MSG_RESULT($ijg_cv_have_prototypes)
|
||||
if test $ijg_cv_have_prototypes = yes; then
|
||||
AC_DEFINE([HAVE_PROTOTYPES],[1],[Compiler supports function prototypes.])
|
||||
else
|
||||
LDVER=`$LD --help </dev/null 2>&1 | grep "\-M"`
|
||||
if test "$LDVER"; then
|
||||
VERSION_SCRIPT=yes
|
||||
VERSION_SCRIPT_FLAG=-Wl,-M,
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
echo Your compiler does not seem to know about function prototypes.
|
||||
echo Perhaps it needs a special switch to enable ANSI C mode.
|
||||
echo If so, we recommend running configure like this:
|
||||
echo " ./configure CC='cc -switch'"
|
||||
echo where -switch is the proper switch.
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(VERSION_SCRIPT, test "x$VERSION_SCRIPT" = "xyes")
|
||||
AC_SUBST(VERSION_SCRIPT_FLAG)
|
||||
# Check header files
|
||||
AC_CHECK_HEADERS(stddef.h stdlib.h locale.h)
|
||||
AC_CHECK_HEADER(string.h, , AC_DEFINE([NEED_BSD_STRINGS],[1],[Compiler has <strings.h> rather than standard <string.h>.]))
|
||||
|
||||
if test "x${GCC}" = "xyes"; then
|
||||
if test "x${SAVED_CFLAGS}" = "x"; then
|
||||
CFLAGS=-O3
|
||||
fi
|
||||
if test "x${SAVED_CXXFLAGS}" = "x"; then
|
||||
CXXFLAGS=-O3
|
||||
fi
|
||||
# See whether type size_t is defined in any ANSI-standard places;
|
||||
# if not, perhaps it is defined in <sys/types.h>.
|
||||
AC_MSG_CHECKING(for size_t)
|
||||
AC_TRY_COMPILE([
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef NEED_BSD_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
typedef size_t my_size_t;
|
||||
], [ my_size_t foovar; ], ijg_size_t_ok=yes,
|
||||
[ijg_size_t_ok="not ANSI, perhaps it is in sys/types.h"])
|
||||
AC_MSG_RESULT($ijg_size_t_ok)
|
||||
if test "$ijg_size_t_ok" != yes; then
|
||||
AC_CHECK_HEADER(sys/types.h, [AC_DEFINE([NEED_SYS_TYPES_H],[1],[Need to include <sys/types.h> in order to obtain size_t.])
|
||||
AC_EGREP_CPP(size_t, [#include <sys/types.h>],
|
||||
[ijg_size_t_ok="size_t is in sys/types.h"], ijg_size_t_ok=no)],
|
||||
ijg_size_t_ok=no)
|
||||
AC_MSG_RESULT($ijg_size_t_ok)
|
||||
if test "$ijg_size_t_ok" = no; then
|
||||
echo Type size_t is not defined in any of the usual places.
|
||||
echo Try putting '"typedef unsigned int size_t;"' in jconfig.h.
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
|
||||
if test "x${SUNCC}" = "xyes"; then
|
||||
if test "x${SAVED_CFLAGS}" = "x"; then
|
||||
CFLAGS=-xO5
|
||||
fi
|
||||
if test "x${SAVED_CXXFLAGS}" = "x"; then
|
||||
CXXFLAGS=-xO5
|
||||
fi
|
||||
fi
|
||||
# Check compiler characteristics
|
||||
AC_MSG_CHECKING(for type unsigned char)
|
||||
AC_TRY_COMPILE(, [ unsigned char un_char; ],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_UNSIGNED_CHAR],[1],[Compiler supports 'unsigned char'.])], AC_MSG_RESULT(no))
|
||||
dnl
|
||||
AC_MSG_CHECKING(for type unsigned short)
|
||||
AC_TRY_COMPILE(, [ unsigned short un_short; ],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_UNSIGNED_SHORT],[1],[Compiler supports 'unsigned short'.])], AC_MSG_RESULT(no))
|
||||
dnl
|
||||
AC_MSG_CHECKING(for type void)
|
||||
AC_TRY_COMPILE([
|
||||
/* Caution: a C++ compiler will insist on valid prototypes */
|
||||
typedef void * void_ptr; /* check void * */
|
||||
#ifdef HAVE_PROTOTYPES /* check ptr to function returning void */
|
||||
typedef void (*void_func) (int a, int b);
|
||||
#else
|
||||
typedef void (*void_func) ();
|
||||
#endif
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([stddef.h stdlib.h string.h])
|
||||
AC_CHECK_HEADER([sys/types.h], AC_DEFINE([NEED_SYS_TYPES_H], 1, [Define if you have sys/types.h]))
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
#ifdef HAVE_PROTOTYPES /* check void function result */
|
||||
void test3function (void_ptr arg1, void_func arg2)
|
||||
#else
|
||||
void test3function (arg1, arg2)
|
||||
void_ptr arg1;
|
||||
void_func arg2;
|
||||
#endif
|
||||
{
|
||||
char * locptr = (char *) arg1; /* check casting to and from void * */
|
||||
arg1 = (void *) locptr;
|
||||
(*arg2) (1, 2); /* check call of fcn returning void */
|
||||
}
|
||||
], [ ], AC_MSG_RESULT(yes), [AC_MSG_RESULT(no)
|
||||
AC_DEFINE([void],[char],[Define 'void' as 'char' for archaic compilers that don't understand it.])])
|
||||
AC_C_CONST
|
||||
AC_C_CHAR_UNSIGNED
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_CHECK_TYPES([unsigned char, unsigned short])
|
||||
|
||||
AC_MSG_CHECKING([if right shift is signed])
|
||||
AC_TRY_RUN(
|
||||
[#include <stdio.h>
|
||||
int is_shifting_signed (long arg) {
|
||||
long res = arg >> 4;
|
||||
# Check for non-broken inline under various spellings
|
||||
AC_MSG_CHECKING(for inline)
|
||||
ijg_cv_inline=""
|
||||
AC_TRY_COMPILE(, [} __inline__ int foo() { return 0; }
|
||||
int bar() { return foo();], ijg_cv_inline="__inline__",
|
||||
AC_TRY_COMPILE(, [} __inline int foo() { return 0; }
|
||||
int bar() { return foo();], ijg_cv_inline="__inline",
|
||||
AC_TRY_COMPILE(, [} inline int foo() { return 0; }
|
||||
int bar() { return foo();], ijg_cv_inline="inline")))
|
||||
AC_MSG_RESULT($ijg_cv_inline)
|
||||
AC_DEFINE_UNQUOTED([INLINE],[$ijg_cv_inline],[How to obtain function inlining.])
|
||||
|
||||
if (res == -0x7F7E80CL)
|
||||
return 1; /* right shift is signed */
|
||||
# We cannot check for bogus warnings, but at least we can check for errors
|
||||
AC_MSG_CHECKING(for broken incomplete types)
|
||||
AC_TRY_COMPILE([ typedef struct undefined_structure * undef_struct_ptr; ], ,
|
||||
AC_MSG_RESULT(ok),
|
||||
[AC_MSG_RESULT(broken)
|
||||
AC_DEFINE([INCOMPLETE_TYPES_BROKEN],[1],[Compiler does not support pointers to unspecified structures.])])
|
||||
|
||||
/* see if unsigned-shift hack will fix it. */
|
||||
/* we can't just test exact value since it depends on width of long... */
|
||||
res |= (~0L) << (32-4);
|
||||
if (res == -0x7F7E80CL)
|
||||
return 0; /* right shift is unsigned */
|
||||
# Test whether global names are unique to at least 15 chars
|
||||
AC_MSG_CHECKING(for short external names)
|
||||
AC_TRY_LINK([
|
||||
int possibly_duplicate_function () { return 0; }
|
||||
int possibly_dupli_function () { return 1; }
|
||||
], [ ], AC_MSG_RESULT(ok), [AC_MSG_RESULT(short)
|
||||
AC_DEFINE([NEED_SHORT_EXTERNAL_NAMES],[1],[Linker requires that global names be unique in first 15 characters.])])
|
||||
|
||||
printf("Right shift isn't acting as I expect it to.\n");
|
||||
printf("I fear the JPEG software will not work at all.\n\n");
|
||||
return 0; /* try it with unsigned anyway */
|
||||
}
|
||||
int main (void) {
|
||||
exit(is_shifting_signed(-0x7F7E80B1L));
|
||||
}],
|
||||
[AC_MSG_RESULT(no)
|
||||
AC_DEFINE([RIGHT_SHIFT_IS_UNSIGNED], 1, [Define if shift is unsigned])],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(Assuming that right shift is signed on target machine.)])
|
||||
# Run-time checks
|
||||
AC_MSG_CHECKING(to see if char is signed)
|
||||
AC_TRY_RUN([
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
int is_char_signed (int arg)
|
||||
#else
|
||||
int is_char_signed (arg)
|
||||
int arg;
|
||||
#endif
|
||||
{
|
||||
if (arg == 189) { /* expected result for unsigned char */
|
||||
return 0; /* type char is unsigned */
|
||||
}
|
||||
else if (arg != -67) { /* expected result for signed char */
|
||||
printf("Hmm, it seems 'char' is not eight bits wide on your machine.\n");
|
||||
printf("I fear the JPEG software will not work at all.\n\n");
|
||||
}
|
||||
return 1; /* assume char is signed otherwise */
|
||||
}
|
||||
char signed_char_check = (char) (-67);
|
||||
int main() {
|
||||
exit(is_char_signed((int) signed_char_check));
|
||||
}], [AC_MSG_RESULT(no)
|
||||
AC_DEFINE([CHAR_IS_UNSIGNED],[1],[Characters are unsigned])], AC_MSG_RESULT(yes),
|
||||
[echo Assuming that char is signed on target machine.
|
||||
echo If it is unsigned, this will be a little bit inefficient.
|
||||
])
|
||||
dnl
|
||||
AC_MSG_CHECKING(to see if right shift is signed)
|
||||
AC_TRY_RUN([
|
||||
#ifdef HAVE_PROTOTYPES
|
||||
int is_shifting_signed (long arg)
|
||||
#else
|
||||
int is_shifting_signed (arg)
|
||||
long arg;
|
||||
#endif
|
||||
/* See whether right-shift on a long is signed or not. */
|
||||
{
|
||||
long res = arg >> 4;
|
||||
|
||||
# test whether global names are unique to at least 15 chars
|
||||
AC_MSG_CHECKING([for short external names])
|
||||
AC_TRY_LINK(
|
||||
[int possibly_duplicate_function () { return 0; }
|
||||
int possibly_dupli_function () { return 1; }], [ ],
|
||||
[AC_MSG_RESULT(ok)],
|
||||
[AC_MSG_RESULT(short)
|
||||
AC_DEFINE([NEED_SHORT_EXTERNAL_NAMES], 1, [Define if you need short function names])])
|
||||
if (res == -0x7F7E80CL) { /* expected result for signed shift */
|
||||
return 1; /* right shift is signed */
|
||||
}
|
||||
/* see if unsigned-shift hack will fix it. */
|
||||
/* we can't just test exact value since it depends on width of long... */
|
||||
res |= (~0L) << (32-4);
|
||||
if (res == -0x7F7E80CL) { /* expected result now? */
|
||||
return 0; /* right shift is unsigned */
|
||||
}
|
||||
printf("Right shift isn't acting as I expect it to.\n");
|
||||
printf("I fear the JPEG software will not work at all.\n\n");
|
||||
return 0; /* try it with unsigned anyway */
|
||||
}
|
||||
int main() {
|
||||
exit(is_shifting_signed(-0x7F7E80B1L));
|
||||
}], [AC_MSG_RESULT(no)
|
||||
AC_DEFINE([RIGHT_SHIFT_IS_UNSIGNED],[1],[Broken compiler shifts signed values as an unsigned shift.])], AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(Assuming that right shift is signed on target machine.))
|
||||
dnl
|
||||
AC_MSG_CHECKING(to see if fopen accepts b spec)
|
||||
AC_TRY_RUN([
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
if (fopen("conftestdata", "wb") != NULL)
|
||||
exit(0);
|
||||
exit(1);
|
||||
}], AC_MSG_RESULT(yes), [AC_MSG_RESULT(no)
|
||||
AC_DEFINE([DONT_USE_B_MODE],[1],[Don't open files in binary mode.])],
|
||||
AC_MSG_RESULT(Assuming that it does.))
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_FUNCS([memset memcpy], [],
|
||||
[AC_DEFINE([NEED_BSD_STRINGS], 1,
|
||||
[Define if you have BSD-like bzero and bcopy])])
|
||||
# Configure libtool
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
# Set flags to indicate platform
|
||||
case "$host_os" in
|
||||
cygwin* | mingw* | pw32* | interix*)
|
||||
is_win32=1
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL([IS_WIN32], [test "x$is_win32" = "x1"])
|
||||
|
||||
# SIMD is optional
|
||||
AC_ARG_WITH([simd],
|
||||
AC_HELP_STRING([--without-simd],[Omit accelerated SIMD routines.]))
|
||||
if test "x${with_simd}" != "xno"; then
|
||||
# Check if we're on a supported CPU
|
||||
AC_MSG_CHECKING([if we have SIMD optimisations for cpu type])
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
AC_MSG_RESULT([yes (x86_64)])
|
||||
AC_PROG_NASM
|
||||
simd_arch=x86_64
|
||||
;;
|
||||
i*86 | x86 | ia32)
|
||||
AC_MSG_RESULT([yes (i386)])
|
||||
AC_PROG_NASM
|
||||
simd_arch=i386
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no ("$host_cpu")])
|
||||
AC_MSG_ERROR([CPU is not supported])
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x${with_simd}" != "xno"; then
|
||||
AC_DEFINE([WITH_SIMD], [1], [Use accelerated SIMD routines.])
|
||||
fi
|
||||
# Select memory manager depending on user input.
|
||||
# If no "-enable-maxmem", use jmemnobs
|
||||
MEMORYMGR='jmemnobs'
|
||||
MAXMEM="no"
|
||||
AC_ARG_ENABLE(maxmem,
|
||||
[ --enable-maxmem[=N] enable use of temp files, set max mem usage to N MB],
|
||||
MAXMEM="$enableval")
|
||||
dnl [# support --with-maxmem for backwards compatibility with IJG V5.]
|
||||
dnl AC_ARG_WITH(maxmem, , MAXMEM="$withval")
|
||||
if test "x$MAXMEM" = xyes; then
|
||||
MAXMEM=1
|
||||
fi
|
||||
if test "x$MAXMEM" != xno; then
|
||||
if test -n "`echo $MAXMEM | sed 's/[[0-9]]//g'`"; then
|
||||
AC_MSG_ERROR(non-numeric argument to --enable-maxmem)
|
||||
fi
|
||||
DEFAULTMAXMEM=`expr $MAXMEM \* 1048576`
|
||||
AC_DEFINE_UNQUOTED([DEFAULT_MAX_MEM], [${DEFAULTMAXMEM}], [Maximum data space library will allocate.])
|
||||
AC_MSG_CHECKING([for 'tmpfile()'])
|
||||
AC_TRY_LINK([#include <stdio.h>], [ FILE * tfile = tmpfile(); ],
|
||||
[AC_MSG_RESULT(yes)
|
||||
MEMORYMGR='jmemansi'],
|
||||
[AC_MSG_RESULT(no)
|
||||
dnl if tmpfile is not present, must use jmemname.
|
||||
MEMORYMGR='jmemname'
|
||||
|
||||
AM_CONDITIONAL([WITH_SIMD], [test "x$with_simd" != "xno"])
|
||||
AM_CONDITIONAL([SIMD_I386], [test "x$simd_arch" = "xi386"])
|
||||
AM_CONDITIONAL([SIMD_X86_64], [test "x$simd_arch" = "xx86_64"])
|
||||
AM_CONDITIONAL([X86_64], [test "x$host_cpu" = "xx86_64"])
|
||||
# Test for the need to remove temporary files using a signal handler (for cjpeg/djpeg)
|
||||
AC_DEFINE([NEED_SIGNAL_CATCHER],[1],[Need signal handler to clean up temporary files.])
|
||||
AC_MSG_CHECKING([for 'mktemp()'])
|
||||
AC_TRY_LINK(, [ char fname[80]; mktemp(fname); ], AC_MSG_RESULT(yes),
|
||||
[AC_MSG_RESULT(no)
|
||||
AC_DEFINE([NO_MKTEMP],[1],[The mktemp() function is not available.])])])
|
||||
fi
|
||||
AC_SUBST(MEMORYMGR)
|
||||
|
||||
case "$host_cpu" in
|
||||
x86_64)
|
||||
RPMARCH=x86_64
|
||||
DEBARCH=amd64
|
||||
;;
|
||||
i*86 | x86 | ia32)
|
||||
RPMARCH=i386
|
||||
DEBARCH=i386
|
||||
;;
|
||||
esac
|
||||
# Extract the library version IDs from jpeglib.h.
|
||||
AC_MSG_CHECKING([libjpeg version number])
|
||||
[JPEG_LIB_VERSION_MAJOR=`sed -e '/^#define JPEG_LIB_VERSION_MAJOR/!d' -e 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/' $srcdir/jpeglib.h`]
|
||||
[JPEG_LIB_VERSION_MINOR=`sed -e '/^#define JPEG_LIB_VERSION_MINOR/!d' -e 's/^[^0-9]*\([0-9][0-9]*\).*$/\1/' $srcdir/jpeglib.h`]
|
||||
[JPEG_LIB_VERSION="`expr $JPEG_LIB_VERSION_MAJOR + $JPEG_LIB_VERSION_MINOR`:0:$JPEG_LIB_VERSION_MINOR"]
|
||||
AC_MSG_RESULT([$JPEG_LIB_VERSION])
|
||||
AC_SUBST([JPEG_LIB_VERSION])
|
||||
|
||||
AC_SUBST(RPMARCH)
|
||||
AC_SUBST(DEBARCH)
|
||||
AC_SUBST(BUILD)
|
||||
|
||||
# jconfig.h is the file we use, but we have another before that to
|
||||
# fool autoheader. the reason is that we include this header in our
|
||||
# API headers, which can screw things up for users of the lib.
|
||||
# jconfig.h is a minimal version that allows this package to be built
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_HEADERS([jconfig.h])
|
||||
AC_CONFIG_FILES([Makefile simd/Makefile])
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
630
depcomp
Executable file
630
depcomp
Executable file
@@ -0,0 +1,630 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputing dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u="sed s,\\\\\\\\,/,g"
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mechanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.o.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
tmpdepfile4=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
17
djpeg.1
17
djpeg.1
@@ -1,4 +1,4 @@
|
||||
.TH DJPEG 1 "22 August 1997"
|
||||
.TH DJPEG 1 "3 October 2009"
|
||||
.SH NAME
|
||||
djpeg \- decompress a JPEG file to an image file
|
||||
.SH SYNOPSIS
|
||||
@@ -61,9 +61,12 @@ monochrome displays; also,
|
||||
runs noticeably faster in this mode.
|
||||
.TP
|
||||
.BI \-scale " M/N"
|
||||
Scale the output image by a factor M/N. Currently the scale factor must be
|
||||
1/1, 1/2, 1/4, or 1/8. Scaling is handy if the image is larger than your
|
||||
screen; also,
|
||||
Scale the output image by a factor M/N. Currently supported scale factors are
|
||||
M/N with all M from 1 to 16, where N is the source DCT size, which is 8 for
|
||||
baseline JPEG. If the /N part is omitted, then M specifies the DCT scaled
|
||||
size to be applied on the given input. For baseline JPEG this is equivalent
|
||||
to M/8 scaling, since the source DCT size for baseline JPEG is 8.
|
||||
Scaling is handy if the image is larger than your screen; also,
|
||||
.B djpeg
|
||||
runs much faster when scaling down the output.
|
||||
.TP
|
||||
@@ -150,7 +153,7 @@ and
|
||||
.BR \-onepass .
|
||||
.TP
|
||||
.B \-nosmooth
|
||||
Use a faster, lower-quality upsampling routine.
|
||||
Don't use high-quality upsampling.
|
||||
.TP
|
||||
.B \-onepass
|
||||
Use one-pass instead of two-pass color quantization. The one-pass method is
|
||||
@@ -243,11 +246,7 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
|
||||
.SH AUTHOR
|
||||
Independent JPEG Group
|
||||
.SH BUGS
|
||||
Arithmetic coding is not supported for legal reasons.
|
||||
.PP
|
||||
To avoid the Unisys LZW patent,
|
||||
.B djpeg
|
||||
produces uncompressed GIF files. These are larger than they should be, but
|
||||
are readable by standard GIF decoders.
|
||||
.PP
|
||||
Still not as fast as we'd like.
|
||||
|
||||
3
djpeg.c
3
djpeg.c
@@ -2,6 +2,7 @@
|
||||
* djpeg.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -327,7 +328,7 @@ parse_switches (j_decompress_ptr cinfo, int argc, char **argv,
|
||||
if (++argn >= argc) /* advance to next argument */
|
||||
usage();
|
||||
if (sscanf(argv[argn], "%d/%d",
|
||||
&cinfo->scale_num, &cinfo->scale_denom) != 2)
|
||||
&cinfo->scale_num, &cinfo->scale_denom) < 1)
|
||||
usage();
|
||||
|
||||
} else if (keymatch(arg, "targa", 1)) {
|
||||
|
||||
12
example.c
12
example.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file illustrates how to use the IJG code as a subroutine library
|
||||
* to read or write JPEG image files. You should look at this code in
|
||||
* conjunction with the documentation file libjpeg.doc.
|
||||
* conjunction with the documentation file libjpeg.txt.
|
||||
*
|
||||
* This code will not do anything useful as-is, but it may be helpful as a
|
||||
* skeleton for constructing routines that call the JPEG library.
|
||||
@@ -196,7 +196,7 @@ write_JPEG_file (char * filename, int quality)
|
||||
* files for anything that doesn't fit within the maximum-memory setting.
|
||||
* (Note that temp files are NOT needed if you use the default parameters.)
|
||||
* On some systems you may need to set up a signal handler to ensure that
|
||||
* temporary files are deleted if the program is interrupted. See libjpeg.doc.
|
||||
* temporary files are deleted if the program is interrupted. See libjpeg.txt.
|
||||
*
|
||||
* Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
|
||||
* files to be compatible with everyone else's. If you cannot readily read
|
||||
@@ -335,7 +335,7 @@ read_JPEG_file (char * filename)
|
||||
/* We can ignore the return value from jpeg_read_header since
|
||||
* (a) suspension is not possible with the stdio data source, and
|
||||
* (b) we passed TRUE to reject a tables-only JPEG file as an error.
|
||||
* See libjpeg.doc for more info.
|
||||
* See libjpeg.txt for more info.
|
||||
*/
|
||||
|
||||
/* Step 4: set parameters for decompression */
|
||||
@@ -413,14 +413,14 @@ read_JPEG_file (char * filename)
|
||||
* In the above code, we ignored the return value of jpeg_read_scanlines,
|
||||
* which is the number of scanlines actually read. We could get away with
|
||||
* this because we asked for only one line at a time and we weren't using
|
||||
* a suspending data source. See libjpeg.doc for more info.
|
||||
* a suspending data source. See libjpeg.txt for more info.
|
||||
*
|
||||
* We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
|
||||
* we should have done it beforehand to ensure that the space would be
|
||||
* counted against the JPEG max_memory setting. In some systems the above
|
||||
* code would risk an out-of-memory error. However, in general we don't
|
||||
* know the output image dimensions before jpeg_start_decompress(), unless we
|
||||
* call jpeg_calc_output_dimensions(). See libjpeg.doc for more about this.
|
||||
* call jpeg_calc_output_dimensions(). See libjpeg.txt for more about this.
|
||||
*
|
||||
* Scanlines are returned in the same order as they appear in the JPEG file,
|
||||
* which is standardly top-to-bottom. If you must emit data bottom-to-top,
|
||||
@@ -429,5 +429,5 @@ read_JPEG_file (char * filename)
|
||||
*
|
||||
* As with compression, some operating modes may require temporary files.
|
||||
* On some systems you may need to set up a signal handler to ensure that
|
||||
* temporary files are deleted if the program is interrupted. See libjpeg.doc.
|
||||
* temporary files are deleted if the program is interrupted. See libjpeg.txt.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
IJG JPEG LIBRARY: FILE LIST
|
||||
|
||||
Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
Copyright (C) 1994-2009, Thomas G. Lane, Guido Vollbeding.
|
||||
This file is part of the Independent JPEG Group's software.
|
||||
For conditions of distribution and use, see the accompanying README file.
|
||||
|
||||
@@ -28,8 +28,6 @@ jerror.h Declares JPEG library's error and trace message codes.
|
||||
jinclude.h Central include file used by all IJG .c files to reference
|
||||
system include files.
|
||||
jpegint.h JPEG library's internal data structures.
|
||||
jchuff.h Private declarations for Huffman encoder modules.
|
||||
jdhuff.h Private declarations for Huffman decoder modules.
|
||||
jdct.h Private declarations for forward & reverse DCT subsystems.
|
||||
jmemsys.h Private declarations for memory management subsystem.
|
||||
jversion.h Version information.
|
||||
@@ -72,10 +70,10 @@ jcdctmgr.c DCT manager (DCT implementation selection & control).
|
||||
jfdctint.c Forward DCT using slow-but-accurate integer method.
|
||||
jfdctfst.c Forward DCT using faster, less accurate integer method.
|
||||
jfdctflt.c Forward DCT using floating-point arithmetic.
|
||||
jchuff.c Huffman entropy coding for sequential JPEG.
|
||||
jcphuff.c Huffman entropy coding for progressive JPEG.
|
||||
jchuff.c Huffman entropy coding.
|
||||
jcarith.c Arithmetic entropy coding.
|
||||
jcmarker.c JPEG marker writing.
|
||||
jdatadst.c Data destination manager for stdio output.
|
||||
jdatadst.c Data destination managers for memory and stdio output.
|
||||
|
||||
Decompression side of the library:
|
||||
|
||||
@@ -85,23 +83,24 @@ jdmainct.c Main buffer controller (JPEG decompressor => postprocessor).
|
||||
jdcoefct.c Buffer controller for DCT coefficient buffer.
|
||||
jdpostct.c Postprocessor buffer controller.
|
||||
jdmarker.c JPEG marker reading.
|
||||
jdhuff.c Huffman entropy decoding for sequential JPEG.
|
||||
jdphuff.c Huffman entropy decoding for progressive JPEG.
|
||||
jdhuff.c Huffman entropy decoding.
|
||||
jdarith.c Arithmetic entropy decoding.
|
||||
jddctmgr.c IDCT manager (IDCT implementation selection & control).
|
||||
jidctint.c Inverse DCT using slow-but-accurate integer method.
|
||||
jidctfst.c Inverse DCT using faster, less accurate integer method.
|
||||
jidctflt.c Inverse DCT using floating-point arithmetic.
|
||||
jidctred.c Inverse DCTs with reduced-size outputs.
|
||||
jdsample.c Upsampling.
|
||||
jdcolor.c Color space conversion.
|
||||
jdmerge.c Merged upsampling/color conversion (faster, lower quality).
|
||||
jquant1.c One-pass color quantization using a fixed-spacing colormap.
|
||||
jquant2.c Two-pass color quantization using a custom-generated colormap.
|
||||
Also handles one-pass quantization to an externally given map.
|
||||
jdatasrc.c Data source manager for stdio input.
|
||||
jdatasrc.c Data source managers for memory and stdio input.
|
||||
|
||||
Support files for both compression and decompression:
|
||||
|
||||
jaricom.c Tables for common use in arithmetic entropy encoding and
|
||||
decoding routines.
|
||||
jerror.c Standard error handling routines (application replaceable).
|
||||
jmemmgr.c System-independent (more or less) memory management code.
|
||||
jutils.c Miscellaneous utility routines.
|
||||
@@ -118,7 +117,7 @@ jmemdos.c Custom implementation for MS-DOS (16-bit environment only):
|
||||
jmemmac.c Custom implementation for Apple Macintosh.
|
||||
|
||||
Exactly one of the system-dependent modules should be configured into an
|
||||
installed JPEG library (see install.doc for hints about which one to use).
|
||||
installed JPEG library (see install.txt for hints about which one to use).
|
||||
On unusual systems you may find it worthwhile to make a special
|
||||
system-dependent memory manager.
|
||||
|
||||
@@ -184,27 +183,33 @@ ADDITIONAL FILES
|
||||
Documentation (see README for a guide to the documentation files):
|
||||
|
||||
README Master documentation file.
|
||||
*.doc Other documentation files.
|
||||
*.txt Other documentation files.
|
||||
*.1 Documentation in Unix man page format.
|
||||
change.log Version-to-version change highlights.
|
||||
example.c Sample code for calling JPEG library.
|
||||
|
||||
Configuration/installation files and programs (see install.doc for more info):
|
||||
Configuration/installation files and programs (see install.txt for more info):
|
||||
|
||||
configure Unix shell script to perform automatic configuration.
|
||||
ltconfig Support scripts for configure (from GNU libtool).
|
||||
ltmain.sh
|
||||
configure.ac Source file for use with Autoconf to generate configure.
|
||||
ltmain.sh Support scripts for configure (from GNU libtool).
|
||||
config.guess
|
||||
config.sub
|
||||
depcomp
|
||||
missing
|
||||
install-sh Install shell script for those Unix systems lacking one.
|
||||
Makefile.in Makefile input for configure.
|
||||
Makefile.am Source file for use with Automake to generate Makefile.in.
|
||||
ckconfig.c Program to generate jconfig.h on non-Unix systems.
|
||||
jconfig.doc Template for making jconfig.h by hand.
|
||||
makefile.* Sample makefiles for particular systems.
|
||||
jconfig.txt Template for making jconfig.h by hand.
|
||||
mak*.* Sample makefiles for particular systems.
|
||||
jconfig.* Sample jconfig.h for particular systems.
|
||||
libjpeg.map Script to generate shared library with versioned symbols.
|
||||
aclocal.m4 M4 macro definitions for use with Autoconf.
|
||||
ansi2knr.c De-ANSIfier for pre-ANSI C compilers (courtesy of
|
||||
L. Peter Deutsch and Aladdin Enterprises).
|
||||
|
||||
Test files (see install.doc for test procedure):
|
||||
Test files (see install.txt for test procedure):
|
||||
|
||||
test*.* Source and comparison files for confidence test.
|
||||
These are binary image files, NOT text files.
|
||||
520
install-sh
Executable file
520
install-sh
Executable file
@@ -0,0 +1,520 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dst_arg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
-*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test -z "$d" && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
@@ -1,6 +1,6 @@
|
||||
INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
|
||||
|
||||
Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
Copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding.
|
||||
This file is part of the Independent JPEG Group's software.
|
||||
For conditions of distribution and use, see the accompanying README file.
|
||||
|
||||
@@ -94,18 +94,13 @@ Configure was created with GNU Autoconf and it follows the usual conventions
|
||||
for GNU configure scripts. It makes a few assumptions that you may want to
|
||||
override. You can do this by providing optional switches to configure:
|
||||
|
||||
* If you want to build libjpeg as a shared library, say
|
||||
./configure --enable-shared
|
||||
To get both shared and static libraries, say
|
||||
./configure --enable-shared --enable-static
|
||||
Note that these switches invoke GNU libtool to take care of system-dependent
|
||||
shared library building methods. If things don't work this way, please try
|
||||
running configure without either switch; that should build a static library
|
||||
without using libtool. If that works, your problem is probably with libtool
|
||||
not with the IJG code. libtool is fairly new and doesn't support all flavors
|
||||
of Unix yet. (You might be able to find a newer version of libtool than the
|
||||
one included with libjpeg; see ftp.gnu.org. Report libtool problems to
|
||||
bug-libtool@gnu.org.)
|
||||
* Configure will build both static and shared libraries, if possible.
|
||||
If you want to build libjpeg only as a static library, say
|
||||
./configure --disable-shared
|
||||
If you want to build libjpeg only as a shared library, say
|
||||
./configure --disable-static
|
||||
Configure uses GNU libtool to take care of system-dependent shared library
|
||||
building methods.
|
||||
|
||||
* Configure will use gcc (GNU C compiler) if it's available, otherwise cc.
|
||||
To force a particular compiler to be selected, use the CC option, for example
|
||||
@@ -115,10 +110,10 @@ For example, on HP-UX you probably want to say
|
||||
./configure CC='cc -Aa'
|
||||
to get HP's compiler to run in ANSI mode.
|
||||
|
||||
* The default CFLAGS setting is "-O" for non-gcc compilers, "-O2" for gcc.
|
||||
* The default CFLAGS setting is "-g" for non-gcc compilers, "-g -O2" for gcc.
|
||||
You can override this by saying, for example,
|
||||
./configure CFLAGS='-g'
|
||||
if you want to compile with debugging support.
|
||||
./configure CFLAGS='-O2'
|
||||
if you want to compile without debugging support.
|
||||
|
||||
* Configure will set up the makefile so that "make install" will install files
|
||||
into /usr/local/bin, /usr/local/man, etc. You can specify an installation
|
||||
@@ -153,7 +148,8 @@ makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU C)
|
||||
makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C (16-bit only)
|
||||
makefile.wat jconfig.wat MS-DOS, OS/2, or Windows NT, Watcom C
|
||||
makefile.vc jconfig.vc Windows NT/95, MS Visual C++
|
||||
make*.ds jconfig.vc Windows NT/95, MS Developer Studio
|
||||
make*.vc6 jconfig.vc Windows NT/95, MS Visual C++ 6
|
||||
make*.v10 jconfig.vc Windows NT/95, MS Visual C++ 2010 (v10)
|
||||
makefile.mms jconfig.vms Digital VMS, with MMS software
|
||||
makefile.vms jconfig.vms Digital VMS, without MMS software
|
||||
|
||||
@@ -166,8 +162,8 @@ Configuring the software by hand
|
||||
--------------------------------
|
||||
|
||||
First, generate a jconfig.h file. If you are moderately familiar with C,
|
||||
the comments in jconfig.doc should be enough information to do this; just
|
||||
copy jconfig.doc to jconfig.h and edit it appropriately. Otherwise, you may
|
||||
the comments in jconfig.txt should be enough information to do this; just
|
||||
copy jconfig.txt to jconfig.h and edit it appropriately. Otherwise, you may
|
||||
prefer to use the ckconfig.c program. You will need to compile and execute
|
||||
ckconfig.c by hand --- we hope you know at least enough to do that.
|
||||
ckconfig.c may not compile the first try (in fact, the whole idea is for it
|
||||
@@ -447,8 +443,8 @@ on our to-do list.)
|
||||
|
||||
The PPM reader (rdppm.c) can read 12-bit data from either text-format or
|
||||
binary-format PPM and PGM files. Binary-format PPM/PGM files which have a
|
||||
maxval greater than 255 are assumed to use 2 bytes per sample, LSB first
|
||||
(little-endian order). As of early 1995, 2-byte binary format is not
|
||||
maxval greater than 255 are assumed to use 2 bytes per sample, MSB first
|
||||
(big-endian order). As of early 1995, 2-byte binary format is not
|
||||
officially supported by the PBMPLUS library, but it is expected that a
|
||||
future release of PBMPLUS will support it. Note that the PPM reader will
|
||||
read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming
|
||||
@@ -521,7 +517,7 @@ that float DCT results may vary slightly across machines.) To do that, add
|
||||
"#define JDCT_DEFAULT JDCT_FLOAT" to jconfig.h. Even if you don't change
|
||||
the default, you should redefine JDCT_FASTEST, which is the method selected
|
||||
by djpeg's -fast switch. Don't forget to update the documentation files
|
||||
(usage.doc and/or cjpeg.1, djpeg.1) to agree with what you've done.
|
||||
(usage.txt and/or cjpeg.1, djpeg.1) to agree with what you've done.
|
||||
|
||||
If access to "short" arrays is slow on your machine, it may be a win to
|
||||
define type JCOEF as int rather than short. This will cost a good deal of
|
||||
@@ -538,17 +534,17 @@ In general, it's worth trying the maximum optimization level of your compiler,
|
||||
and experimenting with any optional optimizations such as loop unrolling.
|
||||
(Unfortunately, far too many compilers have optimizer bugs ... be prepared to
|
||||
back off if the code fails self-test.) If you do any experimentation along
|
||||
these lines, please report the optimal settings to jpeg-info@uunet.uu.net so
|
||||
we can mention them in future releases. Be sure to specify your machine and
|
||||
compiler version.
|
||||
these lines, please report the optimal settings to jpeg-info@uc.ag so we
|
||||
can mention them in future releases. Be sure to specify your machine
|
||||
and compiler version.
|
||||
|
||||
|
||||
HINTS FOR SPECIFIC SYSTEMS
|
||||
==========================
|
||||
|
||||
We welcome reports on changes needed for systems not mentioned here. Submit
|
||||
'em to jpeg-info@uunet.uu.net. Also, if configure or ckconfig.c is wrong
|
||||
about how to configure the JPEG software for your system, please let us know.
|
||||
'em to jpeg-info@uc.ag. Also, if configure or ckconfig.c is wrong about how
|
||||
to configure the JPEG software for your system, please let us know.
|
||||
|
||||
|
||||
Acorn RISC OS:
|
||||
@@ -568,7 +564,7 @@ Also add a new line '.c.o:; $(cc) $< $(cflags) -c -o $@'. Remove the
|
||||
lines '$(RM) libjpeg.o' and '$(AR2) libjpeg.o' and the 'jconfig.h'
|
||||
dependency section.
|
||||
|
||||
Copy jconfig.doc to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE
|
||||
Copy jconfig.txt to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE
|
||||
and CHAR_IS_UNSIGNED.
|
||||
|
||||
Run the makefile using !AMU not !Make. If you want to use the 'clean' and
|
||||
@@ -587,7 +583,7 @@ manager, with temporary files being created on the device named by
|
||||
|
||||
|
||||
Atari ST/STE/TT:
|
||||
|
||||
|
||||
Copy the project files makcjpeg.st, makdjpeg.st, maktjpeg.st, and makljpeg.st
|
||||
to cjpeg.prj, djpeg.prj, jpegtran.prj, and libjpeg.prj respectively. The
|
||||
project files should work as-is with Pure C. For Turbo C, change library
|
||||
@@ -610,7 +606,8 @@ or jpegtran.ttp. You'll have to perform the self-test by hand.
|
||||
|
||||
We haven't bothered to include project files for rdjpgcom and wrjpgcom.
|
||||
Those source files should just be compiled by themselves; they don't
|
||||
depend on the JPEG library.
|
||||
depend on the JPEG library. You can use the default.prj project file
|
||||
of the Pure C distribution to make the programs.
|
||||
|
||||
There is a bug in some older versions of the Turbo C library which causes the
|
||||
space used by temporary files created with "tmpfile()" not to be freed after
|
||||
@@ -872,6 +869,7 @@ Since jmorecfg.h tries to define FAR as empty, you may get a compiler
|
||||
warning if you include both jpeglib.h and windef.h (which windows.h
|
||||
includes). To suppress the warning, you can put "#ifndef FAR"/"#endif"
|
||||
around the line "#define FAR" in jmorecfg.h.
|
||||
(Something like this is already in jmorecfg.h, by the way.)
|
||||
|
||||
When using the library in a Windows application, you will almost certainly
|
||||
want to modify or replace the error handler module jerror.c, since our
|
||||
@@ -890,7 +888,7 @@ jconfig.h to enable it.)
|
||||
|
||||
The proper solution for problem 2 is to return control to your calling
|
||||
application after a library error. This can be done with the setjmp/longjmp
|
||||
technique discussed in libjpeg.doc and illustrated in example.c. (NOTE:
|
||||
technique discussed in libjpeg.txt and illustrated in example.c. (NOTE:
|
||||
some older Windows C compilers provide versions of setjmp/longjmp that
|
||||
don't actually work under Windows. You may need to use the Windows system
|
||||
functions Catch and Throw instead.)
|
||||
@@ -1000,32 +998,67 @@ model. makefile.vc is intended for command-line use. (If you are using
|
||||
the Developer Studio environment, you may prefer the DevStudio project
|
||||
files; see below.)
|
||||
|
||||
Some users feel that it's easier to call the library from C++ code if you
|
||||
force VC++ to treat the library as C++ code, which you can do by renaming
|
||||
all the *.c files to *.cpp (and adjusting the makefile to match). This
|
||||
avoids the need to put extern "C" { ... } around #include "jpeglib.h" in
|
||||
your C++ application.
|
||||
IJG JPEG 7 adds extern "C" to jpeglib.h. This avoids the need to put
|
||||
extern "C" { ... } around #include "jpeglib.h" in your C++ application.
|
||||
You can also force VC++ to treat the library as C++ code by renaming
|
||||
all the *.c files to *.cpp (and adjusting the makefile to match).
|
||||
In this case you also need to define the symbol DONT_USE_EXTERN_C in
|
||||
the configuration to prevent jpeglib.h from using extern "C".
|
||||
|
||||
|
||||
Microsoft Windows, Microsoft Developer Studio:
|
||||
Microsoft Windows, Microsoft Visual C++ 6 Developer Studio:
|
||||
|
||||
We include makefiles that should work as project files in DevStudio 4.2 or
|
||||
We include makefiles that should work as project files in DevStudio 6.0 or
|
||||
later. There is a library makefile that builds the IJG library as a static
|
||||
Win32 library, and an application makefile that builds the sample applications
|
||||
Win32 library, and application makefiles that build the sample applications
|
||||
as Win32 console applications. (Even if you only want the library, we
|
||||
recommend building the applications so that you can run the self-test.)
|
||||
|
||||
To use:
|
||||
1. Copy jconfig.vc to jconfig.h, makelib.ds to jpeg.mak, and
|
||||
makeapps.ds to apps.mak. (Note that the renaming is critical!)
|
||||
2. Click on the .mak files to construct project workspaces.
|
||||
(If you are using DevStudio more recent than 4.2, you'll probably
|
||||
get a message saying that the makefiles are being updated.)
|
||||
3. Build the library project, then the applications project.
|
||||
4. Move the application .exe files from `app`\Release to an
|
||||
1. Open the command prompt, change to the main directory and execute the
|
||||
command line
|
||||
NMAKE /f makefile.vc setup-vc6
|
||||
This will move jconfig.vc to jconfig.h and makefiles to project files.
|
||||
(Note that the renaming is critical!)
|
||||
2. Open the workspace file jpeg.dsw, build the library project.
|
||||
(If you are using DevStudio more recent than 6.0, you'll probably
|
||||
get a message saying that the project files are being updated.)
|
||||
3. Open the workspace file apps.dsw, build the application projects.
|
||||
4. To perform the self-test, execute the command line
|
||||
NMAKE /f makefile.vc test-build
|
||||
5. Move the application .exe files from `app`\Release to an
|
||||
appropriate location on your path.
|
||||
5. To perform the self-test, execute the command line
|
||||
NMAKE /f makefile.vc test
|
||||
|
||||
|
||||
Microsoft Windows, Microsoft Visual C++ 2010 Developer Studio (v10):
|
||||
|
||||
We include makefiles that should work as project files in Visual Studio
|
||||
2010 or later. There is a library makefile that builds the IJG library
|
||||
as a static Win32 library, and application makefiles that build the sample
|
||||
applications as Win32 console applications. (Even if you only want the
|
||||
library, we recommend building the applications so that you can run the
|
||||
self-test.)
|
||||
|
||||
To use:
|
||||
1. Open the command prompt, change to the main directory and execute the
|
||||
command line
|
||||
NMAKE /f makefile.vc setup-v10
|
||||
This will move jconfig.vc to jconfig.h and makefiles to project files.
|
||||
(Note that the renaming is critical!)
|
||||
2. Open the solution file jpeg.sln, build the library project.
|
||||
(If you are using Visual Studio more recent than 2010 (v10), you'll
|
||||
probably get a message saying that the project files are being updated.)
|
||||
3. Open the solution file apps.sln, build the application projects.
|
||||
4. To perform the self-test, execute the command line
|
||||
NMAKE /f makefile.vc test-build
|
||||
5. Move the application .exe files from `app`\Release to an
|
||||
appropriate location on your path.
|
||||
|
||||
Note:
|
||||
There seems to be an optimization bug in the compiler which causes the
|
||||
self-test to fail with the color quantization option.
|
||||
We have disabled optimization for the file jquant2.c in the library
|
||||
project file which causes the self-test to pass properly.
|
||||
|
||||
|
||||
OS/2, Borland C++:
|
||||
153
jaricom.c
Normal file
153
jaricom.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* jaricom.c
|
||||
*
|
||||
* Developed 1997-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains probability estimation tables for common use in
|
||||
* arithmetic entropy encoding and decoding routines.
|
||||
*
|
||||
* This data represents Table D.2 in the JPEG spec (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 recommended in Section 10.3 Table 5 of ITU-T Rec. T.851.
|
||||
*/
|
||||
V( 113, 0x5a1d, 113, 113, 0 )
|
||||
};
|
||||
10
jcapimin.c
10
jcapimin.c
@@ -2,6 +2,7 @@
|
||||
* jcapimin.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -63,14 +64,21 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
|
||||
|
||||
cinfo->comp_info = NULL;
|
||||
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++)
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++) {
|
||||
cinfo->quant_tbl_ptrs[i] = NULL;
|
||||
cinfo->q_scale_factor[i] = 100;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
cinfo->dc_huff_tbl_ptrs[i] = NULL;
|
||||
cinfo->ac_huff_tbl_ptrs[i] = NULL;
|
||||
}
|
||||
|
||||
/* Must do it here for emit_dqt in case jpeg_write_tables is used */
|
||||
cinfo->block_size = DCTSIZE;
|
||||
cinfo->natural_order = jpeg_natural_order;
|
||||
cinfo->lim_Se = DCTSIZE2-1;
|
||||
|
||||
cinfo->script_space = NULL;
|
||||
|
||||
cinfo->input_gamma = 1.0; /* in case application forgets */
|
||||
|
||||
934
jcarith.c
Normal file
934
jcarith.c
Normal file
@@ -0,0 +1,934 @@
|
||||
/*
|
||||
* jcarith.c
|
||||
*
|
||||
* Developed 1997-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains portable arithmetic entropy encoding routines for JPEG
|
||||
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
|
||||
*
|
||||
* Both sequential and progressive modes are supported in this single module.
|
||||
*
|
||||
* Suspension is not currently supported in this module.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Expanded entropy encoder object for arithmetic encoding. */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_encoder pub; /* public fields */
|
||||
|
||||
INT32 c; /* C register, base of coding interval, layout as in sec. D.1.3 */
|
||||
INT32 a; /* A register, normalized size of coding interval */
|
||||
INT32 sc; /* counter for stacked 0xFF values which might overflow */
|
||||
INT32 zc; /* counter for pending 0x00 output values which might *
|
||||
* be discarded at the end ("Pacman" termination) */
|
||||
int ct; /* bit shift counter, determines when next byte will be written */
|
||||
int buffer; /* buffer for most recent output byte != 0xFF */
|
||||
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
|
||||
|
||||
unsigned int restarts_to_go; /* MCUs left in this restart interval */
|
||||
int next_restart_num; /* next restart number to write (0-7) */
|
||||
|
||||
/* Pointers to statistics areas (these workspaces have image lifespan) */
|
||||
unsigned char * dc_stats[NUM_ARITH_TBLS];
|
||||
unsigned char * ac_stats[NUM_ARITH_TBLS];
|
||||
|
||||
/* Statistics bin for coding with fixed probability 0.5 */
|
||||
unsigned char fixed_bin[4];
|
||||
} arith_entropy_encoder;
|
||||
|
||||
typedef arith_entropy_encoder * arith_entropy_ptr;
|
||||
|
||||
/* The following two definitions specify the allocation chunk size
|
||||
* for the statistics area.
|
||||
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
|
||||
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
|
||||
*
|
||||
* We use a compact representation with 1 byte per statistics bin,
|
||||
* thus the numbers directly represent byte sizes.
|
||||
* This 1 byte per statistics bin contains the meaning of the MPS
|
||||
* (more probable symbol) in the highest bit (mask 0x80), and the
|
||||
* index into the probability estimation state machine table
|
||||
* in the lower bits (mask 0x7F).
|
||||
*/
|
||||
|
||||
#define DC_STAT_BINS 64
|
||||
#define AC_STAT_BINS 256
|
||||
|
||||
/* NOTE: Uncomment the following #define if you want to use the
|
||||
* given formula for calculating the AC conditioning parameter Kx
|
||||
* for spectral selection progressive coding in section G.1.3.2
|
||||
* of the spec (Kx = Kmin + SRL (8 + Se - Kmin) 4).
|
||||
* Although the spec and P&M authors claim that this "has proven
|
||||
* to give good results for 8 bit precision samples", I'm not
|
||||
* convinced yet that this is really beneficial.
|
||||
* Early tests gave only very marginal compression enhancements
|
||||
* (a few - around 5 or so - bytes even for very large files),
|
||||
* which would turn out rather negative if we'd suppress the
|
||||
* DAC (Define Arithmetic Conditioning) marker segments for
|
||||
* the default parameters in the future.
|
||||
* Note that currently the marker writing module emits 12-byte
|
||||
* DAC segments for a full-component scan in a color image.
|
||||
* This is not worth worrying about IMHO. However, since the
|
||||
* spec defines the default values to be used if the tables
|
||||
* are omitted (unlike Huffman tables, which are required
|
||||
* anyway), one might optimize this behaviour in the future,
|
||||
* and then it would be disadvantageous to use custom tables if
|
||||
* they don't provide sufficient gain to exceed the DAC size.
|
||||
*
|
||||
* On the other hand, I'd consider it as a reasonable result
|
||||
* that the conditioning has no significant influence on the
|
||||
* compression performance. This means that the basic
|
||||
* statistical model is already rather stable.
|
||||
*
|
||||
* Thus, at the moment, we use the default conditioning values
|
||||
* anyway, and do not use the custom formula.
|
||||
*
|
||||
#define CALCULATE_SPECTRAL_CONDITIONING
|
||||
*/
|
||||
|
||||
/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
|
||||
* We assume that int right shift is unsigned if INT32 right shift is,
|
||||
* which should be safe.
|
||||
*/
|
||||
|
||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#define ISHIFT_TEMPS int ishift_temp;
|
||||
#define IRIGHT_SHIFT(x,shft) \
|
||||
((ishift_temp = (x)) < 0 ? \
|
||||
(ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
|
||||
(ishift_temp >> (shft)))
|
||||
#else
|
||||
#define ISHIFT_TEMPS
|
||||
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
|
||||
#endif
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
emit_byte (int val, j_compress_ptr cinfo)
|
||||
/* Write next output byte; we do not support suspension in this module. */
|
||||
{
|
||||
struct jpeg_destination_mgr * dest = cinfo->dest;
|
||||
|
||||
*dest->next_output_byte++ = (JOCTET) val;
|
||||
if (--dest->free_in_buffer == 0)
|
||||
if (! (*dest->empty_output_buffer) (cinfo))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up at the end of an arithmetic-compressed scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
finish_pass (j_compress_ptr cinfo)
|
||||
{
|
||||
arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
|
||||
INT32 temp;
|
||||
|
||||
/* Section D.1.8: Termination of encoding */
|
||||
|
||||
/* Find the e->c in the coding interval with the largest
|
||||
* number of trailing zero bits */
|
||||
if ((temp = (e->a - 1 + e->c) & 0xFFFF0000L) < e->c)
|
||||
e->c = temp + 0x8000L;
|
||||
else
|
||||
e->c = temp;
|
||||
/* Send remaining bytes to output */
|
||||
e->c <<= e->ct;
|
||||
if (e->c & 0xF8000000L) {
|
||||
/* One final overflow has to be handled */
|
||||
if (e->buffer >= 0) {
|
||||
if (e->zc)
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
emit_byte(e->buffer + 1, cinfo);
|
||||
if (e->buffer + 1 == 0xFF)
|
||||
emit_byte(0x00, cinfo);
|
||||
}
|
||||
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
|
||||
e->sc = 0;
|
||||
} else {
|
||||
if (e->buffer == 0)
|
||||
++e->zc;
|
||||
else if (e->buffer >= 0) {
|
||||
if (e->zc)
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
emit_byte(e->buffer, cinfo);
|
||||
}
|
||||
if (e->sc) {
|
||||
if (e->zc)
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
do {
|
||||
emit_byte(0xFF, cinfo);
|
||||
emit_byte(0x00, cinfo);
|
||||
} while (--e->sc);
|
||||
}
|
||||
}
|
||||
/* Output final bytes only if they are not 0x00 */
|
||||
if (e->c & 0x7FFF800L) {
|
||||
if (e->zc) /* output final pending zero bytes */
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
emit_byte((e->c >> 19) & 0xFF, cinfo);
|
||||
if (((e->c >> 19) & 0xFF) == 0xFF)
|
||||
emit_byte(0x00, cinfo);
|
||||
if (e->c & 0x7F800L) {
|
||||
emit_byte((e->c >> 11) & 0xFF, cinfo);
|
||||
if (((e->c >> 11) & 0xFF) == 0xFF)
|
||||
emit_byte(0x00, cinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The core arithmetic encoding routine (common in JPEG and JBIG).
|
||||
* This needs to go as fast as possible.
|
||||
* Machine-dependent optimization facilities
|
||||
* are not utilized in this portable implementation.
|
||||
* However, this code should be fairly efficient and
|
||||
* may be a good base for further optimizations anyway.
|
||||
*
|
||||
* Parameter 'val' to be encoded may be 0 or 1 (binary decision).
|
||||
*
|
||||
* Note: I've added full "Pacman" termination support to the
|
||||
* byte output routines, which is equivalent to the optional
|
||||
* Discard_final_zeros procedure (Figure D.15) in the spec.
|
||||
* Thus, we always produce the shortest possible output
|
||||
* stream compliant to the spec (no trailing zero bytes,
|
||||
* except for FF stuffing).
|
||||
*
|
||||
* I've also introduced a new scheme for accessing
|
||||
* the probability estimation state machine table,
|
||||
* derived from Markus Kuhn's JBIG implementation.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
arith_encode (j_compress_ptr cinfo, unsigned char *st, int val)
|
||||
{
|
||||
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
|
||||
register unsigned char nl, nm;
|
||||
register INT32 qe, temp;
|
||||
register int sv;
|
||||
|
||||
/* Fetch values from our compact representation of Table D.2:
|
||||
* Qe values and probability estimation state machine
|
||||
*/
|
||||
sv = *st;
|
||||
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
|
||||
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
|
||||
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
|
||||
|
||||
/* Encode & estimation procedures per sections D.1.4 & D.1.5 */
|
||||
e->a -= qe;
|
||||
if (val != (sv >> 7)) {
|
||||
/* Encode the less probable symbol */
|
||||
if (e->a >= qe) {
|
||||
/* If the interval size (qe) for the less probable symbol (LPS)
|
||||
* is larger than the interval size for the MPS, then exchange
|
||||
* the two symbols for coding efficiency, otherwise code the LPS
|
||||
* as usual: */
|
||||
e->c += e->a;
|
||||
e->a = qe;
|
||||
}
|
||||
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
|
||||
} else {
|
||||
/* Encode the more probable symbol */
|
||||
if (e->a >= 0x8000L)
|
||||
return; /* A >= 0x8000 -> ready, no renormalization required */
|
||||
if (e->a < qe) {
|
||||
/* If the interval size (qe) for the less probable symbol (LPS)
|
||||
* is larger than the interval size for the MPS, then exchange
|
||||
* the two symbols for coding efficiency: */
|
||||
e->c += e->a;
|
||||
e->a = qe;
|
||||
}
|
||||
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
|
||||
}
|
||||
|
||||
/* Renormalization & data output per section D.1.6 */
|
||||
do {
|
||||
e->a <<= 1;
|
||||
e->c <<= 1;
|
||||
if (--e->ct == 0) {
|
||||
/* Another byte is ready for output */
|
||||
temp = e->c >> 19;
|
||||
if (temp > 0xFF) {
|
||||
/* Handle overflow over all stacked 0xFF bytes */
|
||||
if (e->buffer >= 0) {
|
||||
if (e->zc)
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
emit_byte(e->buffer + 1, cinfo);
|
||||
if (e->buffer + 1 == 0xFF)
|
||||
emit_byte(0x00, cinfo);
|
||||
}
|
||||
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
|
||||
e->sc = 0;
|
||||
/* Note: The 3 spacer bits in the C register guarantee
|
||||
* that the new buffer byte can't be 0xFF here
|
||||
* (see page 160 in the P&M JPEG book). */
|
||||
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
|
||||
} else if (temp == 0xFF) {
|
||||
++e->sc; /* stack 0xFF byte (which might overflow later) */
|
||||
} else {
|
||||
/* Output all stacked 0xFF bytes, they will not overflow any more */
|
||||
if (e->buffer == 0)
|
||||
++e->zc;
|
||||
else if (e->buffer >= 0) {
|
||||
if (e->zc)
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
emit_byte(e->buffer, cinfo);
|
||||
}
|
||||
if (e->sc) {
|
||||
if (e->zc)
|
||||
do emit_byte(0x00, cinfo);
|
||||
while (--e->zc);
|
||||
do {
|
||||
emit_byte(0xFF, cinfo);
|
||||
emit_byte(0x00, cinfo);
|
||||
} while (--e->sc);
|
||||
}
|
||||
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
|
||||
}
|
||||
e->c &= 0x7FFFFL;
|
||||
e->ct += 8;
|
||||
}
|
||||
} while (e->a < 0x8000L);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit a restart marker & resynchronize predictions.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
emit_restart (j_compress_ptr cinfo, int restart_num)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
finish_pass(cinfo);
|
||||
|
||||
emit_byte(0xFF, cinfo);
|
||||
emit_byte(JPEG_RST0 + restart_num, cinfo);
|
||||
|
||||
/* Re-initialize statistics areas */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
|
||||
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
|
||||
/* Reset DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
}
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->Se) {
|
||||
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset arithmetic encoding variables */
|
||||
entropy->c = 0;
|
||||
entropy->a = 0x10000L;
|
||||
entropy->sc = 0;
|
||||
entropy->zc = 0;
|
||||
entropy->ct = 11;
|
||||
entropy->buffer = -1; /* empty */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for DC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
JBLOCKROW block;
|
||||
unsigned char *st;
|
||||
int blkn, ci, tbl;
|
||||
int v, v2, m;
|
||||
ISHIFT_TEMPS
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
emit_restart(cinfo, entropy->next_restart_num);
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
/* Encode the MCU data blocks */
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
|
||||
|
||||
/* Compute the DC value after the required point transform by Al.
|
||||
* This is simply an arithmetic right shift.
|
||||
*/
|
||||
m = IRIGHT_SHIFT((int) ((*block)[0]), cinfo->Al);
|
||||
|
||||
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
|
||||
|
||||
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
|
||||
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
|
||||
|
||||
/* Figure F.4: Encode_DC_DIFF */
|
||||
if ((v = m - entropy->last_dc_val[ci]) == 0) {
|
||||
arith_encode(cinfo, st, 0);
|
||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
||||
} else {
|
||||
entropy->last_dc_val[ci] = m;
|
||||
arith_encode(cinfo, st, 1);
|
||||
/* Figure F.6: Encoding nonzero value v */
|
||||
/* Figure F.7: Encoding the sign of v */
|
||||
if (v > 0) {
|
||||
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
|
||||
st += 2; /* Table F.4: SP = S0 + 2 */
|
||||
entropy->dc_context[ci] = 4; /* small positive diff category */
|
||||
} else {
|
||||
v = -v;
|
||||
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
|
||||
st += 3; /* Table F.4: SN = S0 + 3 */
|
||||
entropy->dc_context[ci] = 8; /* small negative diff category */
|
||||
}
|
||||
/* Figure F.8: Encoding the magnitude category of v */
|
||||
m = 0;
|
||||
if (v -= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m = 1;
|
||||
v2 = v;
|
||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
||||
while (v2 >>= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m <<= 1;
|
||||
st += 1;
|
||||
}
|
||||
}
|
||||
arith_encode(cinfo, st, 0);
|
||||
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
|
||||
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
|
||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
||||
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
|
||||
entropy->dc_context[ci] += 8; /* large diff category */
|
||||
/* Figure F.9: Encoding the magnitude bit pattern of v */
|
||||
st += 14;
|
||||
while (m >>= 1)
|
||||
arith_encode(cinfo, st, (m & v) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for AC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
JBLOCKROW block;
|
||||
unsigned char *st;
|
||||
int tbl, k, ke;
|
||||
int v, v2, m;
|
||||
const int * natural_order;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
emit_restart(cinfo, entropy->next_restart_num);
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
natural_order = cinfo->natural_order;
|
||||
|
||||
/* Encode the MCU data block */
|
||||
block = MCU_data[0];
|
||||
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
|
||||
|
||||
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
|
||||
|
||||
/* Establish EOB (end-of-block) index */
|
||||
for (ke = cinfo->Se; ke > 0; ke--)
|
||||
/* We must apply the point transform by Al. For AC coefficients this
|
||||
* is an integer division with rounding towards 0. To do this portably
|
||||
* in C, we shift after obtaining the absolute value.
|
||||
*/
|
||||
if ((v = (*block)[natural_order[ke]]) >= 0) {
|
||||
if (v >>= cinfo->Al) break;
|
||||
} else {
|
||||
v = -v;
|
||||
if (v >>= cinfo->Al) break;
|
||||
}
|
||||
|
||||
/* Figure F.5: Encode_AC_Coefficients */
|
||||
for (k = cinfo->Ss; k <= ke; k++) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
arith_encode(cinfo, st, 0); /* EOB decision */
|
||||
for (;;) {
|
||||
if ((v = (*block)[natural_order[k]]) >= 0) {
|
||||
if (v >>= cinfo->Al) {
|
||||
arith_encode(cinfo, st + 1, 1);
|
||||
arith_encode(cinfo, entropy->fixed_bin, 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
v = -v;
|
||||
if (v >>= cinfo->Al) {
|
||||
arith_encode(cinfo, st + 1, 1);
|
||||
arith_encode(cinfo, entropy->fixed_bin, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
arith_encode(cinfo, st + 1, 0); st += 3; k++;
|
||||
}
|
||||
st += 2;
|
||||
/* Figure F.8: Encoding the magnitude category of v */
|
||||
m = 0;
|
||||
if (v -= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m = 1;
|
||||
v2 = v;
|
||||
if (v2 >>= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m <<= 1;
|
||||
st = entropy->ac_stats[tbl] +
|
||||
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
|
||||
while (v2 >>= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m <<= 1;
|
||||
st += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
arith_encode(cinfo, st, 0);
|
||||
/* Figure F.9: Encoding the magnitude bit pattern of v */
|
||||
st += 14;
|
||||
while (m >>= 1)
|
||||
arith_encode(cinfo, st, (m & v) ? 1 : 0);
|
||||
}
|
||||
/* Encode EOB decision only if k <= cinfo->Se */
|
||||
if (k <= cinfo->Se) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
arith_encode(cinfo, st, 1);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for DC successive approximation refinement scan.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
unsigned char *st;
|
||||
int Al, blkn;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
emit_restart(cinfo, entropy->next_restart_num);
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
st = entropy->fixed_bin; /* use fixed probability estimation */
|
||||
Al = cinfo->Al;
|
||||
|
||||
/* Encode the MCU data blocks */
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
/* We simply emit the Al'th bit of the DC coefficient value. */
|
||||
arith_encode(cinfo, st, (MCU_data[blkn][0][0] >> Al) & 1);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for AC successive approximation refinement scan.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
JBLOCKROW block;
|
||||
unsigned char *st;
|
||||
int tbl, k, ke, kex;
|
||||
int v;
|
||||
const int * natural_order;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
emit_restart(cinfo, entropy->next_restart_num);
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
natural_order = cinfo->natural_order;
|
||||
|
||||
/* Encode the MCU data block */
|
||||
block = MCU_data[0];
|
||||
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
|
||||
|
||||
/* Section G.1.3.3: Encoding of AC coefficients */
|
||||
|
||||
/* Establish EOB (end-of-block) index */
|
||||
for (ke = cinfo->Se; ke > 0; ke--)
|
||||
/* We must apply the point transform by Al. For AC coefficients this
|
||||
* is an integer division with rounding towards 0. To do this portably
|
||||
* in C, we shift after obtaining the absolute value.
|
||||
*/
|
||||
if ((v = (*block)[natural_order[ke]]) >= 0) {
|
||||
if (v >>= cinfo->Al) break;
|
||||
} else {
|
||||
v = -v;
|
||||
if (v >>= cinfo->Al) break;
|
||||
}
|
||||
|
||||
/* Establish EOBx (previous stage end-of-block) index */
|
||||
for (kex = ke; kex > 0; kex--)
|
||||
if ((v = (*block)[natural_order[kex]]) >= 0) {
|
||||
if (v >>= cinfo->Ah) break;
|
||||
} else {
|
||||
v = -v;
|
||||
if (v >>= cinfo->Ah) break;
|
||||
}
|
||||
|
||||
/* Figure G.10: Encode_AC_Coefficients_SA */
|
||||
for (k = cinfo->Ss; k <= ke; k++) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
if (k > kex)
|
||||
arith_encode(cinfo, st, 0); /* EOB decision */
|
||||
for (;;) {
|
||||
if ((v = (*block)[natural_order[k]]) >= 0) {
|
||||
if (v >>= cinfo->Al) {
|
||||
if (v >> 1) /* previously nonzero coef */
|
||||
arith_encode(cinfo, st + 2, (v & 1));
|
||||
else { /* newly nonzero coef */
|
||||
arith_encode(cinfo, st + 1, 1);
|
||||
arith_encode(cinfo, entropy->fixed_bin, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
v = -v;
|
||||
if (v >>= cinfo->Al) {
|
||||
if (v >> 1) /* previously nonzero coef */
|
||||
arith_encode(cinfo, st + 2, (v & 1));
|
||||
else { /* newly nonzero coef */
|
||||
arith_encode(cinfo, st + 1, 1);
|
||||
arith_encode(cinfo, entropy->fixed_bin, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
arith_encode(cinfo, st + 1, 0); st += 3; k++;
|
||||
}
|
||||
}
|
||||
/* Encode EOB decision only if k <= cinfo->Se */
|
||||
if (k <= cinfo->Se) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
arith_encode(cinfo, st, 1);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Encode and output one MCU's worth of arithmetic-compressed coefficients.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
jpeg_component_info * compptr;
|
||||
JBLOCKROW block;
|
||||
unsigned char *st;
|
||||
int blkn, ci, tbl, k, ke;
|
||||
int v, v2, m;
|
||||
const int * natural_order;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
emit_restart(cinfo, entropy->next_restart_num);
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
natural_order = cinfo->natural_order;
|
||||
|
||||
/* Encode the MCU data blocks */
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
|
||||
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
|
||||
|
||||
tbl = compptr->dc_tbl_no;
|
||||
|
||||
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
|
||||
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
|
||||
|
||||
/* Figure F.4: Encode_DC_DIFF */
|
||||
if ((v = (*block)[0] - entropy->last_dc_val[ci]) == 0) {
|
||||
arith_encode(cinfo, st, 0);
|
||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
||||
} else {
|
||||
entropy->last_dc_val[ci] = (*block)[0];
|
||||
arith_encode(cinfo, st, 1);
|
||||
/* Figure F.6: Encoding nonzero value v */
|
||||
/* Figure F.7: Encoding the sign of v */
|
||||
if (v > 0) {
|
||||
arith_encode(cinfo, st + 1, 0); /* Table F.4: SS = S0 + 1 */
|
||||
st += 2; /* Table F.4: SP = S0 + 2 */
|
||||
entropy->dc_context[ci] = 4; /* small positive diff category */
|
||||
} else {
|
||||
v = -v;
|
||||
arith_encode(cinfo, st + 1, 1); /* Table F.4: SS = S0 + 1 */
|
||||
st += 3; /* Table F.4: SN = S0 + 3 */
|
||||
entropy->dc_context[ci] = 8; /* small negative diff category */
|
||||
}
|
||||
/* Figure F.8: Encoding the magnitude category of v */
|
||||
m = 0;
|
||||
if (v -= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m = 1;
|
||||
v2 = v;
|
||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
||||
while (v2 >>= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m <<= 1;
|
||||
st += 1;
|
||||
}
|
||||
}
|
||||
arith_encode(cinfo, st, 0);
|
||||
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
|
||||
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
|
||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
||||
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
|
||||
entropy->dc_context[ci] += 8; /* large diff category */
|
||||
/* Figure F.9: Encoding the magnitude bit pattern of v */
|
||||
st += 14;
|
||||
while (m >>= 1)
|
||||
arith_encode(cinfo, st, (m & v) ? 1 : 0);
|
||||
}
|
||||
|
||||
/* Sections F.1.4.2 & F.1.4.4.2: Encoding of AC coefficients */
|
||||
|
||||
tbl = compptr->ac_tbl_no;
|
||||
|
||||
/* Establish EOB (end-of-block) index */
|
||||
for (ke = cinfo->lim_Se; ke > 0; ke--)
|
||||
if ((*block)[natural_order[ke]]) break;
|
||||
|
||||
/* Figure F.5: Encode_AC_Coefficients */
|
||||
for (k = 1; k <= ke; k++) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
arith_encode(cinfo, st, 0); /* EOB decision */
|
||||
while ((v = (*block)[natural_order[k]]) == 0) {
|
||||
arith_encode(cinfo, st + 1, 0); st += 3; k++;
|
||||
}
|
||||
arith_encode(cinfo, st + 1, 1);
|
||||
/* Figure F.6: Encoding nonzero value v */
|
||||
/* Figure F.7: Encoding the sign of v */
|
||||
if (v > 0) {
|
||||
arith_encode(cinfo, entropy->fixed_bin, 0);
|
||||
} else {
|
||||
v = -v;
|
||||
arith_encode(cinfo, entropy->fixed_bin, 1);
|
||||
}
|
||||
st += 2;
|
||||
/* Figure F.8: Encoding the magnitude category of v */
|
||||
m = 0;
|
||||
if (v -= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m = 1;
|
||||
v2 = v;
|
||||
if (v2 >>= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m <<= 1;
|
||||
st = entropy->ac_stats[tbl] +
|
||||
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
|
||||
while (v2 >>= 1) {
|
||||
arith_encode(cinfo, st, 1);
|
||||
m <<= 1;
|
||||
st += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
arith_encode(cinfo, st, 0);
|
||||
/* Figure F.9: Encoding the magnitude bit pattern of v */
|
||||
st += 14;
|
||||
while (m >>= 1)
|
||||
arith_encode(cinfo, st, (m & v) ? 1 : 0);
|
||||
}
|
||||
/* Encode EOB decision only if k <= cinfo->lim_Se */
|
||||
if (k <= cinfo->lim_Se) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
arith_encode(cinfo, st, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an arithmetic-compressed scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass (j_compress_ptr cinfo, boolean gather_statistics)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
int ci, tbl;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
if (gather_statistics)
|
||||
/* Make sure to avoid that in the master control logic!
|
||||
* We are fully adaptive here and need no extra
|
||||
* statistics gathering pass!
|
||||
*/
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
|
||||
/* We assume jcmaster.c already validated the progressive scan parameters. */
|
||||
|
||||
/* Select execution routines */
|
||||
if (cinfo->progressive_mode) {
|
||||
if (cinfo->Ah == 0) {
|
||||
if (cinfo->Ss == 0)
|
||||
entropy->pub.encode_mcu = encode_mcu_DC_first;
|
||||
else
|
||||
entropy->pub.encode_mcu = encode_mcu_AC_first;
|
||||
} else {
|
||||
if (cinfo->Ss == 0)
|
||||
entropy->pub.encode_mcu = encode_mcu_DC_refine;
|
||||
else
|
||||
entropy->pub.encode_mcu = encode_mcu_AC_refine;
|
||||
}
|
||||
} else
|
||||
entropy->pub.encode_mcu = encode_mcu;
|
||||
|
||||
/* Allocate & initialize requested statistics areas */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
|
||||
tbl = compptr->dc_tbl_no;
|
||||
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
|
||||
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
|
||||
if (entropy->dc_stats[tbl] == NULL)
|
||||
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
|
||||
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
|
||||
/* Initialize DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
}
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->Se) {
|
||||
tbl = compptr->ac_tbl_no;
|
||||
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
|
||||
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
|
||||
if (entropy->ac_stats[tbl] == NULL)
|
||||
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
|
||||
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
|
||||
#ifdef CALCULATE_SPECTRAL_CONDITIONING
|
||||
if (cinfo->progressive_mode)
|
||||
/* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
|
||||
cinfo->arith_ac_K[tbl] = cinfo->Ss + ((8 + cinfo->Se - cinfo->Ss) >> 4);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize arithmetic encoding variables */
|
||||
entropy->c = 0;
|
||||
entropy->a = 0x10000L;
|
||||
entropy->sc = 0;
|
||||
entropy->zc = 0;
|
||||
entropy->ct = 11;
|
||||
entropy->buffer = -1; /* empty */
|
||||
|
||||
/* Initialize restart stuff */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for arithmetic entropy encoding.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_arith_encoder (j_compress_ptr cinfo)
|
||||
{
|
||||
arith_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (arith_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(arith_entropy_encoder));
|
||||
cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
|
||||
entropy->pub.start_pass = start_pass;
|
||||
entropy->pub.finish_pass = finish_pass;
|
||||
|
||||
/* Mark tables unallocated */
|
||||
for (i = 0; i < NUM_ARITH_TBLS; i++) {
|
||||
entropy->dc_stats[i] = NULL;
|
||||
entropy->ac_stats[i] = NULL;
|
||||
}
|
||||
|
||||
/* Initialize index for fixed probability estimation */
|
||||
entropy->fixed_bin[0] = 113;
|
||||
}
|
||||
24
jccoefct.c
24
jccoefct.c
@@ -149,6 +149,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
int blkn, bi, ci, yindex, yoffset, blockcnt;
|
||||
JDIMENSION ypos, xpos;
|
||||
jpeg_component_info *compptr;
|
||||
forward_DCT_ptr forward_DCT;
|
||||
|
||||
/* Loop to write as much as one whole iMCU row */
|
||||
for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
|
||||
@@ -167,17 +168,19 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
blkn = 0;
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
forward_DCT = cinfo->fdct->forward_DCT[compptr->component_index];
|
||||
blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
|
||||
: compptr->last_col_width;
|
||||
xpos = MCU_col_num * compptr->MCU_sample_width;
|
||||
ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
|
||||
ypos = yoffset * compptr->DCT_v_scaled_size;
|
||||
/* ypos == (yoffset+yindex) * DCTSIZE */
|
||||
for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
|
||||
if (coef->iMCU_row_num < last_iMCU_row ||
|
||||
yoffset+yindex < compptr->last_row_height) {
|
||||
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
|
||||
input_buf[compptr->component_index],
|
||||
coef->MCU_buffer[blkn],
|
||||
ypos, xpos, (JDIMENSION) blockcnt);
|
||||
(*forward_DCT) (cinfo, compptr,
|
||||
input_buf[compptr->component_index],
|
||||
coef->MCU_buffer[blkn],
|
||||
ypos, xpos, (JDIMENSION) blockcnt);
|
||||
if (blockcnt < compptr->MCU_width) {
|
||||
/* Create some dummy blocks at the right edge of the image. */
|
||||
jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
|
||||
@@ -195,7 +198,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
}
|
||||
}
|
||||
blkn += compptr->MCU_width;
|
||||
ypos += DCTSIZE;
|
||||
ypos += compptr->DCT_v_scaled_size;
|
||||
}
|
||||
}
|
||||
/* Try to write the MCU. In event of a suspension failure, we will
|
||||
@@ -252,6 +255,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
jpeg_component_info *compptr;
|
||||
JBLOCKARRAY buffer;
|
||||
JBLOCKROW thisblockrow, lastblockrow;
|
||||
forward_DCT_ptr forward_DCT;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
@@ -274,15 +278,15 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
||||
ndummy = (int) (blocks_across % h_samp_factor);
|
||||
if (ndummy > 0)
|
||||
ndummy = h_samp_factor - ndummy;
|
||||
forward_DCT = cinfo->fdct->forward_DCT[ci];
|
||||
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
|
||||
* on forward_DCT processes a complete horizontal row of DCT blocks.
|
||||
*/
|
||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
||||
thisblockrow = buffer[block_row];
|
||||
(*cinfo->fdct->forward_DCT) (cinfo, compptr,
|
||||
input_buf[ci], thisblockrow,
|
||||
(JDIMENSION) (block_row * DCTSIZE),
|
||||
(JDIMENSION) 0, blocks_across);
|
||||
(*forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow,
|
||||
(JDIMENSION) (block_row * compptr->DCT_v_scaled_size),
|
||||
(JDIMENSION) 0, blocks_across);
|
||||
if (ndummy > 0) {
|
||||
/* Create dummy blocks at the right edge of the image. */
|
||||
thisblockrow += blocks_across; /* => first dummy block */
|
||||
|
||||
150
jccolor.c
150
jccolor.c
@@ -2,8 +2,6 @@
|
||||
* jccolor.c
|
||||
*
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright 2009 D. R. Commander
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -13,7 +11,6 @@
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
@@ -81,74 +78,6 @@ typedef my_color_converter * my_cconvert_ptr;
|
||||
#define TABLE_SIZE (8*(MAXJSAMPLE+1))
|
||||
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
|
||||
const unsigned char red_lut[256] = {
|
||||
0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 , 4 ,
|
||||
5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 9 ,
|
||||
10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14,
|
||||
14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19,
|
||||
19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24,
|
||||
24, 24, 25, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28,
|
||||
29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33,
|
||||
33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 38, 38,
|
||||
38, 39, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43,
|
||||
43, 43, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48,
|
||||
48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52,
|
||||
53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57,
|
||||
57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 62, 62,
|
||||
62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67,
|
||||
67, 67, 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71,
|
||||
72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76
|
||||
};
|
||||
|
||||
const unsigned char green_lut[256] = {
|
||||
0 , 1 , 1 , 2 , 2 , 3 , 4 , 4 , 5 , 5 , 6 , 6 ,
|
||||
7 , 8 , 8 , 9 , 9 , 10 , 11 , 11 , 12 , 12 , 13 , 14 ,
|
||||
14 , 15 , 15 , 16 , 16 , 17 , 18 , 18 , 19 , 19 , 20 , 21 ,
|
||||
21 , 22 , 22 , 23 , 23 , 24 , 25 , 25 , 26 , 26 , 27 , 28 ,
|
||||
28 , 29 , 29 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 35 ,
|
||||
35 , 36 , 36 , 37 , 38 , 38 , 39 , 39 , 40 , 41 , 41 , 42 ,
|
||||
42 , 43 , 43 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 ,
|
||||
49 , 50 , 50 , 51 , 52 , 52 , 53 , 53 , 54 , 55 , 55 , 56 ,
|
||||
56 , 57 , 58 , 58 , 59 , 59 , 60 , 60 , 61 , 62 , 62 , 63 ,
|
||||
63 , 64 , 65 , 65 , 66 , 66 , 67 , 68 , 68 , 69 , 69 , 70 ,
|
||||
70 , 71 , 72 , 72 , 73 , 73 , 74 , 75 , 75 , 76 , 76 , 77 ,
|
||||
77 , 78 , 79 , 79 , 80 , 80 , 81 , 82 , 82 , 83 , 83 , 84 ,
|
||||
85 , 85 , 86 , 86 , 87 , 87 , 88 , 89 , 89 , 90 , 90 , 91 ,
|
||||
92 , 92 , 93 , 93 , 94 , 95 , 95 , 96 , 96 , 97 , 97 , 98 ,
|
||||
99 , 99 , 100, 100, 101, 102, 102, 103, 103, 104, 104, 105,
|
||||
106, 106, 107, 107, 108, 109, 109, 110, 110, 111, 112, 112,
|
||||
113, 113, 114, 114, 115, 116, 116, 117, 117, 118, 119, 119,
|
||||
120, 120, 121, 122, 122, 123, 123, 124, 124, 125, 126, 126,
|
||||
127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 133, 133,
|
||||
34, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140,
|
||||
141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147,
|
||||
148, 149, 149, 150
|
||||
};
|
||||
|
||||
const unsigned char blue_lut[256] = {
|
||||
0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 ,
|
||||
2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 ,
|
||||
4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
|
||||
5 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 ,
|
||||
7 , 7 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 ,
|
||||
9 , 9 , 9 , 9 , 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for RGB->YCC colorspace conversion.
|
||||
*/
|
||||
@@ -217,10 +146,10 @@ rgb_ycc_convert (j_compress_ptr cinfo,
|
||||
outptr2 = output_buf[2][output_row];
|
||||
output_row++;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[rgb_red[cinfo->in_color_space]]);
|
||||
g = GETJSAMPLE(inptr[rgb_green[cinfo->in_color_space]]);
|
||||
b = GETJSAMPLE(inptr[rgb_blue[cinfo->in_color_space]]);
|
||||
inptr += rgb_pixelsize[cinfo->in_color_space];
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
|
||||
* must be too; we do not need an explicit range-limiting operation.
|
||||
* Hence the value being shifted is never negative, and we don't
|
||||
@@ -259,36 +188,26 @@ rgb_gray_convert (j_compress_ptr cinfo,
|
||||
JDIMENSION output_row, int num_rows)
|
||||
{
|
||||
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
|
||||
#if BITS_IN_JSAMPLE != 8
|
||||
register int r, g, b;
|
||||
register INT32 * ctab = cconvert->rgb_ycc_tab;
|
||||
#endif
|
||||
register JSAMPROW inptr;
|
||||
register JSAMPROW outptr;
|
||||
JSAMPLE *maxoutptr;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->image_width;
|
||||
int rindex = rgb_red[cinfo->in_color_space];
|
||||
int gindex = rgb_green[cinfo->in_color_space];
|
||||
int bindex = rgb_blue[cinfo->in_color_space];
|
||||
int rgbstride = rgb_pixelsize[cinfo->in_color_space];
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = *input_buf++;
|
||||
outptr = output_buf[0][output_row];
|
||||
maxoutptr = &outptr[num_cols];
|
||||
output_row++;
|
||||
for (; outptr < maxoutptr; outptr++, inptr += rgbstride) {
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
r = GETJSAMPLE(inptr[RGB_RED]);
|
||||
g = GETJSAMPLE(inptr[RGB_GREEN]);
|
||||
b = GETJSAMPLE(inptr[RGB_BLUE]);
|
||||
inptr += RGB_PIXELSIZE;
|
||||
/* Y */
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
*outptr = red_lut[inptr[rindex]] + green_lut[inptr[gindex]]
|
||||
+ blue_lut[inptr[bindex]];
|
||||
#else
|
||||
*outptr = (JSAMPLE)
|
||||
((ctab[GETJSAMPLE(inptr[rindex])+R_Y_OFF]
|
||||
+ ctab[GETJSAMPLE(inptr[gindex])+G_Y_OFF]
|
||||
+ ctab[GETJSAMPLE(inptr[bindex])+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
#endif
|
||||
outptr[col] = (JSAMPLE)
|
||||
((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
|
||||
>> SCALEBITS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,15 +368,11 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
case JCS_EXT_RGB:
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_BGR:
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_XRGB:
|
||||
if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
|
||||
#if RGB_PIXELSIZE != 3
|
||||
if (cinfo->input_components != RGB_PIXELSIZE)
|
||||
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
|
||||
break;
|
||||
#endif /* else share code with YCbCr */
|
||||
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->input_components != 3)
|
||||
@@ -483,13 +398,7 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_GRAYSCALE)
|
||||
cconvert->pub.color_convert = grayscale_convert;
|
||||
else if (cinfo->in_color_space == JCS_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBX ||
|
||||
cinfo->in_color_space == JCS_EXT_BGR ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRX ||
|
||||
cinfo->in_color_space == JCS_EXT_XBGR ||
|
||||
cinfo->in_color_space == JCS_EXT_XRGB) {
|
||||
else if (cinfo->in_color_space == JCS_RGB) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_gray_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr)
|
||||
@@ -499,16 +408,9 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
case JCS_EXT_RGB:
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_BGR:
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_XRGB:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == cinfo->jpeg_color_space &&
|
||||
rgb_pixelsize[cinfo->in_color_space] == 3)
|
||||
if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
@@ -517,19 +419,9 @@ jinit_color_converter (j_compress_ptr cinfo)
|
||||
case JCS_YCbCr:
|
||||
if (cinfo->num_components != 3)
|
||||
ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
|
||||
if (cinfo->in_color_space == JCS_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGB ||
|
||||
cinfo->in_color_space == JCS_EXT_RGBX ||
|
||||
cinfo->in_color_space == JCS_EXT_BGR ||
|
||||
cinfo->in_color_space == JCS_EXT_BGRX ||
|
||||
cinfo->in_color_space == JCS_EXT_XBGR ||
|
||||
cinfo->in_color_space == JCS_EXT_XRGB) {
|
||||
if (jsimd_can_rgb_ycc())
|
||||
cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
|
||||
else {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_ycc_convert;
|
||||
}
|
||||
if (cinfo->in_color_space == JCS_RGB) {
|
||||
cconvert->pub.start_pass = rgb_ycc_start;
|
||||
cconvert->pub.color_convert = rgb_ycc_convert;
|
||||
} else if (cinfo->in_color_space == JCS_YCbCr)
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
else
|
||||
|
||||
716
jcdctmgr.c
716
jcdctmgr.c
@@ -2,8 +2,6 @@
|
||||
* jcdctmgr.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Copyright (C) 1999-2006, MIYASAKA Masaru.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -17,35 +15,15 @@
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
#include "jsimddct.h"
|
||||
|
||||
|
||||
/* Private subobject for this module */
|
||||
|
||||
typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
|
||||
typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
|
||||
|
||||
typedef JMETHOD(void, convsamp_method_ptr,
|
||||
(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
DCTELEM * workspace));
|
||||
typedef JMETHOD(void, float_convsamp_method_ptr,
|
||||
(JSAMPARRAY sample_data, JDIMENSION start_col,
|
||||
FAST_FLOAT *workspace));
|
||||
|
||||
typedef JMETHOD(void, quantize_method_ptr,
|
||||
(JCOEFPTR coef_block, DCTELEM * divisors,
|
||||
DCTELEM * workspace));
|
||||
typedef JMETHOD(void, float_quantize_method_ptr,
|
||||
(JCOEFPTR coef_block, FAST_FLOAT * divisors,
|
||||
FAST_FLOAT * workspace));
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_forward_dct pub; /* public fields */
|
||||
|
||||
/* Pointer to the DCT routine actually in use */
|
||||
forward_DCT_method_ptr dct;
|
||||
convsamp_method_ptr convsamp;
|
||||
quantize_method_ptr quantize;
|
||||
forward_DCT_method_ptr do_dct[MAX_COMPONENTS];
|
||||
|
||||
/* The actual post-DCT divisors --- not identical to the quant table
|
||||
* entries, because of scaling (especially for an unnormalized DCT).
|
||||
@@ -53,144 +31,142 @@ typedef struct {
|
||||
*/
|
||||
DCTELEM * divisors[NUM_QUANT_TBLS];
|
||||
|
||||
/* work area for FDCT subroutine */
|
||||
DCTELEM * workspace;
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
/* Same as above for the floating-point case. */
|
||||
float_DCT_method_ptr float_dct;
|
||||
float_convsamp_method_ptr float_convsamp;
|
||||
float_quantize_method_ptr float_quantize;
|
||||
float_DCT_method_ptr do_float_dct[MAX_COMPONENTS];
|
||||
FAST_FLOAT * float_divisors[NUM_QUANT_TBLS];
|
||||
FAST_FLOAT * float_workspace;
|
||||
#endif
|
||||
} my_fdct_controller;
|
||||
|
||||
typedef my_fdct_controller * my_fdct_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Find the highest bit in an integer through binary search.
|
||||
/* The current scaled-DCT routines require ISLOW-style divisor tables,
|
||||
* so be sure to compile that code if either ISLOW or SCALING is requested.
|
||||
*/
|
||||
LOCAL(int)
|
||||
flss (UINT16 val)
|
||||
{
|
||||
int bit;
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
#define PROVIDE_ISLOW_TABLES
|
||||
#else
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
#define PROVIDE_ISLOW_TABLES
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bit = 16;
|
||||
|
||||
if (!val)
|
||||
return 0;
|
||||
|
||||
if (!(val & 0xff00)) {
|
||||
bit -= 8;
|
||||
val <<= 8;
|
||||
}
|
||||
if (!(val & 0xf000)) {
|
||||
bit -= 4;
|
||||
val <<= 4;
|
||||
}
|
||||
if (!(val & 0xc000)) {
|
||||
bit -= 2;
|
||||
val <<= 2;
|
||||
}
|
||||
if (!(val & 0x8000)) {
|
||||
bit -= 1;
|
||||
val <<= 1;
|
||||
}
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute values to do a division using reciprocal.
|
||||
* Perform forward DCT on one or more blocks of a component.
|
||||
*
|
||||
* This implementation is based on an algorithm described in
|
||||
* "How to optimize for the Pentium family of microprocessors"
|
||||
* (http://www.agner.org/assem/).
|
||||
* More information about the basic algorithm can be found in
|
||||
* the paper "Integer Division Using Reciprocals" by Robert Alverson.
|
||||
*
|
||||
* The basic idea is to replace x/d by x * d^-1. In order to store
|
||||
* d^-1 with enough precision we shift it left a few places. It turns
|
||||
* out that this algoright gives just enough precision, and also fits
|
||||
* into DCTELEM:
|
||||
*
|
||||
* b = (the number of significant bits in divisor) - 1
|
||||
* r = (word size) + b
|
||||
* f = 2^r / divisor
|
||||
*
|
||||
* f will not be an integer for most cases, so we need to compensate
|
||||
* for the rounding error introduced:
|
||||
*
|
||||
* no fractional part:
|
||||
*
|
||||
* result = input >> r
|
||||
*
|
||||
* fractional part of f < 0.5:
|
||||
*
|
||||
* round f down to nearest integer
|
||||
* result = ((input + 1) * f) >> r
|
||||
*
|
||||
* fractional part of f > 0.5:
|
||||
*
|
||||
* round f up to nearest integer
|
||||
* result = (input * f) >> r
|
||||
*
|
||||
* This is the original algorithm that gives truncated results. But we
|
||||
* want properly rounded results, so we replace "input" with
|
||||
* "input + divisor/2".
|
||||
*
|
||||
* In order to allow SIMD implementations we also tweak the values to
|
||||
* allow the same calculation to be made at all times:
|
||||
*
|
||||
* dctbl[0] = f rounded to nearest integer
|
||||
* dctbl[1] = divisor / 2 (+ 1 if fractional part of f < 0.5)
|
||||
* dctbl[2] = 1 << ((word size) * 2 - r)
|
||||
* dctbl[3] = r - (word size)
|
||||
*
|
||||
* dctbl[2] is for stupid instruction sets where the shift operation
|
||||
* isn't member wise (e.g. MMX).
|
||||
*
|
||||
* The reason dctbl[2] and dctbl[3] reduce the shift with (word size)
|
||||
* is that most SIMD implementations have a "multiply and store top
|
||||
* half" operation.
|
||||
*
|
||||
* Lastly, we store each of the values in their own table instead
|
||||
* of in a consecutive manner, yet again in order to allow SIMD
|
||||
* routines.
|
||||
* The input samples are taken from the sample_data[] array starting at
|
||||
* position start_row/start_col, and moving to the right for any additional
|
||||
* blocks. The quantized coefficients are returned in coef_blocks[].
|
||||
*/
|
||||
LOCAL(void)
|
||||
compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for integer DCT implementations. */
|
||||
{
|
||||
UDCTELEM2 fq, fr;
|
||||
UDCTELEM c;
|
||||
int b, r;
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
forward_DCT_method_ptr do_dct = fdct->do_dct[compptr->component_index];
|
||||
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
|
||||
DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
|
||||
JDIMENSION bi;
|
||||
|
||||
b = flss(divisor) - 1;
|
||||
r = sizeof(DCTELEM) * 8 + b;
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
fq = ((UDCTELEM2)1 << r) / divisor;
|
||||
fr = ((UDCTELEM2)1 << r) % divisor;
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace, sample_data, start_col);
|
||||
|
||||
c = divisor / 2; /* for rounding */
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
{ register DCTELEM temp, qval;
|
||||
register int i;
|
||||
register JCOEFPTR output_ptr = coef_blocks[bi];
|
||||
|
||||
if (fr == 0) { /* divisor is power of two */
|
||||
/* fq will be one bit too large to fit in DCTELEM, so adjust */
|
||||
fq >>= 1;
|
||||
r--;
|
||||
} else if (fr <= (divisor / 2)) { /* fractional part is < 0.5 */
|
||||
c++;
|
||||
} else { /* fractional part is > 0.5 */
|
||||
fq++;
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
qval = divisors[i];
|
||||
temp = workspace[i];
|
||||
/* Divide the coefficient value by qval, ensuring proper rounding.
|
||||
* Since C does not specify the direction of rounding for negative
|
||||
* quotients, we have to force the dividend positive for portability.
|
||||
*
|
||||
* In most files, at least half of the output values will be zero
|
||||
* (at default quantization settings, more like three-quarters...)
|
||||
* so we should ensure that this case is fast. On many machines,
|
||||
* a comparison is enough cheaper than a divide to make a special test
|
||||
* a win. Since both inputs will be nonnegative, we need only test
|
||||
* for a < b to discover whether a/b is 0.
|
||||
* If your machine's division is fast enough, define FAST_DIVIDE.
|
||||
*/
|
||||
#ifdef FAST_DIVIDE
|
||||
#define DIVIDE_BY(a,b) a /= b
|
||||
#else
|
||||
#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
|
||||
#endif
|
||||
if (temp < 0) {
|
||||
temp = -temp;
|
||||
temp += qval>>1; /* for rounding */
|
||||
DIVIDE_BY(temp, qval);
|
||||
temp = -temp;
|
||||
} else {
|
||||
temp += qval>>1; /* for rounding */
|
||||
DIVIDE_BY(temp, qval);
|
||||
}
|
||||
output_ptr[i] = (JCOEF) temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dtbl[DCTSIZE2 * 0] = (DCTELEM) fq; /* reciprocal */
|
||||
dtbl[DCTSIZE2 * 1] = (DCTELEM) c; /* correction + roundfactor */
|
||||
dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r)); /* scale */
|
||||
dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
|
||||
}
|
||||
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for floating-point DCT implementations. */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
float_DCT_method_ptr do_dct = fdct->do_float_dct[compptr->component_index];
|
||||
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
|
||||
FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
|
||||
JDIMENSION bi;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += compptr->DCT_h_scaled_size) {
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace, sample_data, start_col);
|
||||
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
{ register FAST_FLOAT temp;
|
||||
register int i;
|
||||
register JCOEFPTR output_ptr = coef_blocks[bi];
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
/* Apply the quantization and scaling factor */
|
||||
temp = workspace[i] * divisors[i];
|
||||
/* Round to nearest integer.
|
||||
* Since C does not specify the direction of rounding for negative
|
||||
* quotients, we have to force the dividend positive for portability.
|
||||
* The maximum coefficient size is +-16K (for 12-bit data), so this
|
||||
* code should work for either 16-bit or 32-bit ints.
|
||||
*/
|
||||
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a processing pass.
|
||||
* Verify that all referenced Q-tables are present, and set up
|
||||
@@ -206,11 +182,170 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
int ci, qtblno, i;
|
||||
jpeg_component_info *compptr;
|
||||
int method = 0;
|
||||
JQUANT_TBL * qtbl;
|
||||
DCTELEM * dtbl;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Select the proper DCT routine for this component's scaling */
|
||||
switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) {
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
case ((1 << 8) + 1):
|
||||
fdct->do_dct[ci] = jpeg_fdct_1x1;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((2 << 8) + 2):
|
||||
fdct->do_dct[ci] = jpeg_fdct_2x2;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((3 << 8) + 3):
|
||||
fdct->do_dct[ci] = jpeg_fdct_3x3;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((4 << 8) + 4):
|
||||
fdct->do_dct[ci] = jpeg_fdct_4x4;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((5 << 8) + 5):
|
||||
fdct->do_dct[ci] = jpeg_fdct_5x5;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((6 << 8) + 6):
|
||||
fdct->do_dct[ci] = jpeg_fdct_6x6;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((7 << 8) + 7):
|
||||
fdct->do_dct[ci] = jpeg_fdct_7x7;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((9 << 8) + 9):
|
||||
fdct->do_dct[ci] = jpeg_fdct_9x9;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((10 << 8) + 10):
|
||||
fdct->do_dct[ci] = jpeg_fdct_10x10;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((11 << 8) + 11):
|
||||
fdct->do_dct[ci] = jpeg_fdct_11x11;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((12 << 8) + 12):
|
||||
fdct->do_dct[ci] = jpeg_fdct_12x12;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((13 << 8) + 13):
|
||||
fdct->do_dct[ci] = jpeg_fdct_13x13;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((14 << 8) + 14):
|
||||
fdct->do_dct[ci] = jpeg_fdct_14x14;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((15 << 8) + 15):
|
||||
fdct->do_dct[ci] = jpeg_fdct_15x15;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((16 << 8) + 16):
|
||||
fdct->do_dct[ci] = jpeg_fdct_16x16;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((16 << 8) + 8):
|
||||
fdct->do_dct[ci] = jpeg_fdct_16x8;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((14 << 8) + 7):
|
||||
fdct->do_dct[ci] = jpeg_fdct_14x7;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((12 << 8) + 6):
|
||||
fdct->do_dct[ci] = jpeg_fdct_12x6;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((10 << 8) + 5):
|
||||
fdct->do_dct[ci] = jpeg_fdct_10x5;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((8 << 8) + 4):
|
||||
fdct->do_dct[ci] = jpeg_fdct_8x4;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((6 << 8) + 3):
|
||||
fdct->do_dct[ci] = jpeg_fdct_6x3;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((4 << 8) + 2):
|
||||
fdct->do_dct[ci] = jpeg_fdct_4x2;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((2 << 8) + 1):
|
||||
fdct->do_dct[ci] = jpeg_fdct_2x1;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((8 << 8) + 16):
|
||||
fdct->do_dct[ci] = jpeg_fdct_8x16;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((7 << 8) + 14):
|
||||
fdct->do_dct[ci] = jpeg_fdct_7x14;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((6 << 8) + 12):
|
||||
fdct->do_dct[ci] = jpeg_fdct_6x12;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((5 << 8) + 10):
|
||||
fdct->do_dct[ci] = jpeg_fdct_5x10;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((4 << 8) + 8):
|
||||
fdct->do_dct[ci] = jpeg_fdct_4x8;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((3 << 8) + 6):
|
||||
fdct->do_dct[ci] = jpeg_fdct_3x6;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((2 << 8) + 4):
|
||||
fdct->do_dct[ci] = jpeg_fdct_2x4;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
case ((1 << 8) + 2):
|
||||
fdct->do_dct[ci] = jpeg_fdct_1x2;
|
||||
method = JDCT_ISLOW; /* jfdctint uses islow-style table */
|
||||
break;
|
||||
#endif
|
||||
case ((DCTSIZE << 8) + DCTSIZE):
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
fdct->do_dct[ci] = jpeg_fdct_islow;
|
||||
method = JDCT_ISLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
fdct->do_dct[ci] = jpeg_fdct_ifast;
|
||||
method = JDCT_IFAST;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
fdct->do_float_dct[ci] = jpeg_fdct_float;
|
||||
method = JDCT_FLOAT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
|
||||
compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size);
|
||||
break;
|
||||
}
|
||||
qtblno = compptr->quant_tbl_no;
|
||||
/* Make sure specified quantization table is present */
|
||||
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
|
||||
@@ -219,8 +354,8 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
qtbl = cinfo->quant_tbl_ptrs[qtblno];
|
||||
/* Compute divisors for this quant table */
|
||||
/* We may do this more than once for same table, but it's not a big deal */
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
switch (method) {
|
||||
#ifdef PROVIDE_ISLOW_TABLES
|
||||
case JDCT_ISLOW:
|
||||
/* For LL&M IDCT method, divisors are equal to raw quantization
|
||||
* coefficients multiplied by 8 (to counteract scaling).
|
||||
@@ -228,12 +363,13 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(DCTSIZE2 * 4) * SIZEOF(DCTELEM));
|
||||
DCTSIZE2 * SIZEOF(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
|
||||
dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
|
||||
}
|
||||
fdct->pub.forward_DCT[ci] = forward_DCT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
@@ -262,16 +398,17 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(DCTSIZE2 * 4) * SIZEOF(DCTELEM));
|
||||
DCTSIZE2 * SIZEOF(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
compute_reciprocal(
|
||||
dtbl[i] = (DCTELEM)
|
||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
||||
(INT32) aanscales[i]),
|
||||
CONST_BITS-3), &dtbl[i]);
|
||||
CONST_BITS-3);
|
||||
}
|
||||
}
|
||||
fdct->pub.forward_DCT[ci] = forward_DCT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
@@ -308,6 +445,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
fdct->pub.forward_DCT[ci] = forward_DCT_float;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -318,212 +456,6 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load data into workspace, applying unsigned->signed conversion.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
convsamp (JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM * workspace)
|
||||
{
|
||||
register DCTELEM *workspaceptr;
|
||||
register JSAMPROW elemptr;
|
||||
register int elemr;
|
||||
|
||||
workspaceptr = workspace;
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
#else
|
||||
{
|
||||
register int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--)
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Quantize/descale the coefficients, and store into coef_blocks[].
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
|
||||
{
|
||||
int i;
|
||||
DCTELEM temp;
|
||||
UDCTELEM recip, corr, shift;
|
||||
UDCTELEM2 product;
|
||||
JCOEFPTR output_ptr = coef_block;
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
temp = workspace[i];
|
||||
recip = divisors[i + DCTSIZE2 * 0];
|
||||
corr = divisors[i + DCTSIZE2 * 1];
|
||||
shift = divisors[i + DCTSIZE2 * 3];
|
||||
|
||||
if (temp < 0) {
|
||||
temp = -temp;
|
||||
product = (UDCTELEM2)(temp + corr) * recip;
|
||||
product >>= shift + sizeof(DCTELEM)*8;
|
||||
temp = product;
|
||||
temp = -temp;
|
||||
} else {
|
||||
product = (UDCTELEM2)(temp + corr) * recip;
|
||||
product >>= shift + sizeof(DCTELEM)*8;
|
||||
temp = product;
|
||||
}
|
||||
|
||||
output_ptr[i] = (JCOEF) temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform forward DCT on one or more blocks of a component.
|
||||
*
|
||||
* The input samples are taken from the sample_data[] array starting at
|
||||
* position start_row/start_col, and moving to the right for any additional
|
||||
* blocks. The quantized coefficients are returned in coef_blocks[].
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for integer DCT implementations. */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
|
||||
DCTELEM * workspace;
|
||||
JDIMENSION bi;
|
||||
|
||||
/* Make sure the compiler doesn't look up these every pass */
|
||||
forward_DCT_method_ptr do_dct = fdct->dct;
|
||||
convsamp_method_ptr do_convsamp = fdct->convsamp;
|
||||
quantize_method_ptr do_quantize = fdct->quantize;
|
||||
workspace = fdct->workspace;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
(*do_convsamp) (sample_data, start_col, workspace);
|
||||
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace);
|
||||
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
(*do_quantize) (coef_blocks[bi], divisors, workspace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col, FAST_FLOAT * workspace)
|
||||
{
|
||||
register FAST_FLOAT *workspaceptr;
|
||||
register JSAMPROW elemptr;
|
||||
register int elemr;
|
||||
|
||||
workspaceptr = workspace;
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
#else
|
||||
{
|
||||
register int elemc;
|
||||
for (elemc = DCTSIZE; elemc > 0; elemc--)
|
||||
*workspaceptr++ = (FAST_FLOAT)
|
||||
(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors, FAST_FLOAT * workspace)
|
||||
{
|
||||
register FAST_FLOAT temp;
|
||||
register int i;
|
||||
register JCOEFPTR output_ptr = coef_block;
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
/* Apply the quantization and scaling factor */
|
||||
temp = workspace[i] * divisors[i];
|
||||
|
||||
/* Round to nearest integer.
|
||||
* Since C does not specify the direction of rounding for negative
|
||||
* quotients, we have to force the dividend positive for portability.
|
||||
* The maximum coefficient size is +-16K (for 12-bit data), so this
|
||||
* code should work for either 16-bit or 32-bit ints.
|
||||
*/
|
||||
output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks)
|
||||
/* This version is used for floating-point DCT implementations. */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding it tightly. */
|
||||
my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
|
||||
FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
|
||||
FAST_FLOAT * workspace;
|
||||
JDIMENSION bi;
|
||||
|
||||
|
||||
/* Make sure the compiler doesn't look up these every pass */
|
||||
float_DCT_method_ptr do_dct = fdct->float_dct;
|
||||
float_convsamp_method_ptr do_convsamp = fdct->float_convsamp;
|
||||
float_quantize_method_ptr do_quantize = fdct->float_quantize;
|
||||
workspace = fdct->float_workspace;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
(*do_convsamp) (sample_data, start_col, workspace);
|
||||
|
||||
/* Perform the DCT */
|
||||
(*do_dct) (workspace);
|
||||
|
||||
/* Quantize/descale the coefficients, and store into coef_blocks[] */
|
||||
(*do_quantize) (coef_blocks[bi], divisors, workspace);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DCT_FLOAT_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize FDCT manager.
|
||||
*/
|
||||
@@ -540,88 +472,6 @@ jinit_forward_dct (j_compress_ptr cinfo)
|
||||
cinfo->fdct = (struct jpeg_forward_dct *) fdct;
|
||||
fdct->pub.start_pass = start_pass_fdctmgr;
|
||||
|
||||
/* First determine the DCT... */
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
if (jsimd_can_fdct_islow())
|
||||
fdct->dct = jsimd_fdct_islow;
|
||||
else
|
||||
fdct->dct = jpeg_fdct_islow;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
fdct->pub.forward_DCT = forward_DCT;
|
||||
if (jsimd_can_fdct_ifast())
|
||||
fdct->dct = jsimd_fdct_ifast;
|
||||
else
|
||||
fdct->dct = jpeg_fdct_ifast;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
fdct->pub.forward_DCT = forward_DCT_float;
|
||||
if (jsimd_can_fdct_float())
|
||||
fdct->float_dct = jsimd_fdct_float;
|
||||
else
|
||||
fdct->float_dct = jpeg_fdct_float;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
|
||||
/* ...then the supporting stages. */
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
#endif
|
||||
#if defined(DCT_ISLOW_SUPPORTED) || defined(DCT_IFAST_SUPPORTED)
|
||||
if (jsimd_can_convsamp())
|
||||
fdct->convsamp = jsimd_convsamp;
|
||||
else
|
||||
fdct->convsamp = convsamp;
|
||||
if (jsimd_can_quantize())
|
||||
fdct->quantize = jsimd_quantize;
|
||||
else
|
||||
fdct->quantize = quantize;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
if (jsimd_can_convsamp_float())
|
||||
fdct->float_convsamp = jsimd_convsamp_float;
|
||||
else
|
||||
fdct->float_convsamp = convsamp_float;
|
||||
if (jsimd_can_quantize_float())
|
||||
fdct->float_quantize = jsimd_quantize_float;
|
||||
else
|
||||
fdct->float_quantize = quantize_float;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allocate workspace memory */
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
if (cinfo->dct_method == JDCT_FLOAT)
|
||||
fdct->float_workspace = (FAST_FLOAT *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(FAST_FLOAT) * DCTSIZE2);
|
||||
else
|
||||
#endif
|
||||
fdct->workspace = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(DCTELEM) * DCTSIZE2);
|
||||
|
||||
/* Mark divisor tables unallocated */
|
||||
for (i = 0; i < NUM_QUANT_TBLS; i++) {
|
||||
fdct->divisors[i] = NULL;
|
||||
|
||||
47
jchuff.h
47
jchuff.h
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* jchuff.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains declarations for Huffman entropy encoding routines
|
||||
* that are shared between the sequential encoder (jchuff.c) and the
|
||||
* progressive encoder (jcphuff.c). No other modules need to see these.
|
||||
*/
|
||||
|
||||
/* The legal range of a DCT coefficient is
|
||||
* -1024 .. +1023 for 8-bit data;
|
||||
* -16384 .. +16383 for 12-bit data.
|
||||
* Hence the magnitude should always fit in 10 or 14 bits respectively.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MAX_COEF_BITS 10
|
||||
#else
|
||||
#define MAX_COEF_BITS 14
|
||||
#endif
|
||||
|
||||
/* Derived data constructed for each Huffman table */
|
||||
|
||||
typedef struct {
|
||||
unsigned int ehufco[256]; /* code for each symbol */
|
||||
char ehufsi[256]; /* length of code for each symbol */
|
||||
/* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
|
||||
} c_derived_tbl;
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_make_c_derived_tbl jMkCDerived
|
||||
#define jpeg_gen_optimal_table jGenOptTbl
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
/* Expand a Huffman table definition into the derived format */
|
||||
EXTERN(void) jpeg_make_c_derived_tbl
|
||||
JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
|
||||
c_derived_tbl ** pdtbl));
|
||||
|
||||
/* Generate an optimal table definition given the specified counts */
|
||||
EXTERN(void) jpeg_gen_optimal_table
|
||||
JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
|
||||
15
jcinit.c
15
jcinit.c
@@ -41,17 +41,10 @@ jinit_compress_master (j_compress_ptr cinfo)
|
||||
/* Forward DCT */
|
||||
jinit_forward_dct(cinfo);
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_encoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_encoder(cinfo);
|
||||
if (cinfo->arith_code)
|
||||
jinit_arith_encoder(cinfo);
|
||||
else {
|
||||
jinit_huff_encoder(cinfo);
|
||||
}
|
||||
|
||||
/* Need a full-image coefficient buffer in any multi-pass mode. */
|
||||
|
||||
14
jcmainct.c
14
jcmainct.c
@@ -118,17 +118,17 @@ process_data_simple_main (j_compress_ptr cinfo,
|
||||
|
||||
while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
|
||||
/* Read input data if we haven't filled the main buffer yet */
|
||||
if (main->rowgroup_ctr < DCTSIZE)
|
||||
if (main->rowgroup_ctr < (JDIMENSION) cinfo->min_DCT_v_scaled_size)
|
||||
(*cinfo->prep->pre_process_data) (cinfo,
|
||||
input_buf, in_row_ctr, in_rows_avail,
|
||||
main->buffer, &main->rowgroup_ctr,
|
||||
(JDIMENSION) DCTSIZE);
|
||||
(JDIMENSION) cinfo->min_DCT_v_scaled_size);
|
||||
|
||||
/* If we don't have a full iMCU row buffered, return to application for
|
||||
* more data. Note that preprocessor will always pad to fill the iMCU row
|
||||
* at the bottom of the image.
|
||||
*/
|
||||
if (main->rowgroup_ctr != DCTSIZE)
|
||||
if (main->rowgroup_ctr != (JDIMENSION) cinfo->min_DCT_v_scaled_size)
|
||||
return;
|
||||
|
||||
/* Send the completed row to the compressor */
|
||||
@@ -269,10 +269,10 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
ci++, compptr++) {
|
||||
main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
|
||||
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
|
||||
(long) compptr->v_samp_factor) * DCTSIZE,
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
|
||||
(JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
|
||||
}
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
|
||||
@@ -286,8 +286,8 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
ci++, compptr++) {
|
||||
main->buffer[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
|
||||
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
|
||||
(JDIMENSION) (compptr->v_samp_factor * compptr->DCT_v_scaled_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
132
jcmarker.c
132
jcmarker.c
@@ -2,6 +2,7 @@
|
||||
* jcmarker.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -153,21 +154,22 @@ emit_dqt (j_compress_ptr cinfo, int index)
|
||||
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, index);
|
||||
|
||||
prec = 0;
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if (qtbl->quantval[i] > 255)
|
||||
for (i = 0; i <= cinfo->lim_Se; i++) {
|
||||
if (qtbl->quantval[cinfo->natural_order[i]] > 255)
|
||||
prec = 1;
|
||||
}
|
||||
|
||||
if (! qtbl->sent_table) {
|
||||
emit_marker(cinfo, M_DQT);
|
||||
|
||||
emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
|
||||
emit_2bytes(cinfo,
|
||||
prec ? cinfo->lim_Se * 2 + 2 + 1 + 2 : cinfo->lim_Se + 1 + 1 + 2);
|
||||
|
||||
emit_byte(cinfo, index + (prec<<4));
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
for (i = 0; i <= cinfo->lim_Se; i++) {
|
||||
/* The table entries must be emitted in zigzag order. */
|
||||
unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
|
||||
unsigned int qval = qtbl->quantval[cinfo->natural_order[i]];
|
||||
if (prec)
|
||||
emit_byte(cinfo, (int) (qval >> 8));
|
||||
emit_byte(cinfo, (int) (qval & 0xFF));
|
||||
@@ -229,32 +231,38 @@ emit_dac (j_compress_ptr cinfo)
|
||||
char ac_in_use[NUM_ARITH_TBLS];
|
||||
int length, i;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
|
||||
for (i = 0; i < NUM_ARITH_TBLS; i++)
|
||||
dc_in_use[i] = ac_in_use[i] = 0;
|
||||
|
||||
|
||||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||
compptr = cinfo->cur_comp_info[i];
|
||||
dc_in_use[compptr->dc_tbl_no] = 1;
|
||||
ac_in_use[compptr->ac_tbl_no] = 1;
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->Ss == 0 && cinfo->Ah == 0)
|
||||
dc_in_use[compptr->dc_tbl_no] = 1;
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->Se)
|
||||
ac_in_use[compptr->ac_tbl_no] = 1;
|
||||
}
|
||||
|
||||
|
||||
length = 0;
|
||||
for (i = 0; i < NUM_ARITH_TBLS; i++)
|
||||
length += dc_in_use[i] + ac_in_use[i];
|
||||
|
||||
emit_marker(cinfo, M_DAC);
|
||||
|
||||
emit_2bytes(cinfo, length*2 + 2);
|
||||
|
||||
for (i = 0; i < NUM_ARITH_TBLS; i++) {
|
||||
if (dc_in_use[i]) {
|
||||
emit_byte(cinfo, i);
|
||||
emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
|
||||
}
|
||||
if (ac_in_use[i]) {
|
||||
emit_byte(cinfo, i + 0x10);
|
||||
emit_byte(cinfo, cinfo->arith_ac_K[i]);
|
||||
|
||||
if (length) {
|
||||
emit_marker(cinfo, M_DAC);
|
||||
|
||||
emit_2bytes(cinfo, length*2 + 2);
|
||||
|
||||
for (i = 0; i < NUM_ARITH_TBLS; i++) {
|
||||
if (dc_in_use[i]) {
|
||||
emit_byte(cinfo, i);
|
||||
emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
|
||||
}
|
||||
if (ac_in_use[i]) {
|
||||
emit_byte(cinfo, i + 0x10);
|
||||
emit_byte(cinfo, cinfo->arith_ac_K[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* C_ARITH_CODING_SUPPORTED */
|
||||
@@ -285,13 +293,13 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
|
||||
emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
|
||||
|
||||
/* Make sure image isn't bigger than SOF field can handle */
|
||||
if ((long) cinfo->image_height > 65535L ||
|
||||
(long) cinfo->image_width > 65535L)
|
||||
if ((long) cinfo->jpeg_height > 65535L ||
|
||||
(long) cinfo->jpeg_width > 65535L)
|
||||
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
|
||||
|
||||
emit_byte(cinfo, cinfo->data_precision);
|
||||
emit_2bytes(cinfo, (int) cinfo->image_height);
|
||||
emit_2bytes(cinfo, (int) cinfo->image_width);
|
||||
emit_2bytes(cinfo, (int) cinfo->jpeg_height);
|
||||
emit_2bytes(cinfo, (int) cinfo->jpeg_width);
|
||||
|
||||
emit_byte(cinfo, cinfo->num_components);
|
||||
|
||||
@@ -320,22 +328,16 @@ emit_sos (j_compress_ptr cinfo)
|
||||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||
compptr = cinfo->cur_comp_info[i];
|
||||
emit_byte(cinfo, compptr->component_id);
|
||||
td = compptr->dc_tbl_no;
|
||||
ta = compptr->ac_tbl_no;
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Progressive mode: only DC or only AC tables are used in one scan;
|
||||
* furthermore, Huffman coding of DC refinement uses no table at all.
|
||||
* We emit 0 for unused field(s); this is recommended by the P&M text
|
||||
* but does not seem to be specified in the standard.
|
||||
*/
|
||||
if (cinfo->Ss == 0) {
|
||||
ta = 0; /* DC scan */
|
||||
if (cinfo->Ah != 0 && !cinfo->arith_code)
|
||||
td = 0; /* no DC table either */
|
||||
} else {
|
||||
td = 0; /* AC scan */
|
||||
}
|
||||
}
|
||||
|
||||
/* We emit 0 for unused field(s); this is recommended by the P&M text
|
||||
* but does not seem to be specified in the standard.
|
||||
*/
|
||||
|
||||
/* DC needs no table for refinement scan */
|
||||
td = cinfo->Ss == 0 && cinfo->Ah == 0 ? compptr->dc_tbl_no : 0;
|
||||
/* AC needs no table when not present */
|
||||
ta = cinfo->Se ? compptr->ac_tbl_no : 0;
|
||||
|
||||
emit_byte(cinfo, (td << 4) + ta);
|
||||
}
|
||||
|
||||
@@ -345,6 +347,22 @@ emit_sos (j_compress_ptr cinfo)
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
emit_pseudo_sos (j_compress_ptr cinfo)
|
||||
/* Emit a pseudo SOS marker */
|
||||
{
|
||||
emit_marker(cinfo, M_SOS);
|
||||
|
||||
emit_2bytes(cinfo, 2 + 1 + 3); /* length */
|
||||
|
||||
emit_byte(cinfo, 0); /* Ns */
|
||||
|
||||
emit_byte(cinfo, 0); /* Ss */
|
||||
emit_byte(cinfo, cinfo->block_size * cinfo->block_size - 1); /* Se */
|
||||
emit_byte(cinfo, 0); /* Ah/Al */
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
emit_jfif_app0 (j_compress_ptr cinfo)
|
||||
/* Emit a JFIF-compliant APP0 marker */
|
||||
@@ -484,7 +502,7 @@ write_file_header (j_compress_ptr cinfo)
|
||||
|
||||
/*
|
||||
* Write frame header.
|
||||
* This consists of DQT and SOFn markers.
|
||||
* This consists of DQT and SOFn markers, and a conditional pseudo SOS marker.
|
||||
* Note that we do not emit the SOF until we have emitted the DQT(s).
|
||||
* This avoids compatibility problems with incorrect implementations that
|
||||
* try to error-check the quant table numbers as soon as they see the SOF.
|
||||
@@ -511,7 +529,7 @@ write_frame_header (j_compress_ptr cinfo)
|
||||
* Note we assume that Huffman table numbers won't be changed later.
|
||||
*/
|
||||
if (cinfo->arith_code || cinfo->progressive_mode ||
|
||||
cinfo->data_precision != 8) {
|
||||
cinfo->data_precision != 8 || cinfo->block_size != DCTSIZE) {
|
||||
is_baseline = FALSE;
|
||||
} else {
|
||||
is_baseline = TRUE;
|
||||
@@ -529,7 +547,10 @@ write_frame_header (j_compress_ptr cinfo)
|
||||
|
||||
/* Emit the proper SOF marker */
|
||||
if (cinfo->arith_code) {
|
||||
emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
|
||||
if (cinfo->progressive_mode)
|
||||
emit_sof(cinfo, M_SOF10); /* SOF code for progressive arithmetic */
|
||||
else
|
||||
emit_sof(cinfo, M_SOF9); /* SOF code for sequential arithmetic */
|
||||
} else {
|
||||
if (cinfo->progressive_mode)
|
||||
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
|
||||
@@ -538,6 +559,10 @@ write_frame_header (j_compress_ptr cinfo)
|
||||
else
|
||||
emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
|
||||
}
|
||||
|
||||
/* Check to emit pseudo SOS marker */
|
||||
if (cinfo->progressive_mode && cinfo->block_size != DCTSIZE)
|
||||
emit_pseudo_sos(cinfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -566,19 +591,12 @@ write_scan_header (j_compress_ptr cinfo)
|
||||
*/
|
||||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||
compptr = cinfo->cur_comp_info[i];
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Progressive mode: only DC or only AC tables are used in one scan */
|
||||
if (cinfo->Ss == 0) {
|
||||
if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
|
||||
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
|
||||
} else {
|
||||
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
|
||||
}
|
||||
} else {
|
||||
/* Sequential mode: need both DC and AC tables */
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->Ss == 0 && cinfo->Ah == 0)
|
||||
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->Se)
|
||||
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
342
jcmaster.c
342
jcmaster.c
@@ -2,6 +2,7 @@
|
||||
* jcmaster.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2003-2011 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -42,23 +43,220 @@ typedef my_comp_master * my_master_ptr;
|
||||
* Support routines that do various essential calculations.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
initial_setup (j_compress_ptr cinfo)
|
||||
/*
|
||||
* Compute JPEG image dimensions and related values.
|
||||
* NOTE: this is exported for possible use by application.
|
||||
* Hence it mustn't do anything that can't be done twice.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo)
|
||||
/* Do computations that are needed before master selection phase */
|
||||
{
|
||||
int ci;
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
|
||||
/* Sanity check on input image dimensions to prevent overflow in
|
||||
* following calculation.
|
||||
* We do check jpeg_width and jpeg_height in initial_setup below,
|
||||
* but image_width and image_height can come from arbitrary data,
|
||||
* and we need some space for multiplication by block_size.
|
||||
*/
|
||||
if (((long) cinfo->image_width >> 24) || ((long) cinfo->image_height >> 24))
|
||||
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
|
||||
|
||||
/* Compute actual JPEG image dimensions and DCT scaling choices. */
|
||||
if (cinfo->scale_num >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/1 scaling */
|
||||
cinfo->jpeg_width = cinfo->image_width * cinfo->block_size;
|
||||
cinfo->jpeg_height = cinfo->image_height * cinfo->block_size;
|
||||
cinfo->min_DCT_h_scaled_size = 1;
|
||||
cinfo->min_DCT_v_scaled_size = 1;
|
||||
} else if (cinfo->scale_num * 2 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/2 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 2L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 2L);
|
||||
cinfo->min_DCT_h_scaled_size = 2;
|
||||
cinfo->min_DCT_v_scaled_size = 2;
|
||||
} else if (cinfo->scale_num * 3 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/3 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 3L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 3L);
|
||||
cinfo->min_DCT_h_scaled_size = 3;
|
||||
cinfo->min_DCT_v_scaled_size = 3;
|
||||
} else if (cinfo->scale_num * 4 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/4 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 4L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 4L);
|
||||
cinfo->min_DCT_h_scaled_size = 4;
|
||||
cinfo->min_DCT_v_scaled_size = 4;
|
||||
} else if (cinfo->scale_num * 5 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/5 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 5L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 5L);
|
||||
cinfo->min_DCT_h_scaled_size = 5;
|
||||
cinfo->min_DCT_v_scaled_size = 5;
|
||||
} else if (cinfo->scale_num * 6 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/6 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 6L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 6L);
|
||||
cinfo->min_DCT_h_scaled_size = 6;
|
||||
cinfo->min_DCT_v_scaled_size = 6;
|
||||
} else if (cinfo->scale_num * 7 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/7 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 7L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 7L);
|
||||
cinfo->min_DCT_h_scaled_size = 7;
|
||||
cinfo->min_DCT_v_scaled_size = 7;
|
||||
} else if (cinfo->scale_num * 8 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/8 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 8L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 8L);
|
||||
cinfo->min_DCT_h_scaled_size = 8;
|
||||
cinfo->min_DCT_v_scaled_size = 8;
|
||||
} else if (cinfo->scale_num * 9 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/9 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 9L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 9L);
|
||||
cinfo->min_DCT_h_scaled_size = 9;
|
||||
cinfo->min_DCT_v_scaled_size = 9;
|
||||
} else if (cinfo->scale_num * 10 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/10 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 10L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 10L);
|
||||
cinfo->min_DCT_h_scaled_size = 10;
|
||||
cinfo->min_DCT_v_scaled_size = 10;
|
||||
} else if (cinfo->scale_num * 11 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/11 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 11L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 11L);
|
||||
cinfo->min_DCT_h_scaled_size = 11;
|
||||
cinfo->min_DCT_v_scaled_size = 11;
|
||||
} else if (cinfo->scale_num * 12 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/12 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 12L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 12L);
|
||||
cinfo->min_DCT_h_scaled_size = 12;
|
||||
cinfo->min_DCT_v_scaled_size = 12;
|
||||
} else if (cinfo->scale_num * 13 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/13 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 13L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 13L);
|
||||
cinfo->min_DCT_h_scaled_size = 13;
|
||||
cinfo->min_DCT_v_scaled_size = 13;
|
||||
} else if (cinfo->scale_num * 14 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/14 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 14L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 14L);
|
||||
cinfo->min_DCT_h_scaled_size = 14;
|
||||
cinfo->min_DCT_v_scaled_size = 14;
|
||||
} else if (cinfo->scale_num * 15 >= cinfo->scale_denom * cinfo->block_size) {
|
||||
/* Provide block_size/15 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 15L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 15L);
|
||||
cinfo->min_DCT_h_scaled_size = 15;
|
||||
cinfo->min_DCT_v_scaled_size = 15;
|
||||
} else {
|
||||
/* Provide block_size/16 scaling */
|
||||
cinfo->jpeg_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * cinfo->block_size, 16L);
|
||||
cinfo->jpeg_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * cinfo->block_size, 16L);
|
||||
cinfo->min_DCT_h_scaled_size = 16;
|
||||
cinfo->min_DCT_v_scaled_size = 16;
|
||||
}
|
||||
|
||||
#else /* !DCT_SCALING_SUPPORTED */
|
||||
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->jpeg_width = cinfo->image_width;
|
||||
cinfo->jpeg_height = cinfo->image_height;
|
||||
cinfo->min_DCT_h_scaled_size = DCTSIZE;
|
||||
cinfo->min_DCT_v_scaled_size = DCTSIZE;
|
||||
|
||||
#endif /* DCT_SCALING_SUPPORTED */
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
jpeg_calc_trans_dimensions (j_compress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->min_DCT_h_scaled_size != cinfo->min_DCT_v_scaled_size)
|
||||
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
|
||||
cinfo->min_DCT_h_scaled_size, cinfo->min_DCT_v_scaled_size);
|
||||
|
||||
cinfo->block_size = cinfo->min_DCT_h_scaled_size;
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
initial_setup (j_compress_ptr cinfo, boolean transcode_only)
|
||||
/* Do computations that are needed before master selection phase */
|
||||
{
|
||||
int ci, ssize;
|
||||
jpeg_component_info *compptr;
|
||||
long samplesperrow;
|
||||
JDIMENSION jd_samplesperrow;
|
||||
|
||||
if (transcode_only)
|
||||
jpeg_calc_trans_dimensions(cinfo);
|
||||
else
|
||||
jpeg_calc_jpeg_dimensions(cinfo);
|
||||
|
||||
/* Sanity check on block_size */
|
||||
if (cinfo->block_size < 1 || cinfo->block_size > 16)
|
||||
ERREXIT2(cinfo, JERR_BAD_DCTSIZE, cinfo->block_size, cinfo->block_size);
|
||||
|
||||
/* Derive natural_order from block_size */
|
||||
switch (cinfo->block_size) {
|
||||
case 2: cinfo->natural_order = jpeg_natural_order2; break;
|
||||
case 3: cinfo->natural_order = jpeg_natural_order3; break;
|
||||
case 4: cinfo->natural_order = jpeg_natural_order4; break;
|
||||
case 5: cinfo->natural_order = jpeg_natural_order5; break;
|
||||
case 6: cinfo->natural_order = jpeg_natural_order6; break;
|
||||
case 7: cinfo->natural_order = jpeg_natural_order7; break;
|
||||
default: cinfo->natural_order = jpeg_natural_order; break;
|
||||
}
|
||||
|
||||
/* Derive lim_Se from block_size */
|
||||
cinfo->lim_Se = cinfo->block_size < DCTSIZE ?
|
||||
cinfo->block_size * cinfo->block_size - 1 : DCTSIZE2-1;
|
||||
|
||||
/* Sanity check on image dimensions */
|
||||
if (cinfo->image_height <= 0 || cinfo->image_width <= 0
|
||||
|| cinfo->num_components <= 0 || cinfo->input_components <= 0)
|
||||
if (cinfo->jpeg_height <= 0 || cinfo->jpeg_width <= 0 ||
|
||||
cinfo->num_components <= 0 || cinfo->input_components <= 0)
|
||||
ERREXIT(cinfo, JERR_EMPTY_IMAGE);
|
||||
|
||||
/* Make sure image isn't bigger than I can handle */
|
||||
if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
|
||||
(long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
|
||||
if ((long) cinfo->jpeg_height > (long) JPEG_MAX_DIMENSION ||
|
||||
(long) cinfo->jpeg_width > (long) JPEG_MAX_DIMENSION)
|
||||
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
|
||||
|
||||
/* Width of an input scanline must be representable as JDIMENSION. */
|
||||
@@ -95,22 +293,52 @@ initial_setup (j_compress_ptr cinfo)
|
||||
ci++, compptr++) {
|
||||
/* Fill in the correct component_index value; don't rely on application */
|
||||
compptr->component_index = ci;
|
||||
/* For compression, we never do DCT scaling. */
|
||||
compptr->DCT_scaled_size = DCTSIZE;
|
||||
/* In selecting the actual DCT scaling for each component, we try to
|
||||
* scale down the chroma components via DCT scaling rather than downsampling.
|
||||
* This saves time if the downsampler gets to use 1:1 scaling.
|
||||
* Note this code adapts subsampling ratios which are powers of 2.
|
||||
*/
|
||||
ssize = 1;
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
while (cinfo->min_DCT_h_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
#endif
|
||||
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
|
||||
ssize = 1;
|
||||
#ifdef DCT_SCALING_SUPPORTED
|
||||
while (cinfo->min_DCT_v_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_downsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
#endif
|
||||
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize;
|
||||
|
||||
/* We don't support DCT ratios larger than 2. */
|
||||
if (compptr->DCT_h_scaled_size > compptr->DCT_v_scaled_size * 2)
|
||||
compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2;
|
||||
else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2)
|
||||
compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2;
|
||||
|
||||
/* Size in DCT blocks */
|
||||
compptr->width_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
||||
(long) (cinfo->max_h_samp_factor * DCTSIZE));
|
||||
jdiv_round_up((long) cinfo->jpeg_width * (long) compptr->h_samp_factor,
|
||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
||||
compptr->height_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
||||
(long) (cinfo->max_v_samp_factor * DCTSIZE));
|
||||
jdiv_round_up((long) cinfo->jpeg_height * (long) compptr->v_samp_factor,
|
||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
||||
/* Size in samples */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
|
||||
(long) cinfo->max_h_samp_factor);
|
||||
jdiv_round_up((long) cinfo->jpeg_width *
|
||||
(long) (compptr->h_samp_factor * compptr->DCT_h_scaled_size),
|
||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
||||
compptr->downsampled_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
||||
(long) cinfo->max_v_samp_factor);
|
||||
jdiv_round_up((long) cinfo->jpeg_height *
|
||||
(long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size),
|
||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
||||
/* Mark component needed (this flag isn't actually used for compression) */
|
||||
compptr->component_needed = TRUE;
|
||||
}
|
||||
@@ -119,8 +347,8 @@ initial_setup (j_compress_ptr cinfo)
|
||||
* main controller will call coefficient controller).
|
||||
*/
|
||||
cinfo->total_iMCU_rows = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
jdiv_round_up((long) cinfo->jpeg_height,
|
||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
||||
}
|
||||
|
||||
|
||||
@@ -260,6 +488,39 @@ validate_script (j_compress_ptr cinfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
reduce_script (j_compress_ptr cinfo)
|
||||
/* Adapt scan script for use with reduced block size;
|
||||
* assume that script has been validated before.
|
||||
*/
|
||||
{
|
||||
jpeg_scan_info * scanptr;
|
||||
int idxout, idxin;
|
||||
|
||||
/* Circumvent const declaration for this function */
|
||||
scanptr = (jpeg_scan_info *) cinfo->scan_info;
|
||||
idxout = 0;
|
||||
|
||||
for (idxin = 0; idxin < cinfo->num_scans; idxin++) {
|
||||
/* After skipping, idxout becomes smaller than idxin */
|
||||
if (idxin != idxout)
|
||||
/* Copy rest of data;
|
||||
* note we stay in given chunk of allocated memory.
|
||||
*/
|
||||
scanptr[idxout] = scanptr[idxin];
|
||||
if (scanptr[idxout].Ss > cinfo->lim_Se)
|
||||
/* Entire scan out of range - skip this entry */
|
||||
continue;
|
||||
if (scanptr[idxout].Se > cinfo->lim_Se)
|
||||
/* Limit scan to end of block */
|
||||
scanptr[idxout].Se = cinfo->lim_Se;
|
||||
idxout++;
|
||||
}
|
||||
|
||||
cinfo->num_scans = idxout;
|
||||
}
|
||||
|
||||
#endif /* C_MULTISCAN_FILES_SUPPORTED */
|
||||
|
||||
|
||||
@@ -280,10 +541,13 @@ select_scan_parameters (j_compress_ptr cinfo)
|
||||
cinfo->cur_comp_info[ci] =
|
||||
&cinfo->comp_info[scanptr->component_index[ci]];
|
||||
}
|
||||
cinfo->Ss = scanptr->Ss;
|
||||
cinfo->Se = scanptr->Se;
|
||||
cinfo->Ah = scanptr->Ah;
|
||||
cinfo->Al = scanptr->Al;
|
||||
if (cinfo->progressive_mode) {
|
||||
cinfo->Ss = scanptr->Ss;
|
||||
cinfo->Se = scanptr->Se;
|
||||
cinfo->Ah = scanptr->Ah;
|
||||
cinfo->Al = scanptr->Al;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -296,11 +560,11 @@ select_scan_parameters (j_compress_ptr cinfo)
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
|
||||
}
|
||||
cinfo->Ss = 0;
|
||||
cinfo->Se = DCTSIZE2-1;
|
||||
cinfo->Ah = 0;
|
||||
cinfo->Al = 0;
|
||||
}
|
||||
cinfo->Ss = 0;
|
||||
cinfo->Se = cinfo->block_size * cinfo->block_size - 1;
|
||||
cinfo->Ah = 0;
|
||||
cinfo->Al = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -325,7 +589,7 @@ per_scan_setup (j_compress_ptr cinfo)
|
||||
compptr->MCU_width = 1;
|
||||
compptr->MCU_height = 1;
|
||||
compptr->MCU_blocks = 1;
|
||||
compptr->MCU_sample_width = DCTSIZE;
|
||||
compptr->MCU_sample_width = compptr->DCT_h_scaled_size;
|
||||
compptr->last_col_width = 1;
|
||||
/* For noninterleaved scans, it is convenient to define last_row_height
|
||||
* as the number of block rows present in the last iMCU row.
|
||||
@@ -347,11 +611,11 @@ per_scan_setup (j_compress_ptr cinfo)
|
||||
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width,
|
||||
(long) (cinfo->max_h_samp_factor*DCTSIZE));
|
||||
jdiv_round_up((long) cinfo->jpeg_width,
|
||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
jdiv_round_up((long) cinfo->jpeg_height,
|
||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
||||
|
||||
cinfo->blocks_in_MCU = 0;
|
||||
|
||||
@@ -361,7 +625,7 @@ per_scan_setup (j_compress_ptr cinfo)
|
||||
compptr->MCU_width = compptr->h_samp_factor;
|
||||
compptr->MCU_height = compptr->v_samp_factor;
|
||||
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
|
||||
compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
|
||||
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_h_scaled_size;
|
||||
/* Figure number of non-dummy blocks in last MCU column & row */
|
||||
tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
|
||||
if (tmp == 0) tmp = compptr->MCU_width;
|
||||
@@ -433,7 +697,7 @@ prepare_for_pass (j_compress_ptr cinfo)
|
||||
/* Do Huffman optimization for a scan after the first one. */
|
||||
select_scan_parameters(cinfo);
|
||||
per_scan_setup(cinfo);
|
||||
if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
|
||||
if (cinfo->Ss != 0 || cinfo->Ah == 0) {
|
||||
(*cinfo->entropy->start_pass) (cinfo, TRUE);
|
||||
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
|
||||
master->pub.call_pass_startup = FALSE;
|
||||
@@ -554,11 +818,13 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
||||
master->pub.is_last_pass = FALSE;
|
||||
|
||||
/* Validate parameters, determine derived values */
|
||||
initial_setup(cinfo);
|
||||
initial_setup(cinfo, transcode_only);
|
||||
|
||||
if (cinfo->scan_info != NULL) {
|
||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||
validate_script(cinfo);
|
||||
if (cinfo->block_size < DCTSIZE)
|
||||
reduce_script(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
@@ -567,8 +833,10 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
||||
cinfo->num_scans = 1;
|
||||
}
|
||||
|
||||
if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */
|
||||
cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
|
||||
if ((cinfo->progressive_mode || cinfo->block_size < DCTSIZE) &&
|
||||
!cinfo->arith_code) /* TEMPORARY HACK ??? */
|
||||
/* assume default tables no good for progressive or downscale mode */
|
||||
cinfo->optimize_coding = TRUE;
|
||||
|
||||
/* Initialize my private state */
|
||||
if (transcode_only) {
|
||||
|
||||
48
jconfig.bcc
Normal file
48
jconfig.bcc
Normal file
@@ -0,0 +1,48 @@
|
||||
/* jconfig.bcc --- jconfig.h for Borland C (Turbo C) on MS-DOS or OS/2. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#ifdef __MSDOS__
|
||||
#define NEED_FAR_POINTERS /* for small or medium memory model */
|
||||
#endif
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN /* this assumes you have -w-stu in CFLAGS */
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#ifdef __MSDOS__
|
||||
#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */
|
||||
#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
|
||||
#define USE_FMEM /* Borland has _fmemcpy() and _fmemset() */
|
||||
#endif
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE
|
||||
#define USE_SETMODE /* Borland has setmode() */
|
||||
#ifdef __MSDOS__
|
||||
#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */
|
||||
#endif
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
53
jconfig.cfg
Normal file
53
jconfig.cfg
Normal file
@@ -0,0 +1,53 @@
|
||||
/* jconfig.cfg --- source file edited by configure script */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#undef HAVE_PROTOTYPES
|
||||
#undef HAVE_UNSIGNED_CHAR
|
||||
#undef HAVE_UNSIGNED_SHORT
|
||||
#undef void
|
||||
#undef const
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#undef HAVE_STDDEF_H
|
||||
#undef HAVE_STDLIB_H
|
||||
#undef HAVE_LOCALE_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
/* Define this if you get warnings about undefined structures. */
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, on Windows systems. */
|
||||
#ifdef _WIN32
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
#endif
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#undef INLINE
|
||||
/* These are for configuring the JPEG memory manager. */
|
||||
#undef DEFAULT_MAX_MEM
|
||||
#undef NO_MKTEMP
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#undef TWO_FILE_COMMANDLINE
|
||||
#undef NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
|
||||
/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
|
||||
#undef PROGRESS_REPORT
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
38
jconfig.dj
Normal file
38
jconfig.dj
Normal file
@@ -0,0 +1,38 @@
|
||||
/* jconfig.dj --- jconfig.h for DJGPP (Delorie's GNU C port) on MS-DOS. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS /* DJGPP uses flat 32-bit addressing */
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#undef TWO_FILE_COMMANDLINE /* optional */
|
||||
#define USE_SETMODE /* Needed to make one-file style work in DJGPP */
|
||||
#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
49
jconfig.h.in
49
jconfig.h.in
@@ -1,49 +0,0 @@
|
||||
/* Define if your compiler supports prototypes */
|
||||
#undef HAVE_PROTOTYPES
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if the system has the type `unsigned char'. */
|
||||
#undef HAVE_UNSIGNED_CHAR
|
||||
|
||||
/* Define to 1 if the system has the type `unsigned short'. */
|
||||
#undef HAVE_UNSIGNED_SHORT
|
||||
|
||||
/* Define if you want use complete types */
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
/* Define if you have BSD-like bzero and bcopy */
|
||||
#undef NEED_BSD_STRINGS
|
||||
|
||||
/* Define if you need short function names */
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
|
||||
/* Define if you have sys/types.h */
|
||||
#undef NEED_SYS_TYPES_H
|
||||
|
||||
/* Define if shift is unsigned */
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
/* Use accelerated SIMD routines. */
|
||||
#undef WITH_SIMD
|
||||
|
||||
/* Define to 1 if type `char' is unsigned and you are not using gcc. */
|
||||
#ifndef __CHAR_UNSIGNED__
|
||||
# undef __CHAR_UNSIGNED__
|
||||
#endif
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
43
jconfig.mac
Normal file
43
jconfig.mac
Normal file
@@ -0,0 +1,43 @@
|
||||
/* jconfig.mac --- jconfig.h for CodeWarrior on Apple Macintosh */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#define USE_MAC_MEMMGR /* Define this if you use jmemmac.c */
|
||||
|
||||
#define ALIGN_TYPE long /* Needed for 680x0 Macs */
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define USE_CCOMMAND /* Command line reader for Macintosh */
|
||||
#define TWO_FILE_COMMANDLINE /* Binary I/O thru stdin/stdout doesn't work */
|
||||
|
||||
#undef NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
43
jconfig.manx
Normal file
43
jconfig.manx
Normal file
@@ -0,0 +1,43 @@
|
||||
/* jconfig.manx --- jconfig.h for Amiga systems using Manx Aztec C ver 5.x. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
|
||||
|
||||
#define SHORTxSHORT_32 /* produces better DCT code with Aztec C */
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE
|
||||
#define NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#define signal_catcher _abort /* hack for Aztec C naming requirements */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
52
jconfig.mc6
Normal file
52
jconfig.mc6
Normal file
@@ -0,0 +1,52 @@
|
||||
/* jconfig.mc6 --- jconfig.h for Microsoft C on MS-DOS, version 6.00A & up. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#define NEED_FAR_POINTERS /* for small or medium memory model */
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */
|
||||
|
||||
#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
|
||||
|
||||
#define USE_FMEM /* Microsoft has _fmemcpy() and _fmemset() */
|
||||
|
||||
#define NEED_FHEAPMIN /* far heap management routines are broken */
|
||||
|
||||
#define SHORTxLCONST_32 /* enable compiler-specific DCT optimization */
|
||||
/* Note: the above define is known to improve the code with Microsoft C 6.00A.
|
||||
* I do not know whether it is good for later compiler versions.
|
||||
* Please report any info on this point to jpeg-info@uc.ag.
|
||||
*/
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE
|
||||
#define USE_SETMODE /* Microsoft has setmode() */
|
||||
#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
43
jconfig.sas
Normal file
43
jconfig.sas
Normal file
@@ -0,0 +1,43 @@
|
||||
/* jconfig.sas --- jconfig.h for Amiga systems using SAS C 6.0 and up. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
|
||||
|
||||
#define NO_MKTEMP /* SAS C doesn't have mktemp() */
|
||||
|
||||
#define SHORTxSHORT_32 /* produces better DCT code with SAS C */
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE
|
||||
#define NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
42
jconfig.st
Normal file
42
jconfig.st
Normal file
@@ -0,0 +1,42 @@
|
||||
/* jconfig.st --- jconfig.h for Atari ST/STE/TT using Pure C or Turbo C. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define INCOMPLETE_TYPES_BROKEN /* suppress undefined-structure warnings */
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#define ALIGN_TYPE long /* apparently double is a weird size? */
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE /* optional -- undef if you like Unix style */
|
||||
/* Note: if you undef TWO_FILE_COMMANDLINE, you may need to define
|
||||
* USE_SETMODE. Some Atari compilers require it, some do not.
|
||||
*/
|
||||
#define NEED_SIGNAL_CATCHER /* needed if you use jmemname.c */
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* jconfig.doc
|
||||
* jconfig.txt
|
||||
*
|
||||
* Copyright (C) 1991-1994, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
@@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
/* Does your compiler support function prototypes?
|
||||
* (If not, you also need to use ansi2knr, see install.doc)
|
||||
* (If not, you also need to use ansi2knr, see install.txt)
|
||||
*/
|
||||
#define HAVE_PROTOTYPES
|
||||
|
||||
@@ -91,6 +91,15 @@
|
||||
*/
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
/* Define "boolean" as unsigned char, not int, on Windows systems.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* The following options affect code selection within the JPEG library,
|
||||
@@ -1,5 +1,5 @@
|
||||
/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
|
||||
/* see jconfig.doc for explanations */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
@@ -21,10 +21,25 @@ typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
|
||||
#define inline __inline
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE /* optional */
|
||||
#define USE_SETMODE /* Microsoft has setmode() */
|
||||
#undef NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
37
jconfig.vms
Normal file
37
jconfig.vms
Normal file
@@ -0,0 +1,37 @@
|
||||
/* jconfig.vms --- jconfig.h for use on Digital VMS. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#undef CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#define TWO_FILE_COMMANDLINE /* Needed on VMS */
|
||||
#undef NEED_SIGNAL_CATCHER
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
38
jconfig.wat
Normal file
38
jconfig.wat
Normal file
@@ -0,0 +1,38 @@
|
||||
/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */
|
||||
/* see jconfig.txt for explanations */
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
/* #define void char */
|
||||
/* #define const */
|
||||
#define CHAR_IS_UNSIGNED
|
||||
#define HAVE_STDDEF_H
|
||||
#define HAVE_STDLIB_H
|
||||
#undef NEED_BSD_STRINGS
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
|
||||
#undef RIGHT_SHIFT_IS_UNSIGNED
|
||||
|
||||
#endif /* JPEG_INTERNALS */
|
||||
|
||||
#ifdef JPEG_CJPEG_DJPEG
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
#undef TWO_FILE_COMMANDLINE /* optional */
|
||||
#define USE_SETMODE /* Needed to make one-file style work in Watcom */
|
||||
#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */
|
||||
#undef DONT_USE_B_MODE
|
||||
#undef PROGRESS_REPORT /* optional */
|
||||
|
||||
#endif /* JPEG_CJPEG_DJPEG */
|
||||
79
jcparam.c
79
jcparam.c
@@ -2,7 +2,7 @@
|
||||
* jcparam.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Copyright (C) 2009, D. R. Commander.
|
||||
* Modified 2003-2008 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -61,6 +61,47 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
|
||||
}
|
||||
|
||||
|
||||
/* These are the sample quantization tables given in JPEG spec section K.1.
|
||||
* The spec says that the values given produce "good" quality, and
|
||||
* when divided by 2, "very good" quality.
|
||||
*/
|
||||
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
|
||||
16, 11, 10, 16, 24, 40, 51, 61,
|
||||
12, 12, 14, 19, 26, 58, 60, 55,
|
||||
14, 13, 16, 24, 40, 57, 69, 56,
|
||||
14, 17, 22, 29, 51, 87, 80, 62,
|
||||
18, 22, 37, 56, 68, 109, 103, 77,
|
||||
24, 35, 55, 64, 81, 104, 113, 92,
|
||||
49, 64, 78, 87, 103, 121, 120, 101,
|
||||
72, 92, 95, 98, 112, 100, 103, 99
|
||||
};
|
||||
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
|
||||
17, 18, 24, 47, 99, 99, 99, 99,
|
||||
18, 21, 26, 66, 99, 99, 99, 99,
|
||||
24, 26, 56, 99, 99, 99, 99, 99,
|
||||
47, 66, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99
|
||||
};
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
|
||||
/* Set or change the 'quality' (quantization) setting, using default tables
|
||||
* and straight percentage-scaling quality scales.
|
||||
* This entry point allows different scalings for luminance and chrominance.
|
||||
*/
|
||||
{
|
||||
/* Set up two quantization tables using the specified scaling */
|
||||
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
|
||||
cinfo->q_scale_factor[0], force_baseline);
|
||||
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
|
||||
cinfo->q_scale_factor[1], force_baseline);
|
||||
}
|
||||
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
|
||||
boolean force_baseline)
|
||||
@@ -70,31 +111,6 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
|
||||
* applications that insist on a linear percentage scaling.
|
||||
*/
|
||||
{
|
||||
/* These are the sample quantization tables given in JPEG spec section K.1.
|
||||
* The spec says that the values given produce "good" quality, and
|
||||
* when divided by 2, "very good" quality.
|
||||
*/
|
||||
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
|
||||
16, 11, 10, 16, 24, 40, 51, 61,
|
||||
12, 12, 14, 19, 26, 58, 60, 55,
|
||||
14, 13, 16, 24, 40, 57, 69, 56,
|
||||
14, 17, 22, 29, 51, 87, 80, 62,
|
||||
18, 22, 37, 56, 68, 109, 103, 77,
|
||||
24, 35, 55, 64, 81, 104, 113, 92,
|
||||
49, 64, 78, 87, 103, 121, 120, 101,
|
||||
72, 92, 95, 98, 112, 100, 103, 99
|
||||
};
|
||||
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
|
||||
17, 18, 24, 47, 99, 99, 99, 99,
|
||||
18, 21, 26, 66, 99, 99, 99, 99,
|
||||
24, 26, 56, 99, 99, 99, 99, 99,
|
||||
47, 66, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99
|
||||
};
|
||||
|
||||
/* Set up two quantization tables using the specified scaling */
|
||||
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
|
||||
scale_factor, force_baseline);
|
||||
@@ -285,6 +301,8 @@ jpeg_set_defaults (j_compress_ptr cinfo)
|
||||
|
||||
/* Initialize everything not dependent on the color space */
|
||||
|
||||
cinfo->scale_num = 1; /* 1:1 scaling */
|
||||
cinfo->scale_denom = 1;
|
||||
cinfo->data_precision = BITS_IN_JSAMPLE;
|
||||
/* Set up two quantization tables using default quality of 75 */
|
||||
jpeg_set_quality(cinfo, 75, TRUE);
|
||||
@@ -321,6 +339,9 @@ jpeg_set_defaults (j_compress_ptr cinfo)
|
||||
/* By default, use the simpler non-cosited sampling alignment */
|
||||
cinfo->CCIR601_sampling = FALSE;
|
||||
|
||||
/* By default, apply fancy downsampling */
|
||||
cinfo->do_fancy_downsampling = TRUE;
|
||||
|
||||
/* No input smoothing */
|
||||
cinfo->smoothing_factor = 0;
|
||||
|
||||
@@ -364,12 +385,6 @@ jpeg_default_colorspace (j_compress_ptr cinfo)
|
||||
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
|
||||
break;
|
||||
case JCS_RGB:
|
||||
case JCS_EXT_RGB:
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_BGR:
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_XRGB:
|
||||
jpeg_set_colorspace(cinfo, JCS_YCbCr);
|
||||
break;
|
||||
case JCS_YCbCr:
|
||||
|
||||
831
jcphuff.c
831
jcphuff.c
@@ -1,831 +0,0 @@
|
||||
/*
|
||||
* jcphuff.c
|
||||
*
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains Huffman entropy encoding routines for progressive JPEG.
|
||||
*
|
||||
* We do not support output suspension in this module, since the library
|
||||
* currently does not allow multiple-scan files to be written with output
|
||||
* suspension.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jchuff.h" /* Declarations shared with jchuff.c */
|
||||
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
|
||||
/* Expanded entropy encoder object for progressive Huffman encoding. */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_encoder pub; /* public fields */
|
||||
|
||||
/* Mode flag: TRUE for optimization, FALSE for actual data output */
|
||||
boolean gather_statistics;
|
||||
|
||||
/* Bit-level coding status.
|
||||
* next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
|
||||
*/
|
||||
JOCTET * next_output_byte; /* => next byte to write in buffer */
|
||||
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
|
||||
INT32 put_buffer; /* current bit-accumulation buffer */
|
||||
int put_bits; /* # of bits now in it */
|
||||
j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */
|
||||
|
||||
/* Coding status for DC components */
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
|
||||
/* Coding status for AC components */
|
||||
int ac_tbl_no; /* the table number of the single component */
|
||||
unsigned int EOBRUN; /* run length of EOBs */
|
||||
unsigned int BE; /* # of buffered correction bits before MCU */
|
||||
char * bit_buffer; /* buffer for correction bits (1 per char) */
|
||||
/* packing correction bits tightly would save some space but cost time... */
|
||||
|
||||
unsigned int restarts_to_go; /* MCUs left in this restart interval */
|
||||
int next_restart_num; /* next restart number to write (0-7) */
|
||||
|
||||
/* Pointers to derived tables (these workspaces have image lifespan).
|
||||
* Since any one scan codes only DC or only AC, we only need one set
|
||||
* of tables, not one for DC and one for AC.
|
||||
*/
|
||||
c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
|
||||
|
||||
/* Statistics tables for optimization; again, one set is enough */
|
||||
long * count_ptrs[NUM_HUFF_TBLS];
|
||||
} phuff_entropy_encoder;
|
||||
|
||||
typedef phuff_entropy_encoder * phuff_entropy_ptr;
|
||||
|
||||
/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
|
||||
* buffer can hold. Larger sizes may slightly improve compression, but
|
||||
* 1000 is already well into the realm of overkill.
|
||||
* The minimum safe size is 64 bits.
|
||||
*/
|
||||
|
||||
#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */
|
||||
|
||||
/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
|
||||
* We assume that int right shift is unsigned if INT32 right shift is,
|
||||
* which should be safe.
|
||||
*/
|
||||
|
||||
#ifdef RIGHT_SHIFT_IS_UNSIGNED
|
||||
#define ISHIFT_TEMPS int ishift_temp;
|
||||
#define IRIGHT_SHIFT(x,shft) \
|
||||
((ishift_temp = (x)) < 0 ? \
|
||||
(ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
|
||||
(ishift_temp >> (shft)))
|
||||
#else
|
||||
#define ISHIFT_TEMPS
|
||||
#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
|
||||
METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a Huffman-compressed scan using progressive JPEG.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
boolean is_DC_band;
|
||||
int ci, tbl;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
entropy->cinfo = cinfo;
|
||||
entropy->gather_statistics = gather_statistics;
|
||||
|
||||
is_DC_band = (cinfo->Ss == 0);
|
||||
|
||||
/* We assume jcmaster.c already validated the scan parameters. */
|
||||
|
||||
/* Select execution routines */
|
||||
if (cinfo->Ah == 0) {
|
||||
if (is_DC_band)
|
||||
entropy->pub.encode_mcu = encode_mcu_DC_first;
|
||||
else
|
||||
entropy->pub.encode_mcu = encode_mcu_AC_first;
|
||||
} else {
|
||||
if (is_DC_band)
|
||||
entropy->pub.encode_mcu = encode_mcu_DC_refine;
|
||||
else {
|
||||
entropy->pub.encode_mcu = encode_mcu_AC_refine;
|
||||
/* AC refinement needs a correction bit buffer */
|
||||
if (entropy->bit_buffer == NULL)
|
||||
entropy->bit_buffer = (char *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
MAX_CORR_BITS * SIZEOF(char));
|
||||
}
|
||||
}
|
||||
if (gather_statistics)
|
||||
entropy->pub.finish_pass = finish_pass_gather_phuff;
|
||||
else
|
||||
entropy->pub.finish_pass = finish_pass_phuff;
|
||||
|
||||
/* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
|
||||
* for AC coefficients.
|
||||
*/
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* Initialize DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
/* Get table index */
|
||||
if (is_DC_band) {
|
||||
if (cinfo->Ah != 0) /* DC refinement needs no table */
|
||||
continue;
|
||||
tbl = compptr->dc_tbl_no;
|
||||
} else {
|
||||
entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
|
||||
}
|
||||
if (gather_statistics) {
|
||||
/* Check for invalid table index */
|
||||
/* (make_c_derived_tbl does this in the other path) */
|
||||
if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
|
||||
/* Allocate and zero the statistics tables */
|
||||
/* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
|
||||
if (entropy->count_ptrs[tbl] == NULL)
|
||||
entropy->count_ptrs[tbl] = (long *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
257 * SIZEOF(long));
|
||||
MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
|
||||
} else {
|
||||
/* Compute derived values for Huffman table */
|
||||
/* We may do this more than once for a table, but it's not expensive */
|
||||
jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
|
||||
& entropy->derived_tbls[tbl]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize AC stuff */
|
||||
entropy->EOBRUN = 0;
|
||||
entropy->BE = 0;
|
||||
|
||||
/* Initialize bit buffer to empty */
|
||||
entropy->put_buffer = 0;
|
||||
entropy->put_bits = 0;
|
||||
|
||||
/* Initialize restart stuff */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Outputting bytes to the file.
|
||||
* NB: these must be called only when actually outputting,
|
||||
* that is, entropy->gather_statistics == FALSE.
|
||||
*/
|
||||
|
||||
/* Emit a byte */
|
||||
#define emit_byte(entropy,val) \
|
||||
{ *(entropy)->next_output_byte++ = (JOCTET) (val); \
|
||||
if (--(entropy)->free_in_buffer == 0) \
|
||||
dump_buffer(entropy); }
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
dump_buffer (phuff_entropy_ptr entropy)
|
||||
/* Empty the output buffer; we do not support suspension in this module. */
|
||||
{
|
||||
struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
|
||||
|
||||
if (! (*dest->empty_output_buffer) (entropy->cinfo))
|
||||
ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
|
||||
/* After a successful buffer dump, must reset buffer pointers */
|
||||
entropy->next_output_byte = dest->next_output_byte;
|
||||
entropy->free_in_buffer = dest->free_in_buffer;
|
||||
}
|
||||
|
||||
|
||||
/* Outputting bits to the file */
|
||||
|
||||
/* Only the right 24 bits of put_buffer are used; the valid bits are
|
||||
* left-justified in this part. At most 16 bits can be passed to emit_bits
|
||||
* in one call, and we never retain more than 7 bits in put_buffer
|
||||
* between calls, so 24 bits are sufficient.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
|
||||
/* Emit some bits, unless we are in gather mode */
|
||||
{
|
||||
/* This routine is heavily used, so it's worth coding tightly. */
|
||||
register INT32 put_buffer = (INT32) code;
|
||||
register int put_bits = entropy->put_bits;
|
||||
|
||||
/* if size is 0, caller used an invalid Huffman table entry */
|
||||
if (size == 0)
|
||||
ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
|
||||
|
||||
if (entropy->gather_statistics)
|
||||
return; /* do nothing if we're only getting stats */
|
||||
|
||||
put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
|
||||
|
||||
put_bits += size; /* new number of bits in buffer */
|
||||
|
||||
put_buffer <<= 24 - put_bits; /* align incoming bits */
|
||||
|
||||
put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */
|
||||
|
||||
while (put_bits >= 8) {
|
||||
int c = (int) ((put_buffer >> 16) & 0xFF);
|
||||
|
||||
emit_byte(entropy, c);
|
||||
if (c == 0xFF) { /* need to stuff a zero byte? */
|
||||
emit_byte(entropy, 0);
|
||||
}
|
||||
put_buffer <<= 8;
|
||||
put_bits -= 8;
|
||||
}
|
||||
|
||||
entropy->put_buffer = put_buffer; /* update variables */
|
||||
entropy->put_bits = put_bits;
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
flush_bits (phuff_entropy_ptr entropy)
|
||||
{
|
||||
emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
|
||||
entropy->put_buffer = 0; /* and reset bit-buffer to empty */
|
||||
entropy->put_bits = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit (or just count) a Huffman symbol.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
|
||||
{
|
||||
if (entropy->gather_statistics)
|
||||
entropy->count_ptrs[tbl_no][symbol]++;
|
||||
else {
|
||||
c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
|
||||
emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit bits from a correction bit buffer.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
|
||||
unsigned int nbits)
|
||||
{
|
||||
if (entropy->gather_statistics)
|
||||
return; /* no real work */
|
||||
|
||||
while (nbits > 0) {
|
||||
emit_bits(entropy, (unsigned int) (*bufstart), 1);
|
||||
bufstart++;
|
||||
nbits--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit any pending EOBRUN symbol.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
emit_eobrun (phuff_entropy_ptr entropy)
|
||||
{
|
||||
register int temp, nbits;
|
||||
|
||||
if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */
|
||||
temp = entropy->EOBRUN;
|
||||
nbits = 0;
|
||||
while ((temp >>= 1))
|
||||
nbits++;
|
||||
/* safety check: shouldn't happen given limited correction-bit buffer */
|
||||
if (nbits > 14)
|
||||
ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
|
||||
|
||||
emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
|
||||
if (nbits)
|
||||
emit_bits(entropy, entropy->EOBRUN, nbits);
|
||||
|
||||
entropy->EOBRUN = 0;
|
||||
|
||||
/* Emit any buffered correction bits */
|
||||
emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
|
||||
entropy->BE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit a restart marker & resynchronize predictions.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
emit_restart (phuff_entropy_ptr entropy, int restart_num)
|
||||
{
|
||||
int ci;
|
||||
|
||||
emit_eobrun(entropy);
|
||||
|
||||
if (! entropy->gather_statistics) {
|
||||
flush_bits(entropy);
|
||||
emit_byte(entropy, 0xFF);
|
||||
emit_byte(entropy, JPEG_RST0 + restart_num);
|
||||
}
|
||||
|
||||
if (entropy->cinfo->Ss == 0) {
|
||||
/* Re-initialize DC predictions to 0 */
|
||||
for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
} else {
|
||||
/* Re-initialize all AC-related fields to 0 */
|
||||
entropy->EOBRUN = 0;
|
||||
entropy->BE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for DC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
register int temp, temp2;
|
||||
register int nbits;
|
||||
int blkn, ci;
|
||||
int Al = cinfo->Al;
|
||||
JBLOCKROW block;
|
||||
jpeg_component_info * compptr;
|
||||
ISHIFT_TEMPS
|
||||
|
||||
entropy->next_output_byte = cinfo->dest->next_output_byte;
|
||||
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval)
|
||||
if (entropy->restarts_to_go == 0)
|
||||
emit_restart(entropy, entropy->next_restart_num);
|
||||
|
||||
/* Encode the MCU data blocks */
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
|
||||
/* Compute the DC value after the required point transform by Al.
|
||||
* This is simply an arithmetic right shift.
|
||||
*/
|
||||
temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
|
||||
|
||||
/* DC differences are figured on the point-transformed values. */
|
||||
temp = temp2 - entropy->last_dc_val[ci];
|
||||
entropy->last_dc_val[ci] = temp2;
|
||||
|
||||
/* Encode the DC coefficient difference per section G.1.2.1 */
|
||||
temp2 = temp;
|
||||
if (temp < 0) {
|
||||
temp = -temp; /* temp is abs value of input */
|
||||
/* For a negative input, want temp2 = bitwise complement of abs(input) */
|
||||
/* This code assumes we are on a two's complement machine */
|
||||
temp2--;
|
||||
}
|
||||
|
||||
/* Find the number of bits needed for the magnitude of the coefficient */
|
||||
nbits = 0;
|
||||
while (temp) {
|
||||
nbits++;
|
||||
temp >>= 1;
|
||||
}
|
||||
/* Check for out-of-range coefficient values.
|
||||
* Since we're encoding a difference, the range limit is twice as much.
|
||||
*/
|
||||
if (nbits > MAX_COEF_BITS+1)
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Count/emit the Huffman-coded symbol for the number of bits */
|
||||
emit_symbol(entropy, compptr->dc_tbl_no, nbits);
|
||||
|
||||
/* Emit that number of bits of the value, if positive, */
|
||||
/* or the complement of its magnitude, if negative. */
|
||||
if (nbits) /* emit_bits rejects calls with size 0 */
|
||||
emit_bits(entropy, (unsigned int) temp2, nbits);
|
||||
}
|
||||
|
||||
cinfo->dest->next_output_byte = entropy->next_output_byte;
|
||||
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
|
||||
|
||||
/* Update restart-interval state too */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for AC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
register int temp, temp2;
|
||||
register int nbits;
|
||||
register int r, k;
|
||||
int Se = cinfo->Se;
|
||||
int Al = cinfo->Al;
|
||||
JBLOCKROW block;
|
||||
|
||||
entropy->next_output_byte = cinfo->dest->next_output_byte;
|
||||
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval)
|
||||
if (entropy->restarts_to_go == 0)
|
||||
emit_restart(entropy, entropy->next_restart_num);
|
||||
|
||||
/* Encode the MCU data block */
|
||||
block = MCU_data[0];
|
||||
|
||||
/* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
|
||||
|
||||
r = 0; /* r = run length of zeros */
|
||||
|
||||
for (k = cinfo->Ss; k <= Se; k++) {
|
||||
if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
|
||||
r++;
|
||||
continue;
|
||||
}
|
||||
/* We must apply the point transform by Al. For AC coefficients this
|
||||
* is an integer division with rounding towards 0. To do this portably
|
||||
* in C, we shift after obtaining the absolute value; so the code is
|
||||
* interwoven with finding the abs value (temp) and output bits (temp2).
|
||||
*/
|
||||
if (temp < 0) {
|
||||
temp = -temp; /* temp is abs value of input */
|
||||
temp >>= Al; /* apply the point transform */
|
||||
/* For a negative coef, want temp2 = bitwise complement of abs(coef) */
|
||||
temp2 = ~temp;
|
||||
} else {
|
||||
temp >>= Al; /* apply the point transform */
|
||||
temp2 = temp;
|
||||
}
|
||||
/* Watch out for case that nonzero coef is zero after point transform */
|
||||
if (temp == 0) {
|
||||
r++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Emit any pending EOBRUN */
|
||||
if (entropy->EOBRUN > 0)
|
||||
emit_eobrun(entropy);
|
||||
/* if run length > 15, must emit special run-length-16 codes (0xF0) */
|
||||
while (r > 15) {
|
||||
emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
|
||||
r -= 16;
|
||||
}
|
||||
|
||||
/* Find the number of bits needed for the magnitude of the coefficient */
|
||||
nbits = 1; /* there must be at least one 1 bit */
|
||||
while ((temp >>= 1))
|
||||
nbits++;
|
||||
/* Check for out-of-range coefficient values */
|
||||
if (nbits > MAX_COEF_BITS)
|
||||
ERREXIT(cinfo, JERR_BAD_DCT_COEF);
|
||||
|
||||
/* Count/emit Huffman symbol for run length / number of bits */
|
||||
emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
|
||||
|
||||
/* Emit that number of bits of the value, if positive, */
|
||||
/* or the complement of its magnitude, if negative. */
|
||||
emit_bits(entropy, (unsigned int) temp2, nbits);
|
||||
|
||||
r = 0; /* reset zero run length */
|
||||
}
|
||||
|
||||
if (r > 0) { /* If there are trailing zeroes, */
|
||||
entropy->EOBRUN++; /* count an EOB */
|
||||
if (entropy->EOBRUN == 0x7FFF)
|
||||
emit_eobrun(entropy); /* force it out to avoid overflow */
|
||||
}
|
||||
|
||||
cinfo->dest->next_output_byte = entropy->next_output_byte;
|
||||
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
|
||||
|
||||
/* Update restart-interval state too */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for DC successive approximation refinement scan.
|
||||
* Note: we assume such scans can be multi-component, although the spec
|
||||
* is not very clear on the point.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
register int temp;
|
||||
int blkn;
|
||||
int Al = cinfo->Al;
|
||||
JBLOCKROW block;
|
||||
|
||||
entropy->next_output_byte = cinfo->dest->next_output_byte;
|
||||
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval)
|
||||
if (entropy->restarts_to_go == 0)
|
||||
emit_restart(entropy, entropy->next_restart_num);
|
||||
|
||||
/* Encode the MCU data blocks */
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
|
||||
/* We simply emit the Al'th bit of the DC coefficient value. */
|
||||
temp = (*block)[0];
|
||||
emit_bits(entropy, (unsigned int) (temp >> Al), 1);
|
||||
}
|
||||
|
||||
cinfo->dest->next_output_byte = entropy->next_output_byte;
|
||||
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
|
||||
|
||||
/* Update restart-interval state too */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU encoding for AC successive approximation refinement scan.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
register int temp;
|
||||
register int r, k;
|
||||
int EOB;
|
||||
char *BR_buffer;
|
||||
unsigned int BR;
|
||||
int Se = cinfo->Se;
|
||||
int Al = cinfo->Al;
|
||||
JBLOCKROW block;
|
||||
int absvalues[DCTSIZE2];
|
||||
|
||||
entropy->next_output_byte = cinfo->dest->next_output_byte;
|
||||
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
|
||||
/* Emit restart marker if needed */
|
||||
if (cinfo->restart_interval)
|
||||
if (entropy->restarts_to_go == 0)
|
||||
emit_restart(entropy, entropy->next_restart_num);
|
||||
|
||||
/* Encode the MCU data block */
|
||||
block = MCU_data[0];
|
||||
|
||||
/* It is convenient to make a pre-pass to determine the transformed
|
||||
* coefficients' absolute values and the EOB position.
|
||||
*/
|
||||
EOB = 0;
|
||||
for (k = cinfo->Ss; k <= Se; k++) {
|
||||
temp = (*block)[jpeg_natural_order[k]];
|
||||
/* We must apply the point transform by Al. For AC coefficients this
|
||||
* is an integer division with rounding towards 0. To do this portably
|
||||
* in C, we shift after obtaining the absolute value.
|
||||
*/
|
||||
if (temp < 0)
|
||||
temp = -temp; /* temp is abs value of input */
|
||||
temp >>= Al; /* apply the point transform */
|
||||
absvalues[k] = temp; /* save abs value for main pass */
|
||||
if (temp == 1)
|
||||
EOB = k; /* EOB = index of last newly-nonzero coef */
|
||||
}
|
||||
|
||||
/* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
|
||||
|
||||
r = 0; /* r = run length of zeros */
|
||||
BR = 0; /* BR = count of buffered bits added now */
|
||||
BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
|
||||
|
||||
for (k = cinfo->Ss; k <= Se; k++) {
|
||||
if ((temp = absvalues[k]) == 0) {
|
||||
r++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Emit any required ZRLs, but not if they can be folded into EOB */
|
||||
while (r > 15 && k <= EOB) {
|
||||
/* emit any pending EOBRUN and the BE correction bits */
|
||||
emit_eobrun(entropy);
|
||||
/* Emit ZRL */
|
||||
emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
|
||||
r -= 16;
|
||||
/* Emit buffered correction bits that must be associated with ZRL */
|
||||
emit_buffered_bits(entropy, BR_buffer, BR);
|
||||
BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
|
||||
BR = 0;
|
||||
}
|
||||
|
||||
/* If the coef was previously nonzero, it only needs a correction bit.
|
||||
* NOTE: a straight translation of the spec's figure G.7 would suggest
|
||||
* that we also need to test r > 15. But if r > 15, we can only get here
|
||||
* if k > EOB, which implies that this coefficient is not 1.
|
||||
*/
|
||||
if (temp > 1) {
|
||||
/* The correction bit is the next bit of the absolute value. */
|
||||
BR_buffer[BR++] = (char) (temp & 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Emit any pending EOBRUN and the BE correction bits */
|
||||
emit_eobrun(entropy);
|
||||
|
||||
/* Count/emit Huffman symbol for run length / number of bits */
|
||||
emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
|
||||
|
||||
/* Emit output bit for newly-nonzero coef */
|
||||
temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
|
||||
emit_bits(entropy, (unsigned int) temp, 1);
|
||||
|
||||
/* Emit buffered correction bits that must be associated with this code */
|
||||
emit_buffered_bits(entropy, BR_buffer, BR);
|
||||
BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
|
||||
BR = 0;
|
||||
r = 0; /* reset zero run length */
|
||||
}
|
||||
|
||||
if (r > 0 || BR > 0) { /* If there are trailing zeroes, */
|
||||
entropy->EOBRUN++; /* count an EOB */
|
||||
entropy->BE += BR; /* concat my correction bits to older ones */
|
||||
/* We force out the EOB if we risk either:
|
||||
* 1. overflow of the EOB counter;
|
||||
* 2. overflow of the correction bit buffer during the next MCU.
|
||||
*/
|
||||
if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
|
||||
emit_eobrun(entropy);
|
||||
}
|
||||
|
||||
cinfo->dest->next_output_byte = entropy->next_output_byte;
|
||||
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
|
||||
|
||||
/* Update restart-interval state too */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0) {
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
entropy->next_restart_num++;
|
||||
entropy->next_restart_num &= 7;
|
||||
}
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up at the end of a Huffman-compressed progressive scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
finish_pass_phuff (j_compress_ptr cinfo)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
|
||||
entropy->next_output_byte = cinfo->dest->next_output_byte;
|
||||
entropy->free_in_buffer = cinfo->dest->free_in_buffer;
|
||||
|
||||
/* Flush out any buffered data */
|
||||
emit_eobrun(entropy);
|
||||
flush_bits(entropy);
|
||||
|
||||
cinfo->dest->next_output_byte = entropy->next_output_byte;
|
||||
cinfo->dest->free_in_buffer = entropy->free_in_buffer;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish up a statistics-gathering pass and create the new Huffman tables.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
finish_pass_gather_phuff (j_compress_ptr cinfo)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
boolean is_DC_band;
|
||||
int ci, tbl;
|
||||
jpeg_component_info * compptr;
|
||||
JHUFF_TBL **htblptr;
|
||||
boolean did[NUM_HUFF_TBLS];
|
||||
|
||||
/* Flush out buffered data (all we care about is counting the EOB symbol) */
|
||||
emit_eobrun(entropy);
|
||||
|
||||
is_DC_band = (cinfo->Ss == 0);
|
||||
|
||||
/* It's important not to apply jpeg_gen_optimal_table more than once
|
||||
* per table, because it clobbers the input frequency counts!
|
||||
*/
|
||||
MEMZERO(did, SIZEOF(did));
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
if (is_DC_band) {
|
||||
if (cinfo->Ah != 0) /* DC refinement needs no table */
|
||||
continue;
|
||||
tbl = compptr->dc_tbl_no;
|
||||
} else {
|
||||
tbl = compptr->ac_tbl_no;
|
||||
}
|
||||
if (! did[tbl]) {
|
||||
if (is_DC_band)
|
||||
htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
|
||||
else
|
||||
htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
|
||||
if (*htblptr == NULL)
|
||||
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
|
||||
jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
|
||||
did[tbl] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for progressive Huffman entropy encoding.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_phuff_encoder (j_compress_ptr cinfo)
|
||||
{
|
||||
phuff_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (phuff_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(phuff_entropy_encoder));
|
||||
cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
|
||||
entropy->pub.start_pass = start_pass_phuff;
|
||||
|
||||
/* Mark tables unallocated */
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
entropy->derived_tbls[i] = NULL;
|
||||
entropy->count_ptrs[i] = NULL;
|
||||
}
|
||||
entropy->bit_buffer = NULL; /* needed only in AC refinement scan */
|
||||
}
|
||||
|
||||
#endif /* C_PROGRESSIVE_SUPPORTED */
|
||||
14
jcprepct.c
14
jcprepct.c
@@ -173,10 +173,12 @@ pre_process_data (j_compress_ptr cinfo,
|
||||
*out_row_group_ctr < out_row_groups_avail) {
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
numrows = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
||||
cinfo->min_DCT_v_scaled_size;
|
||||
expand_bottom_edge(output_buf[ci],
|
||||
compptr->width_in_blocks * DCTSIZE,
|
||||
(int) (*out_row_group_ctr * compptr->v_samp_factor),
|
||||
(int) (out_row_groups_avail * compptr->v_samp_factor));
|
||||
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
|
||||
(int) (*out_row_group_ctr * numrows),
|
||||
(int) (out_row_groups_avail * numrows));
|
||||
}
|
||||
*out_row_group_ctr = out_row_groups_avail;
|
||||
break; /* can exit outer loop without test */
|
||||
@@ -288,7 +290,8 @@ create_context_buffer (j_compress_ptr cinfo)
|
||||
*/
|
||||
true_buffer = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks *
|
||||
cinfo->min_DCT_h_scaled_size *
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION) (3 * rgroup_height));
|
||||
/* Copy true buffer row pointers into the middle of the fake row array */
|
||||
@@ -346,7 +349,8 @@ jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
|
||||
ci++, compptr++) {
|
||||
prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
|
||||
(JDIMENSION) (((long) compptr->width_in_blocks *
|
||||
cinfo->min_DCT_h_scaled_size *
|
||||
cinfo->max_h_samp_factor) / compptr->h_samp_factor),
|
||||
(JDIMENSION) cinfo->max_v_samp_factor);
|
||||
}
|
||||
|
||||
106
jcsample.c
106
jcsample.c
@@ -2,7 +2,6 @@
|
||||
* jcsample.c
|
||||
*
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -49,7 +48,6 @@
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
|
||||
|
||||
/* Pointer to routine to downsample a single component */
|
||||
@@ -64,6 +62,15 @@ typedef struct {
|
||||
|
||||
/* Downsampling method pointers, one per component */
|
||||
downsample1_ptr methods[MAX_COMPONENTS];
|
||||
|
||||
/* Height of an output row group for each component. */
|
||||
int rowgroup_height[MAX_COMPONENTS];
|
||||
|
||||
/* These arrays save pixel expansion factors so that int_downsample need not
|
||||
* recompute them each time. They are unused for other downsampling methods.
|
||||
*/
|
||||
UINT8 h_expand[MAX_COMPONENTS];
|
||||
UINT8 v_expand[MAX_COMPONENTS];
|
||||
} my_downsampler;
|
||||
|
||||
typedef my_downsampler * my_downsample_ptr;
|
||||
@@ -125,7 +132,8 @@ sep_downsample (j_compress_ptr cinfo,
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
in_ptr = input_buf[ci] + in_row_index;
|
||||
out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
|
||||
out_ptr = output_buf[ci] +
|
||||
(out_row_group_index * downsample->rowgroup_height[ci]);
|
||||
(*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
|
||||
}
|
||||
}
|
||||
@@ -142,14 +150,15 @@ METHODDEF(void)
|
||||
int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
|
||||
int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
|
||||
JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
|
||||
JSAMPROW inptr, outptr;
|
||||
INT32 outvalue;
|
||||
|
||||
h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
|
||||
v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
|
||||
h_expand = downsample->h_expand[compptr->component_index];
|
||||
v_expand = downsample->v_expand[compptr->component_index];
|
||||
numpix = h_expand * v_expand;
|
||||
numpix2 = numpix/2;
|
||||
|
||||
@@ -160,8 +169,8 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
expand_right_edge(input_data, cinfo->max_v_samp_factor,
|
||||
cinfo->image_width, output_cols * h_expand);
|
||||
|
||||
inrow = 0;
|
||||
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
|
||||
inrow = outrow = 0;
|
||||
while (inrow < cinfo->max_v_samp_factor) {
|
||||
outptr = output_data[outrow];
|
||||
for (outcol = 0, outcol_h = 0; outcol < output_cols;
|
||||
outcol++, outcol_h += h_expand) {
|
||||
@@ -175,6 +184,7 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
*outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
|
||||
}
|
||||
inrow += v_expand;
|
||||
outrow++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,8 +203,8 @@ fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
jcopy_sample_rows(input_data, 0, output_data, 0,
|
||||
cinfo->max_v_samp_factor, cinfo->image_width);
|
||||
/* Edge-expand */
|
||||
expand_right_edge(output_data, cinfo->max_v_samp_factor,
|
||||
cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
|
||||
expand_right_edge(output_data, cinfo->max_v_samp_factor, cinfo->image_width,
|
||||
compptr->width_in_blocks * compptr->DCT_h_scaled_size);
|
||||
}
|
||||
|
||||
|
||||
@@ -214,9 +224,9 @@ METHODDEF(void)
|
||||
h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
int outrow;
|
||||
int inrow;
|
||||
JDIMENSION outcol;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
|
||||
register JSAMPROW inptr, outptr;
|
||||
register int bias;
|
||||
|
||||
@@ -227,9 +237,9 @@ h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
expand_right_edge(input_data, cinfo->max_v_samp_factor,
|
||||
cinfo->image_width, output_cols * 2);
|
||||
|
||||
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
|
||||
outptr = output_data[outrow];
|
||||
inptr = input_data[outrow];
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
outptr = output_data[inrow];
|
||||
inptr = input_data[inrow];
|
||||
bias = 0; /* bias = 0,1,0,1,... for successive samples */
|
||||
for (outcol = 0; outcol < output_cols; outcol++) {
|
||||
*outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
|
||||
@@ -253,7 +263,7 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
{
|
||||
int inrow, outrow;
|
||||
JDIMENSION outcol;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
|
||||
register JSAMPROW inptr0, inptr1, outptr;
|
||||
register int bias;
|
||||
|
||||
@@ -264,8 +274,8 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
expand_right_edge(input_data, cinfo->max_v_samp_factor,
|
||||
cinfo->image_width, output_cols * 2);
|
||||
|
||||
inrow = 0;
|
||||
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
|
||||
inrow = outrow = 0;
|
||||
while (inrow < cinfo->max_v_samp_factor) {
|
||||
outptr = output_data[outrow];
|
||||
inptr0 = input_data[inrow];
|
||||
inptr1 = input_data[inrow+1];
|
||||
@@ -278,6 +288,7 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
inptr0 += 2; inptr1 += 2;
|
||||
}
|
||||
inrow += 2;
|
||||
outrow++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +307,7 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
{
|
||||
int inrow, outrow;
|
||||
JDIMENSION colctr;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
|
||||
register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
|
||||
INT32 membersum, neighsum, memberscale, neighscale;
|
||||
|
||||
@@ -323,8 +334,8 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
|
||||
neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
|
||||
|
||||
inrow = 0;
|
||||
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
|
||||
inrow = outrow = 0;
|
||||
while (inrow < cinfo->max_v_samp_factor) {
|
||||
outptr = output_data[outrow];
|
||||
inptr0 = input_data[inrow];
|
||||
inptr1 = input_data[inrow+1];
|
||||
@@ -380,6 +391,7 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
*outptr = (JSAMPLE) ((membersum + 32768) >> 16);
|
||||
|
||||
inrow += 2;
|
||||
outrow++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,9 +406,9 @@ METHODDEF(void)
|
||||
fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY output_data)
|
||||
{
|
||||
int outrow;
|
||||
int inrow;
|
||||
JDIMENSION colctr;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
|
||||
JDIMENSION output_cols = compptr->width_in_blocks * compptr->DCT_h_scaled_size;
|
||||
register JSAMPROW inptr, above_ptr, below_ptr, outptr;
|
||||
INT32 membersum, neighsum, memberscale, neighscale;
|
||||
int colsum, lastcolsum, nextcolsum;
|
||||
@@ -417,11 +429,11 @@ fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
|
||||
memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
|
||||
neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
|
||||
|
||||
for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
|
||||
outptr = output_data[outrow];
|
||||
inptr = input_data[outrow];
|
||||
above_ptr = input_data[outrow-1];
|
||||
below_ptr = input_data[outrow+1];
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
outptr = output_data[inrow];
|
||||
inptr = input_data[inrow];
|
||||
above_ptr = input_data[inrow-1];
|
||||
below_ptr = input_data[inrow+1];
|
||||
|
||||
/* Special case for first column */
|
||||
colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
|
||||
@@ -469,6 +481,7 @@ jinit_downsampler (j_compress_ptr cinfo)
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
boolean smoothok = TRUE;
|
||||
int h_in_group, v_in_group, h_out_group, v_out_group;
|
||||
|
||||
downsample = (my_downsample_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
@@ -484,8 +497,17 @@ jinit_downsampler (j_compress_ptr cinfo)
|
||||
/* Verify we can handle the sampling factors, and set up method pointers */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
|
||||
compptr->v_samp_factor == cinfo->max_v_samp_factor) {
|
||||
/* Compute size of an "output group" for DCT scaling. This many samples
|
||||
* are to be converted from max_h_samp_factor * max_v_samp_factor pixels.
|
||||
*/
|
||||
h_out_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
|
||||
cinfo->min_DCT_h_scaled_size;
|
||||
v_out_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
||||
cinfo->min_DCT_v_scaled_size;
|
||||
h_in_group = cinfo->max_h_samp_factor;
|
||||
v_in_group = cinfo->max_v_samp_factor;
|
||||
downsample->rowgroup_height[ci] = v_out_group; /* save for use later */
|
||||
if (h_in_group == h_out_group && v_in_group == v_out_group) {
|
||||
#ifdef INPUT_SMOOTHING_SUPPORTED
|
||||
if (cinfo->smoothing_factor) {
|
||||
downsample->methods[ci] = fullsize_smooth_downsample;
|
||||
@@ -493,29 +515,25 @@ jinit_downsampler (j_compress_ptr cinfo)
|
||||
} else
|
||||
#endif
|
||||
downsample->methods[ci] = fullsize_downsample;
|
||||
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
|
||||
compptr->v_samp_factor == cinfo->max_v_samp_factor) {
|
||||
} else if (h_in_group == h_out_group * 2 &&
|
||||
v_in_group == v_out_group) {
|
||||
smoothok = FALSE;
|
||||
if (jsimd_can_h2v1_downsample())
|
||||
downsample->methods[ci] = jsimd_h2v1_downsample;
|
||||
else
|
||||
downsample->methods[ci] = h2v1_downsample;
|
||||
} else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
|
||||
compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
|
||||
downsample->methods[ci] = h2v1_downsample;
|
||||
} else if (h_in_group == h_out_group * 2 &&
|
||||
v_in_group == v_out_group * 2) {
|
||||
#ifdef INPUT_SMOOTHING_SUPPORTED
|
||||
if (cinfo->smoothing_factor) {
|
||||
downsample->methods[ci] = h2v2_smooth_downsample;
|
||||
downsample->pub.need_context_rows = TRUE;
|
||||
} else
|
||||
#endif
|
||||
if (jsimd_can_h2v2_downsample())
|
||||
downsample->methods[ci] = jsimd_h2v2_downsample;
|
||||
else
|
||||
downsample->methods[ci] = h2v2_downsample;
|
||||
} else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
|
||||
(cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
|
||||
downsample->methods[ci] = h2v2_downsample;
|
||||
} else if ((h_in_group % h_out_group) == 0 &&
|
||||
(v_in_group % v_out_group) == 0) {
|
||||
smoothok = FALSE;
|
||||
downsample->methods[ci] = int_downsample;
|
||||
downsample->h_expand[ci] = (UINT8) (h_in_group / h_out_group);
|
||||
downsample->v_expand[ci] = (UINT8) (v_in_group / v_out_group);
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
|
||||
}
|
||||
|
||||
24
jctrans.c
24
jctrans.c
@@ -2,6 +2,7 @@
|
||||
* jctrans.c
|
||||
*
|
||||
* Copyright (C) 1995-1998, Thomas G. Lane.
|
||||
* Modified 2000-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -76,6 +77,10 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
|
||||
dstinfo->image_height = srcinfo->image_height;
|
||||
dstinfo->input_components = srcinfo->num_components;
|
||||
dstinfo->in_color_space = srcinfo->jpeg_color_space;
|
||||
dstinfo->jpeg_width = srcinfo->output_width;
|
||||
dstinfo->jpeg_height = srcinfo->output_height;
|
||||
dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size;
|
||||
dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size;
|
||||
/* Initialize all parameters to default values */
|
||||
jpeg_set_defaults(dstinfo);
|
||||
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
|
||||
@@ -158,25 +163,14 @@ LOCAL(void)
|
||||
transencode_master_selection (j_compress_ptr cinfo,
|
||||
jvirt_barray_ptr * coef_arrays)
|
||||
{
|
||||
/* Although we don't actually use input_components for transcoding,
|
||||
* jcmaster.c's initial_setup will complain if input_components is 0.
|
||||
*/
|
||||
cinfo->input_components = 1;
|
||||
/* Initialize master control (includes parameter checking/processing) */
|
||||
jinit_c_master_control(cinfo, TRUE /* transcode only */);
|
||||
|
||||
/* Entropy encoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_encoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_encoder(cinfo);
|
||||
if (cinfo->arith_code)
|
||||
jinit_arith_encoder(cinfo);
|
||||
else {
|
||||
jinit_huff_encoder(cinfo);
|
||||
}
|
||||
|
||||
/* We need a special coefficient buffer controller. */
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* jdapimin.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* Modified 2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -185,8 +186,8 @@ default_decompress_parms (j_decompress_ptr cinfo)
|
||||
}
|
||||
|
||||
/* Set defaults for other decompression parameters. */
|
||||
cinfo->scale_num = 1; /* 1:1 scaling */
|
||||
cinfo->scale_denom = 1;
|
||||
cinfo->scale_num = cinfo->block_size; /* 1:1 scaling */
|
||||
cinfo->scale_denom = cinfo->block_size;
|
||||
cinfo->output_gamma = 1.0;
|
||||
cinfo->buffered_image = FALSE;
|
||||
cinfo->raw_data_out = FALSE;
|
||||
|
||||
@@ -202,7 +202,7 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
|
||||
}
|
||||
|
||||
/* Verify that at least one iMCU row can be returned. */
|
||||
lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
|
||||
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);
|
||||
|
||||
|
||||
772
jdarith.c
Normal file
772
jdarith.c
Normal file
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
* jdarith.c
|
||||
*
|
||||
* Developed 1997-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains portable arithmetic entropy decoding routines for JPEG
|
||||
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
|
||||
*
|
||||
* Both sequential and progressive modes are supported in this single module.
|
||||
*
|
||||
* Suspension is not currently supported in this module.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
|
||||
|
||||
/* Expanded entropy decoder object for arithmetic decoding. */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_decoder pub; /* public fields */
|
||||
|
||||
INT32 c; /* C register, base of coding interval + input bit buffer */
|
||||
INT32 a; /* A register, normalized size of coding interval */
|
||||
int ct; /* bit shift counter, # of bits left in bit buffer part of C */
|
||||
/* init: ct = -16 */
|
||||
/* run: ct = 0..7 */
|
||||
/* error: ct = -1 */
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */
|
||||
|
||||
unsigned int restarts_to_go; /* MCUs left in this restart interval */
|
||||
|
||||
/* Pointers to statistics areas (these workspaces have image lifespan) */
|
||||
unsigned char * dc_stats[NUM_ARITH_TBLS];
|
||||
unsigned char * ac_stats[NUM_ARITH_TBLS];
|
||||
|
||||
/* Statistics bin for coding with fixed probability 0.5 */
|
||||
unsigned char fixed_bin[4];
|
||||
} arith_entropy_decoder;
|
||||
|
||||
typedef arith_entropy_decoder * arith_entropy_ptr;
|
||||
|
||||
/* The following two definitions specify the allocation chunk size
|
||||
* for the statistics area.
|
||||
* According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least
|
||||
* 49 statistics bins for DC, and 245 statistics bins for AC coding.
|
||||
*
|
||||
* We use a compact representation with 1 byte per statistics bin,
|
||||
* thus the numbers directly represent byte sizes.
|
||||
* This 1 byte per statistics bin contains the meaning of the MPS
|
||||
* (more probable symbol) in the highest bit (mask 0x80), and the
|
||||
* index into the probability estimation state machine table
|
||||
* in the lower bits (mask 0x7F).
|
||||
*/
|
||||
|
||||
#define DC_STAT_BINS 64
|
||||
#define AC_STAT_BINS 256
|
||||
|
||||
|
||||
LOCAL(int)
|
||||
get_byte (j_decompress_ptr cinfo)
|
||||
/* Read next input byte; we do not support suspension in this module. */
|
||||
{
|
||||
struct jpeg_source_mgr * src = cinfo->src;
|
||||
|
||||
if (src->bytes_in_buffer == 0)
|
||||
if (! (*src->fill_input_buffer) (cinfo))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
src->bytes_in_buffer--;
|
||||
return GETJOCTET(*src->next_input_byte++);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The core arithmetic decoding routine (common in JPEG and JBIG).
|
||||
* This needs to go as fast as possible.
|
||||
* Machine-dependent optimization facilities
|
||||
* are not utilized in this portable implementation.
|
||||
* However, this code should be fairly efficient and
|
||||
* may be a good base for further optimizations anyway.
|
||||
*
|
||||
* Return value is 0 or 1 (binary decision).
|
||||
*
|
||||
* Note: I've changed the handling of the code base & bit
|
||||
* buffer register C compared to other implementations
|
||||
* based on the standards layout & procedures.
|
||||
* While it also contains both the actual base of the
|
||||
* coding interval (16 bits) and the next-bits buffer,
|
||||
* the cut-point between these two parts is floating
|
||||
* (instead of fixed) with the bit shift counter CT.
|
||||
* Thus, we also need only one (variable instead of
|
||||
* fixed size) shift for the LPS/MPS decision, and
|
||||
* we can get away with any renormalization update
|
||||
* of C (except for new data insertion, of course).
|
||||
*
|
||||
* I've also introduced a new scheme for accessing
|
||||
* the probability estimation state machine table,
|
||||
* derived from Markus Kuhn's JBIG implementation.
|
||||
*/
|
||||
|
||||
LOCAL(int)
|
||||
arith_decode (j_decompress_ptr cinfo, unsigned char *st)
|
||||
{
|
||||
register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
|
||||
register unsigned char nl, nm;
|
||||
register INT32 qe, temp;
|
||||
register int sv, data;
|
||||
|
||||
/* Renormalization & data input per section D.2.6 */
|
||||
while (e->a < 0x8000L) {
|
||||
if (--e->ct < 0) {
|
||||
/* Need to fetch next data byte */
|
||||
if (cinfo->unread_marker)
|
||||
data = 0; /* stuff zero data */
|
||||
else {
|
||||
data = get_byte(cinfo); /* read next input byte */
|
||||
if (data == 0xFF) { /* zero stuff or marker code */
|
||||
do data = get_byte(cinfo);
|
||||
while (data == 0xFF); /* swallow extra 0xFF bytes */
|
||||
if (data == 0)
|
||||
data = 0xFF; /* discard stuffed zero byte */
|
||||
else {
|
||||
/* Note: Different from the Huffman decoder, hitting
|
||||
* a marker while processing the compressed data
|
||||
* segment is legal in arithmetic coding.
|
||||
* The convention is to supply zero data
|
||||
* then until decoding is complete.
|
||||
*/
|
||||
cinfo->unread_marker = data;
|
||||
data = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
e->c = (e->c << 8) | data; /* insert data into C register */
|
||||
if ((e->ct += 8) < 0) /* update bit shift counter */
|
||||
/* Need more initial bytes */
|
||||
if (++e->ct == 0)
|
||||
/* Got 2 initial bytes -> re-init A and exit loop */
|
||||
e->a = 0x8000L; /* => e->a = 0x10000L after loop exit */
|
||||
}
|
||||
e->a <<= 1;
|
||||
}
|
||||
|
||||
/* Fetch values from our compact representation of Table D.2:
|
||||
* Qe values and probability estimation state machine
|
||||
*/
|
||||
sv = *st;
|
||||
qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */
|
||||
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
|
||||
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
|
||||
|
||||
/* Decode & estimation procedures per sections D.2.4 & D.2.5 */
|
||||
temp = e->a - qe;
|
||||
e->a = temp;
|
||||
temp <<= e->ct;
|
||||
if (e->c >= temp) {
|
||||
e->c -= temp;
|
||||
/* Conditional LPS (less probable symbol) exchange */
|
||||
if (e->a < qe) {
|
||||
e->a = qe;
|
||||
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
|
||||
} else {
|
||||
e->a = qe;
|
||||
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
|
||||
sv ^= 0x80; /* Exchange LPS/MPS */
|
||||
}
|
||||
} else if (e->a < 0x8000L) {
|
||||
/* Conditional MPS (more probable symbol) exchange */
|
||||
if (e->a < qe) {
|
||||
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
|
||||
sv ^= 0x80; /* Exchange LPS/MPS */
|
||||
} else {
|
||||
*st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */
|
||||
}
|
||||
}
|
||||
|
||||
return sv >> 7;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for a restart marker & resynchronize decoder.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
process_restart (j_decompress_ptr cinfo)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
/* Advance past the RSTn marker */
|
||||
if (! (*cinfo->marker->read_restart_marker) (cinfo))
|
||||
ERREXIT(cinfo, JERR_CANT_SUSPEND);
|
||||
|
||||
/* Re-initialize statistics areas */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
|
||||
MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS);
|
||||
/* Reset DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
}
|
||||
if ((! cinfo->progressive_mode && cinfo->lim_Se) ||
|
||||
(cinfo->progressive_mode && cinfo->Ss)) {
|
||||
MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset arithmetic decoding variables */
|
||||
entropy->c = 0;
|
||||
entropy->a = 0;
|
||||
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
|
||||
|
||||
/* Reset restart counter */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Arithmetic MCU decoding.
|
||||
* Each of these routines decodes and returns one MCU's worth of
|
||||
* arithmetic-compressed coefficients.
|
||||
* The coefficients are reordered from zigzag order into natural array order,
|
||||
* but are not dequantized.
|
||||
*
|
||||
* The i'th block of the MCU is stored into the block pointed to by
|
||||
* MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MCU decoding for DC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
JBLOCKROW block;
|
||||
unsigned char *st;
|
||||
int blkn, ci, tbl, sign;
|
||||
int v, m;
|
||||
|
||||
/* Process restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
process_restart(cinfo);
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
tbl = cinfo->cur_comp_info[ci]->dc_tbl_no;
|
||||
|
||||
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
|
||||
|
||||
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
|
||||
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
|
||||
|
||||
/* Figure F.19: Decode_DC_DIFF */
|
||||
if (arith_decode(cinfo, st) == 0)
|
||||
entropy->dc_context[ci] = 0;
|
||||
else {
|
||||
/* Figure F.21: Decoding nonzero value v */
|
||||
/* Figure F.22: Decoding the sign of v */
|
||||
sign = arith_decode(cinfo, st + 1);
|
||||
st += 2; st += sign;
|
||||
/* Figure F.23: Decoding the magnitude category of v */
|
||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
||||
while (arith_decode(cinfo, st)) {
|
||||
if ((m <<= 1) == 0x8000) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* magnitude overflow */
|
||||
return TRUE;
|
||||
}
|
||||
st += 1;
|
||||
}
|
||||
}
|
||||
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
|
||||
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
|
||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
||||
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
|
||||
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
|
||||
else
|
||||
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
|
||||
v = m;
|
||||
/* Figure F.24: Decoding the magnitude bit pattern of v */
|
||||
st += 14;
|
||||
while (m >>= 1)
|
||||
if (arith_decode(cinfo, st)) v |= m;
|
||||
v += 1; if (sign) v = -v;
|
||||
entropy->last_dc_val[ci] += v;
|
||||
}
|
||||
|
||||
/* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */
|
||||
(*block)[0] = (JCOEF) (entropy->last_dc_val[ci] << cinfo->Al);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU decoding for AC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
JBLOCKROW block;
|
||||
unsigned char *st;
|
||||
int tbl, sign, k;
|
||||
int v, m;
|
||||
const int * natural_order;
|
||||
|
||||
/* Process restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
process_restart(cinfo);
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
||||
|
||||
natural_order = cinfo->natural_order;
|
||||
|
||||
/* There is always only one block per MCU */
|
||||
block = MCU_data[0];
|
||||
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
|
||||
|
||||
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
|
||||
|
||||
/* Figure F.20: Decode_AC_coefficients */
|
||||
for (k = cinfo->Ss; k <= cinfo->Se; k++) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
if (arith_decode(cinfo, st)) break; /* EOB flag */
|
||||
while (arith_decode(cinfo, st + 1) == 0) {
|
||||
st += 3; k++;
|
||||
if (k > cinfo->Se) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* spectral overflow */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
/* Figure F.21: Decoding nonzero value v */
|
||||
/* Figure F.22: Decoding the sign of v */
|
||||
sign = arith_decode(cinfo, entropy->fixed_bin);
|
||||
st += 2;
|
||||
/* Figure F.23: Decoding the magnitude category of v */
|
||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
||||
if (arith_decode(cinfo, st)) {
|
||||
m <<= 1;
|
||||
st = entropy->ac_stats[tbl] +
|
||||
(k <= cinfo->arith_ac_K[tbl] ? 189 : 217);
|
||||
while (arith_decode(cinfo, st)) {
|
||||
if ((m <<= 1) == 0x8000) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* magnitude overflow */
|
||||
return TRUE;
|
||||
}
|
||||
st += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
v = m;
|
||||
/* Figure F.24: Decoding the magnitude bit pattern of v */
|
||||
st += 14;
|
||||
while (m >>= 1)
|
||||
if (arith_decode(cinfo, st)) v |= m;
|
||||
v += 1; if (sign) v = -v;
|
||||
/* Scale and output coefficient in natural (dezigzagged) order */
|
||||
(*block)[natural_order[k]] = (JCOEF) (v << cinfo->Al);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU decoding for DC successive approximation refinement scan.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
unsigned char *st;
|
||||
int p1, blkn;
|
||||
|
||||
/* Process restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
process_restart(cinfo);
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
st = entropy->fixed_bin; /* use fixed probability estimation */
|
||||
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
/* Encoded data is simply the next bit of the two's-complement DC value */
|
||||
if (arith_decode(cinfo, st))
|
||||
MCU_data[blkn][0][0] |= p1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU decoding for AC successive approximation refinement scan.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
JBLOCKROW block;
|
||||
JCOEFPTR thiscoef;
|
||||
unsigned char *st;
|
||||
int tbl, k, kex;
|
||||
int p1, m1;
|
||||
const int * natural_order;
|
||||
|
||||
/* Process restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
process_restart(cinfo);
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
||||
|
||||
natural_order = cinfo->natural_order;
|
||||
|
||||
/* There is always only one block per MCU */
|
||||
block = MCU_data[0];
|
||||
tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
|
||||
|
||||
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
||||
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
|
||||
|
||||
/* Establish EOBx (previous stage end-of-block) index */
|
||||
for (kex = cinfo->Se; kex > 0; kex--)
|
||||
if ((*block)[natural_order[kex]]) break;
|
||||
|
||||
for (k = cinfo->Ss; k <= cinfo->Se; k++) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
if (k > kex)
|
||||
if (arith_decode(cinfo, st)) break; /* EOB flag */
|
||||
for (;;) {
|
||||
thiscoef = *block + natural_order[k];
|
||||
if (*thiscoef) { /* previously nonzero coef */
|
||||
if (arith_decode(cinfo, st + 2)) {
|
||||
if (*thiscoef < 0)
|
||||
*thiscoef += m1;
|
||||
else
|
||||
*thiscoef += p1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (arith_decode(cinfo, st + 1)) { /* newly nonzero coef */
|
||||
if (arith_decode(cinfo, entropy->fixed_bin))
|
||||
*thiscoef = m1;
|
||||
else
|
||||
*thiscoef = p1;
|
||||
break;
|
||||
}
|
||||
st += 3; k++;
|
||||
if (k > cinfo->Se) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* spectral overflow */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Decode one MCU's worth of arithmetic-compressed coefficients.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
jpeg_component_info * compptr;
|
||||
JBLOCKROW block;
|
||||
unsigned char *st;
|
||||
int blkn, ci, tbl, sign, k;
|
||||
int v, m;
|
||||
const int * natural_order;
|
||||
|
||||
/* Process restart marker if needed */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
process_restart(cinfo);
|
||||
entropy->restarts_to_go--;
|
||||
}
|
||||
|
||||
if (entropy->ct == -1) return TRUE; /* if error do nothing */
|
||||
|
||||
natural_order = cinfo->natural_order;
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
|
||||
/* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */
|
||||
|
||||
tbl = compptr->dc_tbl_no;
|
||||
|
||||
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
|
||||
st = entropy->dc_stats[tbl] + entropy->dc_context[ci];
|
||||
|
||||
/* Figure F.19: Decode_DC_DIFF */
|
||||
if (arith_decode(cinfo, st) == 0)
|
||||
entropy->dc_context[ci] = 0;
|
||||
else {
|
||||
/* Figure F.21: Decoding nonzero value v */
|
||||
/* Figure F.22: Decoding the sign of v */
|
||||
sign = arith_decode(cinfo, st + 1);
|
||||
st += 2; st += sign;
|
||||
/* Figure F.23: Decoding the magnitude category of v */
|
||||
if ((m = arith_decode(cinfo, st)) != 0) {
|
||||
st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */
|
||||
while (arith_decode(cinfo, st)) {
|
||||
if ((m <<= 1) == 0x8000) {
|
||||
WARNMS(cinfo, JWRN_ARITH_BAD_CODE);
|
||||
entropy->ct = -1; /* magnitude overflow */
|
||||
return TRUE;
|
||||
}
|
||||
st += 1;
|
||||
}
|
||||
}
|
||||
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
|
||||
if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1))
|
||||
entropy->dc_context[ci] = 0; /* zero diff category */
|
||||
else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1))
|
||||
entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */
|
||||
else
|
||||
entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */
|
||||
v = m;
|
||||
/* Figure F.24: Decoding the magnitude bit pattern of v */
|
||||
st += 14;
|
||||
while (m >>= 1)
|
||||
if (arith_decode(cinfo, st)) v |= m;
|
||||
v += 1; if (sign) v = -v;
|
||||
entropy->last_dc_val[ci] += v;
|
||||
}
|
||||
|
||||
(*block)[0] = (JCOEF) entropy->last_dc_val[ci];
|
||||
|
||||
/* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */
|
||||
|
||||
tbl = compptr->ac_tbl_no;
|
||||
|
||||
/* Figure F.20: Decode_AC_coefficients */
|
||||
for (k = 1; k <= cinfo->lim_Se; k++) {
|
||||
st = entropy->ac_stats[tbl] + 3 * (k - 1);
|
||||
if (arith_decode(cinfo, st)) break; /* EOB flag */
|
||||
while (arith_decode(cinfo, st + 1) == 0) {
|
||||
st += 3; k++;
|
||||
if (k > cinfo->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;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for an arithmetic-compressed scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass (j_decompress_ptr cinfo)
|
||||
{
|
||||
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
|
||||
int ci, tbl;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Validate progressive scan parameters */
|
||||
if (cinfo->Ss == 0) {
|
||||
if (cinfo->Se != 0)
|
||||
goto bad;
|
||||
} else {
|
||||
/* need not check Ss/Se < 0 since they came from unsigned bytes */
|
||||
if (cinfo->Se < cinfo->Ss || cinfo->Se > cinfo->lim_Se)
|
||||
goto bad;
|
||||
/* AC scans may have only one component */
|
||||
if (cinfo->comps_in_scan != 1)
|
||||
goto bad;
|
||||
}
|
||||
if (cinfo->Ah != 0) {
|
||||
/* Successive approximation refinement scan: must have Al = Ah-1. */
|
||||
if (cinfo->Ah-1 != cinfo->Al)
|
||||
goto bad;
|
||||
}
|
||||
if (cinfo->Al > 13) { /* need not check for < 0 */
|
||||
bad:
|
||||
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
|
||||
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
|
||||
}
|
||||
/* Update progression status, and verify that scan order is legal.
|
||||
* Note that inter-scan inconsistencies are treated as warnings
|
||||
* not fatal errors ... not clear if this is right way to behave.
|
||||
*/
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
int coefi, cindex = cinfo->cur_comp_info[ci]->component_index;
|
||||
int *coef_bit_ptr = & cinfo->coef_bits[cindex][0];
|
||||
if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
|
||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
|
||||
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
|
||||
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
|
||||
if (cinfo->Ah != expected)
|
||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
|
||||
coef_bit_ptr[coefi] = cinfo->Al;
|
||||
}
|
||||
}
|
||||
/* Select MCU decoding routine */
|
||||
if (cinfo->Ah == 0) {
|
||||
if (cinfo->Ss == 0)
|
||||
entropy->pub.decode_mcu = decode_mcu_DC_first;
|
||||
else
|
||||
entropy->pub.decode_mcu = decode_mcu_AC_first;
|
||||
} else {
|
||||
if (cinfo->Ss == 0)
|
||||
entropy->pub.decode_mcu = decode_mcu_DC_refine;
|
||||
else
|
||||
entropy->pub.decode_mcu = decode_mcu_AC_refine;
|
||||
}
|
||||
} else {
|
||||
/* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
|
||||
* This ought to be an error condition, but we make it a warning.
|
||||
*/
|
||||
if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 ||
|
||||
(cinfo->Se < DCTSIZE2 && cinfo->Se != cinfo->lim_Se))
|
||||
WARNMS(cinfo, JWRN_NOT_SEQUENTIAL);
|
||||
/* Select MCU decoding routine */
|
||||
entropy->pub.decode_mcu = decode_mcu;
|
||||
}
|
||||
|
||||
/* Allocate & initialize requested statistics areas */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
|
||||
tbl = compptr->dc_tbl_no;
|
||||
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
|
||||
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
|
||||
if (entropy->dc_stats[tbl] == NULL)
|
||||
entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS);
|
||||
MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS);
|
||||
/* Initialize DC predictions to 0 */
|
||||
entropy->last_dc_val[ci] = 0;
|
||||
entropy->dc_context[ci] = 0;
|
||||
}
|
||||
if ((! cinfo->progressive_mode && cinfo->lim_Se) ||
|
||||
(cinfo->progressive_mode && cinfo->Ss)) {
|
||||
tbl = compptr->ac_tbl_no;
|
||||
if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
|
||||
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
|
||||
if (entropy->ac_stats[tbl] == NULL)
|
||||
entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
|
||||
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize arithmetic decoding variables */
|
||||
entropy->c = 0;
|
||||
entropy->a = 0;
|
||||
entropy->ct = -16; /* force reading 2 initial bytes to fill C */
|
||||
|
||||
/* Initialize restart counter */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for arithmetic entropy decoding.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_arith_decoder (j_decompress_ptr cinfo)
|
||||
{
|
||||
arith_entropy_ptr entropy;
|
||||
int i;
|
||||
|
||||
entropy = (arith_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(arith_entropy_decoder));
|
||||
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
|
||||
entropy->pub.start_pass = start_pass;
|
||||
|
||||
/* Mark tables unallocated */
|
||||
for (i = 0; i < NUM_ARITH_TBLS; i++) {
|
||||
entropy->dc_stats[i] = NULL;
|
||||
entropy->ac_stats[i] = NULL;
|
||||
}
|
||||
|
||||
/* Initialize index for fixed probability estimation */
|
||||
entropy->fixed_bin[0] = 113;
|
||||
|
||||
if (cinfo->progressive_mode) {
|
||||
/* Create progression status table */
|
||||
int *coef_bit_ptr, ci;
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2])
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components*DCTSIZE2*SIZEOF(int));
|
||||
coef_bit_ptr = & cinfo->coef_bits[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (i = 0; i < DCTSIZE2; i++)
|
||||
*coef_bit_ptr++ = -1;
|
||||
}
|
||||
}
|
||||
122
jdatadst.c
122
jdatadst.c
@@ -2,13 +2,14 @@
|
||||
* jdatadst.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains compression data destination routines for the case of
|
||||
* emitting JPEG data to a file (or any stdio stream). While these routines
|
||||
* are sufficient for most applications, some will want to use a different
|
||||
* destination manager.
|
||||
* emitting JPEG data to memory or to a file (or any stdio stream).
|
||||
* While these routines are sufficient for most applications,
|
||||
* some will want to use a different destination manager.
|
||||
* IMPORTANT: we assume that fwrite() will correctly transcribe an array of
|
||||
* JOCTETs into 8-bit-wide elements on external storage. If char is wider
|
||||
* than 8 bits on your machine, you may need to do some tweaking.
|
||||
@@ -19,6 +20,11 @@
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
#endif
|
||||
|
||||
|
||||
/* Expanded data destination object for stdio output */
|
||||
|
||||
@@ -34,6 +40,21 @@ typedef my_destination_mgr * my_dest_ptr;
|
||||
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
|
||||
|
||||
|
||||
/* Expanded data destination object for memory output */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_destination_mgr pub; /* public fields */
|
||||
|
||||
unsigned char ** outbuffer; /* target buffer */
|
||||
unsigned long * outsize;
|
||||
unsigned char * newbuffer; /* newly allocated buffer */
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
size_t bufsize;
|
||||
} my_mem_destination_mgr;
|
||||
|
||||
typedef my_mem_destination_mgr * my_mem_dest_ptr;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize destination --- called by jpeg_start_compress
|
||||
* before any data is actually written.
|
||||
@@ -53,6 +74,12 @@ init_destination (j_compress_ptr cinfo)
|
||||
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
init_mem_destination (j_compress_ptr cinfo)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty the output buffer --- called whenever buffer fills up.
|
||||
@@ -92,6 +119,36 @@ empty_output_buffer (j_compress_ptr cinfo)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHODDEF(boolean)
|
||||
empty_mem_output_buffer (j_compress_ptr cinfo)
|
||||
{
|
||||
size_t nextsize;
|
||||
JOCTET * nextbuffer;
|
||||
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
|
||||
|
||||
/* Try to allocate new buffer with double size */
|
||||
nextsize = dest->bufsize * 2;
|
||||
nextbuffer = malloc(nextsize);
|
||||
|
||||
if (nextbuffer == NULL)
|
||||
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
|
||||
|
||||
MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
|
||||
|
||||
if (dest->newbuffer != NULL)
|
||||
free(dest->newbuffer);
|
||||
|
||||
dest->newbuffer = nextbuffer;
|
||||
|
||||
dest->pub.next_output_byte = nextbuffer + dest->bufsize;
|
||||
dest->pub.free_in_buffer = dest->bufsize;
|
||||
|
||||
dest->buffer = nextbuffer;
|
||||
dest->bufsize = nextsize;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Terminate destination --- called by jpeg_finish_compress
|
||||
@@ -119,6 +176,15 @@ term_destination (j_compress_ptr cinfo)
|
||||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
term_mem_destination (j_compress_ptr cinfo)
|
||||
{
|
||||
my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
|
||||
|
||||
*dest->outbuffer = dest->buffer;
|
||||
*dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for output to a stdio stream.
|
||||
@@ -149,3 +215,53 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
|
||||
dest->pub.term_destination = term_destination;
|
||||
dest->outfile = outfile;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for output to a memory buffer.
|
||||
* The caller may supply an own initial buffer with appropriate size.
|
||||
* Otherwise, or when the actual data output exceeds the given size,
|
||||
* the library adapts the buffer size as necessary.
|
||||
* The standard library functions malloc/free are used for allocating
|
||||
* larger memory, so the buffer is available to the application after
|
||||
* finishing compression, and then the application is responsible for
|
||||
* freeing the requested memory.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_dest (j_compress_ptr cinfo,
|
||||
unsigned char ** outbuffer, unsigned long * outsize)
|
||||
{
|
||||
my_mem_dest_ptr dest;
|
||||
|
||||
if (outbuffer == NULL || outsize == NULL) /* sanity check */
|
||||
ERREXIT(cinfo, JERR_BUFFER_SIZE);
|
||||
|
||||
/* The destination object is made permanent so that multiple JPEG images
|
||||
* can be written to the same buffer without re-executing jpeg_mem_dest.
|
||||
*/
|
||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_mem_destination_mgr));
|
||||
}
|
||||
|
||||
dest = (my_mem_dest_ptr) cinfo->dest;
|
||||
dest->pub.init_destination = init_mem_destination;
|
||||
dest->pub.empty_output_buffer = empty_mem_output_buffer;
|
||||
dest->pub.term_destination = term_mem_destination;
|
||||
dest->outbuffer = outbuffer;
|
||||
dest->outsize = outsize;
|
||||
dest->newbuffer = NULL;
|
||||
|
||||
if (*outbuffer == NULL || *outsize == 0) {
|
||||
/* Allocate initial buffer */
|
||||
dest->newbuffer = *outbuffer = malloc(OUTPUT_BUF_SIZE);
|
||||
if (dest->newbuffer == NULL)
|
||||
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
|
||||
*outsize = OUTPUT_BUF_SIZE;
|
||||
}
|
||||
|
||||
dest->pub.next_output_byte = dest->buffer = *outbuffer;
|
||||
dest->pub.free_in_buffer = dest->bufsize = *outsize;
|
||||
}
|
||||
|
||||
80
jdatasrc.c
80
jdatasrc.c
@@ -2,13 +2,14 @@
|
||||
* jdatasrc.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2009-2010 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains decompression data source routines for the case of
|
||||
* reading JPEG data from a file (or any stdio stream). While these routines
|
||||
* are sufficient for most applications, some will want to use a different
|
||||
* source manager.
|
||||
* reading JPEG data from memory or from a file (or any stdio stream).
|
||||
* While these routines are sufficient for most applications,
|
||||
* some will want to use a different source manager.
|
||||
* IMPORTANT: we assume that fread() will correctly transcribe an array of
|
||||
* JOCTETs from 8-bit-wide elements on external storage. If char is wider
|
||||
* than 8 bits on your machine, you may need to do some tweaking.
|
||||
@@ -52,6 +53,12 @@ init_source (j_decompress_ptr cinfo)
|
||||
src->start_of_file = TRUE;
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
init_mem_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
/* no work necessary here */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill the input buffer --- called whenever buffer is emptied.
|
||||
@@ -111,6 +118,26 @@ fill_input_buffer (j_decompress_ptr cinfo)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHODDEF(boolean)
|
||||
fill_mem_input_buffer (j_decompress_ptr cinfo)
|
||||
{
|
||||
static JOCTET mybuffer[4];
|
||||
|
||||
/* 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 */
|
||||
mybuffer[0] = (JOCTET) 0xFF;
|
||||
mybuffer[1] = (JOCTET) JPEG_EOI;
|
||||
|
||||
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
|
||||
@@ -127,22 +154,22 @@ fill_input_buffer (j_decompress_ptr cinfo)
|
||||
METHODDEF(void)
|
||||
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
struct jpeg_source_mgr * src = cinfo->src;
|
||||
|
||||
/* Just a dumb implementation for now. Could use fseek() except
|
||||
* it doesn't work on pipes. Not clear that being smart is worth
|
||||
* any trouble anyway --- large skips are infrequent.
|
||||
*/
|
||||
if (num_bytes > 0) {
|
||||
while (num_bytes > (long) src->pub.bytes_in_buffer) {
|
||||
num_bytes -= (long) src->pub.bytes_in_buffer;
|
||||
(void) fill_input_buffer(cinfo);
|
||||
while (num_bytes > (long) src->bytes_in_buffer) {
|
||||
num_bytes -= (long) src->bytes_in_buffer;
|
||||
(void) (*src->fill_input_buffer) (cinfo);
|
||||
/* note we assume that fill_input_buffer will never return FALSE,
|
||||
* so suspension need not be handled.
|
||||
*/
|
||||
}
|
||||
src->pub.next_input_byte += (size_t) num_bytes;
|
||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
||||
src->next_input_byte += (size_t) num_bytes;
|
||||
src->bytes_in_buffer -= (size_t) num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,3 +237,38 @@ jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
|
||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for input from a supplied memory buffer.
|
||||
* The buffer must contain the whole JPEG data.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_src (j_decompress_ptr cinfo,
|
||||
unsigned char * inbuffer, unsigned long insize)
|
||||
{
|
||||
struct jpeg_source_mgr * src;
|
||||
|
||||
if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
|
||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
||||
|
||||
/* The source object is made permanent so that a series of JPEG images
|
||||
* can be read from the same buffer by calling jpeg_mem_src only before
|
||||
* the first one.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(struct jpeg_source_mgr));
|
||||
}
|
||||
|
||||
src = cinfo->src;
|
||||
src->init_source = init_mem_source;
|
||||
src->fill_input_buffer = fill_mem_input_buffer;
|
||||
src->skip_input_data = skip_input_data;
|
||||
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
||||
src->term_source = term_source;
|
||||
src->bytes_in_buffer = (size_t) insize;
|
||||
src->next_input_byte = (JOCTET *) inbuffer;
|
||||
}
|
||||
|
||||
27
jdcoefct.c
27
jdcoefct.c
@@ -47,9 +47,6 @@ typedef struct {
|
||||
*/
|
||||
JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
|
||||
|
||||
/* Temporary workspace for one MCU */
|
||||
JCOEF * workspace;
|
||||
|
||||
#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];
|
||||
@@ -190,7 +187,7 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
|
||||
: compptr->last_col_width;
|
||||
output_ptr = output_buf[compptr->component_index] +
|
||||
yoffset * compptr->DCT_scaled_size;
|
||||
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 ||
|
||||
@@ -200,11 +197,11 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
(*inverse_DCT) (cinfo, compptr,
|
||||
(JCOEFPTR) coef->MCU_buffer[blkn+xindex],
|
||||
output_ptr, output_col);
|
||||
output_col += compptr->DCT_scaled_size;
|
||||
output_col += compptr->DCT_h_scaled_size;
|
||||
}
|
||||
}
|
||||
blkn += compptr->MCU_width;
|
||||
output_ptr += compptr->DCT_scaled_size;
|
||||
output_ptr += compptr->DCT_v_scaled_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,9 +362,9 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
|
||||
output_ptr, output_col);
|
||||
buffer_ptr++;
|
||||
output_col += compptr->DCT_scaled_size;
|
||||
output_col += compptr->DCT_h_scaled_size;
|
||||
}
|
||||
output_ptr += compptr->DCT_scaled_size;
|
||||
output_ptr += compptr->DCT_v_scaled_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,16 +471,13 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
jpeg_component_info *compptr;
|
||||
inverse_DCT_method_ptr inverse_DCT;
|
||||
boolean first_row, last_row;
|
||||
JCOEF * workspace;
|
||||
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;
|
||||
|
||||
/* Keep a local variable to avoid looking it up more than once */
|
||||
workspace = coef->workspace;
|
||||
|
||||
/* 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) {
|
||||
@@ -660,9 +654,9 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
|
||||
DC4 = DC5; DC5 = DC6;
|
||||
DC7 = DC8; DC8 = DC9;
|
||||
buffer_ptr++, prev_block_row++, next_block_row++;
|
||||
output_col += compptr->DCT_scaled_size;
|
||||
output_col += compptr->DCT_h_scaled_size;
|
||||
}
|
||||
output_ptr += compptr->DCT_scaled_size;
|
||||
output_ptr += compptr->DCT_v_scaled_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,9 +733,4 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
coef->pub.decompress_data = decompress_onepass;
|
||||
coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
|
||||
}
|
||||
|
||||
/* Allocate the workspace buffer */
|
||||
coef->workspace = (JCOEF *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(JCOEF) * DCTSIZE2);
|
||||
}
|
||||
|
||||
41
jdcolor.c
41
jdcolor.c
@@ -2,8 +2,6 @@
|
||||
* jdcolor.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2009, D. R. Commander.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -13,7 +11,6 @@
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
|
||||
|
||||
/* Private subobject */
|
||||
@@ -149,12 +146,12 @@ ycc_rgb_convert (j_decompress_ptr cinfo,
|
||||
cb = GETJSAMPLE(inptr1[col]);
|
||||
cr = GETJSAMPLE(inptr2[col]);
|
||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||
outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + Crrtab[cr]];
|
||||
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y +
|
||||
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[cinfo->out_color_space]] = range_limit[y + Cbbtab[cb]];
|
||||
outptr += rgb_pixelsize[cinfo->out_color_space];
|
||||
outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,21 +219,16 @@ gray_rgb_convert (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY output_buf, int num_rows)
|
||||
{
|
||||
register JSAMPROW inptr, outptr;
|
||||
JSAMPLE *maxinptr;
|
||||
register JDIMENSION col;
|
||||
JDIMENSION num_cols = cinfo->output_width;
|
||||
int rindex = rgb_red[cinfo->out_color_space];
|
||||
int gindex = rgb_green[cinfo->out_color_space];
|
||||
int bindex = rgb_blue[cinfo->out_color_space];
|
||||
int rgbstride = rgb_pixelsize[cinfo->out_color_space];
|
||||
|
||||
while (--num_rows >= 0) {
|
||||
inptr = input_buf[0][input_row++];
|
||||
maxinptr = &inptr[num_cols];
|
||||
outptr = *output_buf++;
|
||||
for (; inptr < maxinptr; inptr++, outptr += rgbstride) {
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
/* We can dispense with GETJSAMPLE() here */
|
||||
outptr[rindex] = outptr[gindex] = outptr[bindex] = *inptr;
|
||||
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
||||
outptr += RGB_PIXELSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,24 +356,13 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
case JCS_EXT_RGB:
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_BGR:
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_XRGB:
|
||||
cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
|
||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
||||
if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
if (jsimd_can_ycc_rgb())
|
||||
cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
|
||||
else {
|
||||
cconvert->pub.color_convert = ycc_rgb_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
}
|
||||
cconvert->pub.color_convert = ycc_rgb_convert;
|
||||
build_ycc_rgb_table(cinfo);
|
||||
} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
|
||||
cconvert->pub.color_convert = gray_rgb_convert;
|
||||
} else if (cinfo->jpeg_color_space == cinfo->out_color_space &&
|
||||
rgb_pixelsize[cinfo->out_color_space] == 3) {
|
||||
} else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
|
||||
cconvert->pub.color_convert = null_convert;
|
||||
} else
|
||||
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
||||
|
||||
251
jdct.h
251
jdct.h
@@ -14,35 +14,36 @@
|
||||
|
||||
|
||||
/*
|
||||
* A forward DCT routine is given a pointer to a work area of type DCTELEM[];
|
||||
* the DCT is to be performed in-place in that buffer. Type DCTELEM is int
|
||||
* for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT
|
||||
* implementations use an array of type FAST_FLOAT, instead.)
|
||||
* The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
|
||||
* A forward DCT routine is given a pointer to an input sample array and
|
||||
* a pointer to a work area of type DCTELEM[]; the DCT is to be performed
|
||||
* in-place in that buffer. Type DCTELEM is int for 8-bit samples, INT32
|
||||
* for 12-bit samples. (NOTE: Floating-point DCT implementations use an
|
||||
* array of type FAST_FLOAT, instead.)
|
||||
* The input data is to be fetched from the sample array starting at a
|
||||
* specified column. (Any row offset needed will be applied to the array
|
||||
* pointer before it is passed to the FDCT code.)
|
||||
* Note that the number of samples fetched by the FDCT routine is
|
||||
* DCT_h_scaled_size * DCT_v_scaled_size.
|
||||
* The DCT outputs are returned scaled up by a factor of 8; they therefore
|
||||
* have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
|
||||
* convention improves accuracy in integer implementations and saves some
|
||||
* work in floating-point ones.
|
||||
* Quantization of the output coefficients is done by jcdctmgr.c. This
|
||||
* step requires an unsigned type and also one with twice the bits.
|
||||
* Quantization of the output coefficients is done by jcdctmgr.c.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#ifndef WITH_SIMD
|
||||
typedef int DCTELEM; /* 16 or 32 bits is fine */
|
||||
typedef unsigned int UDCTELEM;
|
||||
typedef unsigned long long UDCTELEM2;
|
||||
#else
|
||||
typedef short DCTELEM; /* prefer 16 bit with SIMD for parellelism */
|
||||
typedef unsigned short UDCTELEM;
|
||||
typedef unsigned int UDCTELEM2;
|
||||
#endif
|
||||
#else
|
||||
typedef INT32 DCTELEM; /* must have 32 bits */
|
||||
typedef UINT32 UDCTELEM;
|
||||
typedef unsigned long long UDCTELEM2;
|
||||
#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
|
||||
@@ -52,7 +53,7 @@ typedef unsigned long long UDCTELEM2;
|
||||
* sample array starting at a specified column. (Any row offset needed will
|
||||
* be applied to the array pointer before it is passed to the IDCT code.)
|
||||
* Note that the number of samples emitted by the IDCT routine is
|
||||
* DCT_scaled_size * DCT_scaled_size.
|
||||
* DCT_h_scaled_size * DCT_v_scaled_size.
|
||||
*/
|
||||
|
||||
/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
|
||||
@@ -92,19 +93,143 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
|
||||
#define jpeg_fdct_islow jFDislow
|
||||
#define jpeg_fdct_ifast jFDifast
|
||||
#define jpeg_fdct_float jFDfloat
|
||||
#define jpeg_fdct_7x7 jFD7x7
|
||||
#define jpeg_fdct_6x6 jFD6x6
|
||||
#define jpeg_fdct_5x5 jFD5x5
|
||||
#define jpeg_fdct_4x4 jFD4x4
|
||||
#define jpeg_fdct_3x3 jFD3x3
|
||||
#define jpeg_fdct_2x2 jFD2x2
|
||||
#define jpeg_fdct_1x1 jFD1x1
|
||||
#define jpeg_fdct_9x9 jFD9x9
|
||||
#define jpeg_fdct_10x10 jFD10x10
|
||||
#define jpeg_fdct_11x11 jFD11x11
|
||||
#define jpeg_fdct_12x12 jFD12x12
|
||||
#define jpeg_fdct_13x13 jFD13x13
|
||||
#define jpeg_fdct_14x14 jFD14x14
|
||||
#define jpeg_fdct_15x15 jFD15x15
|
||||
#define jpeg_fdct_16x16 jFD16x16
|
||||
#define jpeg_fdct_16x8 jFD16x8
|
||||
#define jpeg_fdct_14x7 jFD14x7
|
||||
#define jpeg_fdct_12x6 jFD12x6
|
||||
#define jpeg_fdct_10x5 jFD10x5
|
||||
#define jpeg_fdct_8x4 jFD8x4
|
||||
#define jpeg_fdct_6x3 jFD6x3
|
||||
#define jpeg_fdct_4x2 jFD4x2
|
||||
#define jpeg_fdct_2x1 jFD2x1
|
||||
#define jpeg_fdct_8x16 jFD8x16
|
||||
#define jpeg_fdct_7x14 jFD7x14
|
||||
#define jpeg_fdct_6x12 jFD6x12
|
||||
#define jpeg_fdct_5x10 jFD5x10
|
||||
#define jpeg_fdct_4x8 jFD4x8
|
||||
#define jpeg_fdct_3x6 jFD3x6
|
||||
#define jpeg_fdct_2x4 jFD2x4
|
||||
#define jpeg_fdct_1x2 jFD1x2
|
||||
#define jpeg_idct_islow jRDislow
|
||||
#define jpeg_idct_ifast jRDifast
|
||||
#define jpeg_idct_float jRDfloat
|
||||
#define jpeg_idct_7x7 jRD7x7
|
||||
#define jpeg_idct_6x6 jRD6x6
|
||||
#define jpeg_idct_5x5 jRD5x5
|
||||
#define jpeg_idct_4x4 jRD4x4
|
||||
#define jpeg_idct_3x3 jRD3x3
|
||||
#define jpeg_idct_2x2 jRD2x2
|
||||
#define jpeg_idct_1x1 jRD1x1
|
||||
#define jpeg_idct_9x9 jRD9x9
|
||||
#define jpeg_idct_10x10 jRD10x10
|
||||
#define jpeg_idct_11x11 jRD11x11
|
||||
#define jpeg_idct_12x12 jRD12x12
|
||||
#define jpeg_idct_13x13 jRD13x13
|
||||
#define jpeg_idct_14x14 jRD14x14
|
||||
#define jpeg_idct_15x15 jRD15x15
|
||||
#define jpeg_idct_16x16 jRD16x16
|
||||
#define jpeg_idct_16x8 jRD16x8
|
||||
#define jpeg_idct_14x7 jRD14x7
|
||||
#define jpeg_idct_12x6 jRD12x6
|
||||
#define jpeg_idct_10x5 jRD10x5
|
||||
#define jpeg_idct_8x4 jRD8x4
|
||||
#define jpeg_idct_6x3 jRD6x3
|
||||
#define jpeg_idct_4x2 jRD4x2
|
||||
#define jpeg_idct_2x1 jRD2x1
|
||||
#define jpeg_idct_8x16 jRD8x16
|
||||
#define jpeg_idct_7x14 jRD7x14
|
||||
#define jpeg_idct_6x12 jRD6x12
|
||||
#define jpeg_idct_5x10 jRD5x10
|
||||
#define jpeg_idct_4x8 jRD4x8
|
||||
#define jpeg_idct_3x6 jRD3x8
|
||||
#define jpeg_idct_2x4 jRD2x4
|
||||
#define jpeg_idct_1x2 jRD1x2
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
/* Extern declarations for the forward and inverse DCT routines. */
|
||||
|
||||
EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
|
||||
EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
|
||||
EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
|
||||
EXTERN(void) jpeg_fdct_islow
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_ifast
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_float
|
||||
JPP((FAST_FLOAT * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_7x7
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_6x6
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_5x5
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_4x4
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_3x3
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_2x2
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_1x1
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_9x9
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_10x10
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_11x11
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_12x12
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_13x13
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_14x14
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_15x15
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_16x16
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_16x8
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_14x7
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_12x6
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_10x5
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_8x4
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_6x3
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_4x2
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_2x1
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_8x16
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_7x14
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_6x12
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_5x10
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_4x8
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_3x6
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_2x4
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
EXTERN(void) jpeg_fdct_1x2
|
||||
JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col));
|
||||
|
||||
EXTERN(void) jpeg_idct_islow
|
||||
JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
@@ -115,15 +240,99 @@ EXTERN(void) jpeg_idct_ifast
|
||||
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));
|
||||
|
||||
|
||||
/*
|
||||
|
||||
162
jddctmgr.c
162
jddctmgr.c
@@ -2,7 +2,7 @@
|
||||
* jddctmgr.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Modified 2002-2010 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
#include "jsimddct.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -100,53 +99,150 @@ start_pass (j_decompress_ptr cinfo)
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Select the proper IDCT routine for this component's scaling */
|
||||
switch (compptr->DCT_scaled_size) {
|
||||
switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) {
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
case 1:
|
||||
case ((1 << 8) + 1):
|
||||
method_ptr = jpeg_idct_1x1;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 2:
|
||||
if (jsimd_can_idct_2x2())
|
||||
method_ptr = jsimd_idct_2x2;
|
||||
else
|
||||
method_ptr = jpeg_idct_2x2;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
case ((2 << 8) + 2):
|
||||
method_ptr = jpeg_idct_2x2;
|
||||
method = JDCT_ISLOW; /* jidctint uses islow-style table */
|
||||
break;
|
||||
case 4:
|
||||
if (jsimd_can_idct_4x4())
|
||||
method_ptr = jsimd_idct_4x4;
|
||||
else
|
||||
method_ptr = jpeg_idct_4x4;
|
||||
method = JDCT_ISLOW; /* jidctred uses islow-style table */
|
||||
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:
|
||||
case ((DCTSIZE << 8) + DCTSIZE):
|
||||
switch (cinfo->dct_method) {
|
||||
#ifdef DCT_ISLOW_SUPPORTED
|
||||
case JDCT_ISLOW:
|
||||
if (jsimd_can_idct_islow())
|
||||
method_ptr = jsimd_idct_islow;
|
||||
else
|
||||
method_ptr = jpeg_idct_islow;
|
||||
method_ptr = jpeg_idct_islow;
|
||||
method = JDCT_ISLOW;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
if (jsimd_can_idct_ifast())
|
||||
method_ptr = jsimd_idct_ifast;
|
||||
else
|
||||
method_ptr = jpeg_idct_ifast;
|
||||
method_ptr = jpeg_idct_ifast;
|
||||
method = JDCT_IFAST;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
if (jsimd_can_idct_float())
|
||||
method_ptr = jsimd_idct_float;
|
||||
else
|
||||
method_ptr = jpeg_idct_float;
|
||||
method_ptr = jpeg_idct_float;
|
||||
method = JDCT_FLOAT;
|
||||
break;
|
||||
#endif
|
||||
@@ -156,7 +252,8 @@ start_pass (j_decompress_ptr cinfo)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
|
||||
ERREXIT2(cinfo, JERR_BAD_DCTSIZE,
|
||||
compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size);
|
||||
break;
|
||||
}
|
||||
idct->pub.inverse_DCT[ci] = method_ptr;
|
||||
@@ -228,6 +325,7 @@ start_pass (j_decompress_ptr cinfo)
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 1/8.
|
||||
*/
|
||||
FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
|
||||
int row, col;
|
||||
@@ -241,7 +339,7 @@ start_pass (j_decompress_ptr cinfo)
|
||||
for (col = 0; col < DCTSIZE; col++) {
|
||||
fmtbl[i] = (FLOAT_MULT_TYPE)
|
||||
((double) qtbl->quantval[i] *
|
||||
aanscalefactor[row] * aanscalefactor[col]);
|
||||
aanscalefactor[row] * aanscalefactor[col] * 0.125);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
213
jdhuff.h
213
jdhuff.h
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* jdhuff.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains declarations for Huffman entropy decoding routines
|
||||
* that are shared between the sequential decoder (jdhuff.c) and the
|
||||
* progressive decoder (jdphuff.c). No other modules need to see these.
|
||||
*/
|
||||
|
||||
/* Short forms of external names for systems with brain-damaged linkers. */
|
||||
|
||||
#ifdef NEED_SHORT_EXTERNAL_NAMES
|
||||
#define jpeg_make_d_derived_tbl jMkDDerived
|
||||
#define jpeg_fill_bit_buffer jFilBitBuf
|
||||
#define jpeg_huff_decode jHufDecode
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
/* Derived data constructed for each Huffman table */
|
||||
|
||||
#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
|
||||
|
||||
typedef struct {
|
||||
/* Basic tables: (element [0] of each array is unused) */
|
||||
INT32 maxcode[18]; /* largest code of length k (-1 if none) */
|
||||
/* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
|
||||
INT32 valoffset[17]; /* huffval[] offset for codes of length k */
|
||||
/* valoffset[k] = huffval[] index of 1st symbol of code length k, less
|
||||
* the smallest code of length k; so given a code of length k, the
|
||||
* corresponding symbol is huffval[code + valoffset[k]]
|
||||
*/
|
||||
|
||||
/* Link to public Huffman table (needed only in jpeg_huff_decode) */
|
||||
JHUFF_TBL *pub;
|
||||
|
||||
/* Lookahead table: indexed by the next HUFF_LOOKAHEAD bits of
|
||||
* the input data stream. If the next Huffman code is no more
|
||||
* than HUFF_LOOKAHEAD bits long, we can obtain its length and
|
||||
* the corresponding symbol directly from this tables.
|
||||
*
|
||||
* The lower 8 bits of each table entry contain the number of
|
||||
* bits in the corresponding Huffman code, or HUFF_LOOKAHEAD + 1
|
||||
* if too long. The next 8 bits of each entry contain the
|
||||
* symbol.
|
||||
*/
|
||||
int lookup[1<<HUFF_LOOKAHEAD];
|
||||
} d_derived_tbl;
|
||||
|
||||
/* Expand a Huffman table definition into the derived format */
|
||||
EXTERN(void) jpeg_make_d_derived_tbl
|
||||
JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
|
||||
d_derived_tbl ** pdtbl));
|
||||
|
||||
|
||||
/*
|
||||
* Fetching the next N bits from the input stream is a time-critical operation
|
||||
* for the Huffman decoders. We implement it with a combination of inline
|
||||
* macros and out-of-line subroutines. Note that N (the number of bits
|
||||
* demanded at one time) never exceeds 15 for JPEG use.
|
||||
*
|
||||
* We read source bytes into get_buffer and dole out bits as needed.
|
||||
* If get_buffer already contains enough bits, they are fetched in-line
|
||||
* by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough
|
||||
* bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
|
||||
* as full as possible (not just to the number of bits needed; this
|
||||
* prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
|
||||
* Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
|
||||
* On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer contains
|
||||
* at least the requested number of bits --- dummy zeroes are inserted if
|
||||
* necessary.
|
||||
*/
|
||||
|
||||
#if __WORDSIZE == 64 || defined(_WIN64)
|
||||
|
||||
typedef size_t bit_buf_type; /* type of bit-extraction buffer */
|
||||
#define BIT_BUF_SIZE 64 /* size of buffer in bits */
|
||||
|
||||
#else
|
||||
|
||||
typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
|
||||
#define BIT_BUF_SIZE 32 /* size of buffer in bits */
|
||||
|
||||
#endif
|
||||
|
||||
/* If long is > 32 bits on your machine, and shifting/masking longs is
|
||||
* reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
|
||||
* appropriately should be a win. Unfortunately we can't define the size
|
||||
* with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
|
||||
* because not all machines measure sizeof in 8-bit bytes.
|
||||
*/
|
||||
|
||||
typedef struct { /* Bitreading state saved across MCUs */
|
||||
bit_buf_type get_buffer; /* current bit-extraction buffer */
|
||||
int bits_left; /* # of unused bits in it */
|
||||
} bitread_perm_state;
|
||||
|
||||
typedef struct { /* Bitreading working state within an MCU */
|
||||
/* Current data source location */
|
||||
/* We need a copy, rather than munging the original, in case of suspension */
|
||||
const JOCTET * next_input_byte; /* => next byte to read from source */
|
||||
size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
|
||||
/* Bit input buffer --- note these values are kept in register variables,
|
||||
* not in this struct, inside the inner loops.
|
||||
*/
|
||||
bit_buf_type get_buffer; /* current bit-extraction buffer */
|
||||
int bits_left; /* # of unused bits in it */
|
||||
/* Pointer needed by jpeg_fill_bit_buffer. */
|
||||
j_decompress_ptr cinfo; /* back link to decompress master record */
|
||||
} bitread_working_state;
|
||||
|
||||
/* Macros to declare and load/save bitread local variables. */
|
||||
#define BITREAD_STATE_VARS \
|
||||
register bit_buf_type get_buffer; \
|
||||
register int bits_left; \
|
||||
bitread_working_state br_state
|
||||
|
||||
#define BITREAD_LOAD_STATE(cinfop,permstate) \
|
||||
br_state.cinfo = cinfop; \
|
||||
br_state.next_input_byte = cinfop->src->next_input_byte; \
|
||||
br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
|
||||
get_buffer = permstate.get_buffer; \
|
||||
bits_left = permstate.bits_left;
|
||||
|
||||
#define BITREAD_SAVE_STATE(cinfop,permstate) \
|
||||
cinfop->src->next_input_byte = br_state.next_input_byte; \
|
||||
cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
|
||||
permstate.get_buffer = get_buffer; \
|
||||
permstate.bits_left = bits_left
|
||||
|
||||
/*
|
||||
* These macros provide the in-line portion of bit fetching.
|
||||
* Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
|
||||
* before using GET_BITS, PEEK_BITS, or DROP_BITS.
|
||||
* The variables get_buffer and bits_left are assumed to be locals,
|
||||
* but the state struct might not be (jpeg_huff_decode needs this).
|
||||
* CHECK_BIT_BUFFER(state,n,action);
|
||||
* Ensure there are N bits in get_buffer; if suspend, take action.
|
||||
* val = GET_BITS(n);
|
||||
* Fetch next N bits.
|
||||
* val = PEEK_BITS(n);
|
||||
* Fetch next N bits without removing them from the buffer.
|
||||
* DROP_BITS(n);
|
||||
* Discard next N bits.
|
||||
* The value N should be a simple variable, not an expression, because it
|
||||
* is evaluated multiple times.
|
||||
*/
|
||||
|
||||
#define CHECK_BIT_BUFFER(state,nbits,action) \
|
||||
{ if (bits_left < (nbits)) { \
|
||||
if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \
|
||||
{ action; } \
|
||||
get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
|
||||
|
||||
#define GET_BITS(nbits) \
|
||||
(((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
|
||||
|
||||
#define PEEK_BITS(nbits) \
|
||||
(((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1))
|
||||
|
||||
#define DROP_BITS(nbits) \
|
||||
(bits_left -= (nbits))
|
||||
|
||||
/* Load up the bit buffer to a depth of at least nbits */
|
||||
EXTERN(boolean) jpeg_fill_bit_buffer
|
||||
JPP((bitread_working_state * state, register bit_buf_type get_buffer,
|
||||
register int bits_left, int nbits));
|
||||
|
||||
|
||||
/*
|
||||
* Code for extracting next Huffman-coded symbol from input bit stream.
|
||||
* Again, this is time-critical and we make the main paths be macros.
|
||||
*
|
||||
* We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
|
||||
* without looping. Usually, more than 95% of the Huffman codes will be 8
|
||||
* or fewer bits long. The few overlength codes are handled with a loop,
|
||||
* which need not be inline code.
|
||||
*
|
||||
* Notes about the HUFF_DECODE macro:
|
||||
* 1. Near the end of the data segment, we may fail to get enough bits
|
||||
* for a lookahead. In that case, we do it the hard way.
|
||||
* 2. If the lookahead table contains no entry, the next code must be
|
||||
* more than HUFF_LOOKAHEAD bits long.
|
||||
* 3. jpeg_huff_decode returns -1 if forced to suspend.
|
||||
*/
|
||||
|
||||
#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
|
||||
{ register int nb, look; \
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
if (bits_left < HUFF_LOOKAHEAD) { \
|
||||
nb = 1; goto slowlabel; \
|
||||
} \
|
||||
} \
|
||||
look = PEEK_BITS(HUFF_LOOKAHEAD); \
|
||||
if ((nb = (htbl->lookup[look] >> HUFF_LOOKAHEAD)) <= HUFF_LOOKAHEAD) { \
|
||||
DROP_BITS(nb); \
|
||||
result = htbl->lookup[look] & ((1 << HUFF_LOOKAHEAD) - 1); \
|
||||
} else { \
|
||||
slowlabel: \
|
||||
if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
|
||||
{ failaction; } \
|
||||
get_buffer = state.get_buffer; bits_left = state.bits_left; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Out-of-line case for Huffman code fetching */
|
||||
EXTERN(int) jpeg_huff_decode
|
||||
JPP((bitread_working_state * state, register bit_buf_type get_buffer,
|
||||
register int bits_left, d_derived_tbl * htbl, int min_bits));
|
||||
376
jdinput.c
376
jdinput.c
@@ -2,13 +2,14 @@
|
||||
* jdinput.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 2002-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains input control logic for the JPEG decompressor.
|
||||
* These routines are concerned with controlling the decompressor's input
|
||||
* processing (marker reading and coefficient decoding). The actual input
|
||||
* reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
|
||||
* reading is done in jdmarker.c, jdhuff.c, and jdarith.c.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
@@ -21,7 +22,7 @@
|
||||
typedef struct {
|
||||
struct jpeg_input_controller pub; /* public fields */
|
||||
|
||||
boolean inheaders; /* TRUE until first SOS is reached */
|
||||
int inheaders; /* Nonzero until first SOS is reached */
|
||||
} my_input_controller;
|
||||
|
||||
typedef my_input_controller * my_inputctl_ptr;
|
||||
@@ -35,6 +36,174 @@ METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
|
||||
* Routines to calculate various quantities related to the size of the image.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Compute output image dimensions and related values.
|
||||
* NOTE: this is exported for possible use by application.
|
||||
* Hence it mustn't do anything that can't be done twice.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_core_output_dimensions (j_decompress_ptr cinfo)
|
||||
/* Do computations that are needed before master selection phase.
|
||||
* This function is used for transcoding and full decompression.
|
||||
*/
|
||||
{
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
/* Compute actual output image dimensions and DCT scaling choices. */
|
||||
if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom) {
|
||||
/* Provide 1/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 1;
|
||||
cinfo->min_DCT_v_scaled_size = 1;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 2) {
|
||||
/* Provide 2/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 2L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 2L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 2;
|
||||
cinfo->min_DCT_v_scaled_size = 2;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 3) {
|
||||
/* Provide 3/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 3L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 3L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 3;
|
||||
cinfo->min_DCT_v_scaled_size = 3;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 4) {
|
||||
/* Provide 4/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 4L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 4L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 4;
|
||||
cinfo->min_DCT_v_scaled_size = 4;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 5) {
|
||||
/* Provide 5/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 5L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 5L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 5;
|
||||
cinfo->min_DCT_v_scaled_size = 5;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 6) {
|
||||
/* Provide 6/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 6L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 6L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 6;
|
||||
cinfo->min_DCT_v_scaled_size = 6;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 7) {
|
||||
/* Provide 7/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 7L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 7L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 7;
|
||||
cinfo->min_DCT_v_scaled_size = 7;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 8) {
|
||||
/* Provide 8/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 8L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 8L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 8;
|
||||
cinfo->min_DCT_v_scaled_size = 8;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 9) {
|
||||
/* Provide 9/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 9L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 9L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 9;
|
||||
cinfo->min_DCT_v_scaled_size = 9;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 10) {
|
||||
/* Provide 10/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 10L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 10L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 10;
|
||||
cinfo->min_DCT_v_scaled_size = 10;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 11) {
|
||||
/* Provide 11/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 11L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 11L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 11;
|
||||
cinfo->min_DCT_v_scaled_size = 11;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 12) {
|
||||
/* Provide 12/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 12L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 12L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 12;
|
||||
cinfo->min_DCT_v_scaled_size = 12;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 13) {
|
||||
/* Provide 13/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 13L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 13L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 13;
|
||||
cinfo->min_DCT_v_scaled_size = 13;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 14) {
|
||||
/* Provide 14/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 14L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 14L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 14;
|
||||
cinfo->min_DCT_v_scaled_size = 14;
|
||||
} else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 15) {
|
||||
/* Provide 15/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 15L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 15L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 15;
|
||||
cinfo->min_DCT_v_scaled_size = 15;
|
||||
} else {
|
||||
/* Provide 16/block_size scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width * 16L, (long) cinfo->block_size);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * 16L, (long) cinfo->block_size);
|
||||
cinfo->min_DCT_h_scaled_size = 16;
|
||||
cinfo->min_DCT_v_scaled_size = 16;
|
||||
}
|
||||
|
||||
/* Recompute dimensions of components */
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size;
|
||||
compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size;
|
||||
}
|
||||
|
||||
#else /* !IDCT_SCALING_SUPPORTED */
|
||||
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->output_width = cinfo->image_width;
|
||||
cinfo->output_height = cinfo->image_height;
|
||||
/* jdinput.c has already initialized DCT_scaled_size,
|
||||
* and has computed unscaled downsampled_width and downsampled_height.
|
||||
*/
|
||||
|
||||
#endif /* IDCT_SCALING_SUPPORTED */
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
initial_setup (j_decompress_ptr cinfo)
|
||||
/* Called once, when first SOS marker is reached */
|
||||
@@ -70,23 +239,121 @@ initial_setup (j_decompress_ptr cinfo)
|
||||
compptr->v_samp_factor);
|
||||
}
|
||||
|
||||
/* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
|
||||
* In the full decompressor, this will be overridden by jdmaster.c;
|
||||
* but in the transcoder, jdmaster.c is not used, so we must do it here.
|
||||
/* 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_scaled_size = DCTSIZE;
|
||||
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_scaled_size = DCTSIZE;
|
||||
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 * DCTSIZE));
|
||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
||||
compptr->height_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
|
||||
(long) (cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(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.
|
||||
@@ -107,7 +374,7 @@ initial_setup (j_decompress_ptr cinfo)
|
||||
/* Compute number of fully interleaved MCU rows. */
|
||||
cinfo->total_iMCU_rows = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
(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)
|
||||
@@ -138,7 +405,7 @@ per_scan_setup (j_decompress_ptr cinfo)
|
||||
compptr->MCU_width = 1;
|
||||
compptr->MCU_height = 1;
|
||||
compptr->MCU_blocks = 1;
|
||||
compptr->MCU_sample_width = compptr->DCT_scaled_size;
|
||||
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.
|
||||
@@ -161,10 +428,10 @@ per_scan_setup (j_decompress_ptr cinfo)
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width,
|
||||
(long) (cinfo->max_h_samp_factor*DCTSIZE));
|
||||
(long) (cinfo->max_h_samp_factor * cinfo->block_size));
|
||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
||||
|
||||
cinfo->blocks_in_MCU = 0;
|
||||
|
||||
@@ -174,7 +441,7 @@ per_scan_setup (j_decompress_ptr cinfo)
|
||||
compptr->MCU_width = compptr->h_samp_factor;
|
||||
compptr->MCU_height = compptr->v_samp_factor;
|
||||
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
|
||||
compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
|
||||
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;
|
||||
@@ -282,6 +549,10 @@ finish_input_pass (j_decompress_ptr cinfo)
|
||||
* 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)
|
||||
@@ -293,41 +564,50 @@ consume_markers (j_decompress_ptr cinfo)
|
||||
if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
|
||||
return JPEG_REACHED_EOI;
|
||||
|
||||
val = (*cinfo->marker->read_markers) (cinfo);
|
||||
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 */
|
||||
initial_setup(cinfo);
|
||||
inputctl->inheaders = FALSE;
|
||||
/* Note: start_input_pass must be called by jdmaster.c
|
||||
* before any more input can be consumed. jdapimin.c is
|
||||
* responsible for enforcing this sequencing.
|
||||
*/
|
||||
} else { /* 2nd or later SOS marker */
|
||||
if (! inputctl->pub.has_multiple_scans)
|
||||
ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
|
||||
start_input_pass(cinfo);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case JPEG_REACHED_EOI: /* Found EOI */
|
||||
inputctl->pub.eoi_reached = TRUE;
|
||||
if (inputctl->inheaders) { /* Tables-only datastream, apparently */
|
||||
if (cinfo->marker->saw_SOF)
|
||||
ERREXIT(cinfo, JERR_SOF_NO_SOS);
|
||||
} else {
|
||||
/* Prevent infinite loop in coef ctlr's decompress_data routine
|
||||
* if user set output_scan_number larger than number of scans.
|
||||
*/
|
||||
if (cinfo->output_scan_number > cinfo->input_scan_number)
|
||||
cinfo->output_scan_number = cinfo->input_scan_number;
|
||||
}
|
||||
break;
|
||||
case JPEG_SUSPENDED:
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
@@ -343,7 +623,7 @@ reset_input_controller (j_decompress_ptr cinfo)
|
||||
inputctl->pub.consume_input = consume_markers;
|
||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
||||
inputctl->pub.eoi_reached = FALSE;
|
||||
inputctl->inheaders = TRUE;
|
||||
inputctl->inheaders = 1;
|
||||
/* Reset other modules */
|
||||
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
|
||||
(*cinfo->marker->reset_marker_reader) (cinfo);
|
||||
@@ -377,5 +657,5 @@ jinit_input_controller (j_decompress_ptr cinfo)
|
||||
*/
|
||||
inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
|
||||
inputctl->pub.eoi_reached = FALSE;
|
||||
inputctl->inheaders = TRUE;
|
||||
inputctl->inheaders = 1;
|
||||
}
|
||||
|
||||
42
jdmainct.c
42
jdmainct.c
@@ -161,7 +161,7 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_main_ptr main = (my_main_ptr) cinfo->main;
|
||||
int ci, rgroup;
|
||||
int M = cinfo->min_DCT_scaled_size;
|
||||
int M = cinfo->min_DCT_v_scaled_size;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY xbuf;
|
||||
|
||||
@@ -175,8 +175,8 @@ alloc_funny_pointers (j_decompress_ptr cinfo)
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size; /* height of a row group of component */
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
||||
/* Get space for pointer lists --- M+4 row groups in each list.
|
||||
* We alloc both pointer lists with one call to save a few cycles.
|
||||
*/
|
||||
@@ -202,14 +202,14 @@ make_funny_pointers (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_main_ptr main = (my_main_ptr) cinfo->main;
|
||||
int ci, i, rgroup;
|
||||
int M = cinfo->min_DCT_scaled_size;
|
||||
int M = cinfo->min_DCT_v_scaled_size;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY buf, xbuf0, xbuf1;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size; /* height of a row group of component */
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
||||
xbuf0 = main->xbuffer[0][ci];
|
||||
xbuf1 = main->xbuffer[1][ci];
|
||||
/* First copy the workspace pointers as-is */
|
||||
@@ -242,14 +242,14 @@ set_wraparound_pointers (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_main_ptr main = (my_main_ptr) cinfo->main;
|
||||
int ci, i, rgroup;
|
||||
int M = cinfo->min_DCT_scaled_size;
|
||||
int M = cinfo->min_DCT_v_scaled_size;
|
||||
jpeg_component_info *compptr;
|
||||
JSAMPARRAY xbuf0, xbuf1;
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size; /* height of a row group of component */
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
||||
xbuf0 = main->xbuffer[0][ci];
|
||||
xbuf1 = main->xbuffer[1][ci];
|
||||
for (i = 0; i < rgroup; i++) {
|
||||
@@ -277,8 +277,8 @@ set_bottom_pointers (j_decompress_ptr cinfo)
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
/* Count sample rows in one iMCU row and in one row group */
|
||||
iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
|
||||
rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
|
||||
iMCUheight = compptr->v_samp_factor * compptr->DCT_v_scaled_size;
|
||||
rgroup = iMCUheight / cinfo->min_DCT_v_scaled_size;
|
||||
/* Count nondummy sample rows remaining for this component */
|
||||
rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
|
||||
if (rows_left == 0) rows_left = iMCUheight;
|
||||
@@ -357,7 +357,7 @@ process_data_simple_main (j_decompress_ptr cinfo,
|
||||
}
|
||||
|
||||
/* There are always min_DCT_scaled_size row groups in an iMCU row. */
|
||||
rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
|
||||
rowgroups_avail = (JDIMENSION) cinfo->min_DCT_v_scaled_size;
|
||||
/* Note: at the bottom of the image, we may pass extra garbage row groups
|
||||
* to the postprocessor. The postprocessor has to check for bottom
|
||||
* of image anyway (at row resolution), so no point in us doing it too.
|
||||
@@ -417,7 +417,7 @@ process_data_context_main (j_decompress_ptr cinfo,
|
||||
case CTX_PREPARE_FOR_IMCU:
|
||||
/* Prepare to process first M-1 row groups of this iMCU row */
|
||||
main->rowgroup_ctr = 0;
|
||||
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
|
||||
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1);
|
||||
/* Check for bottom of image: if so, tweak pointers to "duplicate"
|
||||
* the last sample row, and adjust rowgroups_avail to ignore padding rows.
|
||||
*/
|
||||
@@ -440,8 +440,8 @@ process_data_context_main (j_decompress_ptr cinfo,
|
||||
main->buffer_full = FALSE;
|
||||
/* Still need to process last row group of this iMCU row, */
|
||||
/* which is saved at index M+1 of the other xbuffer */
|
||||
main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
|
||||
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
|
||||
main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1);
|
||||
main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2);
|
||||
main->context_state = CTX_POSTPONED_ROW;
|
||||
}
|
||||
}
|
||||
@@ -492,21 +492,21 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
|
||||
* ngroups is the number of row groups we need.
|
||||
*/
|
||||
if (cinfo->upsample->need_context_rows) {
|
||||
if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
|
||||
if (cinfo->min_DCT_v_scaled_size < 2) /* unsupported, see comments above */
|
||||
ERREXIT(cinfo, JERR_NOTIMPL);
|
||||
alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
|
||||
ngroups = cinfo->min_DCT_scaled_size + 2;
|
||||
ngroups = cinfo->min_DCT_v_scaled_size + 2;
|
||||
} else {
|
||||
ngroups = cinfo->min_DCT_scaled_size;
|
||||
ngroups = cinfo->min_DCT_v_scaled_size;
|
||||
}
|
||||
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size; /* height of a row group of component */
|
||||
rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
||||
cinfo->min_DCT_v_scaled_size; /* height of a row group of component */
|
||||
main->buffer[ci] = (*cinfo->mem->alloc_sarray)
|
||||
((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
compptr->width_in_blocks * compptr->DCT_scaled_size,
|
||||
compptr->width_in_blocks * compptr->DCT_h_scaled_size,
|
||||
(JDIMENSION) (rgroup * ngroups));
|
||||
}
|
||||
}
|
||||
|
||||
74
jdmarker.c
74
jdmarker.c
@@ -2,6 +2,7 @@
|
||||
* jdmarker.c
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Modified 2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -234,7 +235,8 @@ get_soi (j_decompress_ptr cinfo)
|
||||
|
||||
|
||||
LOCAL(boolean)
|
||||
get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
|
||||
get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog,
|
||||
boolean is_arith)
|
||||
/* Process a SOFn marker */
|
||||
{
|
||||
INT32 length;
|
||||
@@ -242,6 +244,7 @@ get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
|
||||
jpeg_component_info * compptr;
|
||||
INPUT_VARS(cinfo);
|
||||
|
||||
cinfo->is_baseline = is_baseline;
|
||||
cinfo->progressive_mode = is_prog;
|
||||
cinfo->arith_code = is_arith;
|
||||
|
||||
@@ -315,7 +318,9 @@ get_sos (j_decompress_ptr cinfo)
|
||||
|
||||
TRACEMS1(cinfo, 1, JTRC_SOS, n);
|
||||
|
||||
if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
|
||||
if (length != (n * 2 + 6) || n > MAX_COMPS_IN_SCAN ||
|
||||
(n == 0 && !cinfo->progressive_mode))
|
||||
/* pseudo SOS marker only allowed in progressive mode */
|
||||
ERREXIT(cinfo, JERR_BAD_LENGTH);
|
||||
|
||||
cinfo->comps_in_scan = n;
|
||||
@@ -359,8 +364,8 @@ get_sos (j_decompress_ptr cinfo)
|
||||
/* Prepare to scan data & restart markers */
|
||||
cinfo->marker->next_restart_num = 0;
|
||||
|
||||
/* Count another SOS marker */
|
||||
cinfo->input_scan_number++;
|
||||
/* Count another (non-pseudo) SOS marker */
|
||||
if (n) cinfo->input_scan_number++;
|
||||
|
||||
INPUT_SYNC(cinfo);
|
||||
return TRUE;
|
||||
@@ -490,16 +495,18 @@ LOCAL(boolean)
|
||||
get_dqt (j_decompress_ptr cinfo)
|
||||
/* Process a DQT marker */
|
||||
{
|
||||
INT32 length;
|
||||
int n, i, prec;
|
||||
INT32 length, count, i;
|
||||
int n, prec;
|
||||
unsigned int tmp;
|
||||
JQUANT_TBL *quant_ptr;
|
||||
const int *natural_order;
|
||||
INPUT_VARS(cinfo);
|
||||
|
||||
INPUT_2BYTES(cinfo, length, return FALSE);
|
||||
length -= 2;
|
||||
|
||||
while (length > 0) {
|
||||
length--;
|
||||
INPUT_BYTE(cinfo, n, return FALSE);
|
||||
prec = n >> 4;
|
||||
n &= 0x0F;
|
||||
@@ -513,13 +520,43 @@ get_dqt (j_decompress_ptr cinfo)
|
||||
cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
|
||||
quant_ptr = cinfo->quant_tbl_ptrs[n];
|
||||
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if (prec) {
|
||||
if (length < DCTSIZE2 * 2) {
|
||||
/* Initialize full table for safety. */
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
quant_ptr->quantval[i] = 1;
|
||||
}
|
||||
count = length >> 1;
|
||||
} else
|
||||
count = DCTSIZE2;
|
||||
} else {
|
||||
if (length < DCTSIZE2) {
|
||||
/* Initialize full table for safety. */
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
quant_ptr->quantval[i] = 1;
|
||||
}
|
||||
count = length;
|
||||
} else
|
||||
count = DCTSIZE2;
|
||||
}
|
||||
|
||||
switch (count) {
|
||||
case (2*2): natural_order = jpeg_natural_order2; break;
|
||||
case (3*3): natural_order = jpeg_natural_order3; break;
|
||||
case (4*4): natural_order = jpeg_natural_order4; break;
|
||||
case (5*5): natural_order = jpeg_natural_order5; break;
|
||||
case (6*6): natural_order = jpeg_natural_order6; break;
|
||||
case (7*7): natural_order = jpeg_natural_order7; break;
|
||||
default: natural_order = jpeg_natural_order; break;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (prec)
|
||||
INPUT_2BYTES(cinfo, tmp, return FALSE);
|
||||
else
|
||||
INPUT_BYTE(cinfo, tmp, return FALSE);
|
||||
/* We convert the zigzag-order table to natural array order. */
|
||||
quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
|
||||
quant_ptr->quantval[natural_order[i]] = (UINT16) tmp;
|
||||
}
|
||||
|
||||
if (cinfo->err->trace_level >= 2) {
|
||||
@@ -532,8 +569,8 @@ get_dqt (j_decompress_ptr cinfo)
|
||||
}
|
||||
}
|
||||
|
||||
length -= DCTSIZE2+1;
|
||||
if (prec) length -= DCTSIZE2;
|
||||
length -= count;
|
||||
if (prec) length -= count;
|
||||
}
|
||||
|
||||
if (length != 0)
|
||||
@@ -946,6 +983,11 @@ first_marker (j_decompress_ptr cinfo)
|
||||
*
|
||||
* Returns same codes as are defined for jpeg_consume_input:
|
||||
* JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
|
||||
*
|
||||
* Note: This function may return a pseudo SOS marker (with zero
|
||||
* component number) for treat by input controller's consume_input.
|
||||
* consume_input itself should filter out (skip) the pseudo marker
|
||||
* after processing for the caller.
|
||||
*/
|
||||
|
||||
METHODDEF(int)
|
||||
@@ -975,23 +1017,27 @@ read_markers (j_decompress_ptr cinfo)
|
||||
break;
|
||||
|
||||
case M_SOF0: /* Baseline */
|
||||
if (! get_sof(cinfo, TRUE, FALSE, FALSE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF1: /* Extended sequential, Huffman */
|
||||
if (! get_sof(cinfo, FALSE, FALSE))
|
||||
if (! get_sof(cinfo, FALSE, FALSE, FALSE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF2: /* Progressive, Huffman */
|
||||
if (! get_sof(cinfo, TRUE, FALSE))
|
||||
if (! get_sof(cinfo, FALSE, TRUE, FALSE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF9: /* Extended sequential, arithmetic */
|
||||
if (! get_sof(cinfo, FALSE, TRUE))
|
||||
if (! get_sof(cinfo, FALSE, FALSE, TRUE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
case M_SOF10: /* Progressive, arithmetic */
|
||||
if (! get_sof(cinfo, TRUE, TRUE))
|
||||
if (! get_sof(cinfo, FALSE, TRUE, TRUE))
|
||||
return JPEG_SUSPENDED;
|
||||
break;
|
||||
|
||||
|
||||
125
jdmaster.c
125
jdmaster.c
@@ -2,7 +2,7 @@
|
||||
* jdmaster.c
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Copyright (C) 2009, D. R. Commander.
|
||||
* Modified 2002-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -50,14 +50,8 @@ use_merged_upsample (j_decompress_ptr cinfo)
|
||||
return FALSE;
|
||||
/* jdmerge.c only supports YCC=>RGB color conversion */
|
||||
if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
|
||||
(cinfo->out_color_space != JCS_RGB &&
|
||||
cinfo->out_color_space != JCS_EXT_RGB &&
|
||||
cinfo->out_color_space != JCS_EXT_RGBX &&
|
||||
cinfo->out_color_space != JCS_EXT_BGR &&
|
||||
cinfo->out_color_space != JCS_EXT_BGRX &&
|
||||
cinfo->out_color_space != JCS_EXT_XBGR &&
|
||||
cinfo->out_color_space != JCS_EXT_XRGB) ||
|
||||
cinfo->out_color_components != rgb_pixelsize[cinfo->out_color_space])
|
||||
cinfo->out_color_space != JCS_RGB ||
|
||||
cinfo->out_color_components != RGB_PIXELSIZE)
|
||||
return FALSE;
|
||||
/* and it only handles 2h1v or 2h2v sampling ratios */
|
||||
if (cinfo->comp_info[0].h_samp_factor != 2 ||
|
||||
@@ -68,9 +62,12 @@ use_merged_upsample (j_decompress_ptr cinfo)
|
||||
cinfo->comp_info[2].v_samp_factor != 1)
|
||||
return FALSE;
|
||||
/* furthermore, it doesn't work if we've scaled the IDCTs differently */
|
||||
if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
|
||||
cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
|
||||
cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
|
||||
if (cinfo->comp_info[0].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
|
||||
cinfo->comp_info[1].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
|
||||
cinfo->comp_info[2].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size ||
|
||||
cinfo->comp_info[0].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size ||
|
||||
cinfo->comp_info[1].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size ||
|
||||
cinfo->comp_info[2].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size)
|
||||
return FALSE;
|
||||
/* ??? also need to test for upsample-time rescaling, when & if supported */
|
||||
return TRUE; /* by golly, it'll work... */
|
||||
@@ -89,7 +86,9 @@ use_merged_upsample (j_decompress_ptr cinfo)
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
/* Do computations that are needed before master selection phase */
|
||||
/* Do computations that are needed before master selection phase.
|
||||
* This function is used for full decompression.
|
||||
*/
|
||||
{
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
int ci;
|
||||
@@ -100,52 +99,38 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
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
|
||||
|
||||
/* Compute actual output image dimensions and DCT scaling choices. */
|
||||
if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
|
||||
/* Provide 1/8 scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width, 8L);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height, 8L);
|
||||
cinfo->min_DCT_scaled_size = 1;
|
||||
} else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
|
||||
/* Provide 1/4 scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width, 4L);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height, 4L);
|
||||
cinfo->min_DCT_scaled_size = 2;
|
||||
} else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
|
||||
/* Provide 1/2 scaling */
|
||||
cinfo->output_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width, 2L);
|
||||
cinfo->output_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_height, 2L);
|
||||
cinfo->min_DCT_scaled_size = 4;
|
||||
} else {
|
||||
/* Provide 1/1 scaling */
|
||||
cinfo->output_width = cinfo->image_width;
|
||||
cinfo->output_height = cinfo->image_height;
|
||||
cinfo->min_DCT_scaled_size = DCTSIZE;
|
||||
}
|
||||
/* In selecting the actual DCT scaling for each component, we try to
|
||||
* scale up the chroma components via IDCT scaling rather than upsampling.
|
||||
* This saves time if the upsampler gets to use 1:1 scaling.
|
||||
* Note this code assumes that the supported DCT scalings are powers of 2.
|
||||
* Note this code adapts subsampling ratios which are powers of 2.
|
||||
*/
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
int ssize = cinfo->min_DCT_scaled_size;
|
||||
while (ssize < DCTSIZE &&
|
||||
(compptr->h_samp_factor * ssize * 2 <=
|
||||
cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
|
||||
(compptr->v_samp_factor * ssize * 2 <=
|
||||
cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
|
||||
int ssize = 1;
|
||||
while (cinfo->min_DCT_h_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
compptr->DCT_scaled_size = ssize;
|
||||
compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize;
|
||||
ssize = 1;
|
||||
while (cinfo->min_DCT_v_scaled_size * ssize <=
|
||||
(cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) &&
|
||||
(cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) {
|
||||
ssize = ssize * 2;
|
||||
}
|
||||
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;
|
||||
@@ -156,23 +141,14 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
/* Size in samples, after IDCT scaling */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->image_width *
|
||||
(long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
|
||||
(long) (cinfo->max_h_samp_factor * DCTSIZE));
|
||||
(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_scaled_size),
|
||||
(long) (cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size),
|
||||
(long) (cinfo->max_v_samp_factor * cinfo->block_size));
|
||||
}
|
||||
|
||||
#else /* !IDCT_SCALING_SUPPORTED */
|
||||
|
||||
/* Hardwire it to "no scaling" */
|
||||
cinfo->output_width = cinfo->image_width;
|
||||
cinfo->output_height = cinfo->image_height;
|
||||
/* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
|
||||
* and has computed unscaled downsampled_width and downsampled_height.
|
||||
*/
|
||||
|
||||
#endif /* IDCT_SCALING_SUPPORTED */
|
||||
|
||||
/* Report number of components in selected colorspace. */
|
||||
@@ -182,14 +158,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
|
||||
cinfo->out_color_components = 1;
|
||||
break;
|
||||
case JCS_RGB:
|
||||
case JCS_EXT_RGB:
|
||||
case JCS_EXT_RGBX:
|
||||
case JCS_EXT_BGR:
|
||||
case JCS_EXT_BGRX:
|
||||
case JCS_EXT_XBGR:
|
||||
case JCS_EXT_XRGB:
|
||||
cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
|
||||
#if RGB_PIXELSIZE != 3
|
||||
cinfo->out_color_components = RGB_PIXELSIZE;
|
||||
break;
|
||||
#endif /* else share code with YCbCr */
|
||||
case JCS_YCbCr:
|
||||
cinfo->out_color_components = 3;
|
||||
break;
|
||||
@@ -383,17 +355,10 @@ master_selection (j_decompress_ptr cinfo)
|
||||
/* Inverse DCT */
|
||||
jinit_inverse_dct(cinfo);
|
||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef D_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_decoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_decoder(cinfo);
|
||||
if (cinfo->arith_code)
|
||||
jinit_arith_decoder(cinfo);
|
||||
else {
|
||||
jinit_huff_decoder(cinfo);
|
||||
}
|
||||
|
||||
/* Initialize principal buffer controllers. */
|
||||
|
||||
71
jdmerge.c
71
jdmerge.c
@@ -2,8 +2,6 @@
|
||||
* jdmerge.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Copyright (C) 2009, D. R. Commander.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -37,7 +35,6 @@
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
|
||||
#ifdef UPSAMPLE_MERGING_SUPPORTED
|
||||
|
||||
@@ -258,15 +255,15 @@ h2v1_merged_upsample (j_decompress_ptr cinfo,
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 2 Y values and emit 2 pixels */
|
||||
y = GETJSAMPLE(*inptr0++);
|
||||
outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
outptr += rgb_pixelsize[cinfo->out_color_space];
|
||||
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[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
outptr += rgb_pixelsize[cinfo->out_color_space];
|
||||
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) {
|
||||
@@ -276,9 +273,9 @@ h2v1_merged_upsample (j_decompress_ptr cinfo,
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr0);
|
||||
outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
outptr[RGB_RED] = range_limit[y + cred];
|
||||
outptr[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr[RGB_BLUE] = range_limit[y + cblue];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,24 +319,24 @@ h2v2_merged_upsample (j_decompress_ptr cinfo,
|
||||
cblue = Cbbtab[cb];
|
||||
/* Fetch 4 Y values and emit 4 pixels */
|
||||
y = GETJSAMPLE(*inptr00++);
|
||||
outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
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[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
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[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
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[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
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 */
|
||||
@@ -350,13 +347,13 @@ h2v2_merged_upsample (j_decompress_ptr cinfo,
|
||||
cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
|
||||
cblue = Cbbtab[cb];
|
||||
y = GETJSAMPLE(*inptr00);
|
||||
outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
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[cinfo->out_color_space]] = range_limit[y + cred];
|
||||
outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
|
||||
outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
|
||||
outptr1[RGB_RED] = range_limit[y + cred];
|
||||
outptr1[RGB_GREEN] = range_limit[y + cgreen];
|
||||
outptr1[RGB_BLUE] = range_limit[y + cblue];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,20 +382,14 @@ jinit_merged_upsampler (j_decompress_ptr cinfo)
|
||||
|
||||
if (cinfo->max_v_samp_factor == 2) {
|
||||
upsample->pub.upsample = merged_2v_upsample;
|
||||
if (jsimd_can_h2v2_merged_upsample())
|
||||
upsample->upmethod = jsimd_h2v2_merged_upsample;
|
||||
else
|
||||
upsample->upmethod = h2v2_merged_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;
|
||||
if (jsimd_can_h2v1_merged_upsample())
|
||||
upsample->upmethod = jsimd_h2v1_merged_upsample;
|
||||
else
|
||||
upsample->upmethod = h2v1_merged_upsample;
|
||||
upsample->upmethod = h2v1_merged_upsample;
|
||||
/* No spare row needed */
|
||||
upsample->spare_row = NULL;
|
||||
}
|
||||
|
||||
668
jdphuff.c
668
jdphuff.c
@@ -1,668 +0,0 @@
|
||||
/*
|
||||
* jdphuff.c
|
||||
*
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains Huffman entropy decoding routines for progressive JPEG.
|
||||
*
|
||||
* Much of the complexity here has to do with supporting input suspension.
|
||||
* If the data source module demands suspension, we want to be able to back
|
||||
* up to the start of the current MCU. To do this, we copy state variables
|
||||
* into local working storage, and update them back to the permanent
|
||||
* storage only upon successful completion of an MCU.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdhuff.h" /* Declarations shared with jdhuff.c */
|
||||
|
||||
|
||||
#ifdef D_PROGRESSIVE_SUPPORTED
|
||||
|
||||
/*
|
||||
* Expanded entropy decoder object for progressive Huffman decoding.
|
||||
*
|
||||
* The savable_state subrecord contains fields that change within an MCU,
|
||||
* but must not be updated permanently until we complete the MCU.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned int EOBRUN; /* remaining EOBs in EOBRUN */
|
||||
int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
|
||||
} savable_state;
|
||||
|
||||
/* This macro is to work around compilers with missing or broken
|
||||
* structure assignment. You'll need to fix this code if you have
|
||||
* such a compiler and you change MAX_COMPS_IN_SCAN.
|
||||
*/
|
||||
|
||||
#ifndef NO_STRUCT_ASSIGN
|
||||
#define ASSIGN_STATE(dest,src) ((dest) = (src))
|
||||
#else
|
||||
#if MAX_COMPS_IN_SCAN == 4
|
||||
#define ASSIGN_STATE(dest,src) \
|
||||
((dest).EOBRUN = (src).EOBRUN, \
|
||||
(dest).last_dc_val[0] = (src).last_dc_val[0], \
|
||||
(dest).last_dc_val[1] = (src).last_dc_val[1], \
|
||||
(dest).last_dc_val[2] = (src).last_dc_val[2], \
|
||||
(dest).last_dc_val[3] = (src).last_dc_val[3])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_entropy_decoder pub; /* public fields */
|
||||
|
||||
/* These fields are loaded into local variables at start of each MCU.
|
||||
* In case of suspension, we exit WITHOUT updating them.
|
||||
*/
|
||||
bitread_perm_state bitstate; /* Bit buffer at start of MCU */
|
||||
savable_state saved; /* Other state at start of MCU */
|
||||
|
||||
/* These fields are NOT loaded into local working state. */
|
||||
unsigned int restarts_to_go; /* MCUs left in this restart interval */
|
||||
|
||||
/* Pointers to derived tables (these workspaces have image lifespan) */
|
||||
d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
|
||||
|
||||
d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
|
||||
} phuff_entropy_decoder;
|
||||
|
||||
typedef phuff_entropy_decoder * phuff_entropy_ptr;
|
||||
|
||||
/* Forward declarations */
|
||||
METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
|
||||
|
||||
/*
|
||||
* Initialize for a Huffman-compressed scan.
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
start_pass_phuff_decoder (j_decompress_ptr cinfo)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
boolean is_DC_band, bad;
|
||||
int ci, coefi, tbl;
|
||||
int *coef_bit_ptr;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
is_DC_band = (cinfo->Ss == 0);
|
||||
|
||||
/* Validate scan parameters */
|
||||
bad = FALSE;
|
||||
if (is_DC_band) {
|
||||
if (cinfo->Se != 0)
|
||||
bad = TRUE;
|
||||
} else {
|
||||
/* need not check Ss/Se < 0 since they came from unsigned bytes */
|
||||
if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
|
||||
bad = TRUE;
|
||||
/* AC scans may have only one component */
|
||||
if (cinfo->comps_in_scan != 1)
|
||||
bad = TRUE;
|
||||
}
|
||||
if (cinfo->Ah != 0) {
|
||||
/* Successive approximation refinement scan: must have Al = Ah-1. */
|
||||
if (cinfo->Al != cinfo->Ah-1)
|
||||
bad = TRUE;
|
||||
}
|
||||
if (cinfo->Al > 13) /* need not check for < 0 */
|
||||
bad = TRUE;
|
||||
/* Arguably the maximum Al value should be less than 13 for 8-bit precision,
|
||||
* but the spec doesn't say so, and we try to be liberal about what we
|
||||
* accept. Note: large Al values could result in out-of-range DC
|
||||
* coefficients during early scans, leading to bizarre displays due to
|
||||
* overflows in the IDCT math. But we won't crash.
|
||||
*/
|
||||
if (bad)
|
||||
ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
|
||||
cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
|
||||
/* Update progression status, and verify that scan order is legal.
|
||||
* Note that inter-scan inconsistencies are treated as warnings
|
||||
* not fatal errors ... not clear if this is right way to behave.
|
||||
*/
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
int cindex = cinfo->cur_comp_info[ci]->component_index;
|
||||
coef_bit_ptr = & cinfo->coef_bits[cindex][0];
|
||||
if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
|
||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
|
||||
for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
|
||||
int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
|
||||
if (cinfo->Ah != expected)
|
||||
WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
|
||||
coef_bit_ptr[coefi] = cinfo->Al;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select MCU decoding routine */
|
||||
if (cinfo->Ah == 0) {
|
||||
if (is_DC_band)
|
||||
entropy->pub.decode_mcu = decode_mcu_DC_first;
|
||||
else
|
||||
entropy->pub.decode_mcu = decode_mcu_AC_first;
|
||||
} else {
|
||||
if (is_DC_band)
|
||||
entropy->pub.decode_mcu = decode_mcu_DC_refine;
|
||||
else
|
||||
entropy->pub.decode_mcu = decode_mcu_AC_refine;
|
||||
}
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* Make sure requested tables are present, and compute derived tables.
|
||||
* We may build same derived table more than once, but it's not expensive.
|
||||
*/
|
||||
if (is_DC_band) {
|
||||
if (cinfo->Ah == 0) { /* DC refinement needs no table */
|
||||
tbl = compptr->dc_tbl_no;
|
||||
jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
|
||||
& entropy->derived_tbls[tbl]);
|
||||
}
|
||||
} else {
|
||||
tbl = compptr->ac_tbl_no;
|
||||
jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
|
||||
& entropy->derived_tbls[tbl]);
|
||||
/* remember the single active table */
|
||||
entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
|
||||
}
|
||||
/* Initialize DC predictions to 0 */
|
||||
entropy->saved.last_dc_val[ci] = 0;
|
||||
}
|
||||
|
||||
/* Initialize bitread state variables */
|
||||
entropy->bitstate.bits_left = 0;
|
||||
entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
|
||||
entropy->pub.insufficient_data = FALSE;
|
||||
|
||||
/* Initialize private state variables */
|
||||
entropy->saved.EOBRUN = 0;
|
||||
|
||||
/* Initialize restart counter */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Figure F.12: extend sign bit.
|
||||
* On some machines, a shift and add will be faster than a table lookup.
|
||||
*/
|
||||
|
||||
#ifdef AVOID_TABLES
|
||||
|
||||
#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
|
||||
|
||||
#else
|
||||
|
||||
#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
|
||||
|
||||
static const int extend_test[16] = /* entry n is 2**(n-1) */
|
||||
{ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
|
||||
0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
|
||||
|
||||
static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
|
||||
{ 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
|
||||
((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
|
||||
((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
|
||||
((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
|
||||
|
||||
#endif /* AVOID_TABLES */
|
||||
|
||||
|
||||
/*
|
||||
* Check for a restart marker & resynchronize decoder.
|
||||
* Returns FALSE if must suspend.
|
||||
*/
|
||||
|
||||
LOCAL(boolean)
|
||||
process_restart (j_decompress_ptr cinfo)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
int ci;
|
||||
|
||||
/* Throw away any unused bits remaining in bit buffer; */
|
||||
/* include any full bytes in next_marker's count of discarded bytes */
|
||||
cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
|
||||
entropy->bitstate.bits_left = 0;
|
||||
|
||||
/* Advance past the RSTn marker */
|
||||
if (! (*cinfo->marker->read_restart_marker) (cinfo))
|
||||
return FALSE;
|
||||
|
||||
/* Re-initialize DC predictions to 0 */
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++)
|
||||
entropy->saved.last_dc_val[ci] = 0;
|
||||
/* Re-init EOB run count, too */
|
||||
entropy->saved.EOBRUN = 0;
|
||||
|
||||
/* Reset restart counter */
|
||||
entropy->restarts_to_go = cinfo->restart_interval;
|
||||
|
||||
/* Reset out-of-data flag, unless read_restart_marker left us smack up
|
||||
* against a marker. In that case we will end up treating the next data
|
||||
* segment as empty, and we can avoid producing bogus output pixels by
|
||||
* leaving the flag set.
|
||||
*/
|
||||
if (cinfo->unread_marker == 0)
|
||||
entropy->pub.insufficient_data = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Huffman MCU decoding.
|
||||
* Each of these routines decodes and returns one MCU's worth of
|
||||
* Huffman-compressed coefficients.
|
||||
* The coefficients are reordered from zigzag order into natural array order,
|
||||
* but are not dequantized.
|
||||
*
|
||||
* The i'th block of the MCU is stored into the block pointed to by
|
||||
* MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
|
||||
*
|
||||
* We return FALSE if data source requested suspension. In that case no
|
||||
* changes have been made to permanent state. (Exception: some output
|
||||
* coefficients may already have been assigned. This is harmless for
|
||||
* spectral selection, since we'll just re-assign them on the next call.
|
||||
* Successive approximation AC refinement has to be more careful, however.)
|
||||
*/
|
||||
|
||||
/*
|
||||
* MCU decoding for DC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
int Al = cinfo->Al;
|
||||
register int s, r;
|
||||
int blkn, ci;
|
||||
JBLOCKROW block;
|
||||
BITREAD_STATE_VARS;
|
||||
savable_state state;
|
||||
d_derived_tbl * tbl;
|
||||
jpeg_component_info * compptr;
|
||||
|
||||
/* Process restart marker if needed; may have to suspend */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
if (! process_restart(cinfo))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we've run out of data, just leave the MCU set to zeroes.
|
||||
* This way, we return uniform gray for the remainder of the segment.
|
||||
*/
|
||||
if (! entropy->pub.insufficient_data) {
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
ASSIGN_STATE(state, entropy->saved);
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
ci = cinfo->MCU_membership[blkn];
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
tbl = entropy->derived_tbls[compptr->dc_tbl_no];
|
||||
|
||||
/* Decode a single block's worth of coefficients */
|
||||
|
||||
/* Section F.2.2.1: decode the DC coefficient difference */
|
||||
HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
|
||||
if (s) {
|
||||
CHECK_BIT_BUFFER(br_state, s, return FALSE);
|
||||
r = GET_BITS(s);
|
||||
s = HUFF_EXTEND(r, s);
|
||||
}
|
||||
|
||||
/* Convert DC difference to actual value, update last_dc_val */
|
||||
s += state.last_dc_val[ci];
|
||||
state.last_dc_val[ci] = s;
|
||||
/* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
|
||||
(*block)[0] = (JCOEF) (s << Al);
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
ASSIGN_STATE(entropy->saved, state);
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU decoding for AC initial scan (either spectral selection,
|
||||
* or first pass of successive approximation).
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
int Se = cinfo->Se;
|
||||
int Al = cinfo->Al;
|
||||
register int s, k, r;
|
||||
unsigned int EOBRUN;
|
||||
JBLOCKROW block;
|
||||
BITREAD_STATE_VARS;
|
||||
d_derived_tbl * tbl;
|
||||
|
||||
/* Process restart marker if needed; may have to suspend */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
if (! process_restart(cinfo))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we've run out of data, just leave the MCU set to zeroes.
|
||||
* This way, we return uniform gray for the remainder of the segment.
|
||||
*/
|
||||
if (! entropy->pub.insufficient_data) {
|
||||
|
||||
/* Load up working state.
|
||||
* We can avoid loading/saving bitread state if in an EOB run.
|
||||
*/
|
||||
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
|
||||
|
||||
/* There is always only one block per MCU */
|
||||
|
||||
if (EOBRUN > 0) /* if it's a band of zeroes... */
|
||||
EOBRUN--; /* ...process it now (we do nothing) */
|
||||
else {
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
block = MCU_data[0];
|
||||
tbl = entropy->ac_derived_tbl;
|
||||
|
||||
for (k = cinfo->Ss; k <= Se; k++) {
|
||||
HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
|
||||
r = s >> 4;
|
||||
s &= 15;
|
||||
if (s) {
|
||||
k += r;
|
||||
CHECK_BIT_BUFFER(br_state, s, return FALSE);
|
||||
r = GET_BITS(s);
|
||||
s = HUFF_EXTEND(r, s);
|
||||
/* Scale and output coefficient in natural (dezigzagged) order */
|
||||
(*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
|
||||
} else {
|
||||
if (r == 15) { /* ZRL */
|
||||
k += 15; /* skip 15 zeroes in band */
|
||||
} else { /* EOBr, run length is 2^r + appended bits */
|
||||
EOBRUN = 1 << r;
|
||||
if (r) { /* EOBr, r > 0 */
|
||||
CHECK_BIT_BUFFER(br_state, r, return FALSE);
|
||||
r = GET_BITS(r);
|
||||
EOBRUN += r;
|
||||
}
|
||||
EOBRUN--; /* this band is processed at this moment */
|
||||
break; /* force end-of-band */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU decoding for DC successive approximation refinement scan.
|
||||
* Note: we assume such scans can be multi-component, although the spec
|
||||
* is not very clear on the point.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
||||
int blkn;
|
||||
JBLOCKROW block;
|
||||
BITREAD_STATE_VARS;
|
||||
|
||||
/* Process restart marker if needed; may have to suspend */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
if (! process_restart(cinfo))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Not worth the cycles to check insufficient_data here,
|
||||
* since we will not change the data anyway if we read zeroes.
|
||||
*/
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
|
||||
/* Outer loop handles each block in the MCU */
|
||||
|
||||
for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
|
||||
block = MCU_data[blkn];
|
||||
|
||||
/* Encoded data is simply the next bit of the two's-complement DC value */
|
||||
CHECK_BIT_BUFFER(br_state, 1, return FALSE);
|
||||
if (GET_BITS(1))
|
||||
(*block)[0] |= p1;
|
||||
/* Note: since we use |=, repeating the assignment later is safe */
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MCU decoding for AC successive approximation refinement scan.
|
||||
*/
|
||||
|
||||
METHODDEF(boolean)
|
||||
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
|
||||
{
|
||||
phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
|
||||
int Se = cinfo->Se;
|
||||
int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
|
||||
int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
|
||||
register int s, k, r;
|
||||
unsigned int EOBRUN;
|
||||
JBLOCKROW block;
|
||||
JCOEFPTR thiscoef;
|
||||
BITREAD_STATE_VARS;
|
||||
d_derived_tbl * tbl;
|
||||
int num_newnz;
|
||||
int newnz_pos[DCTSIZE2];
|
||||
|
||||
/* Process restart marker if needed; may have to suspend */
|
||||
if (cinfo->restart_interval) {
|
||||
if (entropy->restarts_to_go == 0)
|
||||
if (! process_restart(cinfo))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we've run out of data, don't modify the MCU.
|
||||
*/
|
||||
if (! entropy->pub.insufficient_data) {
|
||||
|
||||
/* Load up working state */
|
||||
BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
|
||||
EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
|
||||
|
||||
/* There is always only one block per MCU */
|
||||
block = MCU_data[0];
|
||||
tbl = entropy->ac_derived_tbl;
|
||||
|
||||
/* If we are forced to suspend, we must undo the assignments to any newly
|
||||
* nonzero coefficients in the block, because otherwise we'd get confused
|
||||
* next time about which coefficients were already nonzero.
|
||||
* But we need not undo addition of bits to already-nonzero coefficients;
|
||||
* instead, we can test the current bit to see if we already did it.
|
||||
*/
|
||||
num_newnz = 0;
|
||||
|
||||
/* initialize coefficient loop counter to start of band */
|
||||
k = cinfo->Ss;
|
||||
|
||||
if (EOBRUN == 0) {
|
||||
for (; k <= Se; k++) {
|
||||
HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
|
||||
r = s >> 4;
|
||||
s &= 15;
|
||||
if (s) {
|
||||
if (s != 1) /* size of new coef should always be 1 */
|
||||
WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
|
||||
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
|
||||
if (GET_BITS(1))
|
||||
s = p1; /* newly nonzero coef is positive */
|
||||
else
|
||||
s = m1; /* newly nonzero coef is negative */
|
||||
} else {
|
||||
if (r != 15) {
|
||||
EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */
|
||||
if (r) {
|
||||
CHECK_BIT_BUFFER(br_state, r, goto undoit);
|
||||
r = GET_BITS(r);
|
||||
EOBRUN += r;
|
||||
}
|
||||
break; /* rest of block is handled by EOB logic */
|
||||
}
|
||||
/* note s = 0 for processing ZRL */
|
||||
}
|
||||
/* Advance over already-nonzero coefs and r still-zero coefs,
|
||||
* appending correction bits to the nonzeroes. A correction bit is 1
|
||||
* if the absolute value of the coefficient must be increased.
|
||||
*/
|
||||
do {
|
||||
thiscoef = *block + jpeg_natural_order[k];
|
||||
if (*thiscoef != 0) {
|
||||
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
|
||||
if (GET_BITS(1)) {
|
||||
if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
|
||||
if (*thiscoef >= 0)
|
||||
*thiscoef += p1;
|
||||
else
|
||||
*thiscoef += m1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (--r < 0)
|
||||
break; /* reached target zero coefficient */
|
||||
}
|
||||
k++;
|
||||
} while (k <= Se);
|
||||
if (s) {
|
||||
int pos = jpeg_natural_order[k];
|
||||
/* Output newly nonzero coefficient */
|
||||
(*block)[pos] = (JCOEF) s;
|
||||
/* Remember its position in case we have to suspend */
|
||||
newnz_pos[num_newnz++] = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EOBRUN > 0) {
|
||||
/* Scan any remaining coefficient positions after the end-of-band
|
||||
* (the last newly nonzero coefficient, if any). Append a correction
|
||||
* bit to each already-nonzero coefficient. A correction bit is 1
|
||||
* if the absolute value of the coefficient must be increased.
|
||||
*/
|
||||
for (; k <= Se; k++) {
|
||||
thiscoef = *block + jpeg_natural_order[k];
|
||||
if (*thiscoef != 0) {
|
||||
CHECK_BIT_BUFFER(br_state, 1, goto undoit);
|
||||
if (GET_BITS(1)) {
|
||||
if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
|
||||
if (*thiscoef >= 0)
|
||||
*thiscoef += p1;
|
||||
else
|
||||
*thiscoef += m1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Count one block completed in EOB run */
|
||||
EOBRUN--;
|
||||
}
|
||||
|
||||
/* Completed MCU, so update state */
|
||||
BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
|
||||
entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
|
||||
}
|
||||
|
||||
/* Account for restart interval (no-op if not using restarts) */
|
||||
entropy->restarts_to_go--;
|
||||
|
||||
return TRUE;
|
||||
|
||||
undoit:
|
||||
/* Re-zero any output coefficients that we made newly nonzero */
|
||||
while (num_newnz > 0)
|
||||
(*block)[newnz_pos[--num_newnz]] = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for progressive Huffman entropy decoding.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jinit_phuff_decoder (j_decompress_ptr cinfo)
|
||||
{
|
||||
phuff_entropy_ptr entropy;
|
||||
int *coef_bit_ptr;
|
||||
int ci, i;
|
||||
|
||||
entropy = (phuff_entropy_ptr)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
SIZEOF(phuff_entropy_decoder));
|
||||
cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
|
||||
entropy->pub.start_pass = start_pass_phuff_decoder;
|
||||
|
||||
/* Mark derived tables unallocated */
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
entropy->derived_tbls[i] = NULL;
|
||||
}
|
||||
|
||||
/* Create progression status table */
|
||||
cinfo->coef_bits = (int (*)[DCTSIZE2])
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
cinfo->num_components*DCTSIZE2*SIZEOF(int));
|
||||
coef_bit_ptr = & cinfo->coef_bits[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (i = 0; i < DCTSIZE2; i++)
|
||||
*coef_bit_ptr++ = -1;
|
||||
}
|
||||
|
||||
#endif /* D_PROGRESSIVE_SUPPORTED */
|
||||
163
jdsample.c
163
jdsample.c
@@ -2,14 +2,14 @@
|
||||
* jdsample.c
|
||||
*
|
||||
* Copyright (C) 1991-1996, Thomas G. Lane.
|
||||
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
||||
* Modified 2002-2008 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains upsampling routines.
|
||||
*
|
||||
* Upsampling input data is counted in "row groups". A row group
|
||||
* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
|
||||
* is defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size)
|
||||
* sample rows of each component. Upsampling will normally produce
|
||||
* max_v_samp_factor pixel rows from each row group (but this could vary
|
||||
* if the upsampler is applying a scale factor of its own).
|
||||
@@ -22,7 +22,6 @@
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jsimd.h"
|
||||
|
||||
|
||||
/* Pointer to routine to upsample a single component */
|
||||
@@ -239,11 +238,11 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
register JSAMPROW inptr, outptr;
|
||||
register JSAMPLE invalue;
|
||||
JSAMPROW outend;
|
||||
int inrow;
|
||||
int outrow;
|
||||
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
for (outrow = 0; outrow < cinfo->max_v_samp_factor; outrow++) {
|
||||
inptr = input_data[outrow];
|
||||
outptr = output_data[outrow];
|
||||
outend = outptr + cinfo->output_width;
|
||||
while (outptr < outend) {
|
||||
invalue = *inptr++; /* don't need GETJSAMPLE() here */
|
||||
@@ -287,112 +286,6 @@ h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
|
||||
*
|
||||
* The upsampling algorithm is linear interpolation between pixel centers,
|
||||
* also known as a "triangle filter". This is a good compromise between
|
||||
* speed and visual quality. The centers of the output pixels are 1/4 and 3/4
|
||||
* of the way between input pixel centers.
|
||||
*
|
||||
* A note about the "bias" calculations: when rounding fractional values to
|
||||
* integer, we do not want to always round 0.5 up to the next integer.
|
||||
* If we did that, we'd introduce a noticeable bias towards larger values.
|
||||
* Instead, this code is arranged so that 0.5 will be rounded up or down at
|
||||
* alternate pixel locations (a simple ordered dither pattern).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
register JSAMPROW inptr, outptr;
|
||||
register int invalue;
|
||||
register JDIMENSION colctr;
|
||||
int inrow;
|
||||
|
||||
for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
|
||||
inptr = input_data[inrow];
|
||||
outptr = output_data[inrow];
|
||||
/* Special case for first column */
|
||||
invalue = GETJSAMPLE(*inptr++);
|
||||
*outptr++ = (JSAMPLE) invalue;
|
||||
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel */
|
||||
invalue = GETJSAMPLE(*inptr++) * 3;
|
||||
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
invalue = GETJSAMPLE(*inptr);
|
||||
*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
|
||||
*outptr++ = (JSAMPLE) invalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
|
||||
* Again a triangle filter; see comments for h2v1 case, above.
|
||||
*
|
||||
* It is OK for us to reference the adjacent input rows because we demanded
|
||||
* context from the main buffer controller (see initialization code).
|
||||
*/
|
||||
|
||||
METHODDEF(void)
|
||||
h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
|
||||
{
|
||||
JSAMPARRAY output_data = *output_data_ptr;
|
||||
register JSAMPROW inptr0, inptr1, outptr;
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
register int thiscolsum, lastcolsum, nextcolsum;
|
||||
#else
|
||||
register INT32 thiscolsum, lastcolsum, nextcolsum;
|
||||
#endif
|
||||
register JDIMENSION colctr;
|
||||
int inrow, outrow, v;
|
||||
|
||||
inrow = outrow = 0;
|
||||
while (outrow < cinfo->max_v_samp_factor) {
|
||||
for (v = 0; v < 2; v++) {
|
||||
/* inptr0 points to nearest input row, inptr1 points to next nearest */
|
||||
inptr0 = input_data[inrow];
|
||||
if (v == 0) /* next nearest is row above */
|
||||
inptr1 = input_data[inrow-1];
|
||||
else /* next nearest is row below */
|
||||
inptr1 = input_data[inrow+1];
|
||||
outptr = output_data[outrow++];
|
||||
|
||||
/* Special case for first column */
|
||||
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
|
||||
for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
|
||||
/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
|
||||
/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
|
||||
nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
|
||||
lastcolsum = thiscolsum; thiscolsum = nextcolsum;
|
||||
}
|
||||
|
||||
/* Special case for last column */
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
|
||||
*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
|
||||
}
|
||||
inrow++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module initialization routine for upsampling.
|
||||
*/
|
||||
@@ -403,7 +296,7 @@ jinit_upsampler (j_decompress_ptr cinfo)
|
||||
my_upsample_ptr upsample;
|
||||
int ci;
|
||||
jpeg_component_info * compptr;
|
||||
boolean need_buffer, do_fancy;
|
||||
boolean need_buffer;
|
||||
int h_in_group, v_in_group, h_out_group, v_out_group;
|
||||
|
||||
upsample = (my_upsample_ptr)
|
||||
@@ -417,11 +310,6 @@ jinit_upsampler (j_decompress_ptr cinfo)
|
||||
if (cinfo->CCIR601_sampling) /* this isn't supported */
|
||||
ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
|
||||
|
||||
/* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
|
||||
* so don't ask for it.
|
||||
*/
|
||||
do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
|
||||
|
||||
/* Verify we can handle the sampling factors, select per-component methods,
|
||||
* and create storage as needed.
|
||||
*/
|
||||
@@ -430,10 +318,10 @@ jinit_upsampler (j_decompress_ptr cinfo)
|
||||
/* Compute size of an "input group" after IDCT scaling. This many samples
|
||||
* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
|
||||
*/
|
||||
h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size;
|
||||
v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
|
||||
cinfo->min_DCT_scaled_size;
|
||||
h_in_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
|
||||
cinfo->min_DCT_h_scaled_size;
|
||||
v_in_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
|
||||
cinfo->min_DCT_v_scaled_size;
|
||||
h_out_group = cinfo->max_h_samp_factor;
|
||||
v_out_group = cinfo->max_v_samp_factor;
|
||||
upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
|
||||
@@ -448,33 +336,12 @@ jinit_upsampler (j_decompress_ptr cinfo)
|
||||
need_buffer = FALSE;
|
||||
} else if (h_in_group * 2 == h_out_group &&
|
||||
v_in_group == v_out_group) {
|
||||
/* Special cases for 2h1v upsampling */
|
||||
if (do_fancy && compptr->downsampled_width > 2) {
|
||||
if (jsimd_can_h2v1_fancy_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v1_fancy_upsample;
|
||||
else
|
||||
upsample->methods[ci] = h2v1_fancy_upsample;
|
||||
} else {
|
||||
if (jsimd_can_h2v1_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v1_upsample;
|
||||
else
|
||||
upsample->methods[ci] = h2v1_upsample;
|
||||
}
|
||||
/* Special case for 2h1v upsampling */
|
||||
upsample->methods[ci] = h2v1_upsample;
|
||||
} else if (h_in_group * 2 == h_out_group &&
|
||||
v_in_group * 2 == v_out_group) {
|
||||
/* Special cases for 2h2v upsampling */
|
||||
if (do_fancy && compptr->downsampled_width > 2) {
|
||||
if (jsimd_can_h2v2_fancy_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v2_fancy_upsample;
|
||||
else
|
||||
upsample->methods[ci] = h2v2_fancy_upsample;
|
||||
upsample->pub.need_context_rows = TRUE;
|
||||
} else {
|
||||
if (jsimd_can_h2v2_upsample())
|
||||
upsample->methods[ci] = jsimd_h2v2_upsample;
|
||||
else
|
||||
upsample->methods[ci] = h2v2_upsample;
|
||||
}
|
||||
/* 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 */
|
||||
|
||||
19
jdtrans.c
19
jdtrans.c
@@ -2,6 +2,7 @@
|
||||
* jdtrans.c
|
||||
*
|
||||
* Copyright (C) 1995-1997, Thomas G. Lane.
|
||||
* Modified 2000-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -99,18 +100,14 @@ transdecode_master_selection (j_decompress_ptr cinfo)
|
||||
/* This is effectively a buffered-image operation. */
|
||||
cinfo->buffered_image = TRUE;
|
||||
|
||||
/* Compute output image dimensions and related values. */
|
||||
jpeg_core_output_dimensions(cinfo);
|
||||
|
||||
/* Entropy decoding: either Huffman or arithmetic coding. */
|
||||
if (cinfo->arith_code) {
|
||||
ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
|
||||
} else {
|
||||
if (cinfo->progressive_mode) {
|
||||
#ifdef D_PROGRESSIVE_SUPPORTED
|
||||
jinit_phuff_decoder(cinfo);
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else
|
||||
jinit_huff_decoder(cinfo);
|
||||
if (cinfo->arith_code)
|
||||
jinit_arith_decoder(cinfo);
|
||||
else {
|
||||
jinit_huff_decoder(cinfo);
|
||||
}
|
||||
|
||||
/* Always get a full-image coefficient buffer. */
|
||||
|
||||
19
jerror.h
19
jerror.h
@@ -2,6 +2,7 @@
|
||||
* jerror.h
|
||||
*
|
||||
* Copyright (C) 1994-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -39,14 +40,15 @@ typedef enum {
|
||||
JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
|
||||
|
||||
/* For maintenance convenience, list is alphabetical by message code name */
|
||||
JMESSAGE(JERR_ARITH_NOTIMPL,
|
||||
"Sorry, there are legal restrictions on arithmetic coding")
|
||||
JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
|
||||
JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
|
||||
JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
|
||||
JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
|
||||
JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request")
|
||||
JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
|
||||
JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
|
||||
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")
|
||||
@@ -93,6 +95,7 @@ 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")
|
||||
@@ -170,6 +173,7 @@ JMESSAGE(JTRC_UNKNOWN_IDS,
|
||||
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,
|
||||
@@ -227,6 +231,15 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXIT6(cinfo,code,p1,p2,p3,p4,p5,p6) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
(cinfo)->err->msg_parm.i[0] = (p1), \
|
||||
(cinfo)->err->msg_parm.i[1] = (p2), \
|
||||
(cinfo)->err->msg_parm.i[2] = (p3), \
|
||||
(cinfo)->err->msg_parm.i[3] = (p4), \
|
||||
(cinfo)->err->msg_parm.i[4] = (p5), \
|
||||
(cinfo)->err->msg_parm.i[5] = (p6), \
|
||||
(*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
|
||||
#define ERREXITS(cinfo,code,str) \
|
||||
((cinfo)->err->msg_code = (code), \
|
||||
strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
|
||||
|
||||
48
jfdctflt.c
48
jfdctflt.c
@@ -2,6 +2,7 @@
|
||||
* jfdctflt.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2003-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -56,41 +57,46 @@
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_float (FAST_FLOAT * data)
|
||||
jpeg_fdct_float (FAST_FLOAT * data, JSAMPARRAY sample_data, JDIMENSION start_col)
|
||||
{
|
||||
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
|
||||
FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
|
||||
FAST_FLOAT *dataptr;
|
||||
JSAMPROW elemptr;
|
||||
int ctr;
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
elemptr = sample_data[ctr] + start_col;
|
||||
|
||||
/* Load data into workspace */
|
||||
tmp0 = (FAST_FLOAT) (GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]));
|
||||
tmp7 = (FAST_FLOAT) (GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[7]));
|
||||
tmp1 = (FAST_FLOAT) (GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[6]));
|
||||
tmp6 = (FAST_FLOAT) (GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[6]));
|
||||
tmp2 = (FAST_FLOAT) (GETJSAMPLE(elemptr[2]) + GETJSAMPLE(elemptr[5]));
|
||||
tmp5 = (FAST_FLOAT) (GETJSAMPLE(elemptr[2]) - GETJSAMPLE(elemptr[5]));
|
||||
tmp3 = (FAST_FLOAT) (GETJSAMPLE(elemptr[3]) + GETJSAMPLE(elemptr[4]));
|
||||
tmp4 = (FAST_FLOAT) (GETJSAMPLE(elemptr[3]) - GETJSAMPLE(elemptr[4]));
|
||||
|
||||
/* Even part */
|
||||
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = tmp10 + tmp11; /* phase 3 */
|
||||
|
||||
/* Apply unsigned->signed conversion */
|
||||
dataptr[0] = tmp10 + tmp11 - 8 * CENTERJSAMPLE; /* phase 3 */
|
||||
dataptr[4] = tmp10 - tmp11;
|
||||
|
||||
|
||||
z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
dataptr[2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[6] = tmp13 - z1;
|
||||
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
@@ -126,21 +132,21 @@ jpeg_fdct_float (FAST_FLOAT * data)
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
|
||||
/* Even part */
|
||||
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
|
||||
dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[DCTSIZE*4] = tmp10 - tmp11;
|
||||
|
||||
|
||||
z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
|
||||
dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[DCTSIZE*6] = tmp13 - z1;
|
||||
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
|
||||
48
jfdctfst.c
48
jfdctfst.c
@@ -2,6 +2,7 @@
|
||||
* jfdctfst.c
|
||||
*
|
||||
* Copyright (C) 1994-1996, Thomas G. Lane.
|
||||
* Modified 2003-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -111,42 +112,47 @@
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_fdct_ifast (DCTELEM * data)
|
||||
jpeg_fdct_ifast (DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)
|
||||
{
|
||||
DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
DCTELEM tmp10, tmp11, tmp12, tmp13;
|
||||
DCTELEM z1, z2, z3, z4, z5, z11, z13;
|
||||
DCTELEM *dataptr;
|
||||
JSAMPROW elemptr;
|
||||
int ctr;
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process rows. */
|
||||
|
||||
dataptr = data;
|
||||
for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
|
||||
tmp0 = dataptr[0] + dataptr[7];
|
||||
tmp7 = dataptr[0] - dataptr[7];
|
||||
tmp1 = dataptr[1] + dataptr[6];
|
||||
tmp6 = dataptr[1] - dataptr[6];
|
||||
tmp2 = dataptr[2] + dataptr[5];
|
||||
tmp5 = dataptr[2] - dataptr[5];
|
||||
tmp3 = dataptr[3] + dataptr[4];
|
||||
tmp4 = dataptr[3] - dataptr[4];
|
||||
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
elemptr = sample_data[ctr] + start_col;
|
||||
|
||||
/* Load data into workspace */
|
||||
tmp0 = GETJSAMPLE(elemptr[0]) + GETJSAMPLE(elemptr[7]);
|
||||
tmp7 = GETJSAMPLE(elemptr[0]) - GETJSAMPLE(elemptr[7]);
|
||||
tmp1 = GETJSAMPLE(elemptr[1]) + GETJSAMPLE(elemptr[6]);
|
||||
tmp6 = GETJSAMPLE(elemptr[1]) - GETJSAMPLE(elemptr[6]);
|
||||
tmp2 = GETJSAMPLE(elemptr[2]) + GETJSAMPLE(elemptr[5]);
|
||||
tmp5 = GETJSAMPLE(elemptr[2]) - GETJSAMPLE(elemptr[5]);
|
||||
tmp3 = GETJSAMPLE(elemptr[3]) + GETJSAMPLE(elemptr[4]);
|
||||
tmp4 = GETJSAMPLE(elemptr[3]) - GETJSAMPLE(elemptr[4]);
|
||||
|
||||
/* Even part */
|
||||
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
dataptr[0] = tmp10 + tmp11; /* phase 3 */
|
||||
|
||||
/* Apply unsigned->signed conversion */
|
||||
dataptr[0] = tmp10 + tmp11 - 8 * CENTERJSAMPLE; /* phase 3 */
|
||||
dataptr[4] = tmp10 - tmp11;
|
||||
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
||||
dataptr[2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[6] = tmp13 - z1;
|
||||
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
@@ -182,21 +188,21 @@ jpeg_fdct_ifast (DCTELEM * data)
|
||||
tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
|
||||
tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
|
||||
tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
|
||||
|
||||
|
||||
/* Even part */
|
||||
|
||||
|
||||
tmp10 = tmp0 + tmp3; /* phase 2 */
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
|
||||
|
||||
dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
|
||||
dataptr[DCTSIZE*4] = tmp10 - tmp11;
|
||||
|
||||
|
||||
z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
||||
dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
|
||||
dataptr[DCTSIZE*6] = tmp13 - z1;
|
||||
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp10 = tmp4 + tmp5; /* phase 2 */
|
||||
|
||||
4271
jfdctint.c
4271
jfdctint.c
File diff suppressed because it is too large
Load Diff
53
jidctflt.c
53
jidctflt.c
@@ -2,6 +2,7 @@
|
||||
* jidctflt.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* Modified 2010 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -76,10 +77,9 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
FLOAT_MULT_TYPE * quantptr;
|
||||
FAST_FLOAT * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
int ctr;
|
||||
FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
@@ -152,12 +152,12 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
|
||||
|
||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
||||
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
|
||||
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
|
||||
tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
|
||||
tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7; /* phase 2 */
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
tmp4 = tmp10 - tmp5;
|
||||
|
||||
wsptr[DCTSIZE*0] = tmp0 + tmp7;
|
||||
wsptr[DCTSIZE*7] = tmp0 - tmp7;
|
||||
@@ -165,8 +165,8 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
wsptr[DCTSIZE*6] = tmp1 - tmp6;
|
||||
wsptr[DCTSIZE*2] = tmp2 + tmp5;
|
||||
wsptr[DCTSIZE*5] = tmp2 - tmp5;
|
||||
wsptr[DCTSIZE*4] = tmp3 + tmp4;
|
||||
wsptr[DCTSIZE*3] = tmp3 - tmp4;
|
||||
wsptr[DCTSIZE*3] = tmp3 + tmp4;
|
||||
wsptr[DCTSIZE*4] = tmp3 - tmp4;
|
||||
|
||||
inptr++; /* advance pointers to next column */
|
||||
quantptr++;
|
||||
@@ -174,7 +174,6 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
}
|
||||
|
||||
/* Pass 2: process rows from work array, store into output array. */
|
||||
/* Note that we must descale the results by a factor of 8 == 2**3. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < DCTSIZE; ctr++) {
|
||||
@@ -187,8 +186,10 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = wsptr[0] + wsptr[4];
|
||||
tmp11 = wsptr[0] - wsptr[4];
|
||||
/* Apply signed->unsigned and prepare float->int conversion */
|
||||
z5 = wsptr[0] + ((FAST_FLOAT) CENTERJSAMPLE + (FAST_FLOAT) 0.5);
|
||||
tmp10 = z5 + wsptr[4];
|
||||
tmp11 = z5 - wsptr[4];
|
||||
|
||||
tmp13 = wsptr[2] + wsptr[6];
|
||||
tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
|
||||
@@ -209,31 +210,23 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
|
||||
|
||||
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
|
||||
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
|
||||
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
|
||||
tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */
|
||||
tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */
|
||||
|
||||
tmp6 = tmp12 - tmp7;
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
tmp4 = tmp10 - tmp5;
|
||||
|
||||
/* Final output stage: scale down by a factor of 8 and range-limit */
|
||||
/* Final output stage: float->int conversion and range-limit */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
|
||||
& RANGE_MASK];
|
||||
outptr[0] = range_limit[((int) (tmp0 + tmp7)) & RANGE_MASK];
|
||||
outptr[7] = range_limit[((int) (tmp0 - tmp7)) & RANGE_MASK];
|
||||
outptr[1] = range_limit[((int) (tmp1 + tmp6)) & RANGE_MASK];
|
||||
outptr[6] = range_limit[((int) (tmp1 - tmp6)) & RANGE_MASK];
|
||||
outptr[2] = range_limit[((int) (tmp2 + tmp5)) & RANGE_MASK];
|
||||
outptr[5] = range_limit[((int) (tmp2 - tmp5)) & RANGE_MASK];
|
||||
outptr[3] = range_limit[((int) (tmp3 + tmp4)) & RANGE_MASK];
|
||||
outptr[4] = range_limit[((int) (tmp3 - tmp4)) & RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
|
||||
4966
jidctint.c
4966
jidctint.c
File diff suppressed because it is too large
Load Diff
398
jidctred.c
398
jidctred.c
@@ -1,398 +0,0 @@
|
||||
/*
|
||||
* jidctred.c
|
||||
*
|
||||
* Copyright (C) 1994-1998, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains inverse-DCT routines that produce reduced-size output:
|
||||
* either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
|
||||
*
|
||||
* The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
|
||||
* algorithm used in jidctint.c. We simply replace each 8-to-8 1-D IDCT step
|
||||
* with an 8-to-4 step that produces the four averages of two adjacent outputs
|
||||
* (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
|
||||
* These steps were derived by computing the corresponding values at the end
|
||||
* of the normal LL&M code, then simplifying as much as possible.
|
||||
*
|
||||
* 1x1 is trivial: just take the DC coefficient divided by 8.
|
||||
*
|
||||
* See jidctint.c for additional comments.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
|
||||
#ifdef IDCT_SCALING_SUPPORTED
|
||||
|
||||
|
||||
/*
|
||||
* This module is specialized to the case DCTSIZE = 8.
|
||||
*/
|
||||
|
||||
#if DCTSIZE != 8
|
||||
Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
|
||||
#endif
|
||||
|
||||
|
||||
/* Scaling is the same as in jidctint.c. */
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 2
|
||||
#else
|
||||
#define CONST_BITS 13
|
||||
#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
|
||||
#endif
|
||||
|
||||
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
|
||||
* causing a lot of useless floating-point operations at run time.
|
||||
* To get around this we use the following pre-calculated constants.
|
||||
* If you change CONST_BITS you may want to add appropriate values.
|
||||
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
|
||||
*/
|
||||
|
||||
#if CONST_BITS == 13
|
||||
#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */
|
||||
#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */
|
||||
#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */
|
||||
#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */
|
||||
#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
|
||||
#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */
|
||||
#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
|
||||
#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */
|
||||
#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */
|
||||
#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */
|
||||
#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
|
||||
#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */
|
||||
#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
|
||||
#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */
|
||||
#else
|
||||
#define FIX_0_211164243 FIX(0.211164243)
|
||||
#define FIX_0_509795579 FIX(0.509795579)
|
||||
#define FIX_0_601344887 FIX(0.601344887)
|
||||
#define FIX_0_720959822 FIX(0.720959822)
|
||||
#define FIX_0_765366865 FIX(0.765366865)
|
||||
#define FIX_0_850430095 FIX(0.850430095)
|
||||
#define FIX_0_899976223 FIX(0.899976223)
|
||||
#define FIX_1_061594337 FIX(1.061594337)
|
||||
#define FIX_1_272758580 FIX(1.272758580)
|
||||
#define FIX_1_451774981 FIX(1.451774981)
|
||||
#define FIX_1_847759065 FIX(1.847759065)
|
||||
#define FIX_2_172734803 FIX(2.172734803)
|
||||
#define FIX_2_562915447 FIX(2.562915447)
|
||||
#define FIX_3_624509785 FIX(3.624509785)
|
||||
#endif
|
||||
|
||||
|
||||
/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
|
||||
* For 8-bit samples with the recommended scaling, all the variable
|
||||
* and constant values involved are no more than 16 bits wide, so a
|
||||
* 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
|
||||
* For 12-bit samples, a full 32-bit multiplication will be needed.
|
||||
*/
|
||||
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
|
||||
#else
|
||||
#define MULTIPLY(var,const) ((var) * (const))
|
||||
#endif
|
||||
|
||||
|
||||
/* Dequantize a coefficient by multiplying it by the multiplier-table
|
||||
* entry; produce an int result. In this module, both inputs and result
|
||||
* are 16 bits or less, so either int or short multiply will work.
|
||||
*/
|
||||
|
||||
#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 4x4 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp2, tmp10, tmp12;
|
||||
INT32 z1, z2, z3, z4;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE*4]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
|
||||
/* Don't bother to process column 4, because second pass won't use it */
|
||||
if (ctr == DCTSIZE-4)
|
||||
continue;
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
|
||||
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
|
||||
inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero; we need not examine term 4 for 4x4 output */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
wsptr[DCTSIZE*2] = dcval;
|
||||
wsptr[DCTSIZE*3] = dcval;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp0 <<= (CONST_BITS+1);
|
||||
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
|
||||
|
||||
tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
|
||||
|
||||
tmp10 = tmp0 + tmp2;
|
||||
tmp12 = tmp0 - tmp2;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
z2 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
|
||||
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
|
||||
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
|
||||
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
|
||||
|
||||
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
|
||||
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
|
||||
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
|
||||
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
|
||||
wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
|
||||
}
|
||||
|
||||
/* Pass 2: process 4 rows from work array, store into output array. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < 4; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* It's not clear whether a zero row test is worthwhile here ... */
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
|
||||
wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
outptr[2] = dcval;
|
||||
outptr[3] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
|
||||
|
||||
tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
|
||||
+ MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
|
||||
|
||||
tmp10 = tmp0 + tmp2;
|
||||
tmp12 = tmp0 - tmp2;
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = (INT32) wsptr[7];
|
||||
z2 = (INT32) wsptr[5];
|
||||
z3 = (INT32) wsptr[3];
|
||||
z4 = (INT32) wsptr[1];
|
||||
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
|
||||
+ MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
|
||||
+ MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
|
||||
+ MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
|
||||
|
||||
tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
|
||||
+ MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
|
||||
+ MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
|
||||
+ MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+1)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 2x2 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
INT32 tmp0, tmp10, z1;
|
||||
JCOEFPTR inptr;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
int * wsptr;
|
||||
JSAMPROW outptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
int ctr;
|
||||
int workspace[DCTSIZE*2]; /* buffers data between passes */
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Pass 1: process columns from input, store into work array. */
|
||||
|
||||
inptr = coef_block;
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
wsptr = workspace;
|
||||
for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
|
||||
/* Don't bother to process columns 2,4,6 */
|
||||
if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
|
||||
continue;
|
||||
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
|
||||
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
|
||||
/* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
|
||||
int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
|
||||
|
||||
wsptr[DCTSIZE*0] = dcval;
|
||||
wsptr[DCTSIZE*1] = dcval;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Even part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
|
||||
tmp10 = z1 << (CONST_BITS+2);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
|
||||
tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
|
||||
tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
|
||||
tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
|
||||
z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
|
||||
tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
|
||||
wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
|
||||
}
|
||||
|
||||
/* Pass 2: process 2 rows from work array, store into output array. */
|
||||
|
||||
wsptr = workspace;
|
||||
for (ctr = 0; ctr < 2; ctr++) {
|
||||
outptr = output_buf[ctr] + output_col;
|
||||
/* It's not clear whether a zero row test is worthwhile here ... */
|
||||
|
||||
#ifndef NO_ZERO_ROW_TEST
|
||||
if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
|
||||
/* AC terms all zero */
|
||||
JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
|
||||
& RANGE_MASK];
|
||||
|
||||
outptr[0] = dcval;
|
||||
outptr[1] = dcval;
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Even part */
|
||||
|
||||
tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
|
||||
|
||||
/* Odd part */
|
||||
|
||||
tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
|
||||
+ MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
|
||||
+ MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
|
||||
+ MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
|
||||
|
||||
/* Final output stage */
|
||||
|
||||
outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+2)
|
||||
& RANGE_MASK];
|
||||
outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
|
||||
CONST_BITS+PASS1_BITS+3+2)
|
||||
& RANGE_MASK];
|
||||
|
||||
wsptr += DCTSIZE; /* advance pointer to next row */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform dequantization and inverse DCT on one block of coefficients,
|
||||
* producing a reduced-size 1x1 output block.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JCOEFPTR coef_block,
|
||||
JSAMPARRAY output_buf, JDIMENSION output_col)
|
||||
{
|
||||
int dcval;
|
||||
ISLOW_MULT_TYPE * quantptr;
|
||||
JSAMPLE *range_limit = IDCT_range_limit(cinfo);
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* We hardly need an inverse DCT routine for this: just take the
|
||||
* average pixel value, which is one-eighth of the DC coefficient.
|
||||
*/
|
||||
quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
|
||||
dcval = DEQUANTIZE(coef_block[0], quantptr[0]);
|
||||
dcval = (int) DESCALE((INT32) dcval, 3);
|
||||
|
||||
output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
|
||||
}
|
||||
|
||||
#endif /* IDCT_SCALING_SUPPORTED */
|
||||
167
jmemansi.c
Normal file
167
jmemansi.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* jmemansi.c
|
||||
*
|
||||
* Copyright (C) 1992-1996, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file provides a simple generic implementation of the system-
|
||||
* dependent portion of the JPEG memory manager. This implementation
|
||||
* assumes that you have the ANSI-standard library routine tmpfile().
|
||||
* Also, the problem of determining the amount of memory available
|
||||
* is shoved onto the user.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
|
||||
#define SEEK_SET 0 /* if not, assume 0 is correct */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: although we include FAR keywords in the routine declarations,
|
||||
* this file won't actually work in 80x86 small/medium model; at least,
|
||||
* you probably won't be able to process useful-size images in only 64KB.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* It's impossible to do this in a portable way; our current solution is
|
||||
* to make the user tell us (with a default value set at compile time).
|
||||
* If you can actually get the available space, it's a good idea to subtract
|
||||
* a slop factor of 5% or so.
|
||||
*/
|
||||
|
||||
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
|
||||
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
|
||||
#endif
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFREAD(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFWRITE(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
fclose(info->temp_file);
|
||||
/* Since this implementation uses tmpfile() to create the file,
|
||||
* no explicit file deletion is needed.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object.
|
||||
*
|
||||
* This version uses tmpfile(), which constructs a suitable file name
|
||||
* behind the scenes. We don't have to use info->temp_name[] at all;
|
||||
* indeed, we can't even find out the actual name of the temp file.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
if ((info->temp_file = tmpfile()) == NULL)
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
|
||||
info->read_backing_store = read_backing_store;
|
||||
info->write_backing_store = write_backing_store;
|
||||
info->close_backing_store = close_backing_store;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr cinfo)
|
||||
{
|
||||
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* no work */
|
||||
}
|
||||
638
jmemdos.c
Normal file
638
jmemdos.c
Normal file
@@ -0,0 +1,638 @@
|
||||
/*
|
||||
* jmemdos.c
|
||||
*
|
||||
* Copyright (C) 1992-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file provides an MS-DOS-compatible implementation of the system-
|
||||
* dependent portion of the JPEG memory manager. Temporary data can be
|
||||
* stored in extended or expanded memory as well as in regular DOS files.
|
||||
*
|
||||
* If you use this file, you must be sure that NEED_FAR_POINTERS is defined
|
||||
* if you compile in a small-data memory model; it should NOT be defined if
|
||||
* you use a large-data memory model. This file is not recommended if you
|
||||
* are using a flat-memory-space 386 environment such as DJGCC or Watcom C.
|
||||
* Also, this code will NOT work if struct fields are aligned on greater than
|
||||
* 2-byte boundaries.
|
||||
*
|
||||
* Based on code contributed by Ge' Weijers.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If you have both extended and expanded memory, you may want to change the
|
||||
* order in which they are tried in jopen_backing_store. On a 286 machine
|
||||
* expanded memory is usually faster, since extended memory access involves
|
||||
* an expensive protected-mode-and-back switch. On 386 and better, extended
|
||||
* memory is usually faster. As distributed, the code tries extended memory
|
||||
* first (what? not everyone has a 386? :-).
|
||||
*
|
||||
* You can disable use of extended/expanded memory entirely by altering these
|
||||
* definitions or overriding them from the Makefile (eg, -DEMS_SUPPORTED=0).
|
||||
*/
|
||||
|
||||
#ifndef XMS_SUPPORTED
|
||||
#define XMS_SUPPORTED 1
|
||||
#endif
|
||||
#ifndef EMS_SUPPORTED
|
||||
#define EMS_SUPPORTED 1
|
||||
#endif
|
||||
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare these */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
extern char * getenv JPP((const char * name));
|
||||
#endif
|
||||
|
||||
#ifdef NEED_FAR_POINTERS
|
||||
|
||||
#ifdef __TURBOC__
|
||||
/* These definitions work for Borland C (Turbo C) */
|
||||
#include <alloc.h> /* need farmalloc(), farfree() */
|
||||
#define far_malloc(x) farmalloc(x)
|
||||
#define far_free(x) farfree(x)
|
||||
#else
|
||||
/* These definitions work for Microsoft C and compatible compilers */
|
||||
#include <malloc.h> /* need _fmalloc(), _ffree() */
|
||||
#define far_malloc(x) _fmalloc(x)
|
||||
#define far_free(x) _ffree(x)
|
||||
#endif
|
||||
|
||||
#else /* not NEED_FAR_POINTERS */
|
||||
|
||||
#define far_malloc(x) malloc(x)
|
||||
#define far_free(x) free(x)
|
||||
|
||||
#endif /* NEED_FAR_POINTERS */
|
||||
|
||||
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
|
||||
#define READ_BINARY "r"
|
||||
#else
|
||||
#define READ_BINARY "rb"
|
||||
#endif
|
||||
|
||||
#ifndef USE_MSDOS_MEMMGR /* make sure user got configuration right */
|
||||
You forgot to define USE_MSDOS_MEMMGR in jconfig.h. /* deliberate syntax error */
|
||||
#endif
|
||||
|
||||
#if MAX_ALLOC_CHUNK >= 65535L /* make sure jconfig.h got this right */
|
||||
MAX_ALLOC_CHUNK should be less than 64K. /* deliberate syntax error */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Declarations for assembly-language support routines (see jmemdosa.asm).
|
||||
*
|
||||
* The functions are declared "far" as are all their pointer arguments;
|
||||
* this ensures the assembly source code will work regardless of the
|
||||
* compiler memory model. We assume "short" is 16 bits, "long" is 32.
|
||||
*/
|
||||
|
||||
typedef void far * XMSDRIVER; /* actually a pointer to code */
|
||||
typedef struct { /* registers for calling XMS driver */
|
||||
unsigned short ax, dx, bx;
|
||||
void far * ds_si;
|
||||
} XMScontext;
|
||||
typedef struct { /* registers for calling EMS driver */
|
||||
unsigned short ax, dx, bx;
|
||||
void far * ds_si;
|
||||
} EMScontext;
|
||||
|
||||
extern short far jdos_open JPP((short far * handle, char far * filename));
|
||||
extern short far jdos_close JPP((short handle));
|
||||
extern short far jdos_seek JPP((short handle, long offset));
|
||||
extern short far jdos_read JPP((short handle, void far * buffer,
|
||||
unsigned short count));
|
||||
extern short far jdos_write JPP((short handle, void far * buffer,
|
||||
unsigned short count));
|
||||
extern void far jxms_getdriver JPP((XMSDRIVER far *));
|
||||
extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
|
||||
extern short far jems_available JPP((void));
|
||||
extern void far jems_calldriver JPP((EMScontext far *));
|
||||
|
||||
|
||||
/*
|
||||
* Selection of a file name for a temporary file.
|
||||
* This is highly system-dependent, and you may want to customize it.
|
||||
*/
|
||||
|
||||
static int next_file_num; /* to distinguish among several temp files */
|
||||
|
||||
LOCAL(void)
|
||||
select_file_name (char * fname)
|
||||
{
|
||||
const char * env;
|
||||
char * ptr;
|
||||
FILE * tfile;
|
||||
|
||||
/* Keep generating file names till we find one that's not in use */
|
||||
for (;;) {
|
||||
/* Get temp directory name from environment TMP or TEMP variable;
|
||||
* if none, use "."
|
||||
*/
|
||||
if ((env = (const char *) getenv("TMP")) == NULL)
|
||||
if ((env = (const char *) getenv("TEMP")) == NULL)
|
||||
env = ".";
|
||||
if (*env == '\0') /* null string means "." */
|
||||
env = ".";
|
||||
ptr = fname; /* copy name to fname */
|
||||
while (*env != '\0')
|
||||
*ptr++ = *env++;
|
||||
if (ptr[-1] != '\\' && ptr[-1] != '/')
|
||||
*ptr++ = '\\'; /* append backslash if not in env variable */
|
||||
/* Append a suitable file name */
|
||||
next_file_num++; /* advance counter */
|
||||
sprintf(ptr, "JPG%03d.TMP", next_file_num);
|
||||
/* Probe to see if file name is already in use */
|
||||
if ((tfile = fopen(fname, READ_BINARY)) == NULL)
|
||||
break;
|
||||
fclose(tfile); /* oops, it's there; close tfile & try again */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Near-memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are allocated in far memory, if possible
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) far_malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
far_free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* It's impossible to do this in a portable way; our current solution is
|
||||
* to make the user tell us (with a default value set at compile time).
|
||||
* If you can actually get the available space, it's a good idea to subtract
|
||||
* a slop factor of 5% or so.
|
||||
*/
|
||||
|
||||
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
|
||||
#define DEFAULT_MAX_MEM 300000L /* for total usage about 450K */
|
||||
#endif
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For MS-DOS we support three types of backing storage:
|
||||
* 1. Conventional DOS files. We access these by direct DOS calls rather
|
||||
* than via the stdio package. This provides a bit better performance,
|
||||
* but the real reason is that the buffers to be read or written are FAR.
|
||||
* The stdio library for small-data memory models can't cope with that.
|
||||
* 2. Extended memory, accessed per the XMS V2.0 specification.
|
||||
* 3. Expanded memory, accessed per the LIM/EMS 4.0 specification.
|
||||
* You'll need copies of those specs to make sense of the related code.
|
||||
* The specs are available by Internet FTP from the SIMTEL archives
|
||||
* (oak.oakland.edu and its various mirror sites). See files
|
||||
* pub/msdos/microsoft/xms20.arc and pub/msdos/info/limems41.zip.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Access methods for a DOS file.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_file_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (jdos_seek(info->handle.file_handle, file_offset))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
|
||||
if (byte_count > 65535L) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
|
||||
if (jdos_read(info->handle.file_handle, buffer_address,
|
||||
(unsigned short) byte_count))
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_file_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (jdos_seek(info->handle.file_handle, file_offset))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
/* Since MAX_ALLOC_CHUNK is less than 64K, byte_count will be too. */
|
||||
if (byte_count > 65535L) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
|
||||
if (jdos_write(info->handle.file_handle, buffer_address,
|
||||
(unsigned short) byte_count))
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_file_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
jdos_close(info->handle.file_handle); /* close the file */
|
||||
remove(info->temp_name); /* delete the file */
|
||||
/* If your system doesn't have remove(), try unlink() instead.
|
||||
* remove() is the ANSI-standard name for this function, but
|
||||
* unlink() was more common in pre-ANSI systems.
|
||||
*/
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
|
||||
}
|
||||
|
||||
|
||||
LOCAL(boolean)
|
||||
open_file_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
short handle;
|
||||
|
||||
select_file_name(info->temp_name);
|
||||
if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
|
||||
/* might as well exit since jpeg_open_backing_store will fail anyway */
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
|
||||
return FALSE;
|
||||
}
|
||||
info->handle.file_handle = handle;
|
||||
info->read_backing_store = read_file_store;
|
||||
info->write_backing_store = write_file_store;
|
||||
info->close_backing_store = close_file_store;
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
|
||||
return TRUE; /* succeeded */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Access methods for extended memory.
|
||||
*/
|
||||
|
||||
#if XMS_SUPPORTED
|
||||
|
||||
static XMSDRIVER xms_driver; /* saved address of XMS driver */
|
||||
|
||||
typedef union { /* either long offset or real-mode pointer */
|
||||
long offset;
|
||||
void far * ptr;
|
||||
} XMSPTR;
|
||||
|
||||
typedef struct { /* XMS move specification structure */
|
||||
long length;
|
||||
XMSH src_handle;
|
||||
XMSPTR src;
|
||||
XMSH dst_handle;
|
||||
XMSPTR dst;
|
||||
} XMSspec;
|
||||
|
||||
#define ODD(X) (((X) & 1L) != 0)
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
XMScontext ctx;
|
||||
XMSspec spec;
|
||||
char endbuffer[2];
|
||||
|
||||
/* The XMS driver can't cope with an odd length, so handle the last byte
|
||||
* specially if byte_count is odd. We don't expect this to be common.
|
||||
*/
|
||||
|
||||
spec.length = byte_count & (~ 1L);
|
||||
spec.src_handle = info->handle.xms_handle;
|
||||
spec.src.offset = file_offset;
|
||||
spec.dst_handle = 0;
|
||||
spec.dst.ptr = buffer_address;
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x0b00; /* EMB move */
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax != 1)
|
||||
ERREXIT(cinfo, JERR_XMS_READ);
|
||||
|
||||
if (ODD(byte_count)) {
|
||||
read_xms_store(cinfo, info, (void FAR *) endbuffer,
|
||||
file_offset + byte_count - 1L, 2L);
|
||||
((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
XMScontext ctx;
|
||||
XMSspec spec;
|
||||
char endbuffer[2];
|
||||
|
||||
/* The XMS driver can't cope with an odd length, so handle the last byte
|
||||
* specially if byte_count is odd. We don't expect this to be common.
|
||||
*/
|
||||
|
||||
spec.length = byte_count & (~ 1L);
|
||||
spec.src_handle = 0;
|
||||
spec.src.ptr = buffer_address;
|
||||
spec.dst_handle = info->handle.xms_handle;
|
||||
spec.dst.offset = file_offset;
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x0b00; /* EMB move */
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax != 1)
|
||||
ERREXIT(cinfo, JERR_XMS_WRITE);
|
||||
|
||||
if (ODD(byte_count)) {
|
||||
read_xms_store(cinfo, info, (void FAR *) endbuffer,
|
||||
file_offset + byte_count - 1L, 2L);
|
||||
endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
|
||||
write_xms_store(cinfo, info, (void FAR *) endbuffer,
|
||||
file_offset + byte_count - 1L, 2L);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
XMScontext ctx;
|
||||
|
||||
ctx.dx = info->handle.xms_handle;
|
||||
ctx.ax = 0x0a00;
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
|
||||
/* we ignore any error return from the driver */
|
||||
}
|
||||
|
||||
|
||||
LOCAL(boolean)
|
||||
open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
XMScontext ctx;
|
||||
|
||||
/* Get address of XMS driver */
|
||||
jxms_getdriver((XMSDRIVER far *) & xms_driver);
|
||||
if (xms_driver == NULL)
|
||||
return FALSE; /* no driver to be had */
|
||||
|
||||
/* Get version number, must be >= 2.00 */
|
||||
ctx.ax = 0x0000;
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax < (unsigned short) 0x0200)
|
||||
return FALSE;
|
||||
|
||||
/* Try to get space (expressed in kilobytes) */
|
||||
ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
|
||||
ctx.ax = 0x0900;
|
||||
jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
|
||||
if (ctx.ax != 1)
|
||||
return FALSE;
|
||||
|
||||
/* Succeeded, save the handle and away we go */
|
||||
info->handle.xms_handle = ctx.dx;
|
||||
info->read_backing_store = read_xms_store;
|
||||
info->write_backing_store = write_xms_store;
|
||||
info->close_backing_store = close_xms_store;
|
||||
TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
|
||||
return TRUE; /* succeeded */
|
||||
}
|
||||
|
||||
#endif /* XMS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Access methods for expanded memory.
|
||||
*/
|
||||
|
||||
#if EMS_SUPPORTED
|
||||
|
||||
/* The EMS move specification structure requires word and long fields aligned
|
||||
* at odd byte boundaries. Some compilers will align struct fields at even
|
||||
* byte boundaries. While it's usually possible to force byte alignment,
|
||||
* that causes an overall performance penalty and may pose problems in merging
|
||||
* JPEG into a larger application. Instead we accept some rather dirty code
|
||||
* here. Note this code would fail if the hardware did not allow odd-byte
|
||||
* word & long accesses, but all 80x86 CPUs do.
|
||||
*/
|
||||
|
||||
typedef void far * EMSPTR;
|
||||
|
||||
typedef union { /* EMS move specification structure */
|
||||
long length; /* It's easy to access first 4 bytes */
|
||||
char bytes[18]; /* Misaligned fields in here! */
|
||||
} EMSspec;
|
||||
|
||||
/* Macros for accessing misaligned fields */
|
||||
#define FIELD_AT(spec,offset,type) (*((type *) &(spec.bytes[offset])))
|
||||
#define SRC_TYPE(spec) FIELD_AT(spec,4,char)
|
||||
#define SRC_HANDLE(spec) FIELD_AT(spec,5,EMSH)
|
||||
#define SRC_OFFSET(spec) FIELD_AT(spec,7,unsigned short)
|
||||
#define SRC_PAGE(spec) FIELD_AT(spec,9,unsigned short)
|
||||
#define SRC_PTR(spec) FIELD_AT(spec,7,EMSPTR)
|
||||
#define DST_TYPE(spec) FIELD_AT(spec,11,char)
|
||||
#define DST_HANDLE(spec) FIELD_AT(spec,12,EMSH)
|
||||
#define DST_OFFSET(spec) FIELD_AT(spec,14,unsigned short)
|
||||
#define DST_PAGE(spec) FIELD_AT(spec,16,unsigned short)
|
||||
#define DST_PTR(spec) FIELD_AT(spec,14,EMSPTR)
|
||||
|
||||
#define EMSPAGESIZE 16384L /* gospel, see the EMS specs */
|
||||
|
||||
#define HIBYTE(W) (((W) >> 8) & 0xFF)
|
||||
#define LOBYTE(W) ((W) & 0xFF)
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
EMScontext ctx;
|
||||
EMSspec spec;
|
||||
|
||||
spec.length = byte_count;
|
||||
SRC_TYPE(spec) = 1;
|
||||
SRC_HANDLE(spec) = info->handle.ems_handle;
|
||||
SRC_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
|
||||
SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
|
||||
DST_TYPE(spec) = 0;
|
||||
DST_HANDLE(spec) = 0;
|
||||
DST_PTR(spec) = buffer_address;
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x5700; /* move memory region */
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
ERREXIT(cinfo, JERR_EMS_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
EMScontext ctx;
|
||||
EMSspec spec;
|
||||
|
||||
spec.length = byte_count;
|
||||
SRC_TYPE(spec) = 0;
|
||||
SRC_HANDLE(spec) = 0;
|
||||
SRC_PTR(spec) = buffer_address;
|
||||
DST_TYPE(spec) = 1;
|
||||
DST_HANDLE(spec) = info->handle.ems_handle;
|
||||
DST_PAGE(spec) = (unsigned short) (file_offset / EMSPAGESIZE);
|
||||
DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
|
||||
|
||||
ctx.ds_si = (void far *) & spec;
|
||||
ctx.ax = 0x5700; /* move memory region */
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
ERREXIT(cinfo, JERR_EMS_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
EMScontext ctx;
|
||||
|
||||
ctx.ax = 0x4500;
|
||||
ctx.dx = info->handle.ems_handle;
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
|
||||
/* we ignore any error return from the driver */
|
||||
}
|
||||
|
||||
|
||||
LOCAL(boolean)
|
||||
open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
EMScontext ctx;
|
||||
|
||||
/* Is EMS driver there? */
|
||||
if (! jems_available())
|
||||
return FALSE;
|
||||
|
||||
/* Get status, make sure EMS is OK */
|
||||
ctx.ax = 0x4000;
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
return FALSE;
|
||||
|
||||
/* Get version, must be >= 4.0 */
|
||||
ctx.ax = 0x4600;
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
|
||||
return FALSE;
|
||||
|
||||
/* Try to allocate requested space */
|
||||
ctx.ax = 0x4300;
|
||||
ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
|
||||
jems_calldriver((EMScontext far *) & ctx);
|
||||
if (HIBYTE(ctx.ax) != 0)
|
||||
return FALSE;
|
||||
|
||||
/* Succeeded, save the handle and away we go */
|
||||
info->handle.ems_handle = ctx.dx;
|
||||
info->read_backing_store = read_ems_store;
|
||||
info->write_backing_store = write_ems_store;
|
||||
info->close_backing_store = close_ems_store;
|
||||
TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
|
||||
return TRUE; /* succeeded */
|
||||
}
|
||||
|
||||
#endif /* EMS_SUPPORTED */
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
/* Try extended memory, then expanded memory, then regular file. */
|
||||
#if XMS_SUPPORTED
|
||||
if (open_xms_store(cinfo, info, total_bytes_needed))
|
||||
return;
|
||||
#endif
|
||||
#if EMS_SUPPORTED
|
||||
if (open_ems_store(cinfo, info, total_bytes_needed))
|
||||
return;
|
||||
#endif
|
||||
if (open_file_store(cinfo, info, total_bytes_needed))
|
||||
return;
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, "");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr cinfo)
|
||||
{
|
||||
next_file_num = 0; /* initialize temp file name generator */
|
||||
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* Microsoft C, at least in v6.00A, will not successfully reclaim freed
|
||||
* blocks of size > 32Kbytes unless we give it a kick in the rear, like so:
|
||||
*/
|
||||
#ifdef NEED_FHEAPMIN
|
||||
_fheapmin();
|
||||
#endif
|
||||
}
|
||||
379
jmemdosa.asm
Normal file
379
jmemdosa.asm
Normal file
@@ -0,0 +1,379 @@
|
||||
;
|
||||
; jmemdosa.asm
|
||||
;
|
||||
; Copyright (C) 1992, 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 low-level interface routines to support the MS-DOS
|
||||
; backing store manager (jmemdos.c). Routines are provided to access disk
|
||||
; files through direct DOS calls, and to access XMS and EMS drivers.
|
||||
;
|
||||
; This file should assemble with Microsoft's MASM or any compatible
|
||||
; assembler (including Borland's Turbo Assembler). If you haven't got
|
||||
; a compatible assembler, better fall back to jmemansi.c or jmemname.c.
|
||||
;
|
||||
; To minimize dependence on the C compiler's register usage conventions,
|
||||
; we save and restore all 8086 registers, even though most compilers only
|
||||
; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return
|
||||
; values, which everybody returns in AX.
|
||||
;
|
||||
; Based on code contributed by Ge' Weijers.
|
||||
;
|
||||
|
||||
JMEMDOSA_TXT segment byte public 'CODE'
|
||||
|
||||
assume cs:JMEMDOSA_TXT
|
||||
|
||||
public _jdos_open
|
||||
public _jdos_close
|
||||
public _jdos_seek
|
||||
public _jdos_read
|
||||
public _jdos_write
|
||||
public _jxms_getdriver
|
||||
public _jxms_calldriver
|
||||
public _jems_available
|
||||
public _jems_calldriver
|
||||
|
||||
;
|
||||
; short far jdos_open (short far * handle, char far * filename)
|
||||
;
|
||||
; Create and open a temporary file
|
||||
;
|
||||
_jdos_open proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
mov cx,0 ; normal file attributes
|
||||
lds dx,dword ptr [bp+10] ; get filename pointer
|
||||
mov ah,3ch ; create file
|
||||
int 21h
|
||||
jc open_err ; if failed, return error code
|
||||
lds bx,dword ptr [bp+6] ; get handle pointer
|
||||
mov word ptr [bx],ax ; save the handle
|
||||
xor ax,ax ; return zero for OK
|
||||
open_err: pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jdos_open endp
|
||||
|
||||
|
||||
;
|
||||
; short far jdos_close (short handle)
|
||||
;
|
||||
; Close the file handle
|
||||
;
|
||||
_jdos_close proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
mov bx,word ptr [bp+6] ; file handle
|
||||
mov ah,3eh ; close file
|
||||
int 21h
|
||||
jc close_err ; if failed, return error code
|
||||
xor ax,ax ; return zero for OK
|
||||
close_err: pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jdos_close endp
|
||||
|
||||
|
||||
;
|
||||
; short far jdos_seek (short handle, long offset)
|
||||
;
|
||||
; Set file position
|
||||
;
|
||||
_jdos_seek proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
mov bx,word ptr [bp+6] ; file handle
|
||||
mov dx,word ptr [bp+8] ; LS offset
|
||||
mov cx,word ptr [bp+10] ; MS offset
|
||||
mov ax,4200h ; absolute seek
|
||||
int 21h
|
||||
jc seek_err ; if failed, return error code
|
||||
xor ax,ax ; return zero for OK
|
||||
seek_err: pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jdos_seek endp
|
||||
|
||||
|
||||
;
|
||||
; short far jdos_read (short handle, void far * buffer, unsigned short count)
|
||||
;
|
||||
; Read from file
|
||||
;
|
||||
_jdos_read proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
mov bx,word ptr [bp+6] ; file handle
|
||||
lds dx,dword ptr [bp+8] ; buffer address
|
||||
mov cx,word ptr [bp+12] ; number of bytes
|
||||
mov ah,3fh ; read file
|
||||
int 21h
|
||||
jc read_err ; if failed, return error code
|
||||
cmp ax,word ptr [bp+12] ; make sure all bytes were read
|
||||
je read_ok
|
||||
mov ax,1 ; else return 1 for not OK
|
||||
jmp short read_err
|
||||
read_ok: xor ax,ax ; return zero for OK
|
||||
read_err: pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jdos_read endp
|
||||
|
||||
|
||||
;
|
||||
; short far jdos_write (short handle, void far * buffer, unsigned short count)
|
||||
;
|
||||
; Write to file
|
||||
;
|
||||
_jdos_write proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
mov bx,word ptr [bp+6] ; file handle
|
||||
lds dx,dword ptr [bp+8] ; buffer address
|
||||
mov cx,word ptr [bp+12] ; number of bytes
|
||||
mov ah,40h ; write file
|
||||
int 21h
|
||||
jc write_err ; if failed, return error code
|
||||
cmp ax,word ptr [bp+12] ; make sure all bytes written
|
||||
je write_ok
|
||||
mov ax,1 ; else return 1 for not OK
|
||||
jmp short write_err
|
||||
write_ok: xor ax,ax ; return zero for OK
|
||||
write_err: pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jdos_write endp
|
||||
|
||||
|
||||
;
|
||||
; void far jxms_getdriver (XMSDRIVER far *)
|
||||
;
|
||||
; Get the address of the XMS driver, or NULL if not available
|
||||
;
|
||||
_jxms_getdriver proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
mov ax,4300h ; call multiplex interrupt with
|
||||
int 2fh ; a magic cookie, hex 4300
|
||||
cmp al,80h ; AL should contain hex 80
|
||||
je xmsavail
|
||||
xor dx,dx ; no XMS driver available
|
||||
xor ax,ax ; return a nil pointer
|
||||
jmp short xmsavail_done
|
||||
xmsavail: mov ax,4310h ; fetch driver address with
|
||||
int 2fh ; another magic cookie
|
||||
mov dx,es ; copy address to dx:ax
|
||||
mov ax,bx
|
||||
xmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value
|
||||
mov word ptr es:[bx],ax
|
||||
mov word ptr es:[bx+2],dx
|
||||
pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jxms_getdriver endp
|
||||
|
||||
|
||||
;
|
||||
; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
|
||||
;
|
||||
; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.
|
||||
; These are loaded, the XMS call is performed, and the new values of the
|
||||
; AX,DX,BX registers are written back to the context structure.
|
||||
;
|
||||
_jxms_calldriver proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
les bx,dword ptr [bp+10] ; get XMScontext pointer
|
||||
mov ax,word ptr es:[bx] ; load registers
|
||||
mov dx,word ptr es:[bx+2]
|
||||
mov si,word ptr es:[bx+6]
|
||||
mov ds,word ptr es:[bx+8]
|
||||
mov bx,word ptr es:[bx+4]
|
||||
call dword ptr [bp+6] ; call the driver
|
||||
mov cx,bx ; save returned BX for a sec
|
||||
les bx,dword ptr [bp+10] ; get XMScontext pointer
|
||||
mov word ptr es:[bx],ax ; put back ax,dx,bx
|
||||
mov word ptr es:[bx+2],dx
|
||||
mov word ptr es:[bx+4],cx
|
||||
pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jxms_calldriver endp
|
||||
|
||||
|
||||
;
|
||||
; short far jems_available (void)
|
||||
;
|
||||
; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
|
||||
;
|
||||
_jems_available proc far
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
mov ax,3567h ; get interrupt vector 67h
|
||||
int 21h
|
||||
push cs
|
||||
pop ds
|
||||
mov di,000ah ; check offs 10 in returned seg
|
||||
lea si,ASCII_device_name ; against literal string
|
||||
mov cx,8
|
||||
cld
|
||||
repe cmpsb
|
||||
jne no_ems
|
||||
mov ax,1 ; match, it's there
|
||||
jmp short avail_done
|
||||
no_ems: xor ax,ax ; it's not there
|
||||
avail_done: pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
ret
|
||||
|
||||
ASCII_device_name db "EMMXXXX0"
|
||||
|
||||
_jems_available endp
|
||||
|
||||
|
||||
;
|
||||
; void far jems_calldriver (EMScontext far *)
|
||||
;
|
||||
; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers.
|
||||
; These are loaded, the EMS trap is performed, and the new values of the
|
||||
; AX,DX,BX registers are written back to the context structure.
|
||||
;
|
||||
_jems_calldriver proc far
|
||||
push bp ; linkage
|
||||
mov bp,sp
|
||||
push si ; save all registers for safety
|
||||
push di
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
push es
|
||||
push ds
|
||||
les bx,dword ptr [bp+6] ; get EMScontext pointer
|
||||
mov ax,word ptr es:[bx] ; load registers
|
||||
mov dx,word ptr es:[bx+2]
|
||||
mov si,word ptr es:[bx+6]
|
||||
mov ds,word ptr es:[bx+8]
|
||||
mov bx,word ptr es:[bx+4]
|
||||
int 67h ; call the EMS driver
|
||||
mov cx,bx ; save returned BX for a sec
|
||||
les bx,dword ptr [bp+6] ; get EMScontext pointer
|
||||
mov word ptr es:[bx],ax ; put back ax,dx,bx
|
||||
mov word ptr es:[bx+2],dx
|
||||
mov word ptr es:[bx+4],cx
|
||||
pop ds ; restore registers and exit
|
||||
pop es
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret
|
||||
_jems_calldriver endp
|
||||
|
||||
JMEMDOSA_TXT ends
|
||||
|
||||
end
|
||||
289
jmemmac.c
Normal file
289
jmemmac.c
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* jmemmac.c
|
||||
*
|
||||
* Copyright (C) 1992-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* jmemmac.c provides an Apple Macintosh implementation of the system-
|
||||
* dependent portion of the JPEG memory manager.
|
||||
*
|
||||
* If you use jmemmac.c, then you must define USE_MAC_MEMMGR in the
|
||||
* JPEG_INTERNALS part of jconfig.h.
|
||||
*
|
||||
* jmemmac.c uses the Macintosh toolbox routines NewPtr and DisposePtr
|
||||
* instead of malloc and free. It accurately determines the amount of
|
||||
* memory available by using CompactMem. Notice that if left to its
|
||||
* own devices, this code can chew up all available space in the
|
||||
* application's zone, with the exception of the rather small "slop"
|
||||
* factor computed in jpeg_mem_available(). The application can ensure
|
||||
* that more space is left over by reducing max_memory_to_use.
|
||||
*
|
||||
* Large images are swapped to disk using temporary files and System 7.0+'s
|
||||
* temporary folder functionality.
|
||||
*
|
||||
* Note that jmemmac.c depends on two features of MacOS that were first
|
||||
* introduced in System 7: FindFolder and the FSSpec-based calls.
|
||||
* If your application uses jmemmac.c and is run under System 6 or earlier,
|
||||
* and the jpeg library decides it needs a temporary file, it will abort,
|
||||
* printing error messages about requiring System 7. (If no temporary files
|
||||
* are created, it will run fine.)
|
||||
*
|
||||
* If you want to use jmemmac.c in an application that might be used with
|
||||
* System 6 or earlier, then you should remove dependencies on FindFolder
|
||||
* and the FSSpec calls. You will need to replace FindFolder with some
|
||||
* other mechanism for finding a place to put temporary files, and you
|
||||
* should replace the FSSpec calls with their HFS equivalents:
|
||||
*
|
||||
* FSpDelete -> HDelete
|
||||
* FSpGetFInfo -> HGetFInfo
|
||||
* FSpCreate -> HCreate
|
||||
* FSpOpenDF -> HOpen *** Note: not HOpenDF ***
|
||||
* FSMakeFSSpec -> (fill in spec by hand.)
|
||||
*
|
||||
* (Use HOpen instead of HOpenDF. HOpen is just a glue-interface to PBHOpen,
|
||||
* which is on all HFS macs. HOpenDF is a System 7 addition which avoids the
|
||||
* ages-old problem of names starting with a period.)
|
||||
*
|
||||
* Contributed by Sam Bushell (jsam@iagu.on.net) and
|
||||
* Dan Gildor (gyld@in-touch.com).
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef USE_MAC_MEMMGR /* make sure user got configuration right */
|
||||
You forgot to define USE_MAC_MEMMGR in jconfig.h. /* deliberate syntax error */
|
||||
#endif
|
||||
|
||||
#include <Memory.h> /* we use the MacOS memory manager */
|
||||
#include <Files.h> /* we use the MacOS File stuff */
|
||||
#include <Folders.h> /* we use the MacOS HFS stuff */
|
||||
#include <Script.h> /* for smSystemScript */
|
||||
#include <Gestalt.h> /* we use Gestalt to test for specific functionality */
|
||||
|
||||
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
|
||||
#define TEMP_FILE_NAME "JPG%03d.TMP"
|
||||
#endif
|
||||
|
||||
static int next_file_num; /* to distinguish among several temp files */
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the MacOS library
|
||||
* routines NewPtr() and DisposePtr(), which allocate fixed-address
|
||||
* storage. Unfortunately, the IJG library isn't smart enough to cope
|
||||
* with relocatable storage.
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) NewPtr(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
DisposePtr((Ptr) object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: we include FAR keywords in the routine declarations simply for
|
||||
* consistency with the rest of the IJG code; FAR should expand to empty
|
||||
* on rational architectures like the Mac.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) NewPtr(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
DisposePtr((Ptr) object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
long limit = cinfo->mem->max_memory_to_use - already_allocated;
|
||||
long slop, mem;
|
||||
|
||||
/* Don't ask for more than what application has told us we may use */
|
||||
if (max_bytes_needed > limit && limit > 0)
|
||||
max_bytes_needed = limit;
|
||||
/* Find whether there's a big enough free block in the heap.
|
||||
* CompactMem tries to create a contiguous block of the requested size,
|
||||
* and then returns the size of the largest free block (which could be
|
||||
* much more or much less than we asked for).
|
||||
* We add some slop to ensure we don't use up all available memory.
|
||||
*/
|
||||
slop = max_bytes_needed / 16 + 32768L;
|
||||
mem = CompactMem(max_bytes_needed + slop) - slop;
|
||||
if (mem < 0)
|
||||
mem = 0; /* sigh, couldn't even get the slop */
|
||||
/* Don't take more than the application says we can have */
|
||||
if (mem > limit && limit > 0)
|
||||
mem = limit;
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
long bytes = byte_count;
|
||||
long retVal;
|
||||
|
||||
if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
|
||||
retVal = FSRead ( info->temp_file, &bytes,
|
||||
(unsigned char *) buffer_address );
|
||||
if ( retVal != noErr || bytes != byte_count )
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
long bytes = byte_count;
|
||||
long retVal;
|
||||
|
||||
if ( SetFPos ( info->temp_file, fsFromStart, file_offset ) != noErr )
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
|
||||
retVal = FSWrite ( info->temp_file, &bytes,
|
||||
(unsigned char *) buffer_address );
|
||||
if ( retVal != noErr || bytes != byte_count )
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
FSClose ( info->temp_file );
|
||||
FSpDelete ( &(info->tempSpec) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object.
|
||||
*
|
||||
* This version uses FindFolder to find the Temporary Items folder,
|
||||
* and puts the temporary file in there.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
short tmpRef, vRefNum;
|
||||
long dirID;
|
||||
FInfo finderInfo;
|
||||
FSSpec theSpec;
|
||||
Str255 fName;
|
||||
OSErr osErr;
|
||||
long gestaltResponse = 0;
|
||||
|
||||
/* Check that FSSpec calls are available. */
|
||||
osErr = Gestalt( gestaltFSAttr, &gestaltResponse );
|
||||
if ( ( osErr != noErr )
|
||||
|| !( gestaltResponse & (1<<gestaltHasFSSpecCalls) ) )
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required");
|
||||
/* TO DO: add a proper error message to jerror.h. */
|
||||
|
||||
/* Check that FindFolder is available. */
|
||||
osErr = Gestalt( gestaltFindFolderAttr, &gestaltResponse );
|
||||
if ( ( osErr != noErr )
|
||||
|| !( gestaltResponse & (1<<gestaltFindFolderPresent) ) )
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, "- System 7.0 or later required.");
|
||||
/* TO DO: add a proper error message to jerror.h. */
|
||||
|
||||
osErr = FindFolder ( kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
|
||||
&vRefNum, &dirID );
|
||||
if ( osErr != noErr )
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, "- temporary items folder unavailable");
|
||||
/* TO DO: Try putting the temp files somewhere else. */
|
||||
|
||||
/* Keep generating file names till we find one that's not in use */
|
||||
for (;;) {
|
||||
next_file_num++; /* advance counter */
|
||||
|
||||
sprintf(info->temp_name, TEMP_FILE_NAME, next_file_num);
|
||||
strcpy ( (Ptr)fName+1, info->temp_name );
|
||||
*fName = strlen (info->temp_name);
|
||||
osErr = FSMakeFSSpec ( vRefNum, dirID, fName, &theSpec );
|
||||
|
||||
if ( (osErr = FSpGetFInfo ( &theSpec, &finderInfo ) ) != noErr )
|
||||
break;
|
||||
}
|
||||
|
||||
osErr = FSpCreate ( &theSpec, '????', '????', smSystemScript );
|
||||
if ( osErr != noErr )
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
|
||||
|
||||
osErr = FSpOpenDF ( &theSpec, fsRdWrPerm, &(info->temp_file) );
|
||||
if ( osErr != noErr )
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
|
||||
|
||||
info->tempSpec = theSpec;
|
||||
|
||||
info->read_backing_store = read_backing_store;
|
||||
info->write_backing_store = write_backing_store;
|
||||
info->close_backing_store = close_backing_store;
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr cinfo)
|
||||
{
|
||||
next_file_num = 0;
|
||||
|
||||
/* max_memory_to_use will be initialized to FreeMem()'s result;
|
||||
* the calling application might later reduce it, for example
|
||||
* to leave room to invoke multiple JPEG objects.
|
||||
* Note that FreeMem returns the total number of free bytes;
|
||||
* it may not be possible to allocate a single block of this size.
|
||||
*/
|
||||
return FreeMem();
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* no work */
|
||||
}
|
||||
174
jmemmgr.c
174
jmemmgr.c
@@ -57,26 +57,23 @@ extern char * getenv JPP((const char * name));
|
||||
* requirement, and we had better do so too.
|
||||
* There isn't any really portable way to determine the worst-case alignment
|
||||
* requirement. This module assumes that the alignment requirement is
|
||||
* multiples of ALIGN_SIZE.
|
||||
* By default, we define ALIGN_SIZE as sizeof(double). This is necessary on some
|
||||
* multiples of sizeof(ALIGN_TYPE).
|
||||
* By default, we define ALIGN_TYPE as double. This is necessary on some
|
||||
* workstations (where doubles really do need 8-byte alignment) and will work
|
||||
* fine on nearly everything. If your machine has lesser alignment needs,
|
||||
* you can save a few bytes by making ALIGN_SIZE smaller.
|
||||
* you can save a few bytes by making ALIGN_TYPE smaller.
|
||||
* The only place I know of where this will NOT work is certain Macintosh
|
||||
* 680x0 compilers that define double as a 10-byte IEEE extended float.
|
||||
* Doing 10-byte alignment is counterproductive because longwords won't be
|
||||
* aligned well. Put "#define ALIGN_SIZE 4" in jconfig.h if you have
|
||||
* aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have
|
||||
* such a compiler.
|
||||
*/
|
||||
|
||||
#ifndef ALIGN_SIZE /* so can override from jconfig.h */
|
||||
#ifndef WITH_SIMD
|
||||
#define ALIGN_SIZE SIZEOF(double)
|
||||
#else
|
||||
#define ALIGN_SIZE 16 /* Most SIMD implementations require this */
|
||||
#endif
|
||||
#ifndef ALIGN_TYPE /* so can override from jconfig.h */
|
||||
#define ALIGN_TYPE double
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* We allocate objects from "pools", where each pool is gotten with a single
|
||||
* request to jpeg_get_small() or jpeg_get_large(). There is no per-object
|
||||
@@ -84,24 +81,34 @@ extern char * getenv JPP((const char * name));
|
||||
* header with a link to the next pool of the same class.
|
||||
* Small and large pool headers are identical except that the latter's
|
||||
* link pointer must be FAR on 80x86 machines.
|
||||
* Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
|
||||
* field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
|
||||
* of the alignment requirement of ALIGN_TYPE.
|
||||
*/
|
||||
|
||||
typedef struct small_pool_struct * small_pool_ptr;
|
||||
typedef union small_pool_struct * small_pool_ptr;
|
||||
|
||||
typedef struct small_pool_struct {
|
||||
small_pool_ptr next; /* next in list of pools */
|
||||
size_t bytes_used; /* how many bytes already used within pool */
|
||||
size_t bytes_left; /* bytes still available in this pool */
|
||||
typedef union small_pool_struct {
|
||||
struct {
|
||||
small_pool_ptr next; /* next in list of pools */
|
||||
size_t bytes_used; /* how many bytes already used within pool */
|
||||
size_t bytes_left; /* bytes still available in this pool */
|
||||
} hdr;
|
||||
ALIGN_TYPE dummy; /* included in union to ensure alignment */
|
||||
} small_pool_hdr;
|
||||
|
||||
typedef struct large_pool_struct FAR * large_pool_ptr;
|
||||
typedef union large_pool_struct FAR * large_pool_ptr;
|
||||
|
||||
typedef struct large_pool_struct {
|
||||
large_pool_ptr next; /* next in list of pools */
|
||||
size_t bytes_used; /* how many bytes already used within pool */
|
||||
size_t bytes_left; /* bytes still available in this pool */
|
||||
typedef union large_pool_struct {
|
||||
struct {
|
||||
large_pool_ptr next; /* next in list of pools */
|
||||
size_t bytes_used; /* how many bytes already used within pool */
|
||||
size_t bytes_left; /* bytes still available in this pool */
|
||||
} hdr;
|
||||
ALIGN_TYPE dummy; /* included in union to ensure alignment */
|
||||
} large_pool_hdr;
|
||||
|
||||
|
||||
/*
|
||||
* Here is the full definition of a memory manager object.
|
||||
*/
|
||||
@@ -122,7 +129,7 @@ typedef struct {
|
||||
jvirt_barray_ptr virt_barray_list;
|
||||
|
||||
/* This counts total space obtained from jpeg_get_small/large */
|
||||
size_t total_space_allocated;
|
||||
long total_space_allocated;
|
||||
|
||||
/* alloc_sarray and alloc_barray set this value for use by virtual
|
||||
* array routines.
|
||||
@@ -190,16 +197,16 @@ print_mem_stats (j_common_ptr cinfo, int pool_id)
|
||||
pool_id, mem->total_space_allocated);
|
||||
|
||||
for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
|
||||
lhdr_ptr = lhdr_ptr->next) {
|
||||
lhdr_ptr = lhdr_ptr->hdr.next) {
|
||||
fprintf(stderr, " Large chunk used %ld\n",
|
||||
(long) lhdr_ptr->bytes_used);
|
||||
(long) lhdr_ptr->hdr.bytes_used);
|
||||
}
|
||||
|
||||
for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
|
||||
shdr_ptr = shdr_ptr->next) {
|
||||
shdr_ptr = shdr_ptr->hdr.next) {
|
||||
fprintf(stderr, " Small chunk used %ld free %ld\n",
|
||||
(long) shdr_ptr->bytes_used,
|
||||
(long) shdr_ptr->bytes_left);
|
||||
(long) shdr_ptr->hdr.bytes_used,
|
||||
(long) shdr_ptr->hdr.bytes_left);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,10 +236,6 @@ out_of_memory (j_common_ptr cinfo, int which)
|
||||
* and we also distinguish the first pool of a class from later ones.
|
||||
* NOTE: the values given work fairly well on both 16- and 32-bit-int
|
||||
* machines, but may be too small if longs are 64 bits or more.
|
||||
*
|
||||
* Since we do not know what alignment malloc() gives us, we have to
|
||||
* allocate ALIGN_SIZE-1 extra space per pool to have room for alignment
|
||||
* adjustment.
|
||||
*/
|
||||
|
||||
static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
|
||||
@@ -257,36 +260,33 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
||||
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
|
||||
small_pool_ptr hdr_ptr, prev_hdr_ptr;
|
||||
char * data_ptr;
|
||||
size_t min_request, slop;
|
||||
|
||||
/*
|
||||
* Round up the requested size to a multiple of ALIGN_SIZE in order
|
||||
* to assure alignment for the next object allocated in the same pool
|
||||
* and so that algorithms can straddle outside the proper area up
|
||||
* to the next alignment.
|
||||
*/
|
||||
sizeofobject = jround_up(sizeofobject, ALIGN_SIZE);
|
||||
size_t odd_bytes, min_request, slop;
|
||||
|
||||
/* Check for unsatisfiable request (do now to ensure no overflow below) */
|
||||
if ((SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
|
||||
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
|
||||
out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
|
||||
|
||||
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
|
||||
odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
|
||||
if (odd_bytes > 0)
|
||||
sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
|
||||
|
||||
/* See if space is available in any existing pool */
|
||||
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
|
||||
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
|
||||
prev_hdr_ptr = NULL;
|
||||
hdr_ptr = mem->small_list[pool_id];
|
||||
while (hdr_ptr != NULL) {
|
||||
if (hdr_ptr->bytes_left >= sizeofobject)
|
||||
if (hdr_ptr->hdr.bytes_left >= sizeofobject)
|
||||
break; /* found pool with enough space */
|
||||
prev_hdr_ptr = hdr_ptr;
|
||||
hdr_ptr = hdr_ptr->next;
|
||||
hdr_ptr = hdr_ptr->hdr.next;
|
||||
}
|
||||
|
||||
/* Time to make a new pool? */
|
||||
if (hdr_ptr == NULL) {
|
||||
/* min_request is what we need now, slop is what will be leftover */
|
||||
min_request = SIZEOF(small_pool_hdr) + sizeofobject + ALIGN_SIZE - 1;
|
||||
min_request = sizeofobject + SIZEOF(small_pool_hdr);
|
||||
if (prev_hdr_ptr == NULL) /* first pool in class? */
|
||||
slop = first_pool_slop[pool_id];
|
||||
else
|
||||
@@ -305,23 +305,20 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
||||
}
|
||||
mem->total_space_allocated += min_request + slop;
|
||||
/* Success, initialize the new pool header and add to end of list */
|
||||
hdr_ptr->next = NULL;
|
||||
hdr_ptr->bytes_used = 0;
|
||||
hdr_ptr->bytes_left = sizeofobject + slop;
|
||||
hdr_ptr->hdr.next = NULL;
|
||||
hdr_ptr->hdr.bytes_used = 0;
|
||||
hdr_ptr->hdr.bytes_left = sizeofobject + slop;
|
||||
if (prev_hdr_ptr == NULL) /* first pool in class? */
|
||||
mem->small_list[pool_id] = hdr_ptr;
|
||||
else
|
||||
prev_hdr_ptr->next = hdr_ptr;
|
||||
prev_hdr_ptr->hdr.next = hdr_ptr;
|
||||
}
|
||||
|
||||
/* OK, allocate the object from the current pool */
|
||||
data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
|
||||
data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
|
||||
if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
|
||||
data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
|
||||
data_ptr += hdr_ptr->bytes_used; /* point to place for object */
|
||||
hdr_ptr->bytes_used += sizeofobject;
|
||||
hdr_ptr->bytes_left -= sizeofobject;
|
||||
data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
|
||||
data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
|
||||
hdr_ptr->hdr.bytes_used += sizeofobject;
|
||||
hdr_ptr->hdr.bytes_left -= sizeofobject;
|
||||
|
||||
return (void *) data_ptr;
|
||||
}
|
||||
@@ -347,45 +344,37 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
||||
{
|
||||
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
|
||||
large_pool_ptr hdr_ptr;
|
||||
char FAR * data_ptr;
|
||||
|
||||
/*
|
||||
* Round up the requested size to a multiple of ALIGN_SIZE so that
|
||||
* algorithms can straddle outside the proper area up to the next
|
||||
* alignment.
|
||||
*/
|
||||
sizeofobject = jround_up(sizeofobject, ALIGN_SIZE);
|
||||
size_t odd_bytes;
|
||||
|
||||
/* Check for unsatisfiable request (do now to ensure no overflow below) */
|
||||
if ((SIZEOF(large_pool_hdr) + sizeofobject + ALIGN_SIZE - 1) > MAX_ALLOC_CHUNK)
|
||||
if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
|
||||
out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
|
||||
|
||||
/* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
|
||||
odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
|
||||
if (odd_bytes > 0)
|
||||
sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
|
||||
|
||||
/* Always make a new pool */
|
||||
if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
|
||||
ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
|
||||
|
||||
hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
|
||||
SIZEOF(large_pool_hdr) +
|
||||
ALIGN_SIZE - 1);
|
||||
SIZEOF(large_pool_hdr));
|
||||
if (hdr_ptr == NULL)
|
||||
out_of_memory(cinfo, 4); /* jpeg_get_large failed */
|
||||
mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr) + ALIGN_SIZE - 1;
|
||||
mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
|
||||
|
||||
/* Success, initialize the new pool header and add to list */
|
||||
hdr_ptr->next = mem->large_list[pool_id];
|
||||
hdr_ptr->hdr.next = mem->large_list[pool_id];
|
||||
/* We maintain space counts in each pool header for statistical purposes,
|
||||
* even though they are not needed for allocation.
|
||||
*/
|
||||
hdr_ptr->bytes_used = sizeofobject;
|
||||
hdr_ptr->bytes_left = 0;
|
||||
hdr_ptr->hdr.bytes_used = sizeofobject;
|
||||
hdr_ptr->hdr.bytes_left = 0;
|
||||
mem->large_list[pool_id] = hdr_ptr;
|
||||
|
||||
data_ptr = (char *) hdr_ptr; /* point to first data byte in pool... */
|
||||
data_ptr += SIZEOF(small_pool_hdr); /* ...by skipping the header... */
|
||||
if ((size_t)data_ptr % ALIGN_SIZE) /* ...and adjust for alignment */
|
||||
data_ptr += ALIGN_SIZE - (size_t)data_ptr % ALIGN_SIZE;
|
||||
|
||||
return (void FAR *) data_ptr;
|
||||
return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
|
||||
}
|
||||
|
||||
|
||||
@@ -400,10 +389,6 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
|
||||
* this chunking of rows. The rowsperchunk value is left in the mem manager
|
||||
* object so that it can be saved away if this sarray is the workspace for
|
||||
* a virtual array.
|
||||
*
|
||||
* Since we are often upsampling with a factor 2, we align the size (not
|
||||
* the start) to 2 * ALIGN_SIZE so that the upsampling routines don't have
|
||||
* to be as careful about size.
|
||||
*/
|
||||
|
||||
METHODDEF(JSAMPARRAY)
|
||||
@@ -417,11 +402,6 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
|
||||
JDIMENSION rowsperchunk, currow, i;
|
||||
long ltemp;
|
||||
|
||||
/* Make sure each row is properly aligned */
|
||||
if ((ALIGN_SIZE % SIZEOF(JSAMPLE)) != 0)
|
||||
out_of_memory(cinfo, 5); /* safety check */
|
||||
samplesperrow = (JDIMENSION)jround_up(samplesperrow, (2 * ALIGN_SIZE) / SIZEOF(JSAMPLE));
|
||||
|
||||
/* Calculate max # of rows allowed in one allocation chunk */
|
||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||
((long) samplesperrow * SIZEOF(JSAMPLE));
|
||||
@@ -470,10 +450,6 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
|
||||
JDIMENSION rowsperchunk, currow, i;
|
||||
long ltemp;
|
||||
|
||||
/* Make sure each row is properly aligned */
|
||||
if ((SIZEOF(JBLOCK) % ALIGN_SIZE) != 0)
|
||||
out_of_memory(cinfo, 6); /* safety check */
|
||||
|
||||
/* Calculate max # of rows allowed in one allocation chunk */
|
||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||
((long) blocksperrow * SIZEOF(JBLOCK));
|
||||
@@ -608,8 +584,8 @@ realize_virt_arrays (j_common_ptr cinfo)
|
||||
/* Allocate the in-memory buffers for any unrealized virtual arrays */
|
||||
{
|
||||
my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
|
||||
size_t space_per_minheight, maximum_space, avail_mem;
|
||||
size_t minheights, max_minheights;
|
||||
long space_per_minheight, maximum_space, avail_mem;
|
||||
long minheights, max_minheights;
|
||||
jvirt_sarray_ptr sptr;
|
||||
jvirt_barray_ptr bptr;
|
||||
|
||||
@@ -992,9 +968,9 @@ free_pool (j_common_ptr cinfo, int pool_id)
|
||||
mem->large_list[pool_id] = NULL;
|
||||
|
||||
while (lhdr_ptr != NULL) {
|
||||
large_pool_ptr next_lhdr_ptr = lhdr_ptr->next;
|
||||
space_freed = lhdr_ptr->bytes_used +
|
||||
lhdr_ptr->bytes_left +
|
||||
large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
|
||||
space_freed = lhdr_ptr->hdr.bytes_used +
|
||||
lhdr_ptr->hdr.bytes_left +
|
||||
SIZEOF(large_pool_hdr);
|
||||
jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
|
||||
mem->total_space_allocated -= space_freed;
|
||||
@@ -1006,9 +982,9 @@ free_pool (j_common_ptr cinfo, int pool_id)
|
||||
mem->small_list[pool_id] = NULL;
|
||||
|
||||
while (shdr_ptr != NULL) {
|
||||
small_pool_ptr next_shdr_ptr = shdr_ptr->next;
|
||||
space_freed = shdr_ptr->bytes_used +
|
||||
shdr_ptr->bytes_left +
|
||||
small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
|
||||
space_freed = shdr_ptr->hdr.bytes_used +
|
||||
shdr_ptr->hdr.bytes_left +
|
||||
SIZEOF(small_pool_hdr);
|
||||
jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
|
||||
mem->total_space_allocated -= space_freed;
|
||||
@@ -1065,16 +1041,16 @@ jinit_memory_mgr (j_common_ptr cinfo)
|
||||
* in common if and only if X is a power of 2, ie has only one one-bit.
|
||||
* Some compilers may give an "unreachable code" warning here; ignore it.
|
||||
*/
|
||||
if ((ALIGN_SIZE & (ALIGN_SIZE-1)) != 0)
|
||||
if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
|
||||
ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
|
||||
/* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
|
||||
* a multiple of ALIGN_SIZE.
|
||||
* a multiple of SIZEOF(ALIGN_TYPE).
|
||||
* Again, an "unreachable code" warning may be ignored here.
|
||||
* But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
|
||||
*/
|
||||
test_mac = (size_t) MAX_ALLOC_CHUNK;
|
||||
if ((long) test_mac != MAX_ALLOC_CHUNK ||
|
||||
(MAX_ALLOC_CHUNK % ALIGN_SIZE) != 0)
|
||||
(MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
|
||||
ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
|
||||
|
||||
max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
|
||||
|
||||
276
jmemname.c
Normal file
276
jmemname.c
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* jmemname.c
|
||||
*
|
||||
* Copyright (C) 1992-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file provides a generic implementation of the system-dependent
|
||||
* portion of the JPEG memory manager. This implementation assumes that
|
||||
* you must explicitly construct a name for each temp file.
|
||||
* Also, the problem of determining the amount of memory available
|
||||
* is shoved onto the user.
|
||||
*/
|
||||
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h" /* import the system-dependent declarations */
|
||||
|
||||
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
|
||||
extern void * malloc JPP((size_t size));
|
||||
extern void free JPP((void *ptr));
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET /* pre-ANSI systems may not define this; */
|
||||
#define SEEK_SET 0 /* if not, assume 0 is correct */
|
||||
#endif
|
||||
|
||||
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
|
||||
#define READ_BINARY "r"
|
||||
#define RW_BINARY "w+"
|
||||
#else
|
||||
#ifdef VMS /* VMS is very nonstandard */
|
||||
#define READ_BINARY "rb", "ctx=stm"
|
||||
#define RW_BINARY "w+b", "ctx=stm"
|
||||
#else /* standard ANSI-compliant case */
|
||||
#define READ_BINARY "rb"
|
||||
#define RW_BINARY "w+b"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Selection of a file name for a temporary file.
|
||||
* This is system-dependent!
|
||||
*
|
||||
* The code as given is suitable for most Unix systems, and it is easily
|
||||
* modified for most non-Unix systems. Some notes:
|
||||
* 1. The temp file is created in the directory named by TEMP_DIRECTORY.
|
||||
* The default value is /usr/tmp, which is the conventional place for
|
||||
* creating large temp files on Unix. On other systems you'll probably
|
||||
* want to change the file location. You can do this by editing the
|
||||
* #define, or (preferred) by defining TEMP_DIRECTORY in jconfig.h.
|
||||
*
|
||||
* 2. If you need to change the file name as well as its location,
|
||||
* you can override the TEMP_FILE_NAME macro. (Note that this is
|
||||
* actually a printf format string; it must contain %s and %d.)
|
||||
* Few people should need to do this.
|
||||
*
|
||||
* 3. mktemp() is used to ensure that multiple processes running
|
||||
* simultaneously won't select the same file names. If your system
|
||||
* doesn't have mktemp(), define NO_MKTEMP to do it the hard way.
|
||||
* (If you don't have <errno.h>, also define NO_ERRNO_H.)
|
||||
*
|
||||
* 4. You probably want to define NEED_SIGNAL_CATCHER so that cjpeg.c/djpeg.c
|
||||
* will cause the temp files to be removed if you stop the program early.
|
||||
*/
|
||||
|
||||
#ifndef TEMP_DIRECTORY /* can override from jconfig.h or Makefile */
|
||||
#define TEMP_DIRECTORY "/usr/tmp/" /* recommended setting for Unix */
|
||||
#endif
|
||||
|
||||
static int next_file_num; /* to distinguish among several temp files */
|
||||
|
||||
#ifdef NO_MKTEMP
|
||||
|
||||
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
|
||||
#define TEMP_FILE_NAME "%sJPG%03d.TMP"
|
||||
#endif
|
||||
|
||||
#ifndef NO_ERRNO_H
|
||||
#include <errno.h> /* to define ENOENT */
|
||||
#endif
|
||||
|
||||
/* ANSI C specifies that errno is a macro, but on older systems it's more
|
||||
* likely to be a plain int variable. And not all versions of errno.h
|
||||
* bother to declare it, so we have to in order to be most portable. Thus:
|
||||
*/
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
select_file_name (char * fname)
|
||||
{
|
||||
FILE * tfile;
|
||||
|
||||
/* Keep generating file names till we find one that's not in use */
|
||||
for (;;) {
|
||||
next_file_num++; /* advance counter */
|
||||
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
|
||||
if ((tfile = fopen(fname, READ_BINARY)) == NULL) {
|
||||
/* fopen could have failed for a reason other than the file not
|
||||
* being there; for example, file there but unreadable.
|
||||
* If <errno.h> isn't available, then we cannot test the cause.
|
||||
*/
|
||||
#ifdef ENOENT
|
||||
if (errno != ENOENT)
|
||||
continue;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
fclose(tfile); /* oops, it's there; close tfile & try again */
|
||||
}
|
||||
}
|
||||
|
||||
#else /* ! NO_MKTEMP */
|
||||
|
||||
/* Note that mktemp() requires the initial filename to end in six X's */
|
||||
#ifndef TEMP_FILE_NAME /* can override from jconfig.h or Makefile */
|
||||
#define TEMP_FILE_NAME "%sJPG%dXXXXXX"
|
||||
#endif
|
||||
|
||||
LOCAL(void)
|
||||
select_file_name (char * fname)
|
||||
{
|
||||
next_file_num++; /* advance counter */
|
||||
sprintf(fname, TEMP_FILE_NAME, TEMP_DIRECTORY, next_file_num);
|
||||
mktemp(fname); /* make sure file name is unique */
|
||||
/* mktemp replaces the trailing XXXXXX with a unique string of characters */
|
||||
}
|
||||
|
||||
#endif /* NO_MKTEMP */
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocation and freeing are controlled by the regular library
|
||||
* routines malloc() and free().
|
||||
*/
|
||||
|
||||
GLOBAL(void *)
|
||||
jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "Large" objects are treated the same as "small" ones.
|
||||
* NB: although we include FAR keywords in the routine declarations,
|
||||
* this file won't actually work in 80x86 small/medium model; at least,
|
||||
* you probably won't be able to process useful-size images in only 64KB.
|
||||
*/
|
||||
|
||||
GLOBAL(void FAR *)
|
||||
jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
|
||||
{
|
||||
return (void FAR *) malloc(sizeofobject);
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
{
|
||||
free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine computes the total memory space available for allocation.
|
||||
* It's impossible to do this in a portable way; our current solution is
|
||||
* to make the user tell us (with a default value set at compile time).
|
||||
* If you can actually get the available space, it's a good idea to subtract
|
||||
* a slop factor of 5% or so.
|
||||
*/
|
||||
|
||||
#ifndef DEFAULT_MAX_MEM /* so can override from makefile */
|
||||
#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */
|
||||
#endif
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
return cinfo->mem->max_memory_to_use - already_allocated;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Backing store (temporary file) management.
|
||||
* Backing store objects are only used when the value returned by
|
||||
* jpeg_mem_available is less than the total space needed. You can dispense
|
||||
* with these routines if you have plenty of virtual memory; see jmemnobs.c.
|
||||
*/
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
read_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFREAD(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_READ);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
write_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
void FAR * buffer_address,
|
||||
long file_offset, long byte_count)
|
||||
{
|
||||
if (fseek(info->temp_file, file_offset, SEEK_SET))
|
||||
ERREXIT(cinfo, JERR_TFILE_SEEK);
|
||||
if (JFWRITE(info->temp_file, buffer_address, byte_count)
|
||||
!= (size_t) byte_count)
|
||||
ERREXIT(cinfo, JERR_TFILE_WRITE);
|
||||
}
|
||||
|
||||
|
||||
METHODDEF(void)
|
||||
close_backing_store (j_common_ptr cinfo, backing_store_ptr info)
|
||||
{
|
||||
fclose(info->temp_file); /* close the file */
|
||||
unlink(info->temp_name); /* delete the file */
|
||||
/* If your system doesn't have unlink(), use remove() instead.
|
||||
* remove() is the ANSI-standard name for this function, but if
|
||||
* your system was ANSI you'd be using jmemansi.c, right?
|
||||
*/
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initial opening of a backing-store object.
|
||||
*/
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
|
||||
long total_bytes_needed)
|
||||
{
|
||||
select_file_name(info->temp_name);
|
||||
if ((info->temp_file = fopen(info->temp_name, RW_BINARY)) == NULL)
|
||||
ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
|
||||
info->read_backing_store = read_backing_store;
|
||||
info->write_backing_store = write_backing_store;
|
||||
info->close_backing_store = close_backing_store;
|
||||
TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These routines take care of any system-dependent initialization and
|
||||
* cleanup required.
|
||||
*/
|
||||
|
||||
GLOBAL(long)
|
||||
jpeg_mem_init (j_common_ptr cinfo)
|
||||
{
|
||||
next_file_num = 0; /* initialize temp file name generator */
|
||||
return DEFAULT_MAX_MEM; /* default for max_memory_to_use */
|
||||
}
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_term (j_common_ptr cinfo)
|
||||
{
|
||||
/* no work */
|
||||
}
|
||||
@@ -69,9 +69,9 @@ jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
|
||||
* Here we always say, "we got all you want bud!"
|
||||
*/
|
||||
|
||||
GLOBAL(size_t)
|
||||
jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed,
|
||||
size_t max_bytes_needed, size_t already_allocated)
|
||||
GLOBAL(long)
|
||||
jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
|
||||
long max_bytes_needed, long already_allocated)
|
||||
{
|
||||
return max_bytes_needed;
|
||||
}
|
||||
|
||||
@@ -100,10 +100,10 @@ EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
|
||||
* Conversely, zero may be returned to always use the minimum amount of memory.
|
||||
*/
|
||||
|
||||
EXTERN(size_t) jpeg_mem_available JPP((j_common_ptr cinfo,
|
||||
size_t min_bytes_needed,
|
||||
size_t max_bytes_needed,
|
||||
size_t already_allocated));
|
||||
EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
|
||||
long min_bytes_needed,
|
||||
long max_bytes_needed,
|
||||
long already_allocated));
|
||||
|
||||
|
||||
/*
|
||||
|
||||
69
jmorecfg.h
69
jmorecfg.h
@@ -2,7 +2,7 @@
|
||||
* jmorecfg.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Copyright (C) 2009, D. R. Commander.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -63,11 +63,11 @@ typedef unsigned char JSAMPLE;
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JSAMPLE;
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJSAMPLE(value) ((int) (value))
|
||||
#else
|
||||
#define GETJSAMPLE(value) ((int) (value) & 0xFF)
|
||||
#endif /* __CHAR_UNSIGNED__ */
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
@@ -114,11 +114,11 @@ typedef unsigned char JOCTET;
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
|
||||
typedef char JOCTET;
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
#define GETJOCTET(value) (value)
|
||||
#else
|
||||
#define GETJOCTET(value) ((value) & 0xFF)
|
||||
#endif /* __CHAR_UNSIGNED__ */
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
@@ -135,11 +135,11 @@ typedef char JOCTET;
|
||||
#ifdef HAVE_UNSIGNED_CHAR
|
||||
typedef unsigned char UINT8;
|
||||
#else /* not HAVE_UNSIGNED_CHAR */
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
typedef char UINT8;
|
||||
#else /* not __CHAR_UNSIGNED__ */
|
||||
#else /* not CHAR_IS_UNSIGNED */
|
||||
typedef short UINT8;
|
||||
#endif /* __CHAR_UNSIGNED__ */
|
||||
#endif /* CHAR_IS_UNSIGNED */
|
||||
#endif /* HAVE_UNSIGNED_CHAR */
|
||||
|
||||
/* UINT16 must hold at least the values 0..65535. */
|
||||
@@ -159,8 +159,14 @@ typedef short INT16;
|
||||
/* INT32 must hold at least signed 32-bit values. */
|
||||
|
||||
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
|
||||
#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */
|
||||
#ifndef _BASETSD_H /* MinGW is slightly different */
|
||||
#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */
|
||||
typedef long INT32;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Datatype used for image dimensions. The JPEG standard only supports
|
||||
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
||||
@@ -210,11 +216,13 @@ typedef unsigned int JDIMENSION;
|
||||
* explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
|
||||
*/
|
||||
|
||||
#ifndef FAR
|
||||
#ifdef NEED_FAR_POINTERS
|
||||
#define FAR far
|
||||
#else
|
||||
#define FAR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -257,8 +265,6 @@ typedef int boolean;
|
||||
* (You may HAVE to do that if your compiler doesn't like null source files.)
|
||||
*/
|
||||
|
||||
/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
|
||||
|
||||
/* Capability options common to encoder and decoder: */
|
||||
|
||||
#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
|
||||
@@ -267,9 +273,10 @@ typedef int boolean;
|
||||
|
||||
/* Encoder capability options: */
|
||||
|
||||
#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/
|
||||
#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
|
||||
/* Note: if you selected 12-bit data precision, it is dangerous to turn off
|
||||
* ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
|
||||
@@ -283,12 +290,12 @@ typedef int boolean;
|
||||
|
||||
/* Decoder capability options: */
|
||||
|
||||
#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
|
||||
#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
|
||||
#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
|
||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
|
||||
#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
|
||||
#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
|
||||
#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
|
||||
#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? */
|
||||
@@ -317,37 +324,31 @@ typedef int boolean;
|
||||
#define RGB_BLUE 2 /* Offset of Blue */
|
||||
#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
|
||||
|
||||
#define JPEG_NUMCS 12
|
||||
|
||||
static const int rgb_red[JPEG_NUMCS] = {
|
||||
-1, -1, RGB_RED, -1, -1, -1, 0, 0, 2, 2, 3, 1
|
||||
};
|
||||
|
||||
static const int rgb_green[JPEG_NUMCS] = {
|
||||
-1, -1, RGB_GREEN, -1, -1, -1, 1, 1, 1, 1, 2, 2
|
||||
};
|
||||
|
||||
static const int rgb_blue[JPEG_NUMCS] = {
|
||||
-1, -1, RGB_BLUE, -1, -1, -1, 2, 2, 0, 0, 1, 3
|
||||
};
|
||||
|
||||
static const int rgb_pixelsize[JPEG_NUMCS] = {
|
||||
-1, -1, RGB_PIXELSIZE, -1, -1, -1, 3, 4, 3, 4, 4, 4
|
||||
};
|
||||
|
||||
/* 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
|
||||
#ifndef WITH_SIMD
|
||||
#define MULTIPLIER int /* type for fastest integer multiply */
|
||||
#else
|
||||
#define MULTIPLIER short /* prefer 16-bit with SIMD for parellelism */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
45
jpegint.h
45
jpegint.h
@@ -2,6 +2,7 @@
|
||||
* jpegint.h
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* Modified 1997-2009 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -99,14 +100,16 @@ struct jpeg_downsampler {
|
||||
};
|
||||
|
||||
/* 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));
|
||||
/* perhaps this should be an array??? */
|
||||
JMETHOD(void, forward_DCT, (j_compress_ptr cinfo,
|
||||
jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks));
|
||||
/* It is useful to allow each component to have a separate FDCT method. */
|
||||
forward_DCT_ptr forward_DCT[MAX_COMPONENTS];
|
||||
};
|
||||
|
||||
/* Entropy encoding */
|
||||
@@ -210,10 +213,6 @@ struct jpeg_entropy_decoder {
|
||||
JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
|
||||
JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
|
||||
JBLOCKROW *MCU_data));
|
||||
|
||||
/* This is here to share code between baseline and progressive decoders; */
|
||||
/* other modules probably should not use it */
|
||||
boolean insufficient_data; /* set TRUE after emitting warning */
|
||||
};
|
||||
|
||||
/* Inverse DCT (also performs dequantization) */
|
||||
@@ -303,7 +302,7 @@ struct jpeg_color_quantizer {
|
||||
#define jinit_downsampler jIDownsampler
|
||||
#define jinit_forward_dct jIFDCT
|
||||
#define jinit_huff_encoder jIHEncoder
|
||||
#define jinit_phuff_encoder jIPHEncoder
|
||||
#define jinit_arith_encoder jIAEncoder
|
||||
#define jinit_marker_writer jIMWriter
|
||||
#define jinit_master_decompress jIDMaster
|
||||
#define jinit_d_main_controller jIDMainC
|
||||
@@ -312,7 +311,7 @@ struct jpeg_color_quantizer {
|
||||
#define jinit_input_controller jIInCtlr
|
||||
#define jinit_marker_reader jIMReader
|
||||
#define jinit_huff_decoder jIHDecoder
|
||||
#define jinit_phuff_decoder jIPHDecoder
|
||||
#define jinit_arith_decoder jIADecoder
|
||||
#define jinit_inverse_dct jIIDCT
|
||||
#define jinit_upsampler jIUpsampler
|
||||
#define jinit_color_deconverter jIDColor
|
||||
@@ -327,6 +326,13 @@ struct jpeg_color_quantizer {
|
||||
#define jzero_far jZeroFar
|
||||
#define jpeg_zigzag_order jZIGTable
|
||||
#define jpeg_natural_order jZAGTable
|
||||
#define jpeg_natural_order7 jZAGTable7
|
||||
#define jpeg_natural_order6 jZAGTable6
|
||||
#define jpeg_natural_order5 jZAGTable5
|
||||
#define jpeg_natural_order4 jZAGTable4
|
||||
#define jpeg_natural_order3 jZAGTable3
|
||||
#define jpeg_natural_order2 jZAGTable2
|
||||
#define jpeg_aritab jAriTab
|
||||
#endif /* NEED_SHORT_EXTERNAL_NAMES */
|
||||
|
||||
|
||||
@@ -344,7 +350,7 @@ EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
|
||||
EXTERN(void) jinit_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));
|
||||
@@ -357,7 +363,7 @@ EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
|
||||
EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jinit_phuff_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));
|
||||
@@ -369,7 +375,7 @@ 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(size_t) jround_up JPP((size_t a, size_t 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));
|
||||
@@ -381,6 +387,15 @@ EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
|
||||
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. */
|
||||
|
||||
|
||||
120
jpeglib.h
120
jpeglib.h
@@ -2,7 +2,7 @@
|
||||
* jpeglib.h
|
||||
*
|
||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||
* Copyright (C) 2009, D. R. Commander.
|
||||
* Modified 2002-2010 by Guido Vollbeding.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
@@ -14,10 +14,6 @@
|
||||
#ifndef JPEGLIB_H
|
||||
#define JPEGLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* First we include the configuration files that record how this
|
||||
* installation of the JPEG library is set up. jconfig.h can be
|
||||
@@ -31,11 +27,19 @@ extern "C" {
|
||||
#include "jmorecfg.h" /* seldom changed options */
|
||||
|
||||
|
||||
/* Version ID for the JPEG library.
|
||||
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
|
||||
#ifdef __cplusplus
|
||||
#ifndef DONT_USE_EXTERN_C
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Version IDs for the JPEG library.
|
||||
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 80".
|
||||
*/
|
||||
|
||||
#define JPEG_LIB_VERSION 62 /* Version 6b */
|
||||
#define JPEG_LIB_VERSION 80 /* Compatibility version 8.0 */
|
||||
#define JPEG_LIB_VERSION_MAJOR 8
|
||||
#define JPEG_LIB_VERSION_MINOR 3
|
||||
|
||||
|
||||
/* Various constants determining the sizes of things.
|
||||
@@ -143,18 +147,18 @@ typedef struct {
|
||||
*/
|
||||
JDIMENSION width_in_blocks;
|
||||
JDIMENSION height_in_blocks;
|
||||
/* Size of a DCT block in samples. Always DCTSIZE for compression.
|
||||
* For decompression this is the size of the output from one DCT block,
|
||||
* reflecting any scaling we choose to apply during the IDCT step.
|
||||
* Values of 1,2,4,8 are likely to be supported. Note that different
|
||||
* components may receive different IDCT scalings.
|
||||
/* Size of a DCT block in samples,
|
||||
* reflecting any scaling we choose to apply during the DCT step.
|
||||
* Values from 1 to 16 are supported.
|
||||
* Note that different components may receive different DCT scalings.
|
||||
*/
|
||||
int DCT_scaled_size;
|
||||
int DCT_h_scaled_size;
|
||||
int DCT_v_scaled_size;
|
||||
/* The downsampled dimensions are the component's actual, unpadded number
|
||||
* of samples at the main buffer (preprocessing/compression interface), thus
|
||||
* downsampled_width = ceil(image_width * Hi/Hmax)
|
||||
* and similarly for height. For decompression, IDCT scaling is included, so
|
||||
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
|
||||
* of samples at the main buffer (preprocessing/compression interface);
|
||||
* DCT scaling is included, so
|
||||
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_h_scaled_size/DCTSIZE)
|
||||
* and similarly for height.
|
||||
*/
|
||||
JDIMENSION downsampled_width; /* actual width in samples */
|
||||
JDIMENSION downsampled_height; /* actual height in samples */
|
||||
@@ -169,7 +173,7 @@ typedef struct {
|
||||
int MCU_width; /* number of blocks per MCU, horizontally */
|
||||
int MCU_height; /* number of blocks per MCU, vertically */
|
||||
int MCU_blocks; /* MCU_width * MCU_height */
|
||||
int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */
|
||||
int MCU_sample_width; /* MCU width in samples: MCU_width * DCT_h_scaled_size */
|
||||
int last_col_width; /* # of non-dummy blocks across in last MCU */
|
||||
int last_row_height; /* # of non-dummy blocks down in last MCU */
|
||||
|
||||
@@ -208,22 +212,13 @@ struct jpeg_marker_struct {
|
||||
|
||||
/* Known color spaces. */
|
||||
|
||||
#define JCS_EXTENSIONS 1
|
||||
|
||||
typedef enum {
|
||||
JCS_UNKNOWN, /* error/unspecified */
|
||||
JCS_GRAYSCALE, /* monochrome */
|
||||
JCS_RGB, /* red/green/blue as specified by the RGB_RED, RGB_GREEN,
|
||||
RGB_BLUE, and RGB_PIXELSIZE macros */
|
||||
JCS_RGB, /* red/green/blue */
|
||||
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
|
||||
JCS_CMYK, /* C/M/Y/K */
|
||||
JCS_YCCK, /* Y/Cb/Cr/K */
|
||||
JCS_EXT_RGB, /* red/green/blue */
|
||||
JCS_EXT_RGBX, /* red/green/blue/x */
|
||||
JCS_EXT_BGR, /* blue/green/red */
|
||||
JCS_EXT_BGRX, /* blue/green/red/x */
|
||||
JCS_EXT_XBGR, /* x/blue/green/red */
|
||||
JCS_EXT_XRGB /* x/red/green/blue */
|
||||
JCS_YCCK /* Y/Cb/Cr/K */
|
||||
} J_COLOR_SPACE;
|
||||
|
||||
/* DCT/IDCT algorithm options. */
|
||||
@@ -305,6 +300,17 @@ struct jpeg_compress_struct {
|
||||
* helper routines to simplify changing parameters.
|
||||
*/
|
||||
|
||||
unsigned int scale_num, scale_denom; /* fraction by which to scale image */
|
||||
|
||||
JDIMENSION jpeg_width; /* scaled JPEG image width */
|
||||
JDIMENSION jpeg_height; /* scaled JPEG image height */
|
||||
/* Dimensions of actual JPEG image that will be written to file,
|
||||
* derived from input dimensions by scaling factors above.
|
||||
* These fields are computed by jpeg_start_compress().
|
||||
* You can also use jpeg_calc_jpeg_dimensions() to determine these values
|
||||
* in advance of calling jpeg_start_compress().
|
||||
*/
|
||||
|
||||
int data_precision; /* bits of precision in image data */
|
||||
|
||||
int num_components; /* # of color components in JPEG image */
|
||||
@@ -312,14 +318,17 @@ struct jpeg_compress_struct {
|
||||
|
||||
jpeg_component_info * comp_info;
|
||||
/* comp_info[i] describes component that appears i'th in SOF */
|
||||
|
||||
|
||||
JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
|
||||
/* ptrs to coefficient quantization tables, or NULL if not defined */
|
||||
|
||||
int q_scale_factor[NUM_QUANT_TBLS];
|
||||
/* ptrs to coefficient quantization tables, or NULL if not defined,
|
||||
* and corresponding scale factors (percentage, initialized 100).
|
||||
*/
|
||||
|
||||
JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
|
||||
JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
|
||||
/* ptrs to Huffman coding tables, or NULL if not defined */
|
||||
|
||||
|
||||
UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
|
||||
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
|
||||
UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
|
||||
@@ -335,6 +344,7 @@ struct jpeg_compress_struct {
|
||||
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
|
||||
boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
|
||||
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
|
||||
boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */
|
||||
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
|
||||
J_DCT_METHOD dct_method; /* DCT algorithm selector */
|
||||
|
||||
@@ -378,6 +388,9 @@ struct jpeg_compress_struct {
|
||||
int max_h_samp_factor; /* largest h_samp_factor */
|
||||
int max_v_samp_factor; /* largest v_samp_factor */
|
||||
|
||||
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
|
||||
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
|
||||
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
|
||||
/* The coefficient controller receives data in units of MCU rows as defined
|
||||
* for fully interleaved scans (whether the JPEG file is interleaved or not).
|
||||
@@ -403,6 +416,10 @@ struct jpeg_compress_struct {
|
||||
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
|
||||
int block_size; /* the basic DCT block size: 1..16 */
|
||||
const int * natural_order; /* natural-order position array */
|
||||
int lim_Se; /* min( Se, DCTSIZE2-1 ) */
|
||||
|
||||
/*
|
||||
* Links to compression subobjects (methods and private variables of modules)
|
||||
*/
|
||||
@@ -549,6 +566,7 @@ struct jpeg_decompress_struct {
|
||||
jpeg_component_info * comp_info;
|
||||
/* comp_info[i] describes component that appears i'th in SOF */
|
||||
|
||||
boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
|
||||
boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
|
||||
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
|
||||
|
||||
@@ -589,7 +607,8 @@ struct jpeg_decompress_struct {
|
||||
int max_h_samp_factor; /* largest h_samp_factor */
|
||||
int max_v_samp_factor; /* largest v_samp_factor */
|
||||
|
||||
int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
|
||||
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
|
||||
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
|
||||
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
|
||||
/* The coefficient controller's input and output progress is measured in
|
||||
@@ -597,7 +616,7 @@ struct jpeg_decompress_struct {
|
||||
* in fully interleaved JPEG scans, but are used whether the scan is
|
||||
* interleaved or not. We define an iMCU row as v_samp_factor DCT block
|
||||
* rows of each component. Therefore, the IDCT output contains
|
||||
* v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
|
||||
* v_samp_factor*DCT_v_scaled_size sample rows of a component per iMCU row.
|
||||
*/
|
||||
|
||||
JSAMPLE * sample_range_limit; /* table for fast range-limiting */
|
||||
@@ -621,6 +640,12 @@ struct jpeg_decompress_struct {
|
||||
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
|
||||
/* These fields are derived from Se of first SOS marker.
|
||||
*/
|
||||
int block_size; /* the basic DCT block size: 1..16 */
|
||||
const int * natural_order; /* natural-order position array for entropy decode */
|
||||
int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */
|
||||
|
||||
/* This field is shared between entropy decoder and marker parser.
|
||||
* It is either zero or the code of a JPEG marker that has been
|
||||
* read from the data source, but has not yet been processed.
|
||||
@@ -850,11 +875,14 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
|
||||
#define jpeg_destroy_decompress jDestDecompress
|
||||
#define jpeg_stdio_dest jStdDest
|
||||
#define jpeg_stdio_src jStdSrc
|
||||
#define jpeg_mem_dest jMemDest
|
||||
#define jpeg_mem_src jMemSrc
|
||||
#define jpeg_set_defaults jSetDefaults
|
||||
#define jpeg_set_colorspace jSetColorspace
|
||||
#define jpeg_default_colorspace jDefColorspace
|
||||
#define jpeg_set_quality jSetQuality
|
||||
#define jpeg_set_linear_quality jSetLQuality
|
||||
#define jpeg_default_qtables jDefQTables
|
||||
#define jpeg_add_quant_table jAddQuantTable
|
||||
#define jpeg_quality_scaling jQualityScaling
|
||||
#define jpeg_simple_progression jSimProgress
|
||||
@@ -864,6 +892,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
|
||||
#define jpeg_start_compress jStrtCompress
|
||||
#define jpeg_write_scanlines jWrtScanlines
|
||||
#define jpeg_finish_compress jFinCompress
|
||||
#define jpeg_calc_jpeg_dimensions jCjpegDimensions
|
||||
#define jpeg_write_raw_data jWrtRawData
|
||||
#define jpeg_write_marker jWrtMarker
|
||||
#define jpeg_write_m_header jWrtMHeader
|
||||
@@ -880,6 +909,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
|
||||
#define jpeg_input_complete jInComplete
|
||||
#define jpeg_new_colormap jNewCMap
|
||||
#define jpeg_consume_input jConsumeInput
|
||||
#define jpeg_core_output_dimensions jCoreDimensions
|
||||
#define jpeg_calc_output_dimensions jCalcDimensions
|
||||
#define jpeg_save_markers jSaveMarkers
|
||||
#define jpeg_set_marker_processor jSetMarker
|
||||
@@ -924,6 +954,14 @@ EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
|
||||
EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
|
||||
|
||||
/* Data source and destination managers: memory buffers. */
|
||||
EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo,
|
||||
unsigned char ** outbuffer,
|
||||
unsigned long * outsize));
|
||||
EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo,
|
||||
unsigned char * inbuffer,
|
||||
unsigned long insize));
|
||||
|
||||
/* Default parameter setup for compression */
|
||||
EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
|
||||
/* Compression parameter setup aids */
|
||||
@@ -935,6 +973,8 @@ EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
|
||||
EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
|
||||
int scale_factor,
|
||||
boolean force_baseline));
|
||||
EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo,
|
||||
boolean force_baseline));
|
||||
EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
|
||||
const unsigned int *basic_table,
|
||||
int scale_factor,
|
||||
@@ -954,12 +994,15 @@ EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
|
||||
JDIMENSION num_lines));
|
||||
EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
|
||||
|
||||
/* Precalculate JPEG dimensions for current compression parameters. */
|
||||
EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo));
|
||||
|
||||
/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
|
||||
EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
|
||||
JSAMPIMAGE data,
|
||||
JDIMENSION num_lines));
|
||||
|
||||
/* Write a special marker. See libjpeg.doc concerning safe usage. */
|
||||
/* Write a special marker. See libjpeg.txt concerning safe usage. */
|
||||
EXTERN(void) jpeg_write_marker
|
||||
JPP((j_compress_ptr cinfo, int marker,
|
||||
const JOCTET * dataptr, unsigned int datalen));
|
||||
@@ -1013,6 +1056,7 @@ EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
|
||||
#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
|
||||
|
||||
/* Precalculate output dimensions for current decompression parameters. */
|
||||
EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo));
|
||||
EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
|
||||
|
||||
/* Control saving of COM and APPn markers into marker_list. */
|
||||
@@ -1108,7 +1152,9 @@ struct jpeg_color_quantizer { long dummy; };
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifndef DONT_USE_EXTERN_C
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* JPEGLIB_H */
|
||||
|
||||
75
jpegtran.1
75
jpegtran.1
@@ -1,4 +1,4 @@
|
||||
.TH JPEGTRAN 1 "3 August 1997"
|
||||
.TH JPEGTRAN 1 "28 December 2009"
|
||||
.SH NAME
|
||||
jpegtran \- lossless transformation of JPEG files
|
||||
.SH SYNOPSIS
|
||||
@@ -60,6 +60,9 @@ Create progressive JPEG file.
|
||||
Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is
|
||||
attached to the number.
|
||||
.TP
|
||||
.B \-arithmetic
|
||||
Use arithmetic coding.
|
||||
.TP
|
||||
.BI \-scans " file"
|
||||
Use the scan script given in the specified text file.
|
||||
.PP
|
||||
@@ -91,12 +94,12 @@ Transpose image (across UL-to-LR axis).
|
||||
.TP
|
||||
.B \-transverse
|
||||
Transverse transpose (across UR-to-LL axis).
|
||||
.PP
|
||||
.IP
|
||||
The transpose transformation has no restrictions regarding image dimensions.
|
||||
The other transformations operate rather oddly if the image dimensions are not
|
||||
a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
|
||||
transform complete blocks of DCT coefficient data in the desired way.
|
||||
.PP
|
||||
.IP
|
||||
.BR jpegtran 's
|
||||
default behavior when transforming an odd-size image is designed
|
||||
to preserve exact reversibility and mathematical consistency of the
|
||||
@@ -108,7 +111,7 @@ able to flip all columns. The other transforms can be built up as sequences
|
||||
of transpose and flip operations; for consistency, their actions on edge
|
||||
pixels are defined to be the same as the end result of the corresponding
|
||||
transpose-and-flip sequence.
|
||||
.PP
|
||||
.IP
|
||||
For practical use, you may prefer to discard any untransformable edge pixels
|
||||
rather than having a strange-looking strip along the right and/or bottom edges
|
||||
of a transformed image. To do this, add the
|
||||
@@ -117,7 +120,7 @@ switch:
|
||||
.TP
|
||||
.B \-trim
|
||||
Drop non-transformable edge blocks.
|
||||
.PP
|
||||
.IP
|
||||
Obviously, a transformation with
|
||||
.B \-trim
|
||||
is not reversible, so strictly speaking
|
||||
@@ -130,12 +133,43 @@ trims only the bottom edge, but
|
||||
followed by
|
||||
.B \-rot 180 -trim
|
||||
trims both edges.
|
||||
.IP
|
||||
If you are only interested in perfect transformation, add the
|
||||
.B \-perfect
|
||||
switch:
|
||||
.TP
|
||||
.B \-perfect
|
||||
Fails with an error if the transformation is not perfect.
|
||||
.IP
|
||||
For example you may want to do
|
||||
.IP
|
||||
.B (jpegtran \-rot 90 -perfect
|
||||
.I foo.jpg
|
||||
.B || djpeg
|
||||
.I foo.jpg
|
||||
.B | pnmflip \-r90 | cjpeg)
|
||||
.IP
|
||||
to do a perfect rotation if available or an approximated one if not.
|
||||
.PP
|
||||
Another not-strictly-lossless transformation switch is:
|
||||
We also offer a lossless-crop option, which discards data outside a given
|
||||
image region but losslessly preserves what is inside. Like the rotate and
|
||||
flip transforms, lossless crop is restricted by the current JPEG format: the
|
||||
upper left corner of the selected region must fall on an iMCU boundary. If
|
||||
this does not hold for the given crop parameters, we silently move the upper
|
||||
left corner up and/or left to make it so, simultaneously increasing the region
|
||||
dimensions to keep the lower right crop corner unchanged. (Thus, the output
|
||||
image covers at least the requested region, but may cover more.)
|
||||
|
||||
The image can be losslessly cropped by giving the switch:
|
||||
.TP
|
||||
.B \-crop WxH+X+Y
|
||||
Crop to a rectangular subarea of width W, height H starting at point X,Y.
|
||||
.PP
|
||||
Other not-strictly-lossless transformation switches are:
|
||||
.TP
|
||||
.B \-grayscale
|
||||
Force grayscale output.
|
||||
.PP
|
||||
.IP
|
||||
This option discards the chrominance channels if the input image is YCbCr
|
||||
(ie, a standard color JPEG), resulting in a grayscale JPEG file. The
|
||||
luminance channel is preserved exactly, so this is a better method of reducing
|
||||
@@ -144,6 +178,19 @@ is particularly handy for fixing a monochrome picture that was mistakenly
|
||||
encoded as a color JPEG. (In such a case, the space savings from getting rid
|
||||
of the near-empty chroma channels won't be large; but the decoding time for
|
||||
a grayscale JPEG is substantially less than that for a color JPEG.)
|
||||
.TP
|
||||
.BI \-scale " M/N"
|
||||
Scale the output image by a factor M/N.
|
||||
.IP
|
||||
Currently supported scale factors are M/N with all M from 1 to 16, where N is
|
||||
the source DCT size, which is 8 for baseline JPEG. If the /N part is omitted,
|
||||
then M specifies the DCT scaled size to be applied on the given input. For
|
||||
baseline JPEG this is equivalent to M/8 scaling, since the source DCT size
|
||||
for baseline JPEG is 8.
|
||||
.B Caution:
|
||||
An implementation of the JPEG SmartScale extension is required for this
|
||||
feature. SmartScale enabled JPEG is not yet widely implemented, so many
|
||||
decoders will be unable to view a SmartScale extended JPEG file at all.
|
||||
.PP
|
||||
.B jpegtran
|
||||
also recognizes these switches that control what to do with "extra" markers,
|
||||
@@ -155,13 +202,13 @@ comments and other excess baggage present in the source file.
|
||||
.TP
|
||||
.B \-copy comments
|
||||
Copy only comment markers. This setting copies comments from the source file,
|
||||
but discards any other inessential data.
|
||||
but discards any other inessential (for image display) data.
|
||||
.TP
|
||||
.B \-copy all
|
||||
Copy all extra markers. This setting preserves miscellaneous markers
|
||||
found in the source file, such as JFIF thumbnails and Photoshop settings.
|
||||
In some files these extra markers can be sizable.
|
||||
.PP
|
||||
found in the source file, such as JFIF thumbnails, Exif data, and Photoshop
|
||||
settings. In some files these extra markers can be sizable.
|
||||
.IP
|
||||
The default behavior is
|
||||
.BR "\-copy comments" .
|
||||
(Note: in IJG releases v6 and v6a,
|
||||
@@ -227,11 +274,11 @@ Communications of the ACM, April 1991 (vol. 34, no. 4), pp. 30-44.
|
||||
.SH AUTHOR
|
||||
Independent JPEG Group
|
||||
.SH BUGS
|
||||
Arithmetic coding is not supported for legal reasons.
|
||||
.PP
|
||||
The transform options can't transform odd-size images perfectly. Use
|
||||
.B \-trim
|
||||
if you don't like the results without it.
|
||||
or
|
||||
.B \-perfect
|
||||
if you don't like the results.
|
||||
.PP
|
||||
The entire image is read into memory and then written out again, even in
|
||||
cases where this isn't really necessary. Expect swapping on large images,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user