Compare commits

..

68 Commits
v3.2 ... 1.5.2

Author SHA1 Message Date
DRC
e5c1613ccd x86: Fix "short jump is out of range" w/ NASM<2.04 2017-07-07 15:28:49 -05:00
DRC
b0971e47d7 TurboJPEG: Document xform issue w/ big marker data
If the source image for a transform operation has a lot of EXIF or ICC
data embedded in it, then it may cause the output image size to exceed
the worst-case size returned by tjBufSize() (because tjTransform()
transfers all markers to the output image.)  This is only a problem if
TJFLAG_NOREALLOC is passed to the function.  Since the TurboJPEG C API
doesn't require the destination image size to be set in this case, it
makes the documented assumption that the calling program has allocated
the destination buffer to exactly the size returned by tjBufSize().
Changing this assumption would change the API behavior and necessitate
a new function name (tjTransform2().)  At the moment, it's easier to
just document this as a known issue, since it's easy to work around in
the C API.

The Java API is unfortunately a different story, since it must always
use TJFLAG_NOREALLOC (because, when using the TurboJPEG Java API, all
buffers are allocated on the Java heap, and thus they can't be
reallocated by the C code.)  There is no easy way to work around this
without changing the C API as discussed above, because if the source
image contains large amounts of marker data, it's virtually impossible
to determine how big the output image will be.
2017-06-28 15:22:33 -05:00
DRC
e248d430e2 Java TJBench: Fix parsing of -warmup argument
Due to an oversight, this wasn't included in
1db1ce45da.
2017-06-28 15:22:32 -05:00
DRC
acb634931a Build: Disable warmup in TJBench regression tests
Fixes slow-down in 'make test' caused by previous commit.
2017-06-28 15:19:53 -05:00
DRC
1db1ce45da TJBench: Improve consistency of results
Given that libjpeg-turbo can often process hundreds of megapixels/second
on modern hardware, the default of one warmup iteration was essentially
meaningless.  Furthermore, the -warmup option was a bit clunky, since
it required some foreknowledge of how fast the benchmarks were going to
execute.

This commit introduces a 1-second warmup interval for each benchmark by
default, and the -warmup option has been retasked to control the length
of that interval.
2017-06-27 14:28:43 -05:00
DRC
d0c3aa900b TurboJPEG: C API documentation buglet
TJFLAG_NOREALLOC, tjAlloc(), and tjFree() apply to all TurboJPEG
compression functions, not just tjCompress2().
2017-06-27 11:49:38 -05:00
DRC
6a2b067428 TJBench: Code formatting tweaks
Spaces-->tab + remove stray control character that was introduced in
95e4cb2060
2017-06-26 21:15:15 -05:00
DRC
11eec4a398 TJBench: Fix errors when decomp. files w/ ICC data
Embedded ICC profiles can cause the size of a JPEG file to exceed the
size returned by tjBufSize() (which is really meant to be used for
compression anyhow, not for decompression), and this was causing a
segfault (C) or an ArrayIndexOutOfBoundsException (Java) when
decompressing such files with TJBench.  This commit modifies the
benchmark such that, when tiled decompression is disabled, it re-uses
the source buffer as the primary JPEG buffer.
2017-06-26 21:12:40 -05:00
DRC
301ba4f305 BUILDING.md: Include Android/x86 build recipes
Addresses a concern raised in #155.
2017-06-26 21:12:33 -05:00
DRC
70f236ddd7 Travis: Fix OS X build
The Travis xcode7.3 image now apparently includes GnuPG 1.4.x by
default, so use it instead of installing GnuPG 2.  Using GnuPG 2.1.x,
the default version in Homebrew as of this writing, is problematic for
this reason:
https://wiki.archlinux.org/index.php/GnuPG#Unattended_passphrase
2017-05-08 14:42:52 -05:00
DRC
2a4f189444 Restore compatibility with older autoconf releases
(broken by f06cc1200f)

Fixes #149
2017-05-05 20:45:40 -05:00
DRC
9d64f3c60b Attribute ARM runtime detection code to Nokia
This code was submitted in the initial ARM NEON patches
(https://sourceforge.net/p/libjpeg-turbo/patches/7/) by Siarhei while he
was still a Nokia employee.
2017-04-24 14:42:58 -05:00
DRC
da2a27ef05 Honor max_memory_to_use/JPEGMEM/-maxmemory
This re-introduces a feature of the obsolete system-specific libjpeg
memory managers-- namely the ability to limit the amount of main memory
used by the library during decompression or multi-pass compression.
This is mainly beneficial for two reasons:

- Works around a 2 GB limit in libFuzzer
- Allows security-sensitive applications to set a memory limit for the
  JPEG decoder so as to work around the progressive JPEG exploit
  (LJT-01-004) described here:
  http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf

This commit also removes obsolete documentation regarding the MS-DOS
memory manager (which itself was removed long ago) and changes the
documentation of the -maxmemory switch and JPEGMEM environment variable
to reflect the fact that backing stores are never used in libjpeg-turbo.

Inspired by:
066fee2e7d

Closes #143
2017-03-18 17:42:34 -05:00
DRC
c082dc039d AppVeyor: Fix CI build
Something changed in the CI build environment, and our previous trick of
setting the Git URL to file://c:/projects/libjpeg-turbo no longer works.
Using cygpath to translate the Windows path to a MinGW-friendly format
is a better solution anyhow.
2017-03-18 13:25:30 -05:00
DRC
d4c41fe0da TurboJPEG: Fix potential memory leaks
Referring to https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=746,
it seems that the values of local buffer pointers in TurboJPEG API
functions aren't always preserved if longjmp() returns control to a
point prior to the allocation of the local buffers.  This is known to
be an issue with GCC 4.x and clang with -O1 and higher optimization
levels but not with GCC 5.x and later.  It is unknown why GCC 5.x and
6.x do not suffer from the issue, but possibly the local buffer pointers
are not allocated on the stack when using those more recent compilers.

In any case, this commit modifies the TurboJPEG API library code such
that the jump buffer is always updated after any local buffer pointers
are allocated but before any subsequent libjpeg API functions are
called.
2017-03-18 13:12:17 -05:00
DRC
a0b7de9a47 Always tweak EXIF w/h tags w/ lossless transforms
... even if using libjpeg v6b emulation.  Previously
adjust_exif_parameters() was only called with libjpeg v7/v8 emulation,
but due to a bug (which this commit also fixes), it only worked properly
with libjpeg v8 emulation.
2017-01-19 19:00:27 -06:00
DRC
2252795571 Fix error w/ lossless crop & libjpeg v7 emulation
The JPEG_LIB_VERSION #ifdef in jtransform_adjust_parameters() was
incorrect, which caused a "Bogus virtual array access" error when
attempting to use the lossless crop feature.

Introduced in c04bd3cc97.

This also adds libjpeg v7 API/ABI emulation to the Travis CI tests.
2017-01-19 18:41:13 -06:00
DRC
eb38b61bfe Include jpeg_skip/crop_scanlines() in jpeg7.dll
... when the in-memory source/destination managers are included.
Oversight in 306e1d2d77 and
3ab68cf563.
2017-01-19 16:44:10 -06:00
DRC
47b29e8cd9 libjpeg.txt: Include partial decomp. in TOC
(oversight)
2017-01-19 15:36:58 -06:00
DRC
e1e816e665 Slightly de-confusify cjpeg, jpegtran usage info
+ bump copyright year
2017-01-19 15:35:54 -06:00
DRC
6441018150 LICENSE.md: Include text of BSD/zlib licenses
LICENSE.md is included in the binary distributions as well, so it
doesn't make much sense to refer to license headers in source files that
aren't necessarily going to be there.
2016-12-10 09:32:23 -06:00
DRC
fcfc6c5eed Fix build when CFLAGS contains -std=c89 (or -ansi)
This is a subtle point, but AC_C_INLINE defines "inline" to be either
"inline", "__inline__", or "__inline".  The subsequent test for
"inline __attribute__((always_inline))" uses this definition.  The
attribute is irrespective of the inline keyword, so whereas
"__inline__ __attribute__((always_inline))" works under C89,
"inline __attribute__((always_inline))" doesn't, and defining INLINE to
the latter causes the build to fail.  The easiest way around this is
simply to define "inline" ahead of "INLINE" in jconfigint.h,
which causes the inline keyword detected by AC_C_INLINE to modify the
INLINE macro if necessary.
2016-12-05 14:02:59 -06:00
DRC
786b649331 Reorg AltiVec detection code
+ advertise that full AltiVec SIMD acceleration is now available on
OpenBSD.

The relevant compilers probably all support C99 or GNU's variation of
C90 that allows variables to be declared anywhere, but our policy is to
conform to the C90 standard, if for no other reason than that it
improves code readability.
2016-12-05 13:14:19 -06:00
Donovan Watteau
f4ba09b33a Detect AltiVec support on OpenBSD 2016-12-05 12:35:15 -06:00
Colin Cross
0f4fcced0a Fix sign mismatch comparison warnings
Fixes:
rdppm.c:257:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
        ~~~~ ^ ~~~~~~
rdppm.c:284:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
        ~~~~ ^ ~~~~~~
rdppm.c:289:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
        ~~~~ ^ ~~~~~~
rdppm.c:294:14: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
    if (temp > maxval)
2016-12-03 15:30:59 -06:00
DRC
82bf7f5858 Fix md5cmp on AmigaOS 4 (PowerPC big-endian)
+ Document AmigaOS support in the change log.

Based on:
b4f3b75797

Closes #119
2016-12-01 18:23:32 -06:00
DRC
3582ce90bb Travis: Use xcode7.3 image
The xcode7.2 image is verfallen, verlumpt, verblunget, verkackt

This also ensures that the build scripts are checked out from a
branch matching the libjpeg-turbo repository branch (not strictly
necessary when building from master, but it keeps the code in sync with
dev.)
2016-12-01 01:58:34 -06:00
DRC
d6d7b53968 AppVeyor: Use built-in MSYS2 MinGW compilers
AppVeyor already has MinGW32 and MinGW64 flavors of GCC 5.3.0
installed under MSYS2, so there is no need to install our own builds of
MinGW.  MinGW-builds is no longer an active project, and we were getting
occasional timeouts while wgetting those files from SourceForge.
Furthermore, GCC 5.3.0 should produce faster code than GCC 4.8.1.
2016-11-21 23:10:02 -06:00
DRC
f9f0c75bb8 BUILDING.md: Clarifications and wordsmithing
Updated out-of-date information, wordsmithed and clarified many
sections, and generally cleaned up the build recipes (including a
complete overhaul of the iOS recipes.)
2016-11-20 21:47:46 -06:00
DRC
3da94de248 Windows build: Add an "uninstall" target 2016-11-20 19:10:54 -06:00
DRC
ab664e35fc BUILDING.md/README.md: Increment libjpeg SO age
Documentation buglet.  This should have been changed in
6ed4d9d110 to reflect the addition of
libjpeg API functions in libjpeg-turbo 1.5.
2016-11-20 16:22:23 -06:00
DRC
ce26e83f47 README.md: Don't use trailing spaces as line break
Makes it easier to maintain this file using editors that automatically
remove trailing spaces.
2016-11-20 16:22:23 -06:00
DRC
74e4c793cd TJBench: Fix regression/-nowrite always enabled
Introduced by eb59b6e72d
2016-11-20 16:22:23 -06:00
DRC
a280fa630c BUILDING.md: Don't use trailing spaces as line break
Makes it easier to maintain this file using editors that automatically
remove trailing spaces.
2016-11-20 16:22:23 -06:00
DRC
6aae007745 CMake build system: Fix the "testclean" target
Regression caused by f9134384b7

This commit also makes the "testclean" target clean up the 4:1:1 test
images.  This was implemented in the autotools build system in
1f3635c496 but was left out of the CMake
build system due to an oversight.
2016-11-20 16:22:23 -06:00
Chris Young
4ad94b2963 Detect AltiVec support on AmigaOS 4 2016-11-18 13:03:28 -06:00
DRC
2d4b2f14d0 Travis: Deploy to S3 rather than SourceForge
This has the following advantages:
-- It doesn't require checking a private SSH key into the repository.
(With SourceForge, an SSH key is the "keys to the kingdom".)
-- If the S3 key is compromised, it is very easy to revoke it and
generate a new one.
-- The S3 bucket is isolated, so even if it becomes compromised, then
the damage that one could do is limited.
-- It's much easier to manage files through S3's web interface than
through SourceForge.
-- The files are served via HTTPS.
-- Travis fully supports S3 as a deployment target, so this simplifies
.travis.yml somewhat.
2016-10-20 18:17:15 -05:00
DRC
9366cf0bca Travis: GPG sign Linux binaries/source tarballs
Since we're still deploying our Linux/macOS CI artifacts to a web server
(specifically SourceForge Project Web Services) that doesn't support
HTTPS, it's a good idea to sign them.  But since the private key has to
be checked into the repository, we use a different key for signing the
pre-releases (per project policy, the private signing keys for our
release binaries are never made available on any public server.)
2016-10-20 01:13:11 -05:00
DRC
13e6b151b0 Win: Use YASM if it is in the PATH and NASM isn't
Previously, simd/CMakeLists.txt was hard-coded to use NASM, and it was
necessary to override the NASM variable in order to use YASM.  This
commit changes the behavior such that NASM is still preferred, but YASM
will be used if it is in the PATH and NASM isn't available.  This brings
the actual behavior in line with the behavior described in BUILDING.md.

Based on
b0799a1598

Closes #107
2016-10-11 11:58:20 -05:00
DRC
1ee329d617 Travis: Fix deployment issue (2nd attempt) 2016-10-07 12:54:55 -05:00
DRC
b47c5e737f Travis: Fix deployment issue
"Skipping a deployment with the script provider because this branch is
not permitted"
2016-10-07 05:34:33 -05:00
DRC
ce262eb5d7 Fix AppVeyor build on non-master branches
buildljt will clone the Git repository into the temp. directory, even if
the repository is really a local sandbox, so we need to specify the
branch.
2016-10-07 05:20:26 -05:00
DRC
27f817cd11 Travis: Use existing sandbox for official builds
This eliminates the need to specify the remote repository and branch,
and it prevents the code from being checked out twice.
2016-10-07 05:09:16 -05:00
DRC
0df2e2188b Add AppVeyor config for Windows pre-release builds 2016-10-07 04:29:37 -05:00
DRC
6d22430a3a Travis: use correct repo/branch for off. builds
Pass the actual repository and branch that Travis is using into the
builtljt script, so the official builds it generates will come from
the same code base as the other tested builds.
2016-10-05 14:36:46 -05:00
DRC
e9e3a2edd7 Travis CI: Use correct key for this repository 2016-10-05 12:38:59 -05:00
DRC
211c69f317 Add Travis CI config for Un*x pre-release builds 2016-10-05 12:33:28 -05:00
DRC
1625253d49 Fix 32-bit non-SIMD FP regression tests
- Introduce a new FLOATTEST value ("387") on Un*x systems that will
  compare the floating point DCT/IDCT algorithms against the expected
  results from the C algorithms when built using 32-bit code and
  -mfpmath=387.
- Extend the Windows regression tests so that they work properly when
  building libjpeg-turbo with 32-bit code and without SIMD, using either
  Visual C++ (tested with 2008, 2010, 2015) or MinGW.
2016-10-04 13:55:00 -05:00
DRC
a0047bdea4 Fix broken build w/ Visual C++ < 2010
Regression introduced by dfefba7752
(Windows doesn't always have stdint.h.)
2016-10-04 13:25:34 -05:00
DRC
7bfb22af12 Fix broken MIPS build
Regression introduced by 9055fb408d

Fixes #104
2016-09-26 18:01:54 -05:00
DRC
ac4a899511 Fix UBSan warning in arithmetic decoder
Very similar to the ones that were fixed in the Huffman decoders in
8e9cef2e6f.  These are innocuous.

Refer to https://bugzilla.mozilla.org/show_bug.cgi?id=1304567.
2016-09-22 14:40:41 -05:00
DRC
dfefba7752 Fix broken build with NDK platforms < android-21
Regression introduced by a09ba29a55

Fixes #103
2016-09-22 14:22:45 -05:00
DRC
4cf67f2363 Bump version to 1.5.2 to prepare for new commits 2016-09-22 14:14:05 -05:00
Roberto Civille Rodrigues
9407cf7f47 README.md: Fix typo
Introduced in 17de518357

Closes #102
2016-09-22 13:39:24 -05:00
mayeut
cb88e5da80 ARM64 NEON: Fix another ABI conformance issue
Based on
98a5a9dc89
with wordsmithing by DRC.

In the AArch64 ABI, as in many others, it's forbidden to read/store data
below the stack pointer.  Some SIMD functions were doing just that
(stack pointer misuse) when trying to preserve callee-saved registers,
and this resulted in those registers being restored with incorrect
contents under certain circumstances.

This patch fixes that behavior, and callee-saved registers are now
stored above the stack pointer throughout the function call.  The patch
also removes register saving in places where it is unnecessary for this
ABI, or it makes use of unused scratch regiters instead of callee-saved
registers.

Fixes #97.  Closes #101.

Refer also to https://bugzilla.redhat.com/show_bug.cgi?id=1368569
2016-09-20 17:38:39 -05:00
DRC
e9d9c31fd2 Build: Remove ARMv6 support from 'make iosdmg'
The last iDevice to require ARMv6 was the iPhone 3G, which required iOS
4.2.1 or older.  Our binaries have always required iOS 4.3 or newer,
so I'm not sure if the ARMv6 fork of our binaries was ever useful to
begin with.  In any case, if it ever was useful, it no longer is.  Fat
binaries can still be generated with ARMv6 support by invoking
{build_directory}/pkgscripts/makemacpkg manually.
2016-09-20 11:29:22 -05:00
DRC
077e5bb4e0 Fix out-of-bounds write in partial decomp. feature
Reported by Clang UBSan (refer to
https://bugzilla.mozilla.org/show_bug.cgi?id=1301252 for test image.)
This appears to be a legitimate bug introduced by
3ab68cf563.  Any component array, such
as first_MCU_col and last_MCU_col, should always be able to accommodate
MAX_COMPONENTS values.  The aforementioned test image had 8 components,
which was not enough to make the out-of-bounds write bust out of the
jpeg_decomp_master struct (and fortunately the memory after last_MCU_col
is an integer used as a boolean, so stomping on it will do nothing other
than change the decoder state.)  I crafted another special image that
has 10 components (the maximum allowable), but that was apparently not
enough to bust out of the allocated memory, either.  Thus, it is
posited that the security threat posed by this bug is either extremely
minimal or non-existent.
2016-09-08 22:01:09 -05:00
DRC
a1dd35680d Silence additional UBSan warnings
NOTE: The jdhuff.c/jdphuff.c warnings should have already been silenced
by 8e9cef2e6f, but apparently I need to
be REALLY clear that I'm trying to do pointer arithmetic rather than
dereference an array.  Grrr...

Refer to:
https://bugzilla.mozilla.org/show_bug.cgi?id=1301250
https://bugzilla.mozilla.org/show_bug.cgi?id=1301256
2016-09-08 21:29:58 -05:00
DRC
a09ba29a55 Fix unsigned int overflow in libjpeg memory mgr.
When attempting to decode a malformed JPEG image (refer to
https://bugzilla.mozilla.org/show_bug.cgi?id=1295044) with dimensions
61472 x 32800, the maximum_space variable within the
realize_virt_arrays() function will exceed the maximum value of a 32-bit
integer and will wrap around.  The memory manager subsequently fails
with an "Insufficient memory" error (case 4, in alloc_large()), so this
commit simply causes that error to be triggered earlier, before UBSan
has a chance to complain.

Note that this issue did not ever represent an exploitable security
threat, because the POSIX-based memory manager that we use doesn't ever
do anything meaningful with the value of maximum_space.
jpeg_mem_available() simply sets avail_mem = maximum_space, so the
subsequent behavior of the memory manager is the same regardless of
whether maximum_space is correct or not.  This commit simply removes a
UBSan warning in order to make it easier to detect actual security
issues.
2016-09-08 16:17:05 -05:00
DRC
8ce2c9119a TurboJPEG: Decomp. 4:2:2/4:4:0 JPEGs w/unusual SFs
Normally, 4:2:2 JPEGs have horizontal x vertical luminance,chrominance
sampling factors of 2x1,1x1, and 4:4:0 JPEGs have horizontal x vertical
luminance,chrominance sampling factors of 1x2,1x1.  However, it is
technically legal to create 4:2:2 JPEGs with sampling factors of
2x2,1x2 and 4:4:0 JPEGs with sampling factors of 2x2,2x1, since the
sums of the products of those sampling factors (2x2 + 1x2 + 1x2 and
2x2 + 2x1 + 2x1) are still <= 10.  The libjpeg API correctly decodes
such images, so the TurboJPEG API should as well.

Fixes #92
2016-08-01 11:59:31 -05:00
DRC
db04435165 Silence pedantic GCC6 code formatting warnings
Apparently it's "misleading" to put two self-contained if statements
on a single line.  Who knew?
2016-07-14 13:36:47 -05:00
DRC
7723d7f7d0 Use plain upsampling if merged isn't accelerated
Currently, this only affects ARM, since it is the only platform that
accelerates YCbCr-to-RGB conversion but not merged upsampling.  Even if
"plain" upsampling isn't accelerated, the combination of accelerated
color conversion + unaccelerated plain upsampling is still faster than
the unaccelerated merged upsampling algorithms.

Closes #81
2016-07-13 22:06:11 -05:00
Kornel Lesiński
628c168c86 Implement h1v2 fancy upsampling
This allows fancy upsampling to be used when decompressing 4:2:2 images
that have been losslessly rotated or transposed.

(docs and comments added by DRC)

Based on f63aca945d

Closes #89
2016-07-13 17:28:19 -05:00
DRC
1120ff29a1 Fix AArch64 ABI conformance issue in SIMD code
In the AArch64 ABI, the high (unused) DWORD of a 32-bit argument's
register is undefined, so it was incorrect to use 64-bit
instructions to transfer a JDIMENSION argument in the 64-bit NEON SIMD
functions.  The code worked thus far only because the existing compiler
optimizers weren't smart enough to do anything else with the register in
question, so the upper 32 bits happened to be all zeroes.

The latest builds of Clang/LLVM have a smarter optimizer, and under
certain circumstances, it will attempt to load-combine adjacent 32-bit
integers from one of the libjpeg structures into a single 64-bit integer
and pass that 64-bit integer as a 32-bit argument to one of the SIMD
functions (which is allowed by the ABI, since the upper 32 bits of the
32-bit argument's register are undefined.)  This caused the
libjpeg-turbo regression tests to crash.

This patch tries to use the Wn registers whenever possible.  Otherwise,
it uses a zero-extend instruction to avoid using the upper 32 bits of
the 64-bit registers, which are not guaranteed to be valid for 32-bit
arguments.

Based on 1fbae13021

Closes #91.  Refer also to android-ndk/ndk#110 and
https://llvm.org/bugs/show_bug.cgi?id=28393
2016-07-13 14:36:19 -05:00
DRC
1945ad961b Don't install libturbojpeg.pc if TJPEG disabled 2016-07-12 22:21:20 -05:00
DRC
6e9d43e085 Linux/PPC: Only enable AltiVec if CPU supports it
This eliminates "illegal instruction" errors when running libjpeg-turbo
under Linux on PowerPC chips that lack AltiVec support (e.g. the old
7XX/G3 models but also the newer e5500 series.)
2016-07-07 19:02:44 +00:00
DRC
9055fb408d ARM/MIPS: Change the behavior of JSIMD_FORCE*
The JSIMD_FORCE* environment variables previously meant "force the use
of this instruction set if it is available but others are available as
well", but that did nothing on ARM platforms, since there is only ever
one instruction set available.  Since the ARM and MIPS CPU feature
detection code is less than bulletproof, and since there is only one
SIMD instruction set (currently) supported on those platforms, it makes
sense for the JSIMD_FORCE* environment variables on those platforms to
actually force the use of the SIMD instruction set, thus bypassing the
CPU feature detection code.

This addresses a concern raised in #88 whereby parsing /proc/cpuinfo
didn't work within a QEMU environment.  This at least provides a
workaround, allowing users to force-enable or force-disable SIMD
instructions for ARM and MIPS builds of libjpeg-turbo.
2016-07-07 13:38:48 -05:00
DRC
9e6c6a14f8 Bump version to 1.5.1 to prepare for new commits 2016-07-06 16:22:27 +00:00
103 changed files with 2244 additions and 6729 deletions

View File

@@ -1,7 +0,0 @@
dcommander = DRC <dcommander@users.sourceforge.net>
astrand = Peter Åstrand <astrand@cendio.se>
ossman_ = Pierre Ossman <ossman@cendio.se>
const_k = Constantin Kaplinsky <const@tightvnc.com>
atkac = Adam Tkac <atkac@redhat.com>

55
.gitignore vendored
View File

@@ -1,45 +1,14 @@
.DS_Store .DS_Store
Makefile.in Makefile.in
Makefile aclocal.m4
/CMakeFiles ar-lib
/autom4te.cache autom4te.cache
/aclocal.m4 compile
/compile config.guess
/configure config.h.in
/depcomp config.sub
/install-sh configure
/libtool depcomp
/missing install-sh
/stamp-h* ltmain.sh
/java/classnoinst.stamp missing
/pkgscripts/
/jconfig.h
/jconfigint.h
/config.guess
/config.h
/config.h.in
/config.log
/config.status
/config.sub
/ltmain.sh
/ar-lib
/libjpeg.map
/.libs/
/simd/.libs/
/simd/jsimdcfg.inc
*.o
*.lo
*.la
/cjpeg
/djpeg
/jcstest
/jpegtran
/jpegyuv
/md5/md5cmp
/rdjpgcom
/test_enc_*
/tjbench
/tjbenchtest
/tjunittest
/wrjpgcom
/yuvjpeg

129
.travis.yml Normal file
View File

@@ -0,0 +1,129 @@
language: c
matrix:
include:
- os: linux
env: BUILD_OFFICIAL=1
sudo: required
services:
- docker
- os: osx
env: BUILD_OFFICIAL=1
osx_image: xcode7.3
- os: linux
compiler: clang
env:
CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer"
CONFIGURE_FLAGS="--disable-shared"
ASAN_OPTIONS="detect_leaks=1 symbolize=1"
addons:
apt:
packages:
- nasm
- os: linux
compiler: gcc
env: CONFIGURE_FLAGS="--with-12bit"
- os: linux
compiler: gcc
env: CONFIGURE_FLAGS="--with-jpeg7"
addons:
apt:
packages:
- nasm
- os: linux
compiler: gcc
env: CONFIGURE_FLAGS="--with-jpeg8"
addons:
apt:
packages:
- nasm
- os: linux
compiler: gcc
env: CONFIGURE_FLAGS="--without-simd"
before_install:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
brew install nasm homebrew/versions/gcc5 md5sha1sum Caskroom/versions/java6 &&
ln -fs /usr/local/bin/gpg1 /usr/local/bin/gpg &&
git clone --depth=1 https://github.com/libjpeg-turbo/gas-preprocessor.git ~/src/gas-preprocessor &&
ln -fs /Applications/Xcode.app /Applications/Xcode72.app;
fi
- if [ "${BUILD_OFFICIAL:-}" != "" ]; then
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
docker pull dcommander/buildljt;
fi &&
git clone --depth=1 https://github.com/libjpeg-turbo/buildscripts.git -b $TRAVIS_BRANCH ~/src/buildscripts &&
openssl aes-256-cbc -K $encrypted_f92e8533f6f1_key -iv $encrypted_f92e8533f6f1_iv -in ci/keys.enc -out ci/keys -d &&
tar xf ci/keys &&
rm ci/keys &&
mv ci/gpgsign ~/src/buildscripts &&
gpg --import ci/sign_ljt &&
rm ci/sign_ljt;
fi
script:
- if [ "${BUILD_OFFICIAL:-}" != "" ]; then
mkdir -p ~/src/ljt.nightly &&
if [ -f .git/shallow ]; then
mv .git/shallow .git/shallow.bak;
fi &&
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
docker run -v $HOME/src/ljt.nightly:/root/src/ljt.nightly -v $HOME/src/buildscripts:/root/src/buildscripts -v $TRAVIS_BUILD_DIR:/root/src/libjpeg-turbo -v $HOME/.gnupg:/root/.gnupg -t dcommander/buildljt:latest bash -c "rpm --import http://pgp.mit.edu/pks/lookup?op=get\&search=0x0575F26BD5B3FDB1 && ~/src/buildscripts/buildljt -r file:///root/src/libjpeg-turbo $TRAVIS_BRANCH -v" &&
sudo chown -R travis:travis ~/src/ljt.nightly &&
mv ~/src/ljt.nightly/latest/log-$TRAVIS_OS_NAME.txt ~/src/ljt.nightly/latest/files/;
else
PATH=$PATH:~/src/gas-preprocessor ~/src/buildscripts/buildljt -r file://$TRAVIS_BUILD_DIR $TRAVIS_BRANCH -v &&
mv ~/src/ljt.nightly/latest/log-$TRAVIS_OS_NAME.txt ~/src/ljt.nightly/latest/files/;
fi &&
if [ -f .git/shallow.bak ]; then
mv .git/shallow.bak .git/shallow;
fi
fi
- if [ "${BUILD_OFFICIAL:-}" == "" ]; then
autoreconf -fiv &&
mkdir build &&
pushd build &&
../configure ${CONFIGURE_FLAGS} &&
make -j &&
if [[ "${CONFIGURE_FLAGS}" =~ "with-12bit" ||
"${CONFIGURE_FLAGS}" =~ "without-simd" ]]; then
make test FLOATTEST=32bit;
else
make test FLOATTEST=sse &&
JSIMD_FORCENONE=1 make test FLOATTEST=32bit;
fi &&
popd;
fi
after_failure:
- if [ "${BUILD_OFFICIAL:-}" == "" ]; then
if [ -f $TRAVIS_BUILD_DIR/build/config.log ]; then
cat $TRAVIS_BUILD_DIR/build/config.log;
fi
fi
deploy:
- provider: s3
bucket: libjpeg-turbo-pr
access_key_id:
secure: bmFEt4H90/oR/LiN9XI+G26Pd6hiyrTw3+Vg3lS4ynwAYk33weApaVM8CyzQTgIhGSPzFStqVm9fTrb3RmrYP/PnNS+/surOeWLkH2DMRxvc0qmetBuNx1+vAN7FUkY8MO/u5uE9WXHAdp4e64pXcLXEbKmh+wgDm72b35WmMxErtHsGbpqy+j47rQkY4BJGi7XQzjjafaamfm4PzitsjkYYsgX8KLI16jyJEIirvyDHCPTn9wKR/jSjelDl+xTlgZGuCqmLCBW8f6JgycIspWjcYfO4WpWvkbnnI2sl3rCMPvOYc4wHe8SwzG0l4tM1PblZZDRcU7vjE15PmNf1Xfq9Vx3RpgBJv+UBNL/Vn0rKdpUCeEcfC12hxrske8DWpV6waBiDivjQJreE+YRXqa5YBhV/EdkoKYCqafnJvRASlOko9evje8F9KXTNsIGTT1HPmU9QM9WoJwLs/Xa3t09EmA2IjhcuAvvUmwCTuBBQVAlDjExiTT3Zhc9IYZDD92JgpAYLgridtzR87ElOxKhTkR4PowdI6UiLYArPjMFTjoz5Rivb9qNpbLaQC8HCYgLWxpWtUTzlW/9rM8izHpF8ySFHjO6E2aA9OJFc0tcbEGwAs2jLGD01OduU+DbBfsIkW0EgfXCPbD3FVgHsn3tkuzgO/bg20SM7uuCEYKQ=
secret_access_key:
secure: mrkOpEtqd2dEmi/qNJyX9vkME+6xgVBnXaRETKF7jT+flcQCQ0ayQkRkMV7lzGqq44XFg+n6Cpfn6oW0gH9RNdcC8YQvFP+kgzPx6nw6V/M31Vz6ySapJf59HBzVevf0NJkr0/1JoWsp1iq4IoN10WPzsCXZB55Io3Cf7DgpR+yiyBlWOctDfNdjJ97Juw3ENE80MHDf0fVqdUOIknQka1p68yAGkjar9kc2Oe7o94RzzmoqEn8tuFumiBQjIcuVRALsKqz+eIxBNgkL3BF9shVyRjOWLAeBhMPVFxZs5Dgd4ECbvU0i33gfmje3d6qqcw78N2lZaLefoVvWol3pOzVO133ewOSY9/lmpqEiRUU2ohEe8T4aSoS7posBW42itUTO4Y5w+eVOnHsm4sRQaI+/AXWTe7GPel+P8Qbe8Ya10A5gnpoag7o3raRDcHx+/qaZw1Af/u4XiAOYz3be3U90Qc+YMc/kS5i8BH0GXBbSfaWQ00CwRFlZQ3n1xUqmjC2CmjZTki3W/p7mEt0DjhcH9ZIXscK603sCC+mF6pEd9019k5fG/8fr2Y4Ptai9kd3BxZJCX9/jSoMfWOBbgkA5bRgHU0xrAj+p49qD6Ej9Xr8GE3+uebz3sEuhSFRnCKwKoOHOemfgevfO2y/jQXP677WPf3xQX7bVDfTFSHU=
acl: public_read
local-dir: $HOME/src/ljt.nightly/latest/files
upload-dir: $TRAVIS_BRANCH/$TRAVIS_OS_NAME
on:
branch: master
condition: -n "$BUILD_OFFICIAL"
- provider: s3
bucket: libjpeg-turbo-pr
access_key_id:
secure: bmFEt4H90/oR/LiN9XI+G26Pd6hiyrTw3+Vg3lS4ynwAYk33weApaVM8CyzQTgIhGSPzFStqVm9fTrb3RmrYP/PnNS+/surOeWLkH2DMRxvc0qmetBuNx1+vAN7FUkY8MO/u5uE9WXHAdp4e64pXcLXEbKmh+wgDm72b35WmMxErtHsGbpqy+j47rQkY4BJGi7XQzjjafaamfm4PzitsjkYYsgX8KLI16jyJEIirvyDHCPTn9wKR/jSjelDl+xTlgZGuCqmLCBW8f6JgycIspWjcYfO4WpWvkbnnI2sl3rCMPvOYc4wHe8SwzG0l4tM1PblZZDRcU7vjE15PmNf1Xfq9Vx3RpgBJv+UBNL/Vn0rKdpUCeEcfC12hxrske8DWpV6waBiDivjQJreE+YRXqa5YBhV/EdkoKYCqafnJvRASlOko9evje8F9KXTNsIGTT1HPmU9QM9WoJwLs/Xa3t09EmA2IjhcuAvvUmwCTuBBQVAlDjExiTT3Zhc9IYZDD92JgpAYLgridtzR87ElOxKhTkR4PowdI6UiLYArPjMFTjoz5Rivb9qNpbLaQC8HCYgLWxpWtUTzlW/9rM8izHpF8ySFHjO6E2aA9OJFc0tcbEGwAs2jLGD01OduU+DbBfsIkW0EgfXCPbD3FVgHsn3tkuzgO/bg20SM7uuCEYKQ=
secret_access_key:
secure: mrkOpEtqd2dEmi/qNJyX9vkME+6xgVBnXaRETKF7jT+flcQCQ0ayQkRkMV7lzGqq44XFg+n6Cpfn6oW0gH9RNdcC8YQvFP+kgzPx6nw6V/M31Vz6ySapJf59HBzVevf0NJkr0/1JoWsp1iq4IoN10WPzsCXZB55Io3Cf7DgpR+yiyBlWOctDfNdjJ97Juw3ENE80MHDf0fVqdUOIknQka1p68yAGkjar9kc2Oe7o94RzzmoqEn8tuFumiBQjIcuVRALsKqz+eIxBNgkL3BF9shVyRjOWLAeBhMPVFxZs5Dgd4ECbvU0i33gfmje3d6qqcw78N2lZaLefoVvWol3pOzVO133ewOSY9/lmpqEiRUU2ohEe8T4aSoS7posBW42itUTO4Y5w+eVOnHsm4sRQaI+/AXWTe7GPel+P8Qbe8Ya10A5gnpoag7o3raRDcHx+/qaZw1Af/u4XiAOYz3be3U90Qc+YMc/kS5i8BH0GXBbSfaWQ00CwRFlZQ3n1xUqmjC2CmjZTki3W/p7mEt0DjhcH9ZIXscK603sCC+mF6pEd9019k5fG/8fr2Y4Ptai9kd3BxZJCX9/jSoMfWOBbgkA5bRgHU0xrAj+p49qD6Ej9Xr8GE3+uebz3sEuhSFRnCKwKoOHOemfgevfO2y/jQXP677WPf3xQX7bVDfTFSHU=
acl: public_read
local-dir: $HOME/src/ljt.nightly/latest/files
upload-dir: $TRAVIS_BRANCH/$TRAVIS_OS_NAME
on:
branch: dev
condition: -n "$BUILD_OFFICIAL"

File diff suppressed because it is too large Load Diff

View File

@@ -1,902 +0,0 @@
*******************************************************************************
** Building on Un*x Platforms (including Cygwin and OS X)
*******************************************************************************
==================
Build Requirements
==================
-- pkg-config
-- autoconf 2.56 or later
-- automake 1.7 or later
-- libtool 1.4 or later
* If using Xcode 4.3 or later on OS X, autoconf and automake are no longer
provided. The easiest way to obtain them is from MacPorts
(http://www.macports.org/).
-- NASM or YASM (if building x86 or x86-64 SIMD extensions)
* NASM 0.98, or 2.01 or later is required for an x86 build (0.99 and 2.00 do
not work properly with libjpeg-turbo's x86 SIMD code.)
* NASM 2.00 or later is required for an x86-64 build.
* NASM 2.07, or 2.11.09 or later is required for an x86-64 Mac build
(2.11.08 does not work properly with libjpeg-turbo's x86-64 SIMD code when
building macho64 objects.) NASM or YASM can be obtained from MacPorts
(http://www.macports.org/).
The binary RPMs released by the NASM project do not work on older Linux
systems, such as Red Hat Enterprise Linux 4. On such systems, you can
easily build and install NASM from a source RPM by downloading one of the
SRPMs from
http://www.nasm.us/pub/nasm/releasebuilds
and executing the following as root:
ARCH=`uname -m`
rpmbuild --rebuild nasm-{version}.src.rpm
rpm -Uvh /usr/src/redhat/RPMS/$ARCH/nasm-{version}.$ARCH.rpm
NOTE: the NASM build will fail if texinfo is not installed.
-- GCC v4.1 or later recommended for best performance
* Beginning with Xcode 4, Apple stopped distributing GCC and switched to
the LLVM compiler. Xcode v4.0 through v4.6 provides a GCC front end
called LLVM-GCC. Unfortunately, as of this writing, neither LLVM-GCC nor
the LLVM (clang) compiler produces optimal performance with libjpeg-turbo.
Building mozjpeg with LLVM-GCC v4.2 results in a 10% performance
degradation when compressing using 64-bit code, relative to building
libjpeg-turbo with GCC v4.2. Building libjpeg-turbo with LLVM (clang)
results in a 20% performance degradation when compressing using 64-bit
code, relative to building libjpeg-turbo with GCC v4.2. If you are
running Snow Leopard or earlier, it is suggested that you continue to use
Xcode v3.2.6, which provides GCC v4.2. If you are using Lion or later, it
is suggested that you install Apple GCC v4.2 or GCC v5 through MacPorts.
-- If building the TurboJPEG Java wrapper, JDK or OpenJDK 1.5 or later is
required. Some systems, such as Solaris 10 and later and Red Hat Enterprise
Linux 5 and later, have this pre-installed. On OS X 10.5 and later, it will
be necessary to install the Java Developer Package, which can be downloaded
from http://developer.apple.com/downloads (Apple ID required.) For systems
that do not have a JDK installed, you can obtain the Oracle Java Development
Kit from http://www.java.com.
==================
Out-of-Tree Builds
==================
Binary objects, libraries, and executables are generated in the same directory
from which configure was executed (the "binary directory"), and this directory
need not necessarily be the same as the mozjpeg source directory. You
can create multiple independent binary directories, in which different versions
of mozjpeg can be built from the same source tree using different
compilers or settings. In the sections below, {build_directory} refers to the
binary directory, whereas {source_directory} refers to the mozjpeg source
directory. For in-tree builds, these directories are the same.
================
Building mozjpeg
================
The following procedure will build mozjpeg on Linux, FreeBSD, Cygwin, and
Solaris/x86 systems (on Solaris, this generates a 32-bit library. See below
for 64-bit build instructions.)
Simple Release tar.gz Source Build
----------------------------------
cd {source_directory}
./configure [additional configure flags]
make
Non-Release Source Build (e.g. GitHub clone)
--------------------------------------------
cd {source_directory}
autoreconf -fiv
cd {build_directory}
sh {source_directory}/configure [additional configure flags]
make
NOTE: Running autoreconf in the source directory is not necessary if building
mozjpeg from one of the official release tarballs.
This will generate the following files under .libs/
libjpeg.a
Static link library for the libjpeg API
libjpeg.so.{version} (Linux, Unix)
libjpeg.{version}.dylib (OS X)
cygjpeg-{version}.dll (Cygwin)
Shared library for the libjpeg API
By default, {version} is 62.2.0, 7.2.0, or 8.1.2, depending on whether
libjpeg v6b (default), v7, or v8 emulation is enabled. If using Cygwin,
{version} is 62, 7, or 8.
libjpeg.so (Linux, Unix)
libjpeg.dylib (OS X)
Development symlink for the libjpeg API
libjpeg.dll.a (Cygwin)
Import library for the libjpeg API
libturbojpeg.a
Static link library for the TurboJPEG API
libturbojpeg.so.0.1.0 (Linux, Unix)
libturbojpeg.0.1.0.dylib (OS X)
cygturbojpeg-0.dll (Cygwin)
Shared library for the TurboJPEG API
libturbojpeg.so (Linux, Unix)
libturbojpeg.dylib (OS X)
Development symlink for the TurboJPEG API
libturbojpeg.dll.a (Cygwin)
Import library for the TurboJPEG API
libjpeg v7 or v8 API/ABI Emulation
----------------------------------
Add --with-jpeg7 to the configure command line to build a version of
mozjpeg that is API/ABI-compatible with libjpeg v7. Add --with-jpeg8 to
the configure command to build a version of mozjpeg that is
API/ABI-compatible with libjpeg v8. See README-turbo.txt for more information
on libjpeg v7 and v8 emulation.
In-Memory Source/Destination Managers
-------------------------------------
When using libjpeg v6b or v7 API/ABI emulation, add --without-mem-srcdst to the
configure command line to build a version of mozjpeg that lacks the
jpeg_mem_src() and jpeg_mem_dest() functions. These functions were not part of
the original libjpeg v6b and v7 APIs, so removing them ensures strict
conformance with those APIs. See README-turbo.txt for more information.
Arithmetic Coding Support
-------------------------
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of mozjpeg. mozjpeg's implementation is
based on the implementation in libjpeg v8, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add --without-arith-enc or --without-arith-dec to the configure command line to
disable encoding or decoding (respectively.)
TurboJPEG Java Wrapper
----------------------
Add --with-java to the configure command line to incorporate an optional Java
Native Interface wrapper into the TurboJPEG shared library and build the Java
front-end classes to support it. This allows the TurboJPEG shared library to
be used directly from Java applications. See java/README for more details.
You can set the JAVAC, JAR, and JAVA configure variables to specify
alternate commands for javac, jar, and java (respectively.) You can also
set the JAVACFLAGS configure variable to specify arguments that should be
passed to the Java compiler when building the front-end classes, and JNI_CFLAGS
to specify arguments that should be passed to the C compiler when building the
JNI wrapper. Run 'configure --help' for more details.
==================
Installing mozjpeg
==================
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/mozjpeg/include and the library
files in /opt/mozjpeg/lib32 (32-bit) or /opt/mozjpeg/lib64
(64-bit.)
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 mozjpeg into
a non-system directory and manipulate the LD_LIBRARY_PATH or create symlinks
to force applications to use mozjpeg instead of libjpeg. See
README-turbo.txt for more information.
=============
Build Recipes
=============
32-bit Build on 64-bit Linux
----------------------------
Add
--host i686-pc-linux-gnu CFLAGS='-O3 -m32' LDFLAGS=-m32
to the configure command line.
64-bit Build on 64-bit OS X
---------------------------
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm
to the configure command line. NASM 2.07 or later from MacPorts must be
installed.
32-bit Build on 64-bit OS X
---------------------------
Add
--host i686-apple-darwin CFLAGS='-O3 -m32' LDFLAGS=-m32
to the configure command line.
64-bit Backward-Compatible Build on 64-bit OS X
-----------------------------------------------
Add
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm \
CFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5 -O3' \
LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5'
to the configure command line. The OS X 10.5 SDK, and NASM 2.07 or later from
MacPorts, must be installed.
32-bit Backward-Compatible Build on OS X
----------------------------------------
Add
--host i686-apple-darwin \
CFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5 -O3 -m32' \
LDFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk \
-mmacosx-version-min=10.5 -m32'
to the configure command line. The OS X 10.5 SDK must be installed.
64-bit Library Build on 64-bit Solaris
--------------------------------------
Add
--host x86_64-pc-solaris CFLAGS='-O3 -m64' LDFLAGS=-m64
to the configure command line.
32-bit Build on 64-bit FreeBSD
------------------------------
Add
--host i386-unknown-freebsd CC='gcc -B /usr/lib32' CFLAGS='-O3 -m32' \
LDFLAGS='-B/usr/lib32'
to the configure command line. NASM 2.07 or later from FreeBSD ports must be
installed.
Oracle Solaris Studio
---------------------
Add
CC=cc
to the configure command line. mozjpeg will automatically be built with
the maximum optimization level (-xO5) unless you override CFLAGS.
To build a 64-bit version of mozjpeg using Oracle Solaris Studio, add
--host x86_64-pc-solaris CC=cc CFLAGS='-xO5 -m64' LDFLAGS=-m64
to the configure command line.
MinGW Build on Cygwin
---------------------
Use CMake (see recipes below)
===========
ARM Support
===========
This release of mozjpeg can use ARM NEON SIMD instructions to accelerate
JPEG compression/decompression by approximately 2-4x on ARMv7 and later
platforms. If mozjpeg is configured on an ARM Linux platform, then the
build system will automatically include the NEON SIMD routines, if they are
supported. Build instructions for other ARM-based platforms follow.
Building mozjpeg for iOS
------------------------
iOS platforms, such as the iPhone and iPad, use ARM processors, some of which
support NEON instructions. Additional steps are required in order to build
mozjpeg for these platforms.
Additional build requirements:
gas-preprocessor.pl
(https://raw.githubusercontent.com/libjpeg-turbo/gas-preprocessor/master/gas-preprocessor.pl)
should be installed in your PATH.
ARM 32-bit Build (Xcode 4.6.x and earlier, LLVM-GCC):
Set the following shell variables for simplicity:
Xcode 4.2 and earlier:
IOS_PLATFORMDIR=/Developer/Platforms/iPhoneOS.platform
Xcode 4.3 and later:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=$IOS_PLATFORMDIR/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
ARMv6 (code will run on all iOS devices, not SIMD-accelerated):
[NOTE: Requires Xcode 4.4.x or earlier]
IOS_CFLAGS="-march=armv6 -mcpu=arm1176jzf-s -mfpu=vfp"
ARMv7 (code will run on iPhone 3GS-4S/iPad 1st-3rd Generation and newer):
IOS_CFLAGS="-march=armv7 -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon"
ARMv7s (code will run on iPhone 5/iPad 4th Generation and newer):
[NOTE: Requires Xcode 4.5 or later]
IOS_CFLAGS="-march=armv7s -mcpu=swift -mtune=swift -mfpu=neon"
Follow the procedure under "Building mozjpeg" above, adding
--host arm-apple-darwin10 \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS"
to the configure command line.
ARM 32-bit Build (Xcode 5.0.x and later, Clang):
Set the following shell variables for simplicity:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
ARMv7 (code will run on iPhone 3GS-4S/iPad 1st-3rd Generation and newer):
IOS_CFLAGS="-arch armv7"
ARMv7s (code will run on iPhone 5/iPad 4th Generation and newer):
IOS_CFLAGS="-arch armv7s"
Follow the procedure under "Building libjpeg-turbo" above, adding
--host arm-apple-darwin10 \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS" \
CCASFLAGS="-no-integrated-as $IOS_CFLAGS"
to the configure command line.
ARMv8 64-bit Build (Xcode 5.0.x and later, Clang):
Code will run on iPhone 5S/iPad Mini 2/iPad Air and newer.
Set the following shell variables for simplicity:
IOS_PLATFORMDIR=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS*.sdk
IOS_GCC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
IOS_CFLAGS="-arch arm64"
Follow the procedure under "Building libjpeg-turbo" above, adding
--host aarch64-apple-darwin \
CC="$IOS_GCC" LD="$IOS_GCC" \
CFLAGS="-isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
LDFLAGS="-isysroot $IOS_SYSROOT $IOS_CFLAGS"
to the configure command line.
NOTE: You can also add -miphoneos-version-min={version} to $IOS_CFLAGS above
in order to support older versions of iOS than the default version supported by
the SDK.
Once built, lipo can be used to combine the ARMv6, v7, v7s, and/or v8 variants
into a universal library.
Building libjpeg-turbo for Android
----------------------------------
Building libjpeg-turbo for Android platforms requires the Android NDK
(https://developer.android.com/tools/sdk/ndk) and autotools. The following is
a general recipe script that can be modified for your specific needs.
# Set these variables to suit your needs
NDK_PATH={full path to the "ndk" directory-- for example, /opt/android/ndk}
BUILD_PLATFORM={the platform name for the NDK package you installed--
for example, "windows-x86" or "linux-x86_64" or "darwin-x86_64"}
TOOLCHAIN_VERSION={"4.8", "4.9", "clang3.5", etc. This corresponds to a
toolchain directory under ${NDK_PATH}/toolchains/.}
ANDROID_VERSION={The minimum version of Android to support-- for example,
"16", "19", etc. "21" or later is required for a 64-bit build.}
# 32-bit ARMv7 build
HOST=arm-linux-androideabi
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm
ANDROID_CFLAGS="-march=armv7-a -mfloat-abi=softfp -fprefetch-loop-arrays \
--sysroot=${SYSROOT}"
# 64-bit ARMv8 build
HOST=aarch64-linux-android
SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-arm64
ANDROID_CFLAGS="--sysroot=${SYSROOT}"
TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
ANDROID_INCLUDES="-I${SYSROOT}/usr/include -I${TOOLCHAIN}/include"
export CPP=${TOOLCHAIN}/bin/${HOST}-cpp
export AR=${TOOLCHAIN}/bin/${HOST}-ar
export AS=${TOOLCHAIN}/bin/${HOST}-as
export NM=${TOOLCHAIN}/bin/${HOST}-nm
export CC=${TOOLCHAIN}/bin/${HOST}-gcc
export LD=${TOOLCHAIN}/bin/${HOST}-ld
export RANLIB=${TOOLCHAIN}/bin/${HOST}-ranlib
export OBJDUMP=${TOOLCHAIN}/bin/${HOST}-objdump
export STRIP=${TOOLCHAIN}/bin/${HOST}-strip
cd {build_directory}
sh {source_directory}/configure --host=${HOST} \
CFLAGS="${ANDROID_INCLUDES} ${ANDROID_CFLAGS} -O3 -fPIE" \
CPPFLAGS="${ANDROID_INCLUDES} ${ANDROID_CFLAGS}" \
LDFLAGS="${ANDROID_CFLAGS} -pie" --with-simd ${1+"$@"}
make
If building for Android 4.0.x (API level < 16) or earlier, remove -fPIE from
CFLAGS and -pie from LDFLAGS.
*******************************************************************************
** Building on Windows (Visual C++ or MinGW)
*******************************************************************************
==================
Build Requirements
==================
-- CMake (http://www.cmake.org) v2.8.8 or later
-- Microsoft Visual C++ 2005 or later
If you don't already have Visual C++, then the easiest way to get it is by
installing the Windows SDK:
http://msdn.microsoft.com/en-us/windows/bb980924.aspx
The Windows SDK includes both 32-bit and 64-bit Visual C++ compilers and
everything necessary to build mozjpeg.
* You can also use Microsoft Visual Studio Express Edition, which is a free
download. (NOTE: versions prior to 2012 can only be used to build 32-bit
code.)
* If you intend to build mozjpeg from the command line, then add the
appropriate compiler and SDK directories to the INCLUDE, LIB, and PATH
environment variables. This is generally accomplished by executing
vcvars32.bat or vcvars64.bat and SetEnv.cmd. vcvars32.bat and
vcvars64.bat are part of Visual C++ and are located in the same directory
as the compiler. SetEnv.cmd is part of the Windows SDK. You can pass
optional arguments to SetEnv.cmd to specify a 32-bit or 64-bit build
environment.
... OR ...
-- MinGW
MinGW-builds (http://sourceforge.net/projects/mingwbuilds/) or
tdm-gcc (http://tdm-gcc.tdragon.net/) recommended if building on a Windows
machine. Both distributions install a Start Menu link that can be used to
launch a command prompt with the appropriate compiler paths automatically
set.
-- NASM (http://www.nasm.us/) 0.98 or later (NASM 2.05 or later is required for
a 64-bit build)
-- If building the TurboJPEG Java wrapper, JDK 1.5 or later is required. This
can be downloaded from http://www.java.com.
==================
Out-of-Tree Builds
==================
Binary objects, libraries, and executables are generated in the same directory
from which cmake was executed (the "binary directory"), and this directory need
not necessarily be the same as the mozjpeg source directory. You can
create multiple independent binary directories, in which different versions of
mozjpeg can be built from the same source tree using different compilers
or settings. In the sections below, {build_directory} refers to the binary
directory, whereas {source_directory} refers to the mozjpeg source
directory. For in-tree builds, these directories are the same.
================
Building mozjpeg
================
Visual C++ (Command Line)
-------------------------
cd {build_directory}
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release {source_directory}
nmake
This will build either a 32-bit or a 64-bit version of mozjpeg, depending
on which version of cl.exe is in the PATH.
The following files will be generated under {build_directory}:
jpeg-static.lib
Static link library for the libjpeg API
sharedlib/jpeg{version}.dll
DLL for the libjpeg API
sharedlib/jpeg.lib
Import library for the libjpeg API
turbojpeg-static.lib
Static link library for the TurboJPEG API
turbojpeg.dll
DLL for the TurboJPEG API
turbojpeg.lib
Import library for the TurboJPEG API
{version} is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8 emulation is enabled.
Visual C++ (IDE)
----------------
Choose the appropriate CMake generator option for your version of Visual Studio
(run "cmake" with no arguments for a list of available generators.) For
instance:
cd {build_directory}
cmake -G "Visual Studio 10" {source_directory}
NOTE: Add "Win64" to the generator name (for example, "Visual Studio 10
Win64") to build a 64-bit version of libjpeg-turbo. Recent versions of CMake
no longer document that. A separate build directory must be used for 32-bit
and 64-bit builds.
You can then open ALL_BUILD.vcproj in Visual Studio and build one of the
configurations in that project ("Debug", "Release", etc.) to generate a full
build of mozjpeg.
This will generate the following files under {build_directory}:
{configuration}/jpeg-static.lib
Static link library for the libjpeg API
sharedlib/{configuration}/jpeg{version}.dll
DLL for the libjpeg API
sharedlib/{configuration}/jpeg.lib
Import library for the libjpeg API
{configuration}/turbojpeg-static.lib
Static link library for the TurboJPEG API
{configuration}/turbojpeg.dll
DLL for the TurboJPEG API
{configuration}/turbojpeg.lib
Import library for the TurboJPEG API
{configuration} is Debug, Release, RelWithDebInfo, or MinSizeRel, depending on
the configuration you built in the IDE, and {version} is 62, 7, or 8,
depending on whether libjpeg v6b (default), v7, or v8 emulation is enabled.
MinGW
-----
NOTE: This assumes that you are building on a Windows machine. If you are
cross-compiling on a Linux/Unix machine, then see "Build Recipes" below.
cd {build_directory}
cmake -G "MinGW Makefiles" {source_directory}
mingw32-make
This will generate the following files under {build_directory}
libjpeg.a
Static link library for the libjpeg API
sharedlib/libjpeg-{version}.dll
DLL for the libjpeg API
sharedlib/libjpeg.dll.a
Import library for the libjpeg API
libturbojpeg.a
Static link library for the TurboJPEG API
libturbojpeg.dll
DLL for the TurboJPEG API
libturbojpeg.dll.a
Import library for the TurboJPEG API
{version} is 62, 7, or 8, depending on whether libjpeg v6b (default), v7, or
v8 emulation is enabled.
Debug Build
-----------
Add "-DCMAKE_BUILD_TYPE=Debug" to the cmake command line. Or, if building with
NMake, remove "-DCMAKE_BUILD_TYPE=Release" (Debug builds are the default with
NMake.)
libjpeg v7 or v8 API/ABI Emulation
-----------------------------------
Add "-DWITH_JPEG7=1" to the cmake command line to build a version of
mozjpeg that is API/ABI-compatible with libjpeg v7. Add "-DWITH_JPEG8=1"
to the cmake command to build a version of mozjpeg that is
API/ABI-compatible with libjpeg v8. See README-turbo.txt for more information
on libjpeg v7 and v8 emulation.
In-Memory Source/Destination Managers
-------------------------------------
When using libjpeg v6b or v7 API/ABI emulation, add -DWITH_MEM_SRCDST=0 to the
CMake command line to build a version of mozjpeg that lacks the
jpeg_mem_src() and jpeg_mem_dest() functions. These functions were not part of
the original libjpeg v6b and v7 APIs, so removing them ensures strict
conformance with those APIs. See README-turbo.txt for more information.
Arithmetic Coding Support
-------------------------
Since the patent on arithmetic coding has expired, this functionality has been
included in this release of mozjpeg. mozjpeg's implementation is
based on the implementation in libjpeg v8, but it works when emulating libjpeg
v7 or v6b as well. The default is to enable both arithmetic encoding and
decoding, but those who have philosophical objections to arithmetic coding can
add "-DWITH_ARITH_ENC=0" or "-DWITH_ARITH_DEC=0" to the cmake command line to
disable encoding or decoding (respectively.)
TurboJPEG Java Wrapper
----------------------
Add "-DWITH_JAVA=1" to the cmake command line to incorporate an optional Java
Native Interface wrapper into the TurboJPEG shared library and build the Java
front-end classes to support it. This allows the TurboJPEG shared library to
be used directly from Java applications. See java/README for more details.
If you are using CMake 2.8, you can set the Java_JAVAC_EXECUTABLE,
Java_JAVA_EXECUTABLE, and Java_JAR_EXECUTABLE CMake variables to specify
alternate commands or locations for javac, jar, and java (respectively.) If
you are using CMake 2.6, set JAVA_COMPILE, JAVA_RUNTIME, and JAVA_ARCHIVE
instead. You can also set the JAVACFLAGS CMake variable to specify arguments
that should be passed to the Java compiler when building the front-end classes.
==================
Installing mozjpeg
==================
You can use the build system to install mozjpeg into a directory of your
choosing (as opposed to creating an installer.) To do this, add:
-DCMAKE_INSTALL_PREFIX={install_directory}
to the cmake command line.
For example,
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=c:\mozjpeg {source_directory}
nmake install
will install the header files in c:\mozjpeg\include, the library files
in c:\mozjpeg\lib, the DLL's in c:\mozjpeg\bin, and the
documentation in c:\mozjpeg\doc.
=============
Build Recipes
=============
64-bit MinGW Build on Cygwin
----------------------------
cd {build_directory}
CC=/usr/bin/x86_64-w64-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_RC_COMPILER=/usr/bin/x86_64-w64-mingw32-windres.exe \
{source_directory}
make
This produces a 64-bit build of mozjpeg that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-x86_64-gcc-core and
mingw64-x86_64-gcc-g++ packages (and their dependencies) must be installed.
32-bit MinGW Build on Cygwin
----------------------------
cd {build_directory}
CC=/usr/bin/i686-w64-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_RC_COMPILER=/usr/bin/i686-w64-mingw32-windres.exe \
{source_directory}
make
This produces a 32-bit build of mozjpeg that does not depend on
cygwin1.dll or other Cygwin DLL's. The mingw64-i686-gcc-core and
mingw64-i686-gcc-g++ packages (and their dependencies) must be installed.
MinGW Build on Linux
--------------------
cd {build_directory}
CC={mingw_binary_path}/i386-mingw32-gcc \
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Windows \
-DCMAKE_AR={mingw_binary_path}/i386-mingw32-ar \
-DCMAKE_RANLIB={mingw_binary_path}/i386-mingw32-ranlib \
{source_directory}
make
*******************************************************************************
** Creating Release Packages
*******************************************************************************
The following commands can be used to create various types of release packages:
Unix/Linux
----------
make rpm
Create Red Hat-style binary RPM package. Requires RPM v4 or later.
make srpm
This runs 'make dist' to create a pristine source tarball, then creates a
Red Hat-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 pkgbuild and
productbuild, which are installed by default on OS X 10.7 and later and which
can be obtained by installing Xcode 3.2.6 (with the "Unix Development"
option) on OS X 10.6. Packages built in this manner can be installed on OS X
10.5 and later, but they must be built on OS X 10.6 or later.
make udmg [BUILDDIR32={32-bit build directory}]
On 64-bit OS X systems, this creates a Macintosh package and disk image that
contains universal i386/x86-64 binaries. You should first configure a 32-bit
out-of-tree build of mozjpeg, then configure a 64-bit out-of-tree
build, then run 'make udmg' from the 64-bit build directory. The build
system will look for the 32-bit build under {source_directory}/osxx86 by
default, but you can override this by setting the BUILDDIR32 variable on the
make command line as shown above.
make iosdmg [BUILDDIR32={32-bit build directory}] \
[BUILDDIRARMV6={ARMv6 build directory}] \
[BUILDDIRARMV7={ARMv7 build directory}] \
[BUILDDIRARMV7S={ARMv7s build directory}] \
[BUILDDIRARMV8={ARMv8 build directory}]
On OS X systems, this creates a Macintosh package and disk image in which the
mozjpeg static libraries contain ARM architectures necessary to build
iOS applications. If building on an x86-64 system, the binaries will also
contain the i386 architecture, as with 'make udmg' above. You should first
configure ARMv6, ARMv7, ARMv7s, and/or ARMv8 out-of-tree builds of
mozjpeg (see "Building mozjpeg for iOS" above.) If you are
building an x86-64 version of mozjpeg, you should configure a 32-bit
out-of-tree build as well. Next, build mozjpeg as you would normally,
using an out-of-tree build. When it is built, run 'make iosdmg' from the
build directory. The build system will look for the ARMv6 build under
{source_directory}/iosarmv6 by default, the ARMv7 build under
{source_directory}/iosarmv7 by default, the ARMv7s build under
{source_directory}/iosarmv7s by default, the ARMv8 build under
{source_directory}/iosarmv8 by default, and (if applicable) the 32-bit build
under {source_directory}/osxx86 by default, but you can override this by
setting the BUILDDIR32, BUILDDIRARMV6, BUILDDIRARMV7, BUILDDIRARMV7S, and/or
BUILDDIRARMV8 variables on the make command line as shown above.
NOTE: If including an ARMv8 build in the package, then you may need to use
Xcode's version of lipo instead of the operating system's. To do this, pass
an argument of LIPO="xcrun lipo" on the make command line.
make cygwinpkg
Build a Cygwin binary package.
Windows
-------
If using NMake:
cd {build_directory}
nmake installer
If using MinGW:
cd {build_directory}
make installer
If using the Visual Studio IDE, build the "installer" project.
The installer package (mozjpeg[-gcc][64].exe) will be located under
{build_directory}. If building using the Visual Studio IDE, then the installer
package will be located in a subdirectory with the same name as the
configuration you built (such as {build_directory}\Debug\ or
{build_directory}\Release\).
Building a Windows installer requires the Nullsoft Install System
(http://nsis.sourceforge.net/.) makensis.exe should be in your PATH.
*******************************************************************************
** Regression testing
*******************************************************************************
The most common way to test mozjpeg is by invoking 'make test' on
Unix/Linux platforms or 'ctest' on Windows platforms, once the build has
completed. This runs a series of tests to ensure that mathematical
compatibility has been maintained. This also invokes the TurboJPEG unit tests,
which ensure that the colorspace extensions, YUV encoding, decompression
scaling, and other features of the TurboJPEG C and Java APIs are working
properly (and, by extension, that the equivalent features of the underlying
libjpeg API are also working.)
Invoking 'make testclean' or 'nmake testclean' (if using NMake) or building
the 'testclean' target (if using the Visual Studio IDE) will clean up the
output images generated by 'make test'.
On Unix/Linux platforms, more extensive tests of the TurboJPEG C and Java
wrappers can be run by invoking 'make tjtest'. These extended TurboJPEG tests
essentially iterate through all of the available features of the TurboJPEG APIs
that are not covered by the TurboJPEG unit tests (this includes the lossless
transform options) and compare the images generated by each feature to images
generated using the equivalent feature in the libjpeg API. The extended
TurboJPEG tests are meant to test for regressions in the TurboJPEG wrappers,
not in the underlying libjpeg API library.

View File

@@ -8,8 +8,26 @@ if(POLICY CMP0022)
cmake_policy(SET CMP0022 OLD) cmake_policy(SET CMP0022 OLD)
endif() endif()
project(mozjpeg C) project(libjpeg-turbo C)
set(VERSION 3.2) set(VERSION 1.5.2)
string(REPLACE "." ";" VERSION_TRIPLET ${VERSION})
list(GET VERSION_TRIPLET 0 VERSION_MAJOR)
list(GET VERSION_TRIPLET 1 VERSION_MINOR)
list(GET VERSION_TRIPLET 2 VERSION_REVISION)
function(pad_number NUMBER OUTPUT_LEN)
string(LENGTH "${${NUMBER}}" INPUT_LEN)
if(INPUT_LEN LESS OUTPUT_LEN)
math(EXPR ZEROES "${OUTPUT_LEN} - ${INPUT_LEN} - 1")
set(NUM ${${NUMBER}})
foreach(C RANGE ${ZEROES})
set(NUM "0${NUM}")
endforeach()
set(${NUMBER} ${NUM} PARENT_SCOPE)
endif()
endfunction()
pad_number(VERSION_MINOR 3)
pad_number(VERSION_REVISION 3)
set(LIBJPEG_TURBO_VERSION_NUMBER ${VERSION_MAJOR}${VERSION_MINOR}${VERSION_REVISION})
if(NOT WIN32) if(NOT WIN32)
message(FATAL_ERROR "Platform not supported by this build system. Use autotools instead.") message(FATAL_ERROR "Platform not supported by this build system. Use autotools instead.")
@@ -34,10 +52,10 @@ endif()
message(STATUS "VERSION = ${VERSION}, BUILD = ${BUILD}") message(STATUS "VERSION = ${VERSION}, BUILD = ${BUILD}")
option(WITH_SIMD "Include SIMD extensions" TRUE) option(WITH_SIMD "Include SIMD extensions" TRUE)
option(WITH_ARITH_ENC "Include arithmetic encoding support" TRUE) option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE)
option(WITH_ARITH_DEC "Include arithmetic decoding support" TRUE) option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE)
option(WITH_JPEG7 "Emulate libjpeg v7 API/ABI (this makes mozjpeg backward incompatible with libjpeg v6b)" FALSE) option(WITH_JPEG7 "Emulate libjpeg v7 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b)" FALSE)
option(WITH_JPEG8 "Emulate libjpeg v8 API/ABI (this makes mozjpeg backward incompatible with libjpeg v6b)" FALSE) option(WITH_JPEG8 "Emulate libjpeg v8 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b)" FALSE)
option(WITH_MEM_SRCDST "Include in-memory source/destination manager functions when emulating the libjpeg v6b or v7 API/ABI" TRUE) option(WITH_MEM_SRCDST "Include in-memory source/destination manager functions when emulating the libjpeg v6b or v7 API/ABI" TRUE)
option(WITH_TURBOJPEG "Include the TurboJPEG wrapper library and associated test programs" TRUE) option(WITH_TURBOJPEG "Include the TurboJPEG wrapper library and associated test programs" TRUE)
option(WITH_JAVA "Build Java wrapper for the TurboJPEG library" FALSE) option(WITH_JAVA "Build Java wrapper for the TurboJPEG library" FALSE)
@@ -159,7 +177,7 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX_DEFAULT ${CMAKE_INSTALL_PREFIX_DEFAULT}64) set(CMAKE_INSTALL_PREFIX_DEFAULT ${CMAKE_INSTALL_PREFIX_DEFAULT}64)
endif() endif()
set(CMAKE_INSTALL_PREFIX "c:/${CMAKE_INSTALL_PREFIX_DEFAULT}" CACHE PATH set(CMAKE_INSTALL_PREFIX "c:/${CMAKE_INSTALL_PREFIX_DEFAULT}" CACHE PATH
"Directory into which to install mozjpeg (default: c:/${CMAKE_INSTALL_PREFIX_DEFAULT})" "Directory into which to install libjpeg-turbo (default: c:/${CMAKE_INSTALL_PREFIX_DEFAULT})"
FORCE) FORCE)
endif() endif()
@@ -168,7 +186,7 @@ message(STATUS "Install directory = ${CMAKE_INSTALL_PREFIX}")
configure_file(win/jconfig.h.in jconfig.h) configure_file(win/jconfig.h.in jconfig.h)
configure_file(win/jconfigint.h.in jconfigint.h) configure_file(win/jconfigint.h.in jconfigint.h)
include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_SOURCE_DIR}") include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC) string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
@@ -191,13 +209,13 @@ endif()
# Targets # Targets
# #
set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jcext.c set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c
jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c
jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c
jdmarker.c jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c
jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c
jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c) jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
if(WITH_ARITH_ENC OR WITH_ARITH_DEC) if(WITH_ARITH_ENC OR WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c) set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c)
@@ -301,7 +319,7 @@ else()
endif() endif()
if(ENABLE_STATIC) if(ENABLE_STATIC)
add_executable(cjpeg-static cjpeg.c cdjpeg.c rdgif.c rdppm.c rdjpeg.c rdswitch.c add_executable(cjpeg-static cjpeg.c cdjpeg.c rdgif.c rdppm.c rdswitch.c
${CJPEG_BMP_SOURCES}) ${CJPEG_BMP_SOURCES})
set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS}) set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
target_link_libraries(cjpeg-static jpeg-static) target_link_libraries(cjpeg-static jpeg-static)
@@ -349,8 +367,20 @@ if(WITH_12BIT)
set(MD5_PPM_GRAY_ISLOW 7213c10af507ad467da5578ca5ee1fca) set(MD5_PPM_GRAY_ISLOW 7213c10af507ad467da5578ca5ee1fca)
set(MD5_PPM_GRAY_ISLOW_RGB e96ee81c30a6ed422d466338bd3de65d) set(MD5_PPM_GRAY_ISLOW_RGB e96ee81c30a6ed422d466338bd3de65d)
set(MD5_JPEG_420S_IFAST_OPT 7af8e60be4d9c227ec63ac9b6630855e) set(MD5_JPEG_420S_IFAST_OPT 7af8e60be4d9c227ec63ac9b6630855e)
set(MD5_JPEG_3x2_FLOAT_PROG a8c17daf77b457725ec929e215b603f8) if(64BIT)
set(MD5_PPM_3x2_FLOAT 42876ab9e5c2f76a87d08db5fbd57956) # Windows/x64 uses SSE for floating point
set(MD5_JPEG_3x2_FLOAT_PROG a8c17daf77b457725ec929e215b603f8)
set(MD5_PPM_3x2_FLOAT 42876ab9e5c2f76a87d08db5fbd57956)
else()
# Windows/x86 uses the 387 FPU for floating point
if(MSVC)
set(MD5_JPEG_3x2_FLOAT_PROG e27840755870fa849872e58aa0cd1400)
set(MD5_PPM_3x2_FLOAT 6c2880b83bb1aa41dfe330e7a9768690)
else()
set(MD5_JPEG_3x2_FLOAT_PROG bc6dbbefac2872f6b9d6c4a0ae60c3c0)
set(MD5_PPM_3x2_FLOAT f58119ee294198ac9b4a9f5645a34266)
endif()
endif()
set(MD5_PPM_420M_ISLOW_2_1 4ca6be2a6f326ff9eaab63e70a8259c0) set(MD5_PPM_420M_ISLOW_2_1 4ca6be2a6f326ff9eaab63e70a8259c0)
set(MD5_PPM_420M_ISLOW_15_8 12aa9f9534c1b3d7ba047322226365eb) set(MD5_PPM_420M_ISLOW_15_8 12aa9f9534c1b3d7ba047322226365eb)
set(MD5_PPM_420M_ISLOW_13_8 f7e22817c7b25e1393e4ec101e9d4e96) set(MD5_PPM_420M_ISLOW_13_8 f7e22817c7b25e1393e4ec101e9d4e96)
@@ -392,8 +422,18 @@ else()
set(MD5_JPEG_3x2_FLOAT_PROG 343e3f8caf8af5986ebaf0bdc13b5c71) set(MD5_JPEG_3x2_FLOAT_PROG 343e3f8caf8af5986ebaf0bdc13b5c71)
set(MD5_PPM_3x2_FLOAT 1a75f36e5904d6fc3a85a43da9ad89bb) set(MD5_PPM_3x2_FLOAT 1a75f36e5904d6fc3a85a43da9ad89bb)
else() else()
set(MD5_JPEG_3x2_FLOAT_PROG 9bca803d2042bd1eb03819e2bf92b3e5) if(64BIT)
set(MD5_PPM_3x2_FLOAT f6bfab038438ed8f5522fbd33595dcdc) set(MD5_JPEG_3x2_FLOAT_PROG 9bca803d2042bd1eb03819e2bf92b3e5)
set(MD5_PPM_3x2_FLOAT f6bfab038438ed8f5522fbd33595dcdc)
else()
if(MSVC)
set(MD5_JPEG_3x2_FLOAT_PROG 7999ce9cd0ee9b6c7043b7351ab7639d)
set(MD5_PPM_3x2_FLOAT 28cdc448a6b75e97892f0e0f8d4b21f3)
else()
set(MD5_JPEG_3x2_FLOAT_PROG 1657664a410e0822c924b54f6f65e6e9)
set(MD5_PPM_3x2_FLOAT cb0a1f027f3d2917c902b5640214e025)
endif()
endif()
endif() endif()
set(MD5_JPEG_420_ISLOW_ARI e986fb0a637a8d833d96e8a6d6d84ea1) set(MD5_JPEG_420_ISLOW_ARI e986fb0a637a8d833d96e8a6d6d84ea1)
set(MD5_JPEG_444_ISLOW_PROGARI 0a8f1c8f66e113c3cf635df0a475a617) set(MD5_JPEG_444_ISLOW_PROGARI 0a8f1c8f66e113c3cf635df0a475a617)
@@ -489,7 +529,7 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: null SAMP: fullsize FDCT: islow ENT: huff # CC: null SAMP: fullsize FDCT: islow ENT: huff
add_test(cjpeg${suffix}-rgb-islow add_test(cjpeg${suffix}-rgb-islow
${dir}cjpeg${suffix} -revert -rgb -dct int ${dir}cjpeg${suffix} -rgb -dct int
-outfile testout_rgb_islow.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_rgb_islow.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-rgb-islow-cmp add_test(cjpeg${suffix}-rgb-islow-cmp
${MD5CMP} ${MD5_JPEG_RGB_ISLOW} testout_rgb_islow.jpg) ${MD5CMP} ${MD5_JPEG_RGB_ISLOW} testout_rgb_islow.jpg)
@@ -519,7 +559,7 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: RGB->YCC SAMP: fullsize/h2v1 FDCT: ifast ENT: 2-pass huff # CC: RGB->YCC SAMP: fullsize/h2v1 FDCT: ifast ENT: 2-pass huff
add_test(cjpeg${suffix}-422-ifast-opt add_test(cjpeg${suffix}-422-ifast-opt
${dir}cjpeg${suffix} -revert -sample 2x1 -dct fast -opt ${dir}cjpeg${suffix} -sample 2x1 -dct fast -opt
-outfile testout_422_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_422_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-422-ifast-opt-cmp add_test(cjpeg${suffix}-422-ifast-opt-cmp
${MD5CMP} ${MD5_JPEG_422_IFAST_OPT} testout_422_ifast_opt.jpg) ${MD5CMP} ${MD5_JPEG_422_IFAST_OPT} testout_422_ifast_opt.jpg)
@@ -556,7 +596,7 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff # CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff
add_test(cjpeg${suffix}-420-q100-ifast-prog add_test(cjpeg${suffix}-420-q100-ifast-prog
${dir}cjpeg${suffix} -revert -sample 2x2 -quality 100 -dct fast -prog ${dir}cjpeg${suffix} -sample 2x2 -quality 100 -dct fast -prog
-outfile testout_420_q100_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_420_q100_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-420-q100-ifast-prog-cmp add_test(cjpeg${suffix}-420-q100-ifast-prog-cmp
${MD5CMP} ${MD5_JPEG_420_IFAST_Q100_PROG} testout_420_q100_ifast_prog.jpg) ${MD5CMP} ${MD5_JPEG_420_IFAST_Q100_PROG} testout_420_q100_ifast_prog.jpg)
@@ -577,7 +617,7 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: RGB->Gray SAMP: fullsize FDCT: islow ENT: huff # CC: RGB->Gray SAMP: fullsize FDCT: islow ENT: huff
add_test(cjpeg${suffix}-gray-islow add_test(cjpeg${suffix}-gray-islow
${dir}cjpeg${suffix} -revert -gray -dct int ${dir}cjpeg${suffix} -gray -dct int
-outfile testout_gray_islow.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_gray_islow.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-gray-islow-cmp add_test(cjpeg${suffix}-gray-islow-cmp
${MD5CMP} ${MD5_JPEG_GRAY_ISLOW} testout_gray_islow.jpg) ${MD5CMP} ${MD5_JPEG_GRAY_ISLOW} testout_gray_islow.jpg)
@@ -622,7 +662,7 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: RGB->YCC SAMP: fullsize/int FDCT: float ENT: prog huff # CC: RGB->YCC SAMP: fullsize/int FDCT: float ENT: prog huff
add_test(cjpeg${suffix}-3x2-float-prog add_test(cjpeg${suffix}-3x2-float-prog
${dir}cjpeg${suffix} -revert -sample 3x2 -dct float -prog ${dir}cjpeg${suffix} -sample 3x2 -dct float -prog
-outfile testout_3x2_float_prog.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_3x2_float_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-3x2-float-prog-cmp add_test(cjpeg${suffix}-3x2-float-prog-cmp
${MD5CMP} ${MD5_JPEG_3x2_FLOAT_PROG} testout_3x2_float_prog.jpg) ${MD5CMP} ${MD5_JPEG_3x2_FLOAT_PROG} testout_3x2_float_prog.jpg)
@@ -637,20 +677,20 @@ foreach(libtype ${TEST_LIBTYPES})
if(WITH_ARITH_ENC) if(WITH_ARITH_ENC)
# CC: YCC->RGB SAMP: fullsize/h2v2 FDCT: islow ENT: arith # CC: YCC->RGB SAMP: fullsize/h2v2 FDCT: islow ENT: arith
add_test(cjpeg${suffix}-420-islow-ari add_test(cjpeg${suffix}-420-islow-ari
${dir}cjpeg${suffix} -revert -dct int -arithmetic ${dir}cjpeg${suffix} -dct int -arithmetic
-outfile testout_420_islow_ari.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_420_islow_ari.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-420-islow-ari-cmp add_test(cjpeg${suffix}-420-islow-ari-cmp
${MD5CMP} ${MD5_JPEG_420_ISLOW_ARI} testout_420_islow_ari.jpg) ${MD5CMP} ${MD5_JPEG_420_ISLOW_ARI} testout_420_islow_ari.jpg)
add_test(jpegtran${suffix}-420-islow-ari add_test(jpegtran${suffix}-420-islow-ari
${dir}jpegtran${suffix} -revert -arithmetic ${dir}jpegtran${suffix} -arithmetic
-outfile testout_420_islow_ari.jpg ${TESTIMAGES}/testimgint.jpg) -outfile testout_420_islow_ari.jpg ${TESTIMAGES}/testimgint.jpg)
add_test(jpegtran${suffix}-420-islow-ari-cmp add_test(jpegtran${suffix}-420-islow-ari-cmp
${MD5CMP} ${MD5_JPEG_420_ISLOW_ARI} testout_420_islow_ari.jpg) ${MD5CMP} ${MD5_JPEG_420_ISLOW_ARI} testout_420_islow_ari.jpg)
# CC: YCC->RGB SAMP: fullsize FDCT: islow ENT: prog arith # CC: YCC->RGB SAMP: fullsize FDCT: islow ENT: prog arith
add_test(cjpeg${suffix}-444-islow-progari add_test(cjpeg${suffix}-444-islow-progari
${dir}cjpeg${suffix} -revert -sample 1x1 -dct int -prog -arithmetic ${dir}cjpeg${suffix} -sample 1x1 -dct int -prog -arithmetic
-outfile testout_444_islow_progari.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_444_islow_progari.jpg ${TESTIMAGES}/testorig.ppm)
add_test(cjpeg${suffix}-444-islow-progari-cmp add_test(cjpeg${suffix}-444-islow-progari-cmp
${MD5CMP} ${MD5_JPEG_444_ISLOW_PROGARI} testout_444_islow_progari.jpg) ${MD5CMP} ${MD5_JPEG_444_ISLOW_PROGARI} testout_444_islow_progari.jpg)
@@ -665,7 +705,7 @@ foreach(libtype ${TEST_LIBTYPES})
${MD5CMP} ${MD5_PPM_420M_IFAST_ARI} testout_420m_ifast_ari.ppm) ${MD5CMP} ${MD5_PPM_420M_IFAST_ARI} testout_420m_ifast_ari.ppm)
add_test(jpegtran${suffix}-420-islow add_test(jpegtran${suffix}-420-islow
${dir}jpegtran${suffix} -revert ${dir}jpegtran${suffix}
-outfile testout_420_islow.jpg ${TESTIMAGES}/testimgari.jpg) -outfile testout_420_islow.jpg ${TESTIMAGES}/testimgari.jpg)
add_test(jpegtran${suffix}-420-islow-cmp add_test(jpegtran${suffix}-420-islow-cmp
${MD5CMP} ${MD5_JPEG_420_ISLOW} testout_420_islow.jpg) ${MD5CMP} ${MD5_JPEG_420_ISLOW} testout_420_islow.jpg)
@@ -819,14 +859,14 @@ foreach(libtype ${TEST_LIBTYPES})
endif() endif()
add_test(jpegtran${suffix}-crop add_test(jpegtran${suffix}-crop
${dir}jpegtran${suffix} -revert -crop 120x90+20+50 -transpose -perfect ${dir}jpegtran${suffix} -crop 120x90+20+50 -transpose -perfect
-outfile testout_crop.jpg ${TESTIMAGES}/${TESTORIG}) -outfile testout_crop.jpg ${TESTIMAGES}/${TESTORIG})
add_test(jpegtran${suffix}-crop-cmp add_test(jpegtran${suffix}-crop-cmp
${MD5CMP} ${MD5_JPEG_CROP} testout_crop.jpg) ${MD5CMP} ${MD5_JPEG_CROP} testout_crop.jpg)
endforeach() endforeach()
add_custom_target(testclean COMMAND ${MD5CMP} -P add_custom_target(testclean COMMAND ${CMAKE_COMMAND} -P
${CMAKE_SOURCE_DIR}/cmakescripts/testclean.cmake) ${CMAKE_SOURCE_DIR}/cmakescripts/testclean.cmake)
@@ -848,7 +888,7 @@ endif()
if(64BIT) if(64BIT)
set(INST_PLATFORM "${INST_PLATFORM} 64-bit") set(INST_PLATFORM "${INST_PLATFORM} 64-bit")
set(INST_NAME ${INST_NAME}64) set(INST_NAME ${INST_NAME}64)
set(INST_REG_NAME "${INST_DIR}64") set(INST_REG_NAME ${INST_DIR}64)
set(INST_DEFS ${INST_DEFS} -DWIN64) set(INST_DEFS ${INST_DEFS} -DWIN64)
endif() endif()
@@ -862,18 +902,18 @@ else()
set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=") set(INST_DEFS ${INST_DEFS} "-DBUILDDIR=")
endif() endif()
STRING(REGEX REPLACE "/" "\\\\" INST_DIR "${CMAKE_INSTALL_PREFIX}") STRING(REGEX REPLACE "/" "\\\\" INST_DIR ${CMAKE_INSTALL_PREFIX})
configure_file(release/mozjpeg.nsi.in mozjpeg.nsi @ONLY) configure_file(release/libjpeg-turbo.nsi.in libjpeg-turbo.nsi @ONLY)
if(WITH_JAVA) if(WITH_JAVA)
set(JAVA_DEPEND java) set(JAVA_DEPEND java)
endif() endif()
add_custom_target(installer add_custom_target(installer
makensis -nocd ${INST_DEFS} mozjpeg.nsi makensis -nocd ${INST_DEFS} libjpeg-turbo.nsi
DEPENDS jpeg jpeg-static turbojpeg turbojpeg-static rdjpgcom wrjpgcom DEPENDS jpeg jpeg-static turbojpeg turbojpeg-static rdjpgcom wrjpgcom
cjpeg djpeg jpegtran tjbench ${JAVA_DEPEND} cjpeg djpeg jpegtran tjbench ${JAVA_DEPEND}
SOURCES mozjpeg.nsi) SOURCES libjpeg-turbo.nsi)
if(WITH_TURBOJPEG) if(WITH_TURBOJPEG)
if(ENABLE_SHARED) if(ENABLE_SHARED)
@@ -906,7 +946,7 @@ endif()
install(TARGETS rdjpgcom wrjpgcom RUNTIME DESTINATION bin) install(TARGETS rdjpgcom wrjpgcom RUNTIME DESTINATION bin)
install(FILES ${CMAKE_SOURCE_DIR}/README.ijg ${CMAKE_SOURCE_DIR}/README-mozilla.txt install(FILES ${CMAKE_SOURCE_DIR}/README.ijg ${CMAKE_SOURCE_DIR}/README.md
${CMAKE_SOURCE_DIR}/example.c ${CMAKE_SOURCE_DIR}/libjpeg.txt ${CMAKE_SOURCE_DIR}/example.c ${CMAKE_SOURCE_DIR}/libjpeg.txt
${CMAKE_SOURCE_DIR}/structure.txt ${CMAKE_SOURCE_DIR}/usage.txt ${CMAKE_SOURCE_DIR}/structure.txt ${CMAKE_SOURCE_DIR}/usage.txt
${CMAKE_SOURCE_DIR}/wizard.txt ${CMAKE_SOURCE_DIR}/wizard.txt
@@ -915,3 +955,8 @@ install(FILES ${CMAKE_SOURCE_DIR}/README.ijg ${CMAKE_SOURCE_DIR}/README-mozilla.
install(FILES ${CMAKE_BINARY_DIR}/jconfig.h ${CMAKE_SOURCE_DIR}/jerror.h install(FILES ${CMAKE_BINARY_DIR}/jconfig.h ${CMAKE_SOURCE_DIR}/jerror.h
${CMAKE_SOURCE_DIR}/jmorecfg.h ${CMAKE_SOURCE_DIR}/jpeglib.h ${CMAKE_SOURCE_DIR}/jmorecfg.h ${CMAKE_SOURCE_DIR}/jpeglib.h
DESTINATION include) DESTINATION include)
configure_file("${CMAKE_SOURCE_DIR}/cmakescripts/cmake_uninstall.cmake.in"
"cmake_uninstall.cmake" IMMEDIATE @ONLY)
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P cmake_uninstall.cmake)

View File

@@ -1,3 +1,165 @@
1.5.2
=====
### Significant changes relative to 1.5.1:
1. Fixed a regression introduced by 1.5.1[7] that prevented libjpeg-turbo from
building with Android NDK platforms prior to android-21 (5.0).
2. Fixed a regression introduced by 1.5.1[1] that prevented the MIPS DSPR2 SIMD
code in libjpeg-turbo from building.
3. Fixed a regression introduced by 1.5 beta1[11] that prevented the Java
version of TJBench from outputting any reference images (the `-nowrite` switch
was accidentally enabled by default.)
4. libjpeg-turbo should now build and run with full AltiVec SIMD acceleration
on PowerPC-based AmigaOS 4 and OpenBSD systems.
5. Fixed build and runtime errors on Windows that occurred when building
libjpeg-turbo with libjpeg v7 API/ABI emulation and the in-memory
source/destination managers. Due to an oversight, the `jpeg_skip_scanlines()`
and `jpeg_crop_scanlines()` functions were not being included in jpeg7.dll when
libjpeg-turbo was built with `-DWITH_JPEG7=1` and `-DWITH_MEMSRCDST=1`.
6. Fixed "Bogus virtual array access" error that occurred when using the
lossless crop feature in jpegtran or the TurboJPEG API, if libjpeg-turbo was
built with libjpeg v7 API/ABI emulation. This was apparently a long-standing
bug that has existed since the introduction of libjpeg v7/v8 API/ABI emulation
in libjpeg-turbo v1.1.
7. The lossless transform features in jpegtran and the TurboJPEG API will now
always attempt to adjust the EXIF image width and height tags if the image size
changed as a result of the transform. This behavior has always existed when
using libjpeg v8 API/ABI emulation. It was supposed to be available with
libjpeg v7 API/ABI emulation as well but did not work properly due to a bug.
Furthermore, there was never any good reason not to enable it with libjpeg v6b
API/ABI emulation, since the behavior is entirely internal. Note that
`-copy all` must be passed to jpegtran in order to transfer the EXIF tags from
the source image to the destination image.
8. Fixed several memory leaks in the TurboJPEG API library that could occur
if the library was built with certain compilers and optimization levels
(known to occur with GCC 4.x and clang with `-O1` and higher but not with
GCC 5.x or 6.x) and one of the underlying libjpeg API functions threw an error
after a TurboJPEG API function allocated a local buffer.
9. The libjpeg-turbo memory manager will now honor the `max_memory_to_use`
structure member in jpeg\_memory\_mgr, which can be set to the maximum amount
of memory (in bytes) that libjpeg-turbo should use during decompression or
multi-pass (including progressive) compression. This limit can also be set
using the `JPEGMEM` environment variable or using the `-maxmemory` switch in
cjpeg/djpeg/jpegtran (refer to the respective man pages for more details.)
This has been a documented feature of libjpeg since v5, but the
`malloc()`/`free()` implementation of the memory manager (jmemnobs.c) never
implemented the feature. Restricting libjpeg-turbo's memory usage is useful
for two reasons: it allows testers to more easily work around the 2 GB limit
in libFuzzer, and it allows developers of security-sensitive applications to
more easily defend against one of the progressive JPEG exploits (LJT-01-004)
identified in
[this report](http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf).
10. TJBench will now run each benchmark for 1 second prior to starting the
timer, in order to improve the consistency of the results. Furthermore, the
`-warmup` option is now used to specify the amount of warmup time rather than
the number of warmup iterations.
11. Fixed an error (`short jump is out of range`) that occurred when assembling
the 32-bit x86 SIMD extensions with NASM versions prior to 2.04. This was a
regression introduced by 1.5 beta1[12].
1.5.1
=====
### Significant changes relative to 1.5.0:
1. Previously, the undocumented `JSIMD_FORCE*` environment variables could be
used to force-enable a particular SIMD instruction set if multiple instruction
sets were available on a particular platform. On x86 platforms, where CPU
feature detection is bulletproof and multiple SIMD instruction sets are
available, it makes sense for those environment variables to allow forcing the
use of an instruction set only if that instruction set is available. However,
since the ARM implementations of libjpeg-turbo can only use one SIMD
instruction set, and since their feature detection code is less bulletproof
(parsing /proc/cpuinfo), it makes sense for the `JSIMD_FORCENEON` environment
variable to bypass the feature detection code and really force the use of NEON
instructions. A new environment variable (`JSIMD_FORCEDSPR2`) was introduced
in the MIPS implementation for the same reasons, and the existing
`JSIMD_FORCENONE` environment variable was extended to that implementation.
These environment variables provide a workaround for those attempting to test
ARM and MIPS builds of libjpeg-turbo in QEMU, which passes through
/proc/cpuinfo from the host system.
2. libjpeg-turbo previously assumed that AltiVec instructions were always
available on PowerPC platforms, which led to "illegal instruction" errors when
running on PowerPC chips that lack AltiVec support (such as the older 7xx/G3
and newer e5500 series.) libjpeg-turbo now examines /proc/cpuinfo on
Linux/Android systems and enables AltiVec instructions only if the CPU supports
them. It also now provides two environment variables, `JSIMD_FORCEALTIVEC` and
`JSIMD_FORCENONE`, to force-enable and force-disable AltiVec instructions in
environments where /proc/cpuinfo is an unreliable means of CPU feature
detection (such as when running in QEMU.) On OS X, libjpeg-turbo continues to
assume that AltiVec support is always available, which means that libjpeg-turbo
cannot be used with G3 Macs unless you set the environment variable
`JSIMD_FORCENONE` to `1`.
3. Fixed an issue whereby 64-bit ARM (AArch64) builds of libjpeg-turbo would
crash when built with recent releases of the Clang/LLVM compiler. This was
caused by an ABI conformance issue in some of libjpeg-turbo's 64-bit NEON SIMD
routines. Those routines were incorrectly using 64-bit instructions to
transfer a 32-bit JDIMENSION argument, whereas the ABI allows the upper
(unused) 32 bits of a 32-bit argument's register to be undefined. The new
Clang/LLVM optimizer uses load combining to transfer multiple adjacent 32-bit
structure members into a single 64-bit register, and this exposed the ABI
conformance issue.
4. Fancy upsampling is now supported when decompressing JPEG images that use
4:4:0 (h1v2) chroma subsampling. These images are generated when losslessly
rotating or transposing JPEG images that use 4:2:2 (h2v1) chroma subsampling.
The h1v2 fancy upsampling algorithm is not currently SIMD-accelerated.
5. If merged upsampling isn't SIMD-accelerated but YCbCr-to-RGB conversion is,
then libjpeg-turbo will now disable merged upsampling when decompressing YCbCr
JPEG images into RGB or extended RGB output images. This significantly speeds
up the decompression of 4:2:0 and 4:2:2 JPEGs on ARM platforms if fancy
upsampling is not used (for example, if the `-nosmooth` option to djpeg is
specified.)
6. The TurboJPEG API will now decompress 4:2:2 and 4:4:0 JPEG images with
2x2 luminance sampling factors and 2x1 or 1x2 chrominance sampling factors.
This is a non-standard way of specifying 2x subsampling (normally 4:2:2 JPEGs
have 2x1 luminance and 1x1 chrominance sampling factors, and 4:4:0 JPEGs have
1x2 luminance and 1x1 chrominance sampling factors), but the JPEG specification
and the libjpeg API both allow it.
7. Fixed an unsigned integer overflow in the libjpeg memory manager, detected
by the Clang undefined behavior sanitizer, that could be triggered by
attempting to decompress a specially-crafted malformed JPEG image. This issue
affected only 32-bit code and did not pose a security threat, but removing the
warning makes it easier to detect actual security issues, should they arise in
the future.
8. Fixed additional negative left shifts and other issues reported by the GCC
and Clang undefined behavior sanitizers when attempting to decompress
specially-crafted malformed JPEG images. None of these issues posed a security
threat, but removing the warnings makes it easier to detect actual security
issues, should they arise in the future.
9. Fixed an out-of-bounds array reference, introduced by 1.4.90[2] (partial
image decompression) and detected by the Clang undefined behavior sanitizer,
that could be triggered by a specially-crafted malformed JPEG image with more
than four components. Because the out-of-bounds reference was still within the
same structure, it was not known to pose a security threat, but removing the
warning makes it easier to detect actual security issues, should they arise in
the future.
10. Fixed another ABI conformance issue in the 64-bit ARM (AArch64) NEON SIMD
code. Some of the routines were incorrectly reading and storing data below the
stack pointer, which caused segfaults in certain applications under specific
circumstances.
1.5.0 1.5.0
===== =====

View File

@@ -9,12 +9,11 @@ libjpeg-turbo is covered by three compatible BSD-style open source licenses:
This license applies to the libjpeg API library and associated programs This license applies to the libjpeg API library and associated programs
(any code inherited from libjpeg, and any modifications to that code.) (any code inherited from libjpeg, and any modifications to that code.)
- The Modified (3-clause) BSD License, which is listed in - The Modified (3-clause) BSD License, which is listed below
[turbojpeg.c](turbojpeg.c)
This license covers the TurboJPEG API library and associated programs. This license covers the TurboJPEG API library and associated programs.
- The zlib License, which is listed in [simd/jsimdext.inc](simd/jsimdext.inc) - The zlib License, which is listed below
This license is a subset of the other two, and it covers the libjpeg-turbo This license is a subset of the other two, and it covers the libjpeg-turbo
SIMD extensions. SIMD extensions.
@@ -86,3 +85,55 @@ best of our understanding.
- IJG License - IJG License
- Modified BSD License - Modified BSD License
- zlib License - zlib License
The Modified (3-clause) BSD License
===================================
Copyright (C)\<YEAR\> \<AUTHOR\>. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of the libjpeg-turbo Project nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
The zlib License
================
Copyright (C) \<YEAR\>, \<AUTHOR\>.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@@ -11,20 +11,23 @@ endif
nodist_include_HEADERS = jconfig.h nodist_include_HEADERS = jconfig.h
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = pkgscripts/libjpeg.pc pkgscripts/libturbojpeg.pc pkgconfig_DATA = pkgscripts/libjpeg.pc
if WITH_TURBOJPEG
pkgconfig_DATA += pkgscripts/libturbojpeg.pc
endif
HDRS = jchuff.h jcmaster.h jdct.h jdhuff.h jerror.h jinclude.h jmemsys.h \ HDRS = jchuff.h jdct.h jdhuff.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
jmorecfg.h jpegint.h jpeglib.h jversion.h jsimd.h jsimddct.h jpegcomp.h \ jpegint.h jpeglib.h jversion.h jsimd.h jsimddct.h jpegcomp.h \
jpeg_nbits_table.h jpeg_nbits_table.h
libjpeg_la_SOURCES = $(HDRS) jcapimin.c jcapistd.c jccoefct.c jccolor.c \ libjpeg_la_SOURCES = $(HDRS) jcapimin.c jcapistd.c jccoefct.c jccolor.c \
jcdctmgr.c jcext.c jchuff.c jcinit.c jcmainct.c jcmarker.c \ jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
jcmaster.c jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c \ jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c \ jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c \ jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c \ jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c \ jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
jidctint.c jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c
if WITH_ARITH if WITH_ARITH
libjpeg_la_SOURCES += jaricom.c libjpeg_la_SOURCES += jaricom.c
@@ -87,7 +90,7 @@ endif
bin_PROGRAMS = cjpeg djpeg jpegtran rdjpgcom wrjpgcom bin_PROGRAMS = cjpeg djpeg jpegtran rdjpgcom wrjpgcom
noinst_PROGRAMS = jcstest jpegyuv yuvjpeg noinst_PROGRAMS = jcstest
if WITH_TURBOJPEG if WITH_TURBOJPEG
@@ -110,7 +113,7 @@ tjunittest_LDADD = libturbojpeg.la
endif endif
cjpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c cjpeg.c rdgif.c rdppm.c rdswitch.c rdjpeg.c cjpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c cjpeg.c rdgif.c rdppm.c rdswitch.c
if WITH_12BIT if WITH_12BIT
else else
cjpeg_SOURCES += rdbmp.c rdtarga.c cjpeg_SOURCES += rdbmp.c rdtarga.c
@@ -124,12 +127,6 @@ else
cjpeg_CFLAGS += -DBMP_SUPPORTED -DTARGA_SUPPORTED cjpeg_CFLAGS += -DBMP_SUPPORTED -DTARGA_SUPPORTED
endif endif
if HAVE_LIBPNG
cjpeg_CFLAGS += -DPNG_SUPPORTED $(libpng_CFLAGS)
cjpeg_LDADD += $(libpng_LIBS)
cjpeg_SOURCES += rdpng.c
endif
djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \ djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
wrgif.c wrppm.c wrgif.c wrppm.c
if WITH_12BIT if WITH_12BIT
@@ -161,14 +158,6 @@ jcstest_SOURCES = jcstest.c
jcstest_LDADD = libjpeg.la jcstest_LDADD = libjpeg.la
jpegyuv_SOURCES = jpegyuv.c
jpegyuv_LDADD = libjpeg.la
yuvjpeg_SOURCES = yuvjpeg.c
yuvjpeg_LDADD = libjpeg.la
dist_man1_MANS = cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1 dist_man1_MANS = cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1
DOCS= coderules.txt jconfig.txt change.log rdrle.c wrrle.c BUILDING.md \ DOCS= coderules.txt jconfig.txt change.log rdrle.c wrrle.c BUILDING.md \
@@ -213,6 +202,8 @@ MD5_PPM_3x2_FLOAT_SSE = 42876ab9e5c2f76a87d08db5fbd57956
MD5_JPEG_3x2_FLOAT_PROG_32BIT = a8c17daf77b457725ec929e215b603f8 MD5_JPEG_3x2_FLOAT_PROG_32BIT = a8c17daf77b457725ec929e215b603f8
MD5_PPM_3x2_FLOAT_32BIT = 42876ab9e5c2f76a87d08db5fbd57956 MD5_PPM_3x2_FLOAT_32BIT = 42876ab9e5c2f76a87d08db5fbd57956
MD5_PPM_3x2_FLOAT_64BIT = d6fbc71153b3d8ded484dbc17c7b9cf4 MD5_PPM_3x2_FLOAT_64BIT = d6fbc71153b3d8ded484dbc17c7b9cf4
MD5_JPEG_3x2_FLOAT_PROG_387 = bc6dbbefac2872f6b9d6c4a0ae60c3c0
MD5_PPM_3x2_FLOAT_387 = bcc5723c61560463ac60f772e742d092
MD5_JPEG_3x2_IFAST_PROG = 1396cc2b7185cfe943d408c9d305339e MD5_JPEG_3x2_IFAST_PROG = 1396cc2b7185cfe943d408c9d305339e
MD5_PPM_3x2_IFAST = 3975985ef6eeb0a2cdc58daa651ccc00 MD5_PPM_3x2_IFAST = 3975985ef6eeb0a2cdc58daa651ccc00
MD5_PPM_420M_ISLOW_2_1 = 4ca6be2a6f326ff9eaab63e70a8259c0 MD5_PPM_420M_ISLOW_2_1 = 4ca6be2a6f326ff9eaab63e70a8259c0
@@ -260,6 +251,8 @@ MD5_PPM_3x2_FLOAT_SSE = 1a75f36e5904d6fc3a85a43da9ad89bb
MD5_JPEG_3x2_FLOAT_PROG_32BIT = 9bca803d2042bd1eb03819e2bf92b3e5 MD5_JPEG_3x2_FLOAT_PROG_32BIT = 9bca803d2042bd1eb03819e2bf92b3e5
MD5_PPM_3x2_FLOAT_32BIT = f6bfab038438ed8f5522fbd33595dcdc MD5_PPM_3x2_FLOAT_32BIT = f6bfab038438ed8f5522fbd33595dcdc
MD5_PPM_3x2_FLOAT_64BIT = 0e917a34193ef976b679a6b069b1be26 MD5_PPM_3x2_FLOAT_64BIT = 0e917a34193ef976b679a6b069b1be26
MD5_JPEG_3x2_FLOAT_PROG_387 = 1657664a410e0822c924b54f6f65e6e9
MD5_PPM_3x2_FLOAT_387 = cb0a1f027f3d2917c902b5640214e025
MD5_JPEG_3x2_IFAST_PROG = 1ee5d2c1a77f2da495f993c8c7cceca5 MD5_JPEG_3x2_IFAST_PROG = 1ee5d2c1a77f2da495f993c8c7cceca5
MD5_PPM_3x2_IFAST = fd283664b3b49127984af0a7f118fccd MD5_PPM_3x2_IFAST = fd283664b3b49127984af0a7f118fccd
MD5_JPEG_420_ISLOW_ARI = e986fb0a637a8d833d96e8a6d6d84ea1 MD5_JPEG_420_ISLOW_ARI = e986fb0a637a8d833d96e8a6d6d84ea1
@@ -348,7 +341,7 @@ MD5_PPM_444_TILE = 7964e41e67cfb8d0a587c0aa4798f9c3
# Test compressing from/decompressing to an arbitrary subregion of a larger # Test compressing from/decompressing to an arbitrary subregion of a larger
# image buffer # image buffer
cp $(srcdir)/testimages/testorig.ppm testout_tile.ppm cp $(srcdir)/testimages/testorig.ppm testout_tile.ppm
TJ_REVERT=1 ./tjbench testout_tile.ppm 95 -rgb -quiet -tile -benchtime 0.01 >/dev/null 2>&1 ./tjbench testout_tile.ppm 95 -rgb -quiet -tile -benchtime 0.01 -warmup 0 >/dev/null 2>&1
for i in 8 16 32 64 128; do \ for i in 8 16 32 64 128; do \
md5/md5cmp $(MD5_PPM_GRAY_TILE) testout_tile_GRAY_Q95_$$i\x$$i.ppm; \ md5/md5cmp $(MD5_PPM_GRAY_TILE) testout_tile_GRAY_Q95_$$i\x$$i.ppm; \
done done
@@ -367,7 +360,7 @@ MD5_PPM_444_TILE = 7964e41e67cfb8d0a587c0aa4798f9c3
done done
rm -f testout_tile_GRAY_* testout_tile_420_* testout_tile_422_* testout_tile_444_* rm -f testout_tile_GRAY_* testout_tile_420_* testout_tile_422_* testout_tile_444_*
TJ_REVERT=1 ./tjbench testout_tile.ppm 95 -rgb -fastupsample -quiet -tile -benchtime 0.01 >/dev/null 2>&1 ./tjbench testout_tile.ppm 95 -rgb -fastupsample -quiet -tile -benchtime 0.01 -warmup 0 >/dev/null 2>&1
md5/md5cmp $(MD5_PPM_420M_8x8_TILE) testout_tile_420_Q95_8x8.ppm md5/md5cmp $(MD5_PPM_420M_8x8_TILE) testout_tile_420_Q95_8x8.ppm
for i in 16 32 64 128; do \ for i in 16 32 64 128; do \
md5/md5cmp $(MD5_PPM_420M_TILE) testout_tile_420_Q95_$$i\x$$i.ppm; \ md5/md5cmp $(MD5_PPM_420M_TILE) testout_tile_420_Q95_$$i\x$$i.ppm; \
@@ -392,7 +385,7 @@ endif
# ones.) # ones.)
# CC: null SAMP: fullsize FDCT: islow ENT: huff # CC: null SAMP: fullsize FDCT: islow ENT: huff
./cjpeg -revert -rgb -dct int -outfile testout_rgb_islow.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -rgb -dct int -outfile testout_rgb_islow.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_RGB_ISLOW) testout_rgb_islow.jpg md5/md5cmp $(MD5_JPEG_RGB_ISLOW) testout_rgb_islow.jpg
# CC: null SAMP: fullsize IDCT: islow ENT: huff # CC: null SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -ppm -outfile testout_rgb_islow.ppm testout_rgb_islow.jpg ./djpeg -dct int -ppm -outfile testout_rgb_islow.ppm testout_rgb_islow.jpg
@@ -412,7 +405,7 @@ else
endif endif
# CC: RGB->YCC SAMP: fullsize/h2v1 FDCT: ifast ENT: 2-pass huff # CC: RGB->YCC SAMP: fullsize/h2v1 FDCT: ifast ENT: 2-pass huff
./cjpeg -revert -sample 2x1 -dct fast -opt -outfile testout_422_ifast_opt.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -sample 2x1 -dct fast -opt -outfile testout_422_ifast_opt.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_422_IFAST_OPT) testout_422_ifast_opt.jpg md5/md5cmp $(MD5_JPEG_422_IFAST_OPT) testout_422_ifast_opt.jpg
# CC: YCC->RGB SAMP: fullsize/h2v1 fancy IDCT: ifast ENT: huff # CC: YCC->RGB SAMP: fullsize/h2v1 fancy IDCT: ifast ENT: huff
./djpeg -dct fast -outfile testout_422_ifast.ppm testout_422_ifast_opt.jpg ./djpeg -dct fast -outfile testout_422_ifast.ppm testout_422_ifast_opt.jpg
@@ -436,7 +429,7 @@ else
endif endif
# CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff # CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff
./cjpeg -revert -sample 2x2 -quality 100 -dct fast -prog -outfile testout_420_q100_ifast_prog.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -sample 2x2 -quality 100 -dct fast -prog -outfile testout_420_q100_ifast_prog.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_420_IFAST_Q100_PROG) testout_420_q100_ifast_prog.jpg md5/md5cmp $(MD5_JPEG_420_IFAST_Q100_PROG) testout_420_q100_ifast_prog.jpg
# CC: YCC->RGB SAMP: fullsize/h2v2 fancy IDCT: ifast ENT: prog huff # CC: YCC->RGB SAMP: fullsize/h2v2 fancy IDCT: ifast ENT: prog huff
./djpeg -dct fast -outfile testout_420_q100_ifast.ppm testout_420_q100_ifast_prog.jpg ./djpeg -dct fast -outfile testout_420_q100_ifast.ppm testout_420_q100_ifast_prog.jpg
@@ -448,7 +441,7 @@ endif
rm -f testout_420m_q100_ifast.ppm testout_420_q100_ifast_prog.jpg rm -f testout_420m_q100_ifast.ppm testout_420_q100_ifast_prog.jpg
# CC: RGB->Gray SAMP: fullsize FDCT: islow ENT: huff # CC: RGB->Gray SAMP: fullsize FDCT: islow ENT: huff
./cjpeg -revert -gray -dct int -outfile testout_gray_islow.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -gray -dct int -outfile testout_gray_islow.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_GRAY_ISLOW) testout_gray_islow.jpg md5/md5cmp $(MD5_JPEG_GRAY_ISLOW) testout_gray_islow.jpg
# CC: Gray->Gray SAMP: fullsize IDCT: islow ENT: huff # CC: Gray->Gray SAMP: fullsize IDCT: islow ENT: huff
./djpeg -dct int -outfile testout_gray_islow.ppm testout_gray_islow.jpg ./djpeg -dct int -outfile testout_gray_islow.ppm testout_gray_islow.jpg
@@ -473,7 +466,7 @@ endif
# CC: RGB->YCC SAMP: fullsize smooth/h2v2 smooth FDCT: islow # CC: RGB->YCC SAMP: fullsize smooth/h2v2 smooth FDCT: islow
# ENT: 2-pass huff # ENT: 2-pass huff
./cjpeg -revert -sample 2x2 -smooth 1 -dct int -opt -outfile testout_420s_ifast_opt.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -sample 2x2 -smooth 1 -dct int -opt -outfile testout_420s_ifast_opt.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_420S_IFAST_OPT) testout_420s_ifast_opt.jpg md5/md5cmp $(MD5_JPEG_420S_IFAST_OPT) testout_420s_ifast_opt.jpg
rm -f testout_420s_ifast_opt.jpg rm -f testout_420s_ifast_opt.jpg
@@ -492,13 +485,18 @@ endif
# x86-64 compilers) # x86-64 compilers)
# FLOATTEST=64bit validate against the exepected results from the C code # FLOATTEST=64bit validate against the exepected results from the C code
# when running on a 64-bit FPU # when running on a 64-bit FPU
# FLOATTEST=387 validate against the expected results from the C code when
# the 387 FPU is being used for floating point math (which is
# generally the default with x86 compilers)
# CC: RGB->YCC SAMP: fullsize/int FDCT: float ENT: prog huff # CC: RGB->YCC SAMP: fullsize/int FDCT: float ENT: prog huff
./cjpeg -revert -sample 3x2 -dct float -prog -outfile testout_3x2_float_prog.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -sample 3x2 -dct float -prog -outfile testout_3x2_float_prog.jpg $(srcdir)/testimages/testorig.ppm
if [ "${FLOATTEST}" = "sse" ]; then \ if [ "${FLOATTEST}" = "sse" ]; then \
md5/md5cmp $(MD5_JPEG_3x2_FLOAT_PROG_SSE) testout_3x2_float_prog.jpg; \ md5/md5cmp $(MD5_JPEG_3x2_FLOAT_PROG_SSE) testout_3x2_float_prog.jpg; \
elif [ "${FLOATTEST}" = "32bit" -o "${FLOATTEST}" = "64bit" ]; then \ elif [ "${FLOATTEST}" = "32bit" -o "${FLOATTEST}" = "64bit" ]; then \
md5/md5cmp $(MD5_JPEG_3x2_FLOAT_PROG_32BIT) testout_3x2_float_prog.jpg; \ md5/md5cmp $(MD5_JPEG_3x2_FLOAT_PROG_32BIT) testout_3x2_float_prog.jpg; \
elif [ "${FLOATTEST}" = "387" ]; then \
md5/md5cmp $(MD5_JPEG_3x2_FLOAT_PROG_387) testout_3x2_float_prog.jpg; \
fi fi
# CC: YCC->RGB SAMP: fullsize/int IDCT: float ENT: prog huff # CC: YCC->RGB SAMP: fullsize/int IDCT: float ENT: prog huff
./djpeg -dct float -outfile testout_3x2_float.ppm testout_3x2_float_prog.jpg ./djpeg -dct float -outfile testout_3x2_float.ppm testout_3x2_float_prog.jpg
@@ -508,11 +506,13 @@ endif
md5/md5cmp $(MD5_PPM_3x2_FLOAT_32BIT) testout_3x2_float.ppm; \ md5/md5cmp $(MD5_PPM_3x2_FLOAT_32BIT) testout_3x2_float.ppm; \
elif [ "${FLOATTEST}" = "64bit" ]; then \ elif [ "${FLOATTEST}" = "64bit" ]; then \
md5/md5cmp $(MD5_PPM_3x2_FLOAT_64BIT) testout_3x2_float.ppm; \ md5/md5cmp $(MD5_PPM_3x2_FLOAT_64BIT) testout_3x2_float.ppm; \
elif [ "${FLOATTEST}" = "387" ]; then \
md5/md5cmp $(MD5_PPM_3x2_FLOAT_387) testout_3x2_float.ppm; \
fi fi
rm -f testout_3x2_float.ppm testout_3x2_float_prog.jpg rm -f testout_3x2_float.ppm testout_3x2_float_prog.jpg
# CC: RGB->YCC SAMP: fullsize/int FDCT: ifast ENT: prog huff # CC: RGB->YCC SAMP: fullsize/int FDCT: ifast ENT: prog huff
./cjpeg -revert -sample 3x2 -dct fast -prog -outfile testout_3x2_ifast_prog.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -sample 3x2 -dct fast -prog -outfile testout_3x2_ifast_prog.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_3x2_IFAST_PROG) testout_3x2_ifast_prog.jpg md5/md5cmp $(MD5_JPEG_3x2_IFAST_PROG) testout_3x2_ifast_prog.jpg
# CC: YCC->RGB SAMP: fullsize/int IDCT: ifast ENT: prog huff # CC: YCC->RGB SAMP: fullsize/int IDCT: ifast ENT: prog huff
./djpeg -dct fast -outfile testout_3x2_ifast.ppm testout_3x2_ifast_prog.jpg ./djpeg -dct fast -outfile testout_3x2_ifast.ppm testout_3x2_ifast_prog.jpg
@@ -521,14 +521,14 @@ endif
if WITH_ARITH_ENC if WITH_ARITH_ENC
# CC: YCC->RGB SAMP: fullsize/h2v2 FDCT: islow ENT: arith # CC: YCC->RGB SAMP: fullsize/h2v2 FDCT: islow ENT: arith
./cjpeg -revert -dct int -arithmetic -outfile testout_420_islow_ari.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -dct int -arithmetic -outfile testout_420_islow_ari.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_420_ISLOW_ARI) testout_420_islow_ari.jpg md5/md5cmp $(MD5_JPEG_420_ISLOW_ARI) testout_420_islow_ari.jpg
rm -f testout_420_islow_ari.jpg rm -f testout_420_islow_ari.jpg
./jpegtran -revert -arithmetic -outfile testout_420_islow_ari.jpg $(srcdir)/testimages/testimgint.jpg ./jpegtran -arithmetic -outfile testout_420_islow_ari.jpg $(srcdir)/testimages/testimgint.jpg
md5/md5cmp $(MD5_JPEG_420_ISLOW_ARI) testout_420_islow_ari.jpg md5/md5cmp $(MD5_JPEG_420_ISLOW_ARI) testout_420_islow_ari.jpg
rm -f testout_420_islow_ari.jpg rm -f testout_420_islow_ari.jpg
# CC: YCC->RGB SAMP: fullsize FDCT: islow ENT: prog arith # CC: YCC->RGB SAMP: fullsize FDCT: islow ENT: prog arith
./cjpeg -revert -sample 1x1 -dct int -prog -arithmetic -outfile testout_444_islow_progari.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -sample 1x1 -dct int -prog -arithmetic -outfile testout_444_islow_progari.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_444_ISLOW_PROGARI) testout_444_islow_progari.jpg md5/md5cmp $(MD5_JPEG_444_ISLOW_PROGARI) testout_444_islow_progari.jpg
rm -f testout_444_islow_progari.jpg rm -f testout_444_islow_progari.jpg
endif endif
@@ -537,7 +537,7 @@ if WITH_ARITH_DEC
./djpeg -fast -ppm -outfile testout_420m_ifast_ari.ppm $(srcdir)/testimages/testimgari.jpg ./djpeg -fast -ppm -outfile testout_420m_ifast_ari.ppm $(srcdir)/testimages/testimgari.jpg
md5/md5cmp $(MD5_PPM_420M_IFAST_ARI) testout_420m_ifast_ari.ppm md5/md5cmp $(MD5_PPM_420M_IFAST_ARI) testout_420m_ifast_ari.ppm
rm -f testout_420m_ifast_ari.ppm rm -f testout_420m_ifast_ari.ppm
./jpegtran -revert -outfile testout_420_islow.jpg $(srcdir)/testimages/testimgari.jpg ./jpegtran -outfile testout_420_islow.jpg $(srcdir)/testimages/testimgari.jpg
md5/md5cmp $(MD5_JPEG_420_ISLOW) testout_420_islow.jpg md5/md5cmp $(MD5_JPEG_420_ISLOW) testout_420_islow.jpg
rm -f testout_420_islow.jpg rm -f testout_420_islow.jpg
endif endif
@@ -628,7 +628,7 @@ if WITH_ARITH_DEC
rm -f testout_420_islow_ari_skip16,139.ppm rm -f testout_420_islow_ari_skip16,139.ppm
endif endif
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: prog huff # Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: prog huff
./cjpeg -revert -dct int -prog -outfile testout_420_islow_prog.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -dct int -prog -outfile testout_420_islow_prog.jpg $(srcdir)/testimages/testorig.ppm
./djpeg -dct int -crop 62x62+71+71 -ppm -outfile testout_420_islow_prog_crop62x62,71,71.ppm testout_420_islow_prog.jpg ./djpeg -dct int -crop 62x62+71+71 -ppm -outfile testout_420_islow_prog_crop62x62,71,71.ppm testout_420_islow_prog.jpg
md5/md5cmp $(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71) testout_420_islow_prog_crop62x62,71,71.ppm md5/md5cmp $(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71) testout_420_islow_prog_crop62x62,71,71.ppm
rm -f testout_420_islow_prog_crop62x62,71,71.ppm testout_420_islow_prog.jpg rm -f testout_420_islow_prog_crop62x62,71,71.ppm testout_420_islow_prog.jpg
@@ -639,18 +639,18 @@ if WITH_ARITH_DEC
rm -f testout_420_islow_ari_crop53x53,4,4.ppm rm -f testout_420_islow_ari_crop53x53,4,4.ppm
endif endif
# Context rows: No Intra-iMCU row: Yes ENT: huff # Context rows: No Intra-iMCU row: Yes ENT: huff
./cjpeg -revert -dct int -sample 1x1 -outfile testout_444_islow.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -dct int -sample 1x1 -outfile testout_444_islow.jpg $(srcdir)/testimages/testorig.ppm
./djpeg -dct int -skip 1,6 -ppm -outfile testout_444_islow_skip1,6.ppm testout_444_islow.jpg ./djpeg -dct int -skip 1,6 -ppm -outfile testout_444_islow_skip1,6.ppm testout_444_islow.jpg
md5/md5cmp $(MD5_PPM_444_ISLOW_SKIP1_6) testout_444_islow_skip1,6.ppm md5/md5cmp $(MD5_PPM_444_ISLOW_SKIP1_6) testout_444_islow_skip1,6.ppm
rm -f testout_444_islow_skip1,6.ppm testout_444_islow.jpg rm -f testout_444_islow_skip1,6.ppm testout_444_islow.jpg
# Context rows: No Intra-iMCU row: No ENT: prog huff # Context rows: No Intra-iMCU row: No ENT: prog huff
./cjpeg -revert -dct int -prog -sample 1x1 -outfile testout_444_islow_prog.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -dct int -prog -sample 1x1 -outfile testout_444_islow_prog.jpg $(srcdir)/testimages/testorig.ppm
./djpeg -dct int -crop 98x98+13+13 -ppm -outfile testout_444_islow_prog_crop98x98,13,13.ppm testout_444_islow_prog.jpg ./djpeg -dct int -crop 98x98+13+13 -ppm -outfile testout_444_islow_prog_crop98x98,13,13.ppm testout_444_islow_prog.jpg
md5/md5cmp $(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13) testout_444_islow_prog_crop98x98,13,13.ppm md5/md5cmp $(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13) testout_444_islow_prog_crop98x98,13,13.ppm
rm -f testout_444_islow_prog_crop98x98,13,13.ppm testout_444_islow_prog.jpg rm -f testout_444_islow_prog_crop98x98,13,13.ppm testout_444_islow_prog.jpg
# Context rows: No Intra-iMCU row: No ENT: arith # Context rows: No Intra-iMCU row: No ENT: arith
if WITH_ARITH_ENC if WITH_ARITH_ENC
./cjpeg -revert -dct int -arithmetic -sample 1x1 -outfile testout_444_islow_ari.jpg $(srcdir)/testimages/testorig.ppm ./cjpeg -dct int -arithmetic -sample 1x1 -outfile testout_444_islow_ari.jpg $(srcdir)/testimages/testorig.ppm
if WITH_ARITH_DEC if WITH_ARITH_DEC
./djpeg -dct int -crop 37x37+0+0 -ppm -outfile testout_444_islow_ari_crop37x37,0,0.ppm testout_444_islow_ari.jpg ./djpeg -dct int -crop 37x37+0+0 -ppm -outfile testout_444_islow_ari_crop37x37,0,0.ppm testout_444_islow_ari.jpg
md5/md5cmp $(MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0) testout_444_islow_ari_crop37x37,0,0.ppm md5/md5cmp $(MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0) testout_444_islow_ari_crop37x37,0,0.ppm
@@ -659,7 +659,7 @@ endif
rm -f testout_444_islow_ari.jpg rm -f testout_444_islow_ari.jpg
endif endif
./jpegtran -revert -crop 120x90+20+50 -transpose -perfect -outfile testout_crop.jpg $(srcdir)/testimages/$(TESTORIG) ./jpegtran -crop 120x90+20+50 -transpose -perfect -outfile testout_crop.jpg $(srcdir)/testimages/$(TESTORIG)
md5/md5cmp $(MD5_JPEG_CROP) testout_crop.jpg md5/md5cmp $(MD5_JPEG_CROP) testout_crop.jpg
rm -f testout_crop.jpg rm -f testout_crop.jpg
echo GREAT SUCCESS! echo GREAT SUCCESS!
@@ -710,26 +710,26 @@ if WITH_JAVA
endif endif
pkgscripts/mozjpeg.spec: pkgscripts/mozjpeg.spec.tmpl pkgscripts/libjpeg-turbo.spec: pkgscripts/libjpeg-turbo.spec.tmpl
cat pkgscripts/mozjpeg.spec.tmpl | sed s@%{__prefix}@$(prefix)@g | \ cat pkgscripts/libjpeg-turbo.spec.tmpl | sed s@%{__prefix}@$(prefix)@g | \
sed s@%{__bindir}@$(bindir)@g | sed s@%{__datadir}@$(datadir)@g | \ sed s@%{__bindir}@$(bindir)@g | sed s@%{__datadir}@$(datadir)@g | \
sed s@%{__docdir}@$(docdir)@g | sed s@%{__includedir}@$(includedir)@g | \ sed s@%{__docdir}@$(docdir)@g | sed s@%{__includedir}@$(includedir)@g | \
sed s@%{__libdir}@$(libdir)@g | sed s@%{__mandir}@$(mandir)@g \ sed s@%{__libdir}@$(libdir)@g | sed s@%{__mandir}@$(mandir)@g \
> pkgscripts/mozjpeg.spec > pkgscripts/libjpeg-turbo.spec
rpm: all pkgscripts/mozjpeg.spec rpm: all pkgscripts/libjpeg-turbo.spec
TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \ TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \
mkdir -p $$TMPDIR/RPMS; \ mkdir -p $$TMPDIR/RPMS; \
ln -fs `pwd` $$TMPDIR/BUILD; \ ln -fs `pwd` $$TMPDIR/BUILD; \
rm -f ${PKGNAME}-${VERSION}.${RPMARCH}.rpm; \ rm -f ${PKGNAME}-${VERSION}.${RPMARCH}.rpm; \
rpmbuild -bb --define "_blddir $$TMPDIR/buildroot" \ rpmbuild -bb --define "_blddir $$TMPDIR/buildroot" \
--define "_topdir $$TMPDIR" \ --define "_topdir $$TMPDIR" \
--target ${RPMARCH} pkgscripts/mozjpeg.spec; \ --target ${RPMARCH} pkgscripts/libjpeg-turbo.spec; \
cp $$TMPDIR/RPMS/${RPMARCH}/${PKGNAME}-${VERSION}-${BUILD}.${RPMARCH}.rpm \ cp $$TMPDIR/RPMS/${RPMARCH}/${PKGNAME}-${VERSION}-${BUILD}.${RPMARCH}.rpm \
${PKGNAME}-${VERSION}.${RPMARCH}.rpm; \ ${PKGNAME}-${VERSION}.${RPMARCH}.rpm; \
rm -rf $$TMPDIR rm -rf $$TMPDIR
srpm: dist-gzip pkgscripts/mozjpeg.spec srpm: dist-gzip pkgscripts/libjpeg-turbo.spec
TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \ TMPDIR=`mktemp -d /tmp/${PACKAGE_NAME}-build.XXXXXX`; \
mkdir -p $$TMPDIR/RPMS; \ mkdir -p $$TMPDIR/RPMS; \
mkdir -p $$TMPDIR/SRPMS; \ mkdir -p $$TMPDIR/SRPMS; \
@@ -738,10 +738,10 @@ srpm: dist-gzip pkgscripts/mozjpeg.spec
mkdir -p $$TMPDIR/SPECS; \ mkdir -p $$TMPDIR/SPECS; \
rm -f ${PKGNAME}-${VERSION}.src.rpm; \ rm -f ${PKGNAME}-${VERSION}.src.rpm; \
cp ${PACKAGE_NAME}-${VERSION}.tar.gz $$TMPDIR/SOURCES; \ cp ${PACKAGE_NAME}-${VERSION}.tar.gz $$TMPDIR/SOURCES; \
cat pkgscripts/mozjpeg.spec | sed s/%{_blddir}/%{_tmppath}/g \ cat pkgscripts/libjpeg-turbo.spec | sed s/%{_blddir}/%{_tmppath}/g \
| sed s/#--\>//g \ | sed s/#--\>//g \
> $$TMPDIR/SPECS/mozjpeg.spec; \ > $$TMPDIR/SPECS/libjpeg-turbo.spec; \
rpmbuild -bs --define "_topdir $$TMPDIR" $$TMPDIR/SPECS/mozjpeg.spec; \ rpmbuild -bs --define "_topdir $$TMPDIR" $$TMPDIR/SPECS/libjpeg-turbo.spec; \
cp $$TMPDIR/SRPMS/${PKGNAME}-${VERSION}-${BUILD}.src.rpm \ cp $$TMPDIR/SRPMS/${PKGNAME}-${VERSION}-${BUILD}.src.rpm \
${PKGNAME}-${VERSION}.src.rpm; \ ${PKGNAME}-${VERSION}.src.rpm; \
rm -rf $$TMPDIR rm -rf $$TMPDIR
@@ -771,12 +771,12 @@ udmg: all pkgscripts/makemacpkg pkgscripts/uninstall
sh pkgscripts/makemacpkg -build32 ${BUILDDIR32} sh pkgscripts/makemacpkg -build32 ${BUILDDIR32}
iosdmg: all pkgscripts/makemacpkg pkgscripts/uninstall iosdmg: all pkgscripts/makemacpkg pkgscripts/uninstall
sh pkgscripts/makemacpkg -build32 ${BUILDDIR32} -buildarmv6 ${BUILDDIRARMV6} -buildarmv7 ${BUILDDIRARMV7} -buildarmv7s ${BUILDDIRARMV7S} -buildarmv8 ${BUILDDIRARMV8} -lipo "${LIPO}" sh pkgscripts/makemacpkg -build32 ${BUILDDIR32} -buildarmv7 ${BUILDDIRARMV7} -buildarmv7s ${BUILDDIRARMV7S} -buildarmv8 ${BUILDDIRARMV8} -lipo "${LIPO}"
else else
iosdmg: all pkgscripts/makemacpkg pkgscripts/uninstall iosdmg: all pkgscripts/makemacpkg pkgscripts/uninstall
sh pkgscripts/makemacpkg -buildarmv6 ${BUILDDIRARMV6} -buildarmv7 ${BUILDDIRARMV7} -buildarmv7s ${BUILDDIRARMV7S} -buildarmv8 ${BUILDDIRARMV8} -lipo "${LIPO}" sh pkgscripts/makemacpkg -buildarmv7 ${BUILDDIRARMV7} -buildarmv7s ${BUILDDIRARMV7S} -buildarmv8 ${BUILDDIRARMV8} -lipo "${LIPO}"
endif endif

View File

@@ -1,194 +0,0 @@
Mozilla JPEG Encoder Project
============================
mozjpeg is a fork of libjpeg-turbo that aims to speed up load times of web
pages by reducing the size (and, by extension, the transmission time) of JPEG
files. It accomplishes this by enabling optimized Huffman trees and
progressive entropy coding by default in the JPEG compressor, as well as
splitting the spectrum of DCT coefficients into separate scans and using
Trellis quantisation.
Although it is based on libjpeg-turbo, mozjpeg is not intended to be a
general-purpose or high-performance JPEG library. Its performance is highly
"asymmetric". That is, the JPEG files it generates require much more time to
compress than to decompress. When the default settings are used, mozjpeg is
considerably slower than libjpeg-turbo or even libjpeg at compressing images.
Thus, it is not generally suitable for real-time compression. It is best used
as part of a web encoding workflow.
libjpeg API Extensibility Framework
===================================
mozjpeg's implementation of the libjpeg API includes an extensibility framework
that allows new features to be added without modifying the transparent libjpeg
compress/decompress structures (which would break backward ABI compatibility.)
Extension parameters are placed into the opaque jpeg_comp_master structure, and
a set of accessor functions and globally unique tokens allows for
getting/setting those parameters without directly accessing the structure.
Currently, only the accessor functions necessary to support the mozjpeg
extensions are implemented, but the framework can be easily extended in the
future to accommodate additional simple parameter types, complex or
multi-valued parameters, or decompressor extensions.
The currently-implemented accessor functions are as follows:
boolean jpeg_c_bool_param_supported (j_compress_ptr cinfo,
J_BOOLEAN_PARAM param)
Returns TRUE if the given boolean extension parameter is supported by
this implementation of the libjpeg API, or FALSE otherwise.
void jpeg_c_set_bool_param (j_compress_ptr cinfo,
J_BOOLEAN_PARAM param, boolean value);
Set the given boolean extension parameter to the given value (TRUE or
FALSE.)
boolean jpeg_c_get_bool_param (j_compress_ptr cinfo, J_BOOLEAN_PARAM param)
Get the value of the given boolean extension parameter (TRUE or FALSE.)
boolean jpeg_c_float_param_supported (j_compress_ptr cinfo,
J_FLOAT_PARAM param)
Returns TRUE if the given floating point extension parameter is
supported by this implementation of the libjpeg API, or FALSE
otherwise.
void jpeg_c_set_float_param (j_compress_ptr cinfo, J_FLOAT_PARAM param,
float value)
Set the given floating point extension parameter to the given value.
float jpeg_c_get_float_param (j_compress_ptr cinfo, J_FLOAT_PARAM param);
Get the value of the given floating point extension parameter.
boolean jpeg_c_int_param_supported (j_compress_ptr cinfo,
J_INT_PARAM param)
Returns TRUE if the given integer extension parameter is supported by
this implementation of the libjpeg API, or FALSE otherwise.
void jpeg_c_set_int_param (j_compress_ptr cinfo, J_INT_PARAM param,
int value)
Set the given integer extension parameter to the given value.
int jpeg_c_get_int_param (j_compress_ptr cinfo, J_INT_PARAM param)
Get the value of the given integer extension parameter.
Boolean Extension Parameters Supported by mozjpeg
-------------------------------------------------
* JBOOLEAN_OPTIMIZE_SCANS (default: TRUE)
Specifies whether scan parameters should be optimized. Parameter
optimization is done as in jpgcrush. jpeg_simple_progression() should be called
after setting JBOOLEAN_OPTIMIZE_SCANS.
When disabling JBOOLEAN_OPTIMIZE_SCANS, cinfo.scan_info should additionally be
set to NULL to disable use of the progressive coding mode, if so desired.
* JBOOLEAN_TRELLIS_QUANT (default: TRUE)
Specifies whether to apply trellis quantization. For each 8x8 block, trellis
quantization determines the best tradeoff between rate and distortion.
* JBOOLEAN_TRELLIS_QUANT_DC (default: TRUE)
Specifies whether to apply trellis quantization to DC coefficients.
* JBOOLEAN_TRELLIS_EOB_OPT (default: FALSE)
Specifies whether to optimize runs of zero blocks in trellis quantization.
This is applicable only when JBOOLEAN_USE_SCANS_IN_TRELLIS is enabled.
* JBOOLEAN_USE_LAMBDA_WEIGHT_TBL currently has no effect.
* JBOOLEAN_USE_SCANS_IN_TRELLIS (default: FALSE)
Specifies whether multiple scans should be considered during trellis
quantization.
* JBOOLEAN_TRELLIS_Q_OPT (default: FALSE)
Specifies whether to optimize the quantization table after trellis
quantization. If enabled, then a revised quantization table is derived so
as to minimize the reconstruction error of the quantized coefficients.
* JBOOLEAN_OVERSHOOT_DERINGING (default: TRUE)
Specifies whether overshooting is applied to samples with extreme values
(for example, 0 and 255 for 8-bit samples). Overshooting may reduce ringing
artifacts from compression, in particular in areas where black text appears
on a white background.
Floating Point Extension Parameters Supported by mozjpeg
--------------------------------------------------------
* JFLOAT_LAMBDA_LOG_SCALE1 (default: 14.75)
JFLOAT_LAMBDA_LOG_SCALE2 (default: 16.5)
These parameters specify the lambda value used in trellis quantization. The
lambda value (Lagrange multiplier) in the
R + lambda * D
equation is derived from
lambda = 2^s1 / ((2^s2 + n) * q^2),
where s1 and s2 are the values of JFLOAT_LAMBDA_LOG_SCALE1 and
JFLOAT_LAMBDA_LOG_SCALE2, n is the average of the squared unquantized AC
coefficients within the current 8x8 block, and q is the quantization table
entry associated with the current coefficient frequency. If
JFLOAT_LAMBDA_LOG_SCALE2 is 0, then an alternate form is used that does not
rely on n:
lambda = 2^(s1-12) / q^2.
* JFLOAT_TRELLIS_DELTA_DC_WEIGHT (default: 0.0)
This parameter controls how distortion is calculated in DC trellis quantization
(enabled with JBOOLEAN_TRELLIS_QUANT_DC). It defines weighting between distortion
of the DC coefficient and distortion of the vertical gradient of DC coefficients.
The value of the parameter corresponds to the weight applied to the distortion
of the vertical gradient.
Integer Extension Parameters Supported by mozjpeg
-------------------------------------------------
* JINT_COMPRESS_PROFILE (default: JCP_MAX_COMPRESSION)
Select a compression profile, which is a set of default parameters that will
achieve a desired compression goal. This parameter controls the behavior of
the jpeg_set_defaults() function. Thus, setting JINT_COMPRESS_PROFILE does
not cause any other parameters to be modified until jpeg_set_defaults() is
called. The following compression profiles are supported:
- JCP_MAX_COMPRESSION (default)
Increase the compression ratio as much as possible, at the expense of
increased encoding time. This enables progressive entropy coding and all
mozjpeg extensions.
- JCP_FASTEST
Use the libjpeg[-turbo] defaults (baseline entropy coding, no mozjpeg
extensions enabled.)
* JINT_TRELLIS_FREQ_SPLIT (default: 8)
Specifies the position within the zigzag scan at which the split between
scans is positioned in the context of trellis quantization.
JBOOLEAN_USE_SCANS_IN_TRELLIS must be enabled for this parameter to have any
effect.
* JINT_TRELLIS_NUM_LOOPS (default: 1)
Specifies the number of trellis quantization passes. Huffman tables are
updated between passes.
* JINT_BASE_QUANT_TBL_IDX (default: 3)
Specifies which quantization table set to use. The following options are
available:
0 = Tables from JPEG Annex K
1 = Flat table
2 = Table tuned for MSSIM on Kodak image set
3 = Table from http://www.imagemagick.org/discourse-server/viewtopic.php?f=22&t=20333&p=98008#p98008
4 = Table tuned for PSNR-HVS-M on Kodak image set
5 = Table from: Relevance of Human Vision to JPEG-DCT Compression
(1992) Klein, Silverstein and Carney
6 = Table from: DCTune Perceptual Optimization of Compressed Dental X-Rays
(1997) Watson, Taylor, Borthwick
7 = Table from: A Visual Detection Model for DCT Coefficient Quantization
(12/9/93) Ahumada, Watson, Peterson
8 = Table from: An Improved Detection Model for DCT Coefficient Quantization
(1993) Peterson, Ahumada and Watson
* JINT_DC_SCAN_OPT_MODE (default: 1)
Specifies the DC scan optimization mode. The following options are
available:
0 = One scan for all components
1 = One scan per component
2 = Optimize between one scan for all components and one scan for the first
component plus one scan for the remaining components

View File

@@ -1,342 +0,0 @@
Background
==========
libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
NEON, AltiVec) to accelerate baseline JPEG compression and decompression on
x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
generally 2-6x as fast as libjpeg, all else being equal. On other types of
systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by
virtue of its highly-optimized Huffman coding routines. In many cases, the
performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.
libjpeg-turbo implements both the traditional libjpeg API as well as the less
powerful but more straightforward TurboJPEG API. libjpeg-turbo also features
colorspace extensions that allow it to compress from/decompress to 32-bit and
big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java
interface.
libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated
derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and
VirtualGL projects made numerous enhancements to the codec in 2009, and in
early 2010, libjpeg-turbo spun off into an independent project, with the goal
of making high-speed JPEG compression/decompression technology available to a
broader range of users and developers.
License
=======
libjpeg-turbo is covered by three compatible BSD-style open source licenses.
Refer to [LICENSE.md](LICENSE.md) for a roll-up of license terms.
Building libjpeg-turbo
======================
Refer to [BUILDING.md](BUILDING.md) for complete instructions.
Using libjpeg-turbo
===================
libjpeg-turbo includes two APIs that can be used to compress and decompress
JPEG images:
- **TurboJPEG API**
This API provides an easy-to-use interface for compressing and decompressing
JPEG images in memory. It also provides some functionality that would not be
straightforward to achieve using the underlying libjpeg API, such as
generating planar YUV images and performing multiple simultaneous lossless
transforms on an image. The Java interface for libjpeg-turbo is written on
top of the TurboJPEG API.
- **libjpeg API**
This is the de facto industry-standard API for compressing and decompressing
JPEG images. It is more difficult to use than the TurboJPEG API but also
more powerful. The libjpeg API implementation in libjpeg-turbo is both
API/ABI-compatible and mathematically compatible with libjpeg v6b. It can
also optionally be configured to be API/ABI-compatible with libjpeg v7 and v8
(see below.)
There is no significant performance advantage to either API when both are used
to perform similar operations.
Colorspace Extensions
---------------------
libjpeg-turbo includes extensions that allow JPEG images to be compressed
directly from (and decompressed directly to) buffers that use BGR, BGRX,
RGBX, XBGR, and XRGB pixel ordering. This is implemented with ten 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 */
JCS_EXT_RGBA /* red/green/blue/alpha */
JCS_EXT_BGRA /* blue/green/red/alpha */
JCS_EXT_ABGR /* alpha/blue/green/red */
JCS_EXT_ARGB /* alpha/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 compressing from/decompressing to an RGB buffer.
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 libjpeg implementation
that does not support them will result in a "Bogus input colorspace" error.
Applications can trap this error in order to test whether run-time support is
available for the colorspace extensions.
When using the RGBX, BGRX, XBGR, and XRGB colorspaces during decompression, the
X byte is undefined, and in order to ensure the best performance, libjpeg-turbo
can set that byte to whatever value it wishes. If an application expects the X
byte to be used as an alpha channel, then it should specify `JCS_EXT_RGBA`,
`JCS_EXT_BGRA`, `JCS_EXT_ABGR`, or `JCS_EXT_ARGB`. When these colorspace
constants are used, the X byte is guaranteed to be 0xFF, which is interpreted
as opaque.
Your application can check for the existence of the alpha channel colorspace
extensions at compile time with:
#ifdef JCS_ALPHA_EXTENSIONS
[jcstest.c](jcstest.c), located in the libjpeg-turbo source tree, demonstrates
how to check for the existence of the colorspace extensions at compile time and
run time.
libjpeg v7 and v8 API/ABI Emulation
-----------------------------------
With libjpeg v7 and v8, new features were added that necessitated extending the
compression and decompression structures. Unfortunately, due to the exposed
nature of those structures, extending them also necessitated breaking backward
ABI compatibility with previous libjpeg releases. Thus, programs that were
built to use libjpeg v7 or v8 did not work with libjpeg-turbo, since it is
based on the libjpeg v6b code base. Although libjpeg v7 and v8 are not
as widely used as v6b, enough programs (including a few Linux distros) made
the switch that there was a demand to emulate the libjpeg v7 and v8 ABIs
in libjpeg-turbo. It should be noted, however, that this feature was added
primarily so that applications that had already been compiled to use libjpeg
v7+ could take advantage of accelerated baseline JPEG encoding/decoding
without recompiling. libjpeg-turbo does not claim to support all of the
libjpeg v7+ features, nor to produce identical output to libjpeg v7+ in all
cases (see below.)
By passing an argument of `--with-jpeg7` or `--with-jpeg8` to `configure`, or
an argument of `-DWITH_JPEG7=1` or `-DWITH_JPEG8=1` to `cmake`, you can build a
version of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so that
programs that are built against libjpeg v7 or v8 can be run with libjpeg-turbo.
The following section describes which libjpeg v7+ features are supported and
which aren't.
### Support for libjpeg v7 and v8 Features
#### Fully supported
- **libjpeg: IDCT scaling extensions in decompressor**
libjpeg-turbo supports IDCT scaling with scaling factors of 1/8, 1/4, 3/8,
1/2, 5/8, 3/4, 7/8, 9/8, 5/4, 11/8, 3/2, 13/8, 7/4, 15/8, and 2/1 (only 1/4
and 1/2 are SIMD-accelerated.)
- **libjpeg: Arithmetic coding**
- **libjpeg: In-memory source and destination managers**
See notes below.
- **cjpeg: Separate quality settings for luminance and chrominance**
Note that the libpjeg v7+ API was extended to accommodate this feature only
for convenience purposes. It has always been possible to implement this
feature with libjpeg v6b (see rdswitch.c for an example.)
- **cjpeg: 32-bit BMP support**
- **cjpeg: `-rgb` option**
- **jpegtran: Lossless cropping**
- **jpegtran: `-perfect` option**
- **jpegtran: Forcing width/height when performing lossless crop**
- **rdjpgcom: `-raw` option**
- **rdjpgcom: Locale awareness**
#### Not supported
NOTE: As of this writing, extensive research has been conducted into the
usefulness of DCT scaling as a means of data reduction and SmartScale as a
means of quality improvement. The reader is invited to peruse the research at
<http://www.libjpeg-turbo.org/About/SmartScale> and draw his/her own conclusions,
but it is the general belief of our project that these features have not
demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.
- **libjpeg: DCT scaling in compressor**
`cinfo.scale_num` and `cinfo.scale_denom` are silently ignored.
There is no technical reason why DCT scaling could not be supported when
emulating the libjpeg v7+ API/ABI, but without the SmartScale extension (see
below), only scaling factors of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and
8/9 would be available, which is of limited usefulness.
- **libjpeg: SmartScale**
`cinfo.block_size` is silently ignored.
SmartScale is an extension to the JPEG format that allows for DCT block
sizes other than 8x8. Providing support for this new format would be
feasible (particularly without full acceleration.) However, until/unless
the format becomes either an official industry standard or, at minimum, an
accepted solution in the community, we are hesitant to implement it, as
there is no sense of whether or how it might change in the future. It is
our belief that SmartScale has not demonstrated sufficient usefulness as a
lossless format nor as a means of quality enhancement, and thus our primary
interest in providing this feature would be as a means of supporting
additional DCT scaling factors.
- **libjpeg: Fancy downsampling in compressor**
`cinfo.do_fancy_downsampling` is silently ignored.
This requires the DCT scaling feature, which is not supported.
- **jpegtran: Scaling**
This requires both the DCT scaling and SmartScale features, which are not
supported.
- **Lossless RGB JPEG files**
This requires the SmartScale feature, which is not supported.
### What About libjpeg v9?
libjpeg v9 introduced yet another field to the JPEG compression structure
(`color_transform`), thus making the ABI backward incompatible with that of
libjpeg v8. This new field was introduced solely for the purpose of supporting
lossless SmartScale encoding. Furthermore, there was actually no reason to
extend the API in this manner, as the color transform could have just as easily
been activated by way of a new JPEG colorspace constant, thus preserving
backward ABI compatibility.
Our research (see link above) has shown that lossless SmartScale does not
generally accomplish anything that can't already be accomplished better with
existing, standard lossless formats. Therefore, at this time it is our belief
that there is not sufficient technical justification for software projects to
upgrade from libjpeg v8 to libjpeg v9, and thus there is not sufficient
echnical justification for us to emulate the libjpeg v9 ABI.
In-Memory Source/Destination Managers
-------------------------------------
By default, libjpeg-turbo 1.3 and later includes the `jpeg_mem_src()` and
`jpeg_mem_dest()` functions, even when not emulating the libjpeg v8 API/ABI.
Previously, it was necessary to build libjpeg-turbo from source with libjpeg v8
API/ABI emulation in order to use the in-memory source/destination managers,
but several projects requested that those functions be included when emulating
the libjpeg v6b API/ABI as well. This allows the use of those functions by
programs that need them, without breaking ABI compatibility for programs that
don't, and it allows those functions to be provided in the "official"
libjpeg-turbo binaries.
Those who are concerned about maintaining strict conformance with the libjpeg
v6b or v7 API can pass an argument of `--without-mem-srcdst` to `configure` or
an argument of `-DWITH_MEM_SRCDST=0` to `cmake` prior to building
libjpeg-turbo. This will restore the pre-1.3 behavior, in which
`jpeg_mem_src()` and `jpeg_mem_dest()` are only included when emulating the
libjpeg v8 API/ABI.
On Un*x systems, including the in-memory source/destination managers changes
the dynamic library version from 62.0.0 to 62.1.0 if using libjpeg v6b API/ABI
emulation and from 7.0.0 to 7.1.0 if using libjpeg v7 API/ABI emulation.
Note that, on most Un*x systems, the dynamic linker will not look for a
function in a library until that function is actually used. Thus, if a program
is built against libjpeg-turbo 1.3+ and uses `jpeg_mem_src()` or
`jpeg_mem_dest()`, that program will not fail if run against an older version
of libjpeg-turbo or against libjpeg v7- until the program actually tries to
call `jpeg_mem_src()` or `jpeg_mem_dest()`. Such is not the case on Windows.
If a program is built against the libjpeg-turbo 1.3+ DLL and uses
`jpeg_mem_src()` or `jpeg_mem_dest()`, then it must use the libjpeg-turbo 1.3+
DLL at run time.
Both cjpeg and djpeg have been extended to allow testing the in-memory
source/destination manager functions. See their respective man pages for more
details.
Mathematical Compatibility
==========================
For the most part, libjpeg-turbo should produce identical output to libjpeg
v6b. The one exception to this is when using the floating point DCT/IDCT, in
which case the outputs of libjpeg v6b and libjpeg-turbo can differ for the
following reasons:
- The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever so
slightly more accurate than the implementation in libjpeg v6b, but not by
any amount perceptible to human vision (generally in the range of 0.01 to
0.08 dB gain in PNSR.)
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate
(and slightly faster) floating point IDCT algorithm introduced in libjpeg
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the floating
point IDCT in line with the accuracy of the slow integer IDCT. The floating
point DCT/IDCT algorithms are mainly a legacy feature, and they do not
produce significantly more accuracy than the slow integer algorithms (to put
numbers on this, the typical difference in PNSR between the two algorithms
is less than 0.10 dB, whereas changing the quality level by 1 in the upper
range of the quality scale is typically more like a 1.0 dB difference.)
- If the floating point algorithms in libjpeg-turbo are not implemented using
SIMD instructions on a particular platform, then the accuracy of the
floating point DCT/IDCT can depend on the compiler settings.
While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is
still using the same algorithms as libjpeg v6b, so there are several specific
cases in which libjpeg-turbo cannot be expected to produce the same output as
libjpeg v8:
- When decompressing using scaling factors of 1/2 and 1/4, because libjpeg v8
implements those scaling algorithms differently than libjpeg v6b does, and
libjpeg-turbo's SIMD extensions are based on the libjpeg v6b behavior.
- When using chrominance subsampling, because libjpeg v8 implements this
with its DCT/IDCT scaling algorithms rather than with a separate
downsampling/upsampling algorithm. In our testing, the subsampled/upsampled
output of libjpeg v8 is less accurate than that of libjpeg v6b for this
reason.
- When decompressing using a scaling factor > 1 and merged (AKA "non-fancy" or
"non-smooth") chrominance upsampling, because libjpeg v8 does not support
merged upsampling with scaling factors > 1.
Performance Pitfalls
====================
Restart Markers
---------------
The optimized Huffman decoder in libjpeg-turbo does not handle restart markers
in a way that makes the rest of the libjpeg infrastructure happy, so it is
necessary to use the slow Huffman decoder when decompressing a JPEG image that
has restart markers. This can cause the decompression performance to drop by
as much as 20%, but the performance will still be much greater than that of
libjpeg. Many consumer packages, such as PhotoShop, use restart markers when
generating JPEG images, so images generated by those programs will experience
this issue.
Fast Integer Forward DCT at High Quality Levels
-----------------------------------------------
The algorithm used by the SIMD-accelerated quantization function cannot produce
correct results whenever the fast integer forward DCT is used along with a JPEG
quality of 98-100. Thus, libjpeg-turbo must use the non-SIMD quantization
function in those cases. This causes performance to drop by as much as 40%.
It is therefore strongly advised that you use the slow integer forward DCT
whenever encoding images with a JPEG quality of 98 or higher.

350
README.md Normal file → Executable file
View File

@@ -1,23 +1,341 @@
Mozilla JPEG Encoder Project Background
============================ ==========
MozJPEG reduces file sizes of JPEG images while retaining quality and compatibility with the vast majority of the world's deployed decoders. libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
NEON, AltiVec) to accelerate baseline JPEG compression and decompression on
x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
generally 2-6x as fast as libjpeg, all else being equal. On other types of
systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by
virtue of its highly-optimized Huffman coding routines. In many cases, the
performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.
MozJPEG is based on [libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo). It's compatible with libjpeg API and ABI, and can be used as a drop-in replacement for libjpeg. MozJPEG makes tradeoffs that are intended to benefit Web use cases and focuses solely on improving encoding, so it's best used as part of a Web encoding workflow. libjpeg-turbo implements both the traditional libjpeg API as well as the less
powerful but more straightforward TurboJPEG API. libjpeg-turbo also features
colorspace extensions that allow it to compress from/decompress to 32-bit and
big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java
interface.
MozJPEG is meant to be used as a library in graphics programs and image processing tools. We include a demo `cjpeg` tool, but it's not intended for serious use. We encourage authors of graphics programs to use MozJPEG's [C API](libjpeg.txt) instead. libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated
derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and
VirtualGL projects made numerous enhancements to the codec in 2009, and in
early 2010, libjpeg-turbo spun off into an independent project, with the goal
of making high-speed JPEG compression/decompression technology available to a
broader range of users and developers.
## Features
* Progressive encoding with "jpegrescan" optimization. It can be applied to any JPEG file (with `jpegtran`) to losslessly reduce file size. License
* Trellis quantization. When converting other formats to JPEG it maximizes quality/filesize ratio. =======
* Comes with new quantization table presets, e.g. tuned for high-resolution displays.
* Fully compatible with all web browsers.
* Can be seamlessly integrated into any program using libjpeg.
## Releases libjpeg-turbo is covered by three compatible BSD-style open source licenses.
Refer to [LICENSE.md](LICENSE.md) for a roll-up of license terms.
* [Latest release](https://github.com/mozilla/mozjpeg/releases/latest)
* [Version 3.0 Announcement](https://boomswaggerboom.wordpress.com/2014/12/30/mozjpeg-3-0-released/) ([overview of 3.0 features](https://calendar.perfplanet.com/2014/mozjpeg-3-0/)) Building libjpeg-turbo
* [Version 2.0 Announcement](https://blog.mozilla.org/research/2014/07/15/mozilla-advances-jpeg-encoding-with-mozjpeg-2-0/) ======================
* [Version 1.0 Announcement](https://blog.mozilla.org/research/2014/03/05/introducing-the-mozjpeg-project/)
Refer to [BUILDING.md](BUILDING.md) for complete instructions.
Using libjpeg-turbo
===================
libjpeg-turbo includes two APIs that can be used to compress and decompress
JPEG images:
- **TurboJPEG API**<br>
This API provides an easy-to-use interface for compressing and decompressing
JPEG images in memory. It also provides some functionality that would not be
straightforward to achieve using the underlying libjpeg API, such as
generating planar YUV images and performing multiple simultaneous lossless
transforms on an image. The Java interface for libjpeg-turbo is written on
top of the TurboJPEG API.
- **libjpeg API**<br>
This is the de facto industry-standard API for compressing and decompressing
JPEG images. It is more difficult to use than the TurboJPEG API but also
more powerful. The libjpeg API implementation in libjpeg-turbo is both
API/ABI-compatible and mathematically compatible with libjpeg v6b. It can
also optionally be configured to be API/ABI-compatible with libjpeg v7 and v8
(see below.)
There is no significant performance advantage to either API when both are used
to perform similar operations.
Colorspace Extensions
---------------------
libjpeg-turbo includes extensions that allow JPEG images to be compressed
directly from (and decompressed directly to) buffers that use BGR, BGRX,
RGBX, XBGR, and XRGB pixel ordering. This is implemented with ten 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 */
JCS_EXT_RGBA /* red/green/blue/alpha */
JCS_EXT_BGRA /* blue/green/red/alpha */
JCS_EXT_ABGR /* alpha/blue/green/red */
JCS_EXT_ARGB /* alpha/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 compressing from/decompressing to an RGB buffer.
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 libjpeg implementation
that does not support them will result in a "Bogus input colorspace" error.
Applications can trap this error in order to test whether run-time support is
available for the colorspace extensions.
When using the RGBX, BGRX, XBGR, and XRGB colorspaces during decompression, the
X byte is undefined, and in order to ensure the best performance, libjpeg-turbo
can set that byte to whatever value it wishes. If an application expects the X
byte to be used as an alpha channel, then it should specify `JCS_EXT_RGBA`,
`JCS_EXT_BGRA`, `JCS_EXT_ABGR`, or `JCS_EXT_ARGB`. When these colorspace
constants are used, the X byte is guaranteed to be 0xFF, which is interpreted
as opaque.
Your application can check for the existence of the alpha channel colorspace
extensions at compile time with:
#ifdef JCS_ALPHA_EXTENSIONS
[jcstest.c](jcstest.c), located in the libjpeg-turbo source tree, demonstrates
how to check for the existence of the colorspace extensions at compile time and
run time.
libjpeg v7 and v8 API/ABI Emulation
-----------------------------------
With libjpeg v7 and v8, new features were added that necessitated extending the
compression and decompression structures. Unfortunately, due to the exposed
nature of those structures, extending them also necessitated breaking backward
ABI compatibility with previous libjpeg releases. Thus, programs that were
built to use libjpeg v7 or v8 did not work with libjpeg-turbo, since it is
based on the libjpeg v6b code base. Although libjpeg v7 and v8 are not
as widely used as v6b, enough programs (including a few Linux distros) made
the switch that there was a demand to emulate the libjpeg v7 and v8 ABIs
in libjpeg-turbo. It should be noted, however, that this feature was added
primarily so that applications that had already been compiled to use libjpeg
v7+ could take advantage of accelerated baseline JPEG encoding/decoding
without recompiling. libjpeg-turbo does not claim to support all of the
libjpeg v7+ features, nor to produce identical output to libjpeg v7+ in all
cases (see below.)
By passing an argument of `--with-jpeg7` or `--with-jpeg8` to `configure`, or
an argument of `-DWITH_JPEG7=1` or `-DWITH_JPEG8=1` to `cmake`, you can build a
version of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so that
programs that are built against libjpeg v7 or v8 can be run with libjpeg-turbo.
The following section describes which libjpeg v7+ features are supported and
which aren't.
### Support for libjpeg v7 and v8 Features
#### Fully supported
- **libjpeg: IDCT scaling extensions in decompressor**<br>
libjpeg-turbo supports IDCT scaling with scaling factors of 1/8, 1/4, 3/8,
1/2, 5/8, 3/4, 7/8, 9/8, 5/4, 11/8, 3/2, 13/8, 7/4, 15/8, and 2/1 (only 1/4
and 1/2 are SIMD-accelerated.)
- **libjpeg: Arithmetic coding**
- **libjpeg: In-memory source and destination managers**<br>
See notes below.
- **cjpeg: Separate quality settings for luminance and chrominance**<br>
Note that the libpjeg v7+ API was extended to accommodate this feature only
for convenience purposes. It has always been possible to implement this
feature with libjpeg v6b (see rdswitch.c for an example.)
- **cjpeg: 32-bit BMP support**
- **cjpeg: `-rgb` option**
- **jpegtran: Lossless cropping**
- **jpegtran: `-perfect` option**
- **jpegtran: Forcing width/height when performing lossless crop**
- **rdjpgcom: `-raw` option**
- **rdjpgcom: Locale awareness**
#### Not supported
NOTE: As of this writing, extensive research has been conducted into the
usefulness of DCT scaling as a means of data reduction and SmartScale as a
means of quality improvement. The reader is invited to peruse the research at
<http://www.libjpeg-turbo.org/About/SmartScale> and draw his/her own conclusions,
but it is the general belief of our project that these features have not
demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.
- **libjpeg: DCT scaling in compressor**<br>
`cinfo.scale_num` and `cinfo.scale_denom` are silently ignored.
There is no technical reason why DCT scaling could not be supported when
emulating the libjpeg v7+ API/ABI, but without the SmartScale extension (see
below), only scaling factors of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and
8/9 would be available, which is of limited usefulness.
- **libjpeg: SmartScale**<br>
`cinfo.block_size` is silently ignored.
SmartScale is an extension to the JPEG format that allows for DCT block
sizes other than 8x8. Providing support for this new format would be
feasible (particularly without full acceleration.) However, until/unless
the format becomes either an official industry standard or, at minimum, an
accepted solution in the community, we are hesitant to implement it, as
there is no sense of whether or how it might change in the future. It is
our belief that SmartScale has not demonstrated sufficient usefulness as a
lossless format nor as a means of quality enhancement, and thus our primary
interest in providing this feature would be as a means of supporting
additional DCT scaling factors.
- **libjpeg: Fancy downsampling in compressor**<br>
`cinfo.do_fancy_downsampling` is silently ignored.
This requires the DCT scaling feature, which is not supported.
- **jpegtran: Scaling**<br>
This requires both the DCT scaling and SmartScale features, which are not
supported.
- **Lossless RGB JPEG files**<br>
This requires the SmartScale feature, which is not supported.
### What About libjpeg v9?
libjpeg v9 introduced yet another field to the JPEG compression structure
(`color_transform`), thus making the ABI backward incompatible with that of
libjpeg v8. This new field was introduced solely for the purpose of supporting
lossless SmartScale encoding. Furthermore, there was actually no reason to
extend the API in this manner, as the color transform could have just as easily
been activated by way of a new JPEG colorspace constant, thus preserving
backward ABI compatibility.
Our research (see link above) has shown that lossless SmartScale does not
generally accomplish anything that can't already be accomplished better with
existing, standard lossless formats. Therefore, at this time it is our belief
that there is not sufficient technical justification for software projects to
upgrade from libjpeg v8 to libjpeg v9, and thus there is not sufficient
technical justification for us to emulate the libjpeg v9 ABI.
In-Memory Source/Destination Managers
-------------------------------------
By default, libjpeg-turbo 1.3 and later includes the `jpeg_mem_src()` and
`jpeg_mem_dest()` functions, even when not emulating the libjpeg v8 API/ABI.
Previously, it was necessary to build libjpeg-turbo from source with libjpeg v8
API/ABI emulation in order to use the in-memory source/destination managers,
but several projects requested that those functions be included when emulating
the libjpeg v6b API/ABI as well. This allows the use of those functions by
programs that need them, without breaking ABI compatibility for programs that
don't, and it allows those functions to be provided in the "official"
libjpeg-turbo binaries.
Those who are concerned about maintaining strict conformance with the libjpeg
v6b or v7 API can pass an argument of `--without-mem-srcdst` to `configure` or
an argument of `-DWITH_MEM_SRCDST=0` to `cmake` prior to building
libjpeg-turbo. This will restore the pre-1.3 behavior, in which
`jpeg_mem_src()` and `jpeg_mem_dest()` are only included when emulating the
libjpeg v8 API/ABI.
On Un*x systems, including the in-memory source/destination managers changes
the dynamic library version from 62.1.0 to 62.2.0 if using libjpeg v6b API/ABI
emulation and from 7.1.0 to 7.2.0 if using libjpeg v7 API/ABI emulation.
Note that, on most Un*x systems, the dynamic linker will not look for a
function in a library until that function is actually used. Thus, if a program
is built against libjpeg-turbo 1.3+ and uses `jpeg_mem_src()` or
`jpeg_mem_dest()`, that program will not fail if run against an older version
of libjpeg-turbo or against libjpeg v7- until the program actually tries to
call `jpeg_mem_src()` or `jpeg_mem_dest()`. Such is not the case on Windows.
If a program is built against the libjpeg-turbo 1.3+ DLL and uses
`jpeg_mem_src()` or `jpeg_mem_dest()`, then it must use the libjpeg-turbo 1.3+
DLL at run time.
Both cjpeg and djpeg have been extended to allow testing the in-memory
source/destination manager functions. See their respective man pages for more
details.
Mathematical Compatibility
==========================
For the most part, libjpeg-turbo should produce identical output to libjpeg
v6b. The one exception to this is when using the floating point DCT/IDCT, in
which case the outputs of libjpeg v6b and libjpeg-turbo can differ for the
following reasons:
- The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever so
slightly more accurate than the implementation in libjpeg v6b, but not by
any amount perceptible to human vision (generally in the range of 0.01 to
0.08 dB gain in PNSR.)
- When not using the SIMD extensions, libjpeg-turbo uses the more accurate
(and slightly faster) floating point IDCT algorithm introduced in libjpeg
v8a as opposed to the algorithm used in libjpeg v6b. It should be noted,
however, that this algorithm basically brings the accuracy of the floating
point IDCT in line with the accuracy of the slow integer IDCT. The floating
point DCT/IDCT algorithms are mainly a legacy feature, and they do not
produce significantly more accuracy than the slow integer algorithms (to put
numbers on this, the typical difference in PNSR between the two algorithms
is less than 0.10 dB, whereas changing the quality level by 1 in the upper
range of the quality scale is typically more like a 1.0 dB difference.)
- If the floating point algorithms in libjpeg-turbo are not implemented using
SIMD instructions on a particular platform, then the accuracy of the
floating point DCT/IDCT can depend on the compiler settings.
While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is
still using the same algorithms as libjpeg v6b, so there are several specific
cases in which libjpeg-turbo cannot be expected to produce the same output as
libjpeg v8:
- When decompressing using scaling factors of 1/2 and 1/4, because libjpeg v8
implements those scaling algorithms differently than libjpeg v6b does, and
libjpeg-turbo's SIMD extensions are based on the libjpeg v6b behavior.
- When using chrominance subsampling, because libjpeg v8 implements this
with its DCT/IDCT scaling algorithms rather than with a separate
downsampling/upsampling algorithm. In our testing, the subsampled/upsampled
output of libjpeg v8 is less accurate than that of libjpeg v6b for this
reason.
- When decompressing using a scaling factor > 1 and merged (AKA "non-fancy" or
"non-smooth") chrominance upsampling, because libjpeg v8 does not support
merged upsampling with scaling factors > 1.
Performance Pitfalls
====================
Restart Markers
---------------
The optimized Huffman decoder in libjpeg-turbo does not handle restart markers
in a way that makes the rest of the libjpeg infrastructure happy, so it is
necessary to use the slow Huffman decoder when decompressing a JPEG image that
has restart markers. This can cause the decompression performance to drop by
as much as 20%, but the performance will still be much greater than that of
libjpeg. Many consumer packages, such as PhotoShop, use restart markers when
generating JPEG images, so images generated by those programs will experience
this issue.
Fast Integer Forward DCT at High Quality Levels
-----------------------------------------------
The algorithm used by the SIMD-accelerated quantization function cannot produce
correct results whenever the fast integer forward DCT is used along with a JPEG
quality of 98-100. Thus, libjpeg-turbo must use the non-SIMD quantization
function in those cases. This causes performance to drop by as much as 40%.
It is therefore strongly advised that you use the slow integer forward DCT
whenever encoding images with a JPEG quality of 98 or higher.

57
appveyor.yml Normal file
View File

@@ -0,0 +1,57 @@
install:
- cmd: >-
mkdir c:\installers
mkdir c:\temp
curl -fSL -o c:\installers\nasm-2.10.01-win32.zip http://www.nasm.us/pub/nasm/releasebuilds/2.10.01/win32/nasm-2.10.01-win32.zip
7z x c:\installers\nasm-2.10.01-win32.zip -oc:\ > c:\installers\nasm.install.log
set INCLUDE=c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include;c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\include
set LIB=c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\lib\x64
set PATH=c:\nasm-2.10.01;c:\Program Files (x86)\NSIS;c:\msys64\mingw32\bin;c:\msys64\usr\bin;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE;c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\bin\x64;c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\bin;%PATH%
set MSYSTEM=MINGW32
bash -c "pacman --noconfirm -S autoconf automake libtool zip"
mklink /d "%ProgramData%\Oracle\Java32" "c:\Program Files (x86)\Java\jdk1.6.0"
git clone --depth=1 https://github.com/libjpeg-turbo/buildscripts.git c:/buildscripts
build_script:
- cmd: >-
for /f %%i in ('"cygpath %CD%"') do set MINGWPATH=%%i
bash c:/buildscripts/buildljt -r file://%MINGWPATH% -b /c/ljt.nightly %APPVEYOR_REPO_BRANCH% -v
move c:\ljt.nightly\files\*.tar.gz .
move c:\ljt.nightly\files\*.exe .
move c:\ljt.nightly\files\*.zip .
move c:\ljt.nightly\log-windows.txt .
artifacts:
- path: '*.tar.gz'
name: Source tarball
- path: '*-gcc*.exe'
name: SDK for MinGW
- path: '*-vc*.exe'
name: SDK for Visual C++
- path: '*.zip'
name: Windows JNI JARs
- path: 'log-windows.txt'
name: Build log
test: off
deploy: off

21
bmp.c
View File

@@ -108,10 +108,14 @@ static void pixelconvert(unsigned char *srcbuf, int srcpf, int srcbottomup,
m=(m-k)/(1.0-k); m=(m-k)/(1.0-k);
y=(y-k)/(1.0-k); y=(y-k)/(1.0-k);
} }
if(c>1.0) c=1.0; if(c<0.) c=0.; if(c>1.0) c=1.0;
if(m>1.0) m=1.0; if(m<0.) m=0.; if(c<0.) c=0.;
if(y>1.0) y=1.0; if(y<0.) y=0.; if(m>1.0) m=1.0;
if(k>1.0) k=1.0; if(k<0.) k=0.; if(m<0.) m=0.;
if(y>1.0) y=1.0;
if(y<0.) y=0.;
if(k>1.0) k=1.0;
if(k<0.) k=0.;
*dstcolptr++=(unsigned char)(255.0-c*255.0+0.5); *dstcolptr++=(unsigned char)(255.0-c*255.0+0.5);
*dstcolptr++=(unsigned char)(255.0-m*255.0+0.5); *dstcolptr++=(unsigned char)(255.0-m*255.0+0.5);
*dstcolptr++=(unsigned char)(255.0-y*255.0+0.5); *dstcolptr++=(unsigned char)(255.0-y*255.0+0.5);
@@ -133,9 +137,12 @@ static void pixelconvert(unsigned char *srcbuf, int srcpf, int srcbottomup,
double r=c*k/255.; double r=c*k/255.;
double g=m*k/255.; double g=m*k/255.;
double b=y*k/255.; double b=y*k/255.;
if(r>255.0) r=255.0; if(r<0.) r=0.; if(r>255.0) r=255.0;
if(g>255.0) g=255.0; if(g<0.) g=0.; if(r<0.) r=0.;
if(b>255.0) b=255.0; if(b<0.) b=0.; if(g>255.0) g=255.0;
if(g<0.) g=0.;
if(b>255.0) b=255.0;
if(b<0.) b=0.;
dstcolptr[tjRedOffset[dstpf]]=(unsigned char)(r+0.5); dstcolptr[tjRedOffset[dstpf]]=(unsigned char)(r+0.5);
dstcolptr[tjGreenOffset[dstpf]]=(unsigned char)(g+0.5); dstcolptr[tjGreenOffset[dstpf]]=(unsigned char)(g+0.5);
dstcolptr[tjBlueOffset[dstpf]]=(unsigned char)(b+0.5); dstcolptr[tjBlueOffset[dstpf]]=(unsigned char)(b+0.5);

View File

@@ -124,10 +124,6 @@ JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
#endif #endif
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format") JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
#ifdef PNG_SUPPORTED
JMESSAGE(JERR_PNG_ERROR, "Unable to read PNG file: %s")
#endif
#ifdef JMAKE_ENUM_LIST #ifdef JMAKE_ENUM_LIST
JMSG_LASTADDONCODE JMSG_LASTADDONCODE

View File

@@ -5,9 +5,8 @@
* Copyright (C) 1994-1997, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* It was modified by The libjpeg-turbo Project to include only code relevant * It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo. * to libjpeg-turbo.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README.ijg file.
* *
* This file contains common declarations for the sample applications * This file contains common declarations for the sample applications
* cjpeg and djpeg. It is NOT used by the core JPEG library. * cjpeg and djpeg. It is NOT used by the core JPEG library.
@@ -20,7 +19,6 @@
#include "jerror.h" /* get library error codes too */ #include "jerror.h" /* get library error codes too */
#include "cderror.h" /* get application-specific error codes */ #include "cderror.h" /* get application-specific error codes */
#define JPEG_RAW_READER 0
/* /*
* Object interface for cjpeg's source file decoding modules * Object interface for cjpeg's source file decoding modules
@@ -37,13 +35,6 @@ struct cjpeg_source_struct {
JSAMPARRAY buffer; JSAMPARRAY buffer;
JDIMENSION buffer_height; JDIMENSION buffer_height;
#if JPEG_RAW_READER
// For reading JPEG
JSAMPARRAY plane_pointer[4];
#endif
jpeg_saved_marker_ptr marker_list;
}; };
@@ -102,9 +93,7 @@ EXTERN(djpeg_dest_ptr) jinit_write_bmp (j_decompress_ptr cinfo,
boolean is_os2); boolean is_os2);
EXTERN(cjpeg_source_ptr) jinit_read_gif (j_compress_ptr cinfo); EXTERN(cjpeg_source_ptr) jinit_read_gif (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_gif (j_decompress_ptr cinfo); EXTERN(djpeg_dest_ptr) jinit_write_gif (j_decompress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_jpeg (j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_ppm (j_compress_ptr cinfo); EXTERN(cjpeg_source_ptr) jinit_read_ppm (j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_png (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_ppm (j_decompress_ptr cinfo); EXTERN(djpeg_dest_ptr) jinit_write_ppm (j_decompress_ptr cinfo);
EXTERN(cjpeg_source_ptr) jinit_read_rle (j_compress_ptr cinfo); EXTERN(cjpeg_source_ptr) jinit_read_rle (j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_rle (j_decompress_ptr cinfo); EXTERN(djpeg_dest_ptr) jinit_write_rle (j_decompress_ptr cinfo);

BIN
ci/keys.enc Normal file

Binary file not shown.

View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "17 February 2016" .TH CJPEG 1 "18 March 2017"
.SH NAME .SH NAME
cjpeg \- compress an image file to a JPEG file cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS .SH SYNOPSIS
@@ -202,7 +202,7 @@ Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example, number. For example,
.B \-max 4m .B \-max 4m
selects 4000000 bytes. If more space is needed, temporary files will be used. selects 4000000 bytes. If more space is needed, an error will occur.
.TP .TP
.BI \-outfile " name" .BI \-outfile " name"
Send output image to the named file, not to standard output. Send output image to the named file, not to standard output.

224
cjpeg.c
View File

@@ -5,10 +5,9 @@
* Copyright (C) 1991-1998, Thomas G. Lane. * Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding. * Modified 2003-2011 by Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2010, 2013-2014, D. R. Commander. * Copyright (C) 2010, 2013-2014, 2017, D. R. Commander.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains a command-line user interface for the JPEG compressor. * This file contains a command-line user interface for the JPEG compressor.
* It should work on any system with Unix- or MS-DOS-style command lines. * It should work on any system with Unix- or MS-DOS-style command lines.
@@ -80,7 +79,7 @@ static const char * const cdjpeg_message_table[] = {
*/ */
static boolean is_targa; /* records user -targa switch */ static boolean is_targa; /* records user -targa switch */
static boolean is_jpeg;
LOCAL(cjpeg_source_ptr) LOCAL(cjpeg_source_ptr)
select_file_type (j_compress_ptr cinfo, FILE *infile) select_file_type (j_compress_ptr cinfo, FILE *infile)
@@ -113,10 +112,6 @@ select_file_type (j_compress_ptr cinfo, FILE *infile)
case 'P': case 'P':
return jinit_read_ppm(cinfo); return jinit_read_ppm(cinfo);
#endif #endif
#ifdef PNG_SUPPORTED
case 0x89:
return jinit_read_png(cinfo);
#endif
#ifdef RLE_SUPPORTED #ifdef RLE_SUPPORTED
case 'R': case 'R':
return jinit_read_rle(cinfo); return jinit_read_rle(cinfo);
@@ -125,9 +120,6 @@ select_file_type (j_compress_ptr cinfo, FILE *infile)
case 0x00: case 0x00:
return jinit_read_targa(cinfo); return jinit_read_targa(cinfo);
#endif #endif
case 0xff:
is_jpeg = TRUE;
return jinit_read_jpeg(cinfo);
default: default:
ERREXIT(cinfo, JERR_UNKNOWN_FORMAT); ERREXIT(cinfo, JERR_UNKNOWN_FORMAT);
break; break;
@@ -168,31 +160,15 @@ usage (void)
fprintf(stderr, " -grayscale Create monochrome JPEG file\n"); fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
fprintf(stderr, " -rgb Create RGB JPEG file\n"); fprintf(stderr, " -rgb Create RGB JPEG file\n");
#ifdef ENTROPY_OPT_SUPPORTED #ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression, enabled by default)\n"); fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
#endif #endif
#ifdef C_PROGRESSIVE_SUPPORTED #ifdef C_PROGRESSIVE_SUPPORTED
fprintf(stderr, " -progressive Create progressive JPEG file (enabled by default)\n"); fprintf(stderr, " -progressive Create progressive JPEG file\n");
#endif #endif
fprintf(stderr, " -baseline Create baseline JPEG file (disable progressive coding)\n");
#ifdef TARGA_SUPPORTED #ifdef TARGA_SUPPORTED
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n"); fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
#endif #endif
fprintf(stderr, " -revert Revert to standard defaults (instead of mozjpeg defaults)\n");
fprintf(stderr, " -fastcrush Disable progressive scan optimization\n");
fprintf(stderr, " -dc-scan-opt DC scan optimization mode\n");
fprintf(stderr, " - 0 One scan for all components\n");
fprintf(stderr, " - 1 One scan per component (default)\n");
fprintf(stderr, " - 2 Optimize between one scan for all components and one scan for 1st component\n");
fprintf(stderr, " plus one scan for remaining components\n");
fprintf(stderr, " -notrellis Disable trellis optimization\n");
fprintf(stderr, " -trellis-dc Enable trellis optimization of DC coefficients (default)\n");
fprintf(stderr, " -notrellis-dc Disable trellis optimization of DC coefficients\n");
fprintf(stderr, " -tune-psnr Tune trellis optimization for PSNR\n");
fprintf(stderr, " -tune-hvs-psnr Tune trellis optimization for PSNR-HVS (default)\n");
fprintf(stderr, " -tune-ssim Tune trellis optimization for SSIM\n");
fprintf(stderr, " -tune-ms-ssim Tune trellis optimization for MS-SSIM\n");
fprintf(stderr, "Switches for advanced users:\n"); fprintf(stderr, "Switches for advanced users:\n");
fprintf(stderr, " -noovershoot Disable black-on-white deringing via overshoot\n");
#ifdef C_ARITH_CODING_SUPPORTED #ifdef C_ARITH_CODING_SUPPORTED
fprintf(stderr, " -arithmetic Use arithmetic coding\n"); fprintf(stderr, " -arithmetic Use arithmetic coding\n");
#endif #endif
@@ -208,14 +184,6 @@ usage (void)
fprintf(stderr, " -dct float Use floating-point DCT method%s\n", fprintf(stderr, " -dct float Use floating-point DCT method%s\n",
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif #endif
fprintf(stderr, " -quant-baseline Use 8-bit quantization table entries for baseline JPEG compatibility\n");
fprintf(stderr, " -quant-table N Use predefined quantization table N:\n");
fprintf(stderr, " - 0 JPEG Annex K\n");
fprintf(stderr, " - 1 Flat\n");
fprintf(stderr, " - 2 Custom, tuned for MS-SSIM\n");
fprintf(stderr, " - 3 ImageMagick table by N. Robidoux\n");
fprintf(stderr, " - 4 Custom, tuned for PSNR-HVS\n");
fprintf(stderr, " - 5 Table from paper by Klein, Silverstein and Carney\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n"); fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
#ifdef INPUT_SMOOTHING_SUPPORTED #ifdef INPUT_SMOOTHING_SUPPORTED
fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n"); fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
@@ -228,11 +196,12 @@ usage (void)
fprintf(stderr, " -verbose or -debug Emit debug output\n"); fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, " -version Print version information and exit\n"); fprintf(stderr, " -version Print version information and exit\n");
fprintf(stderr, "Switches for wizards:\n"); fprintf(stderr, "Switches for wizards:\n");
fprintf(stderr, " -qtables file Use quantization tables given in file\n"); fprintf(stderr, " -baseline Force baseline quantization tables\n");
fprintf(stderr, " -qtables FILE Use quantization tables given in FILE\n");
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n"); fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n"); fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); fprintf(stderr, " -scans FILE Create multi-scan JPEG per script FILE\n");
#endif #endif
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -263,11 +232,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Set up default JPEG parameters. */ /* Set up default JPEG parameters. */
force_baseline = FALSE; /* by default, allow 16-bit quantizers */ force_baseline = FALSE; /* by default, allow 16-bit quantizers */
#ifdef C_PROGRESSIVE_SUPPORTED
simple_progressive = cinfo->num_scans == 0 ? FALSE : TRUE;
#else
simple_progressive = FALSE; simple_progressive = FALSE;
#endif
is_targa = FALSE; is_targa = FALSE;
outfilename = NULL; outfilename = NULL;
memdst = FALSE; memdst = FALSE;
@@ -291,9 +256,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Use arithmetic coding. */ /* Use arithmetic coding. */
#ifdef C_ARITH_CODING_SUPPORTED #ifdef C_ARITH_CODING_SUPPORTED
cinfo->arith_code = TRUE; cinfo->arith_code = TRUE;
/* No table optimization required for AC */
cinfo->optimize_coding = FALSE;
#else #else
fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
progname); progname);
@@ -303,27 +265,19 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "baseline", 1)) { } else if (keymatch(arg, "baseline", 1)) {
/* Force baseline-compatible output (8-bit quantizer values). */ /* Force baseline-compatible output (8-bit quantizer values). */
force_baseline = TRUE; force_baseline = TRUE;
/* Disable multiple scans */
simple_progressive = FALSE;
cinfo->num_scans = 0;
cinfo->scan_info = NULL;
} else if (keymatch(arg, "dct", 2)) { } else if (keymatch(arg, "dct", 2)) {
/* Select DCT algorithm. */ /* Select DCT algorithm. */
if (++argn >= argc) { /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
fprintf(stderr, "%s: missing argument for dct\n", progname);
usage(); usage();
}
if (keymatch(argv[argn], "int", 1)) { if (keymatch(argv[argn], "int", 1)) {
cinfo->dct_method = JDCT_ISLOW; cinfo->dct_method = JDCT_ISLOW;
} else if (keymatch(argv[argn], "fast", 2)) { } else if (keymatch(argv[argn], "fast", 2)) {
cinfo->dct_method = JDCT_IFAST; cinfo->dct_method = JDCT_IFAST;
} else if (keymatch(argv[argn], "float", 2)) { } else if (keymatch(argv[argn], "float", 2)) {
cinfo->dct_method = JDCT_FLOAT; cinfo->dct_method = JDCT_FLOAT;
} else { } else
fprintf(stderr, "%s: invalid argument for dct\n", progname);
usage(); usage();
}
} else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
/* Enable debug printouts. */ /* Enable debug printouts. */
@@ -345,9 +299,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
PACKAGE_NAME, VERSION, BUILD); PACKAGE_NAME, VERSION, BUILD);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} else if (keymatch(arg, "fastcrush", 4)) {
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OPTIMIZE_SCANS, FALSE);
} else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) {
/* Force a monochrome JPEG file to be generated. */ /* Force a monochrome JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
@@ -356,18 +307,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Force an RGB JPEG file to be generated. */ /* Force an RGB JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_RGB); jpeg_set_colorspace(cinfo, JCS_RGB);
} else if (keymatch(arg, "lambda1", 7)) {
if (++argn >= argc) /* advance to next argument */
usage();
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1,
atof(argv[argn]));
} else if (keymatch(arg, "lambda2", 7)) {
if (++argn >= argc) /* advance to next argument */
usage();
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2,
atof(argv[argn]));
} else if (keymatch(arg, "maxmemory", 3)) { } else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */ /* Maximum memory in Kb (or Mb with 'm'). */
long lval; long lval;
@@ -381,13 +320,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
lval *= 1000L; lval *= 1000L;
cinfo->mem->max_memory_to_use = lval * 1000L; cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "dc-scan-opt", 3)) {
if (++argn >= argc) { /* advance to next argument */
fprintf(stderr, "%s: missing argument for dc-scan-opt\n", progname);
usage();
}
jpeg_c_set_int_param(cinfo, JINT_DC_SCAN_OPT_MODE, atoi(argv[argn]));
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) { } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
/* Enable entropy parm optimization. */ /* Enable entropy parm optimization. */
#ifdef ENTROPY_OPT_SUPPORTED #ifdef ENTROPY_OPT_SUPPORTED
@@ -400,10 +332,8 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "outfile", 4)) { } else if (keymatch(arg, "outfile", 4)) {
/* Set output file name. */ /* Set output file name. */
if (++argn >= argc) { /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
fprintf(stderr, "%s: missing argument for outfile\n", progname);
usage(); usage();
}
outfilename = argv[argn]; /* save it away for later use */ outfilename = argv[argn]; /* save it away for later use */
} else if (keymatch(arg, "progressive", 1)) { } else if (keymatch(arg, "progressive", 1)) {
@@ -429,10 +359,8 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "quality", 1)) { } else if (keymatch(arg, "quality", 1)) {
/* Quality ratings (quantization table scaling factors). */ /* Quality ratings (quantization table scaling factors). */
if (++argn >= argc) { /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
fprintf(stderr, "%s: missing argument for quality\n", progname);
usage(); usage();
}
qualityarg = argv[argn]; qualityarg = argv[argn];
} else if (keymatch(arg, "qslots", 2)) { } else if (keymatch(arg, "qslots", 2)) {
@@ -452,22 +380,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
qtablefile = argv[argn]; qtablefile = argv[argn];
/* We postpone actually reading the file in case -quality comes later. */ /* We postpone actually reading the file in case -quality comes later. */
} else if (keymatch(arg, "quant-table", 7)) {
int val;
if (++argn >= argc) /* advance to next argument */
usage();
val = atoi(argv[argn]);
jpeg_c_set_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX, val);
if (jpeg_c_get_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX) != val) {
fprintf(stderr, "%s: %d is invalid argument for quant-table\n", progname, val);
usage();
}
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "quant-baseline", 7)) {
/* Force quantization table to meet baseline requirements */
force_baseline = TRUE;
} else if (keymatch(arg, "restart", 1)) { } else if (keymatch(arg, "restart", 1)) {
/* Restart interval in MCU rows (or in MCUs with 'b'). */ /* Restart interval in MCU rows (or in MCUs with 'b'). */
long lval; long lval;
@@ -487,11 +399,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* restart_interval will be computed during startup */ /* restart_interval will be computed during startup */
} }
} else if (keymatch(arg, "revert", 3)) {
/* revert to old JPEG default */
jpeg_c_set_int_param(cinfo, JINT_COMPRESS_PROFILE, JCP_FASTEST);
jpeg_set_defaults(cinfo);
} else if (keymatch(arg, "sample", 2)) { } else if (keymatch(arg, "sample", 2)) {
/* Set sampling factors. */ /* Set sampling factors. */
if (++argn >= argc) /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
@@ -531,57 +438,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Input file is Targa format. */ /* Input file is Targa format. */
is_targa = TRUE; is_targa = TRUE;
} else if (keymatch(arg, "notrellis-dc", 11)) {
/* disable trellis quantization */
jpeg_c_set_bool_param(cinfo, JBOOLEAN_TRELLIS_QUANT_DC, FALSE);
} else if (keymatch(arg, "notrellis", 1)) {
/* disable trellis quantization */
jpeg_c_set_bool_param(cinfo, JBOOLEAN_TRELLIS_QUANT, FALSE);
} else if (keymatch(arg, "trellis-dc-ver-weight", 12)) {
if (++argn >= argc) { /* advance to next argument */
fprintf(stderr, "%s: missing argument for trellis-dc-ver-weight\n", progname);
usage();
}
jpeg_c_set_float_param(cinfo, JFLOAT_TRELLIS_DELTA_DC_WEIGHT, atof(argv[argn]));
} else if (keymatch(arg, "trellis-dc", 9)) {
/* enable DC trellis quantization */
jpeg_c_set_bool_param(cinfo, JBOOLEAN_TRELLIS_QUANT_DC, TRUE);
} else if (keymatch(arg, "tune-psnr", 6)) {
jpeg_c_set_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX, 1);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 9.0);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 0.0);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, FALSE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-ssim", 6)) {
jpeg_c_set_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX, 1);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 11.5);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 12.75);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, FALSE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-ms-ssim", 6)) {
jpeg_c_set_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX, 3);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 12.0);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 13.0);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, TRUE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-hvs-psnr", 6)) {
jpeg_c_set_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX, 3);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 14.75);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 16.5);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, TRUE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "noovershoot", 11)) {
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OVERSHOOT_DERINGING, FALSE);
} else { } else {
fprintf(stderr, "%s: unknown option '%s'\n", progname, arg);
usage(); /* bogus switch */ usage(); /* bogus switch */
} }
} }
@@ -593,28 +450,20 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Set quantization tables for selected quality. */ /* Set quantization tables for selected quality. */
/* Some or all may be overridden if -qtables is present. */ /* Some or all may be overridden if -qtables is present. */
if (qualityarg != NULL) /* process -quality if it was present */ if (qualityarg != NULL) /* process -quality if it was present */
if (! set_quality_ratings(cinfo, qualityarg, force_baseline)) { if (! set_quality_ratings(cinfo, qualityarg, force_baseline))
fprintf(stderr, "%s: can't set quality ratings\n", progname);
usage(); usage();
}
if (qtablefile != NULL) /* process -qtables if it was present */ if (qtablefile != NULL) /* process -qtables if it was present */
if (! read_quant_tables(cinfo, qtablefile, force_baseline)) { if (! read_quant_tables(cinfo, qtablefile, force_baseline))
fprintf(stderr, "%s: can't read qtable file\n", progname);
usage(); usage();
}
if (qslotsarg != NULL) /* process -qslots if it was present */ if (qslotsarg != NULL) /* process -qslots if it was present */
if (! set_quant_slots(cinfo, qslotsarg)) if (! set_quant_slots(cinfo, qslotsarg))
usage(); usage();
/* set_quality_ratings sets default subsampling, so the explicit
subsampling must be set after it */
if (samplearg != NULL) /* process -sample if it was present */ if (samplearg != NULL) /* process -sample if it was present */
if (! set_sample_factors(cinfo, samplearg)) { if (! set_sample_factors(cinfo, samplearg))
fprintf(stderr, "%s: can't set sample factors\n", progname);
usage(); usage();
}
#ifdef C_PROGRESSIVE_SUPPORTED #ifdef C_PROGRESSIVE_SUPPORTED
if (simple_progressive) /* process -progressive; -scans can override */ if (simple_progressive) /* process -progressive; -scans can override */
@@ -746,9 +595,6 @@ main (int argc, char **argv)
(*src_mgr->start_input) (&cinfo, src_mgr); (*src_mgr->start_input) (&cinfo, src_mgr);
/* Now that we know input colorspace, fix colorspace-dependent defaults */ /* Now that we know input colorspace, fix colorspace-dependent defaults */
#if JPEG_RAW_READER
if (!is_jpeg)
#endif
jpeg_default_colorspace(&cinfo); jpeg_default_colorspace(&cinfo);
/* Adjust default compression parameters by re-parsing the options */ /* Adjust default compression parameters by re-parsing the options */
@@ -765,47 +611,9 @@ main (int argc, char **argv)
/* Start compressor */ /* Start compressor */
jpeg_start_compress(&cinfo, TRUE); jpeg_start_compress(&cinfo, TRUE);
/* Copy metadata */
if (is_jpeg) {
jpeg_saved_marker_ptr marker;
/* In the current implementation, we don't actually need to examine the
* option flag here; we just copy everything that got saved.
* But to avoid confusion, we do not output JFIF and Adobe APP14 markers
* if the encoder library already wrote one.
*/
for (marker = src_mgr->marker_list; marker != NULL; marker = marker->next) {
if (cinfo.write_JFIF_header &&
marker->marker == JPEG_APP0 &&
marker->data_length >= 5 &&
GETJOCTET(marker->data[0]) == 0x4A &&
GETJOCTET(marker->data[1]) == 0x46 &&
GETJOCTET(marker->data[2]) == 0x49 &&
GETJOCTET(marker->data[3]) == 0x46 &&
GETJOCTET(marker->data[4]) == 0)
continue; /* reject duplicate JFIF */
if (cinfo.write_Adobe_marker &&
marker->marker == JPEG_APP0+14 &&
marker->data_length >= 5 &&
GETJOCTET(marker->data[0]) == 0x41 &&
GETJOCTET(marker->data[1]) == 0x64 &&
GETJOCTET(marker->data[2]) == 0x6F &&
GETJOCTET(marker->data[3]) == 0x62 &&
GETJOCTET(marker->data[4]) == 0x65)
continue; /* reject duplicate Adobe */
jpeg_write_marker(&cinfo, marker->marker, marker->data,
marker->data_length);
}
}
/* Process data */ /* Process data */
while (cinfo.next_scanline < cinfo.image_height) { while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
#if JPEG_RAW_READER
if (is_jpeg)
(void) jpeg_write_raw_data(&cinfo, src_mgr->plane_pointer, num_scanlines);
else
#endif
(void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
} }

View File

@@ -0,0 +1,24 @@
# This code is from the CMake FAQ
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
list(REVERSE files)
foreach (file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif (NOT ${rm_retval} EQUAL 0)
else (EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif (EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)

View File

@@ -24,7 +24,12 @@ file(GLOB FILES
*_440_*.png *_440_*.png
*_440_*.ppm *_440_*.ppm
*_440_*.jpg *_440_*.jpg
*_440.yuv) *_440.yuv
*_411_*.bmp
*_411_*.png
*_411_*.ppm
*_411_*.jpg
*_411.yuv)
if(NOT FILES STREQUAL "") if(NOT FILES STREQUAL "")
message(STATUS "Removing test files") message(STATUS "Removing test files")

View File

@@ -2,11 +2,10 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ([2.56]) AC_PREREQ([2.56])
AC_INIT([mozjpeg], [3.2]) AC_INIT([libjpeg-turbo], [1.5.2])
BUILD=`date +%Y%m%d`
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2]) AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
AC_PREFIX_DEFAULT(/opt/mozjpeg) AC_PREFIX_DEFAULT(/opt/libjpeg-turbo)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -19,7 +18,6 @@ m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AM_PROG_AS AM_PROG_AS
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_PROG_INSTALL AC_PROG_INSTALL
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_PROG_LN_S AC_PROG_LN_S
@@ -62,7 +60,7 @@ AC_CHECK_SIZEOF(size_t)
if test "x${libdir}" = 'x${exec_prefix}/lib' -o "x${libdir}" = 'x${prefix}/lib'; then if test "x${libdir}" = 'x${exec_prefix}/lib' -o "x${libdir}" = 'x${prefix}/lib'; then
LIBDIR=`eval echo ${libdir}` LIBDIR=`eval echo ${libdir}`
LIBDIR=`eval echo $LIBDIR` LIBDIR=`eval echo $LIBDIR`
if test "$LIBDIR" = "/opt/mozjpeg/lib"; then if test "$LIBDIR" = "/opt/libjpeg-turbo/lib"; then
case $host_os in case $host_os in
darwin*) darwin*)
;; ;;
@@ -104,12 +102,6 @@ if test "x${SUNCC}" = "xyes"; then
fi fi
# Checks for libraries. # Checks for libraries.
AC_CHECK_LIB([m],[pow])
PKG_CHECK_MODULES([libpng], [libpng], [HAVE_LIBPNG=1], [
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
])
AM_CONDITIONAL([HAVE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])
# Checks for header files. # Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
@@ -162,10 +154,10 @@ AC_ARG_VAR(JPEG_LIB_VERSION, [libjpeg API version (62, 70, or 80)])
if test "x$JPEG_LIB_VERSION" = "x"; then if test "x$JPEG_LIB_VERSION" = "x"; then
AC_ARG_WITH([jpeg7], AC_ARG_WITH([jpeg7],
AC_HELP_STRING([--with-jpeg7], AC_HELP_STRING([--with-jpeg7],
[Emulate libjpeg v7 API/ABI (this makes mozjpeg backward incompatible with libjpeg v6b.)])) [Emulate libjpeg v7 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b.)]))
AC_ARG_WITH([jpeg8], AC_ARG_WITH([jpeg8],
AC_HELP_STRING([--with-jpeg8], AC_HELP_STRING([--with-jpeg8],
[Emulate libjpeg v8 API/ABI (this makes mozjpeg backward incompatible with libjpeg v6b.)])) [Emulate libjpeg v8 API/ABI (this makes libjpeg-turbo backward incompatible with libjpeg v6b.)]))
if test "x${with_jpeg8}" = "xyes"; then if test "x${with_jpeg8}" = "xyes"; then
JPEG_LIB_VERSION=80 JPEG_LIB_VERSION=80
else else
@@ -183,9 +175,9 @@ AC_DEFINE_UNQUOTED(JPEG_LIB_VERSION, [$JPEG_LIB_VERSION],
[libjpeg API version]) [libjpeg API version])
AC_ARG_VAR(SO_MAJOR_VERSION, AC_ARG_VAR(SO_MAJOR_VERSION,
[Major version of the mozjpeg shared library (default is determined by the API version)]) [Major version of the libjpeg-turbo shared library (default is determined by the API version)])
AC_ARG_VAR(SO_MINOR_VERSION, AC_ARG_VAR(SO_MINOR_VERSION,
[Minor version of the mozjpeg shared library (default is determined by the API version)]) [Minor version of the libjpeg-turbo shared library (default is determined by the API version)])
if test "x$SO_MAJOR_VERSION" = "x"; then if test "x$SO_MAJOR_VERSION" = "x"; then
case "$JPEG_LIB_VERSION" in case "$JPEG_LIB_VERSION" in
62) SO_MAJOR_VERSION=$JPEG_LIB_VERSION ;; 62) SO_MAJOR_VERSION=$JPEG_LIB_VERSION ;;
@@ -230,12 +222,12 @@ AC_SUBST(SO_MINOR_VERSION)
AC_SUBST(SO_AGE) AC_SUBST(SO_AGE)
AC_SUBST(MEM_SRCDST_FUNCTIONS) AC_SUBST(MEM_SRCDST_FUNCTIONS)
AC_DEFINE_UNQUOTED(MOZJPEG_VERSION, [$VERSION], [mozjpeg version]) AC_DEFINE_UNQUOTED(LIBJPEG_TURBO_VERSION, [$VERSION], [libjpeg-turbo version])
m4_define(version_triplet,m4_split(AC_PACKAGE_VERSION,[[.]])) m4_define(version_triplet,m4_split(AC_PACKAGE_VERSION,[[.]]))
m4_define(version_major,m4_argn(1,version_triplet)) m4_define(version_major,m4_car(m4_shiftn(1,[],version_triplet)))
m4_define(version_minor,m4_argn(2,version_triplet)) m4_define(version_minor,m4_car(m4_shiftn(2,[],version_triplet)))
m4_define(version_revision,m4_argn(3,version_triplet)) m4_define(version_revision,m4_car(m4_shiftn(3,[],version_triplet)))
VERSION_MAJOR=version_major VERSION_MAJOR=version_major
VERSION_MINOR=version_minor VERSION_MINOR=version_minor
VERSION_REVISION=version_revision VERSION_REVISION=version_revision
@@ -245,7 +237,7 @@ AC_DEFINE_UNQUOTED(LIBJPEG_TURBO_VERSION_NUMBER, [$LIBJPEG_TURBO_VERSION_NUMBER]
VERSION_SCRIPT=yes VERSION_SCRIPT=yes
AC_ARG_ENABLE([ld-version-script], AC_ARG_ENABLE([ld-version-script],
AS_HELP_STRING([--disable-ld-version-script], AS_HELP_STRING([--disable-ld-version-script],
[Disable linker version script for mozjpeg (default is to use linker version script if the linker supports it)]), [Disable linker version script for libjpeg-turbo (default is to use linker version script if the linker supports it)]),
[VERSION_SCRIPT=$enableval], []) [VERSION_SCRIPT=$enableval], [])
AC_MSG_CHECKING([whether the linker supports version scripts]) AC_MSG_CHECKING([whether the linker supports version scripts])
@@ -256,13 +248,13 @@ VERS_1 {
global: *; global: *;
}; };
EOF EOF
AC_LINK_IFELSE([AC_LANG_SOURCE([AC_LANG_PROGRAM([], [])])], AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
[VERSION_SCRIPT_FLAG=-Wl,--version-script,; [VERSION_SCRIPT_FLAG=-Wl,--version-script,;
AC_MSG_RESULT([yes (GNU style)])], AC_MSG_RESULT([yes (GNU style)])],
[]) [])
if test "x$VERSION_SCRIPT_FLAG" = "x"; then if test "x$VERSION_SCRIPT_FLAG" = "x"; then
LDFLAGS="$SAVED_LDFLAGS -Wl,-M,conftest.map" LDFLAGS="$SAVED_LDFLAGS -Wl,-M,conftest.map"
AC_LINK_IFELSE([AC_LANG_SOURCE([AC_LANG_PROGRAM([], [])])], AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
[VERSION_SCRIPT_FLAG=-Wl,-M,; [VERSION_SCRIPT_FLAG=-Wl,-M,;
AC_MSG_RESULT([yes (Sun style)])], AC_MSG_RESULT([yes (Sun style)])],
[]) [])
@@ -273,7 +265,7 @@ if test "x$VERSION_SCRIPT_FLAG" = "x"; then
fi fi
LDFLAGS="$SAVED_LDFLAGS" LDFLAGS="$SAVED_LDFLAGS"
AC_MSG_CHECKING([whether to use version script when building mozjpeg]) AC_MSG_CHECKING([whether to use version script when building libjpeg-turbo])
AC_MSG_RESULT($VERSION_SCRIPT) AC_MSG_RESULT($VERSION_SCRIPT)
AM_CONDITIONAL(VERSION_SCRIPT, test "x$VERSION_SCRIPT" = "xyes") AM_CONDITIONAL(VERSION_SCRIPT, test "x$VERSION_SCRIPT" = "xyes")
@@ -558,7 +550,7 @@ AM_CONDITIONAL([X86_64], [test "x$host_cpu" = "xx86_64" -o "x$host_cpu" = "xamd6
AM_CONDITIONAL([WITH_TURBOJPEG], [test "x$with_turbojpeg" != "xno"]) AM_CONDITIONAL([WITH_TURBOJPEG], [test "x$with_turbojpeg" != "xno"])
AM_CONDITIONAL([CROSS_COMPILING], [test "x$cross_compiling" = "xyes"]) AM_CONDITIONAL([CROSS_COMPILING], [test "x$cross_compiling" = "xyes"])
AC_ARG_VAR(PKGNAME, [distribution package name (default: mozjpeg)]) AC_ARG_VAR(PKGNAME, [distribution package name (default: libjpeg-turbo)])
if test "x$PKGNAME" = "x"; then if test "x$PKGNAME" = "x"; then
PKGNAME=$PACKAGE_NAME PKGNAME=$PACKAGE_NAME
fi fi
@@ -598,7 +590,7 @@ AC_DEFINE_UNQUOTED([BUILD], "$BUILD", [libjpeg-turbo build number])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADERS([jconfig.h]) AC_CONFIG_HEADERS([jconfig.h])
AC_CONFIG_HEADERS([jconfigint.h]) AC_CONFIG_HEADERS([jconfigint.h])
AC_CONFIG_FILES([pkgscripts/mozjpeg.spec.tmpl:release/mozjpeg.spec.in]) AC_CONFIG_FILES([pkgscripts/libjpeg-turbo.spec.tmpl:release/libjpeg-turbo.spec.in])
AC_CONFIG_FILES([pkgscripts/makecygwinpkg.tmpl:release/makecygwinpkg.in]) AC_CONFIG_FILES([pkgscripts/makecygwinpkg.tmpl:release/makecygwinpkg.in])
AC_CONFIG_FILES([pkgscripts/makedpkg.tmpl:release/makedpkg.in]) AC_CONFIG_FILES([pkgscripts/makedpkg.tmpl:release/makedpkg.in])
AC_CONFIG_FILES([pkgscripts/makemacpkg.tmpl:release/makemacpkg.in]) AC_CONFIG_FILES([pkgscripts/makemacpkg.tmpl:release/makemacpkg.in])

View File

@@ -1,4 +1,4 @@
.TH DJPEG 1 "18 February 2016" .TH DJPEG 1 "18 March 2017"
.SH NAME .SH NAME
djpeg \- decompress a JPEG file to an image file djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS .SH SYNOPSIS
@@ -185,7 +185,7 @@ Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example, number. For example,
.B \-max 4m .B \-max 4m
selects 4000000 bytes. If more space is needed, temporary files will be used. selects 4000000 bytes. If more space is needed, an error will occur.
.TP .TP
.BI \-outfile " name" .BI \-outfile " name"
Send output image to the named file, not to standard output. Send output image to the named file, not to standard output.

View File

@@ -455,7 +455,7 @@ Variables</h2></td></tr>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Disable buffer (re)allocation. </p> <p>Disable buffer (re)allocation. </p>
<p>If passed to <a class="el" href="group___turbo_j_p_e_g.html#gaf38f2ed44bdc88e730e08b632fa6e88e" title="Compress an RGB, grayscale, or CMYK image into a JPEG image.">tjCompress2()</a> or <a class="el" href="group___turbo_j_p_e_g.html#gad02cd42b69f193a0623a9c801788df3a" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a>, this flag will cause those functions to generate an error if the JPEG image buffer is invalid or too small rather than attempting to allocate or reallocate that buffer. This reproduces the behavior of earlier versions of TurboJPEG. </p> <p>If passed to one of the JPEG compression or transform functions, this flag will cause those functions to generate an error if the JPEG image buffer is invalid or too small rather than attempting to allocate or reallocate that buffer. This reproduces the behavior of earlier versions of TurboJPEG. </p>
</div> </div>
</div> </div>
@@ -812,7 +812,7 @@ Variables</h2></td></tr>
</div><div class="memdoc"> </div><div class="memdoc">
<p>Allocate an image buffer for use with TurboJPEG. </p> <p>Allocate an image buffer for use with TurboJPEG. </p>
<p>You should always use this function to allocate the JPEG destination buffer(s) for <a class="el" href="group___turbo_j_p_e_g.html#gaf38f2ed44bdc88e730e08b632fa6e88e" title="Compress an RGB, grayscale, or CMYK image into a JPEG image.">tjCompress2()</a> and <a class="el" href="group___turbo_j_p_e_g.html#gad02cd42b69f193a0623a9c801788df3a" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> unless you are disabling automatic buffer (re)allocation (by setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>.)</p> <p>You should always use this function to allocate the JPEG destination buffer(s) for the compression and transform functions unless you are disabling automatic buffer (re)allocation (by setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>.)</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
<table class="params"> <table class="params">
<tr><td class="paramname">bytes</td><td>the number of bytes to allocate</td></tr> <tr><td class="paramname">bytes</td><td>the number of bytes to allocate</td></tr>
@@ -1008,7 +1008,7 @@ Variables</h2></td></tr>
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1"> <tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li> <li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li> <li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees this.)</li> <li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.)</li>
</ol> </ol>
If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr> If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr> <tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
@@ -1106,7 +1106,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1"> <tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li> <li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li> <li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees this.)</li> <li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.)</li>
</ol> </ol>
If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr> If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr> <tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
@@ -1203,7 +1203,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1"> <tr><td class="paramname">jpegBuf</td><td>address of a pointer to an image buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li> <li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li> <li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees this.)</li> <li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a>. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.)</li>
</ol> </ol>
If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr> If you choose option 1, <code>*jpegSize</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr> <tr><td class="paramname">jpegSize</td><td>pointer to an unsigned long variable that holds the size of the JPEG image buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.) If <code>*jpegBuf</code> points to a JPEG image buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is ignored.</td></tr>
@@ -1942,7 +1942,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
</div><div class="memdoc"> </div><div class="memdoc">
<p>Free an image buffer previously allocated by TurboJPEG. </p> <p>Free an image buffer previously allocated by TurboJPEG. </p>
<p>You should always use this function to free JPEG destination buffer(s) that were automatically (re)allocated by <a class="el" href="group___turbo_j_p_e_g.html#gaf38f2ed44bdc88e730e08b632fa6e88e" title="Compress an RGB, grayscale, or CMYK image into a JPEG image.">tjCompress2()</a> or <a class="el" href="group___turbo_j_p_e_g.html#gad02cd42b69f193a0623a9c801788df3a" title="Losslessly transform a JPEG image into another JPEG image.">tjTransform()</a> or that were manually allocated using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a>.</p> <p>You should always use this function to free JPEG destination buffer(s) that were automatically (re)allocated by the compression and transform functions or that were manually allocated using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a>.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
<table class="params"> <table class="params">
<tr><td class="paramname">buffer</td><td>address of the buffer to free</td></tr> <tr><td class="paramname">buffer</td><td>address of the buffer to free</td></tr>
@@ -2270,7 +2270,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<tr><td class="paramname">dstBufs</td><td>pointer to an array of n image buffers. <code>dstBufs[i]</code> will receive a JPEG image that has been transformed using the parameters in <code>transforms[i]</code>. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1"> <tr><td class="paramname">dstBufs</td><td>pointer to an array of n image buffers. <code>dstBufs[i]</code> will receive a JPEG image that has been transformed using the parameters in <code>transforms[i]</code>. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li> <li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga5c9234bda6d993cdaffdd89bf81a00ff" title="Allocate an image buffer for use with TurboJPEG.">tjAlloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>dstBufs[i]</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li> <li>set <code>dstBufs[i]</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a> with the transformed or cropped width and height. This should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees this.)</li> <li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gaccc5bca7f12fcdcc302e6e1c6d4b311b" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters...">tjBufSize()</a> with the transformed or cropped width and height. Under normal circumstances, this should ensure that the buffer never has to be re-allocated (setting <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> guarantees that it won't be.) Note, however, that there are some rare cases (such as transforming images with a large amount of embedded EXIF or ICC profile data) in which the output image will be larger than the worst-case size, and <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a> cannot be used in those cases.</li>
</ol> </ol>
If you choose option 1, <code>dstSizes[i]</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>dstBufs[i]</code> upon return from this function, as it may have changed.</td></tr> If you choose option 1, <code>dstSizes[i]</code> should be set to the size of your pre-allocated buffer. In any case, unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ga8808d403c68b62aaa58a4c1e58e98963" title="Disable buffer (re)allocation.">TJFLAG_NOREALLOC</a>, you should always check <code>dstBufs[i]</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">dstSizes</td><td>pointer to an array of n unsigned long variables that will receive the actual sizes (in bytes) of each transformed JPEG image. If <code>dstBufs[i]</code> points to a pre-allocated buffer, then <code>dstSizes[i]</code> should be set to the size of the buffer. Upon return, <code>dstSizes[i]</code> will contain the size of the JPEG image (in bytes.)</td></tr> <tr><td class="paramname">dstSizes</td><td>pointer to an array of n unsigned long variables that will receive the actual sizes (in bytes) of each transformed JPEG image. If <code>dstBufs[i]</code> points to a pre-allocated buffer, then <code>dstSizes[i]</code> should be set to the size of the buffer. Upon return, <code>dstSizes[i]</code> will contain the size of the JPEG image (in bytes.)</td></tr>

View File

@@ -1,26 +0,0 @@
#!/bin/sh
set -e
# Make a local, clean libjpeg-turbo branch that tracks the remote libjpeg-turbo.
# This will allow pushing of imported libjpeg-turbo commits to the mozjpeg repository.
# The libjpeg-turbo branch must only contain imported SVN commits (with git-svn-id: in the message).
git branch -f -t libjpeg-turbo origin/libjpeg-turbo
# Configure git-svn. "git svn fetch" will rebuild remaining git-svn metadata.
git config svn-remote.svn.url svn://svn.code.sf.net/p/libjpeg-turbo/code
git config svn-remote.svn.fetch trunk:refs/heads/libjpeg-turbo
# Enable mapping of SVN usernames to git authors.
git config svn.authorsfile .gitauthors
# Mark which libjpeg-turbo commit has been used to start mozjpeg.
# Required for accurate merging and blame.
echo > .git/info/grafts "72b66f9c77b3e4ae363b21e48145f635cec0b193 540789427ccae8e9e778151cbc16ab8ee88ac6a8"
# To get changes from SVN:
# git svn fetch
# git push origin libjpeg-turbo
#
# To merge SVN changes with mozjpeg:
# git checkout master
# git merge libjpeg-turbo

View File

@@ -1,5 +1,5 @@
set(JAR_FILE turbojpeg.jar) set(JAR_FILE turbojpeg.jar)
set(MANIFEST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.MF") set(MANIFEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.MF)
set(JAVA_CLASSNAMES org/libjpegturbo/turbojpeg/TJ set(JAVA_CLASSNAMES org/libjpegturbo/turbojpeg/TJ
org/libjpegturbo/turbojpeg/TJCompressor org/libjpegturbo/turbojpeg/TJCompressor
@@ -17,7 +17,7 @@ set(JAVA_CLASSNAMES org/libjpegturbo/turbojpeg/TJ
if(MSVC_IDE) if(MSVC_IDE)
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
else() else()
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}") set(OBJDIR ${CMAKE_CURRENT_BINARY_DIR})
endif() endif()
set(TURBOJPEG_DLL_NAME "turbojpeg") set(TURBOJPEG_DLL_NAME "turbojpeg")
@@ -25,34 +25,33 @@ if(MINGW)
set(TURBOJPEG_DLL_NAME "libturbojpeg") set(TURBOJPEG_DLL_NAME "libturbojpeg")
endif() endif()
configure_file(org/libjpegturbo/turbojpeg/TJLoader.java.in configure_file(org/libjpegturbo/turbojpeg/TJLoader.java.in
"${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java") ${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java)
set(JAVA_SOURCES "") set(JAVA_SOURCES "")
set(JAVA_CLASSES "") set(JAVA_CLASSES "")
set(JAVA_CLASSES_FULL "") set(JAVA_CLASSES_FULL "")
foreach(class ${JAVA_CLASSNAMES}) foreach(class ${JAVA_CLASSNAMES})
list(APPEND JAVA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${class}.java") set(JAVA_SOURCES ${JAVA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/${class}.java)
list(APPEND JAVA_CLASSES "${class}.class") set(JAVA_CLASSES ${JAVA_CLASSES} ${class}.class)
list(APPEND JAVA_CLASSES_FULL "${OBJDIR}/${class}.class") set(JAVA_CLASSES_FULL ${JAVA_CLASSES_FULL} ${OBJDIR}/${class}.class)
endforeach() endforeach()
list(APPEND JAVA_SOURCES set(JAVA_SOURCES ${JAVA_SOURCES}
"${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java") ${CMAKE_CURRENT_BINARY_DIR}/org/libjpegturbo/turbojpeg/TJLoader.java)
list(APPEND JAVA_CLASSES org/libjpegturbo/turbojpeg/TJLoader.class) set(JAVA_CLASSES ${JAVA_CLASSES}
list(APPEND JAVA_CLASSES_FULL org/libjpegturbo/turbojpeg/TJLoader.class)
"${OBJDIR}/org/libjpegturbo/turbojpeg/TJLoader.class") set(JAVA_CLASSES_FULL ${JAVA_CLASSES_FULL}
${OBJDIR}/org/libjpegturbo/turbojpeg/TJLoader.class)
string(REGEX REPLACE " " ";" JAVACFLAGS "${JAVACFLAGS}") string(REGEX REPLACE " " ";" JAVACFLAGS "${JAVACFLAGS}")
add_custom_command(OUTPUT ${JAVA_CLASSES_FULL} DEPENDS ${JAVA_SOURCES} add_custom_command(OUTPUT ${JAVA_CLASSES_FULL} DEPENDS ${JAVA_SOURCES}
COMMAND "${JAVA_COMPILE}" ARGS ${JAVACFLAGS} -d "${OBJDIR}" ${JAVA_SOURCES} COMMAND ${JAVA_COMPILE} ARGS ${JAVACFLAGS} -d ${OBJDIR} ${JAVA_SOURCES})
VERBATIM)
add_custom_command(OUTPUT "${JAR_FILE}" DEPENDS ${JAVA_CLASSES_FULL} add_custom_command(OUTPUT ${JAR_FILE} DEPENDS ${JAVA_CLASSES_FULL}
"${MANIFEST_FILE}" ${MANIFEST_FILE}
COMMAND "${JAVA_ARCHIVE}" cfm "${JAR_FILE}" "${MANIFEST_FILE}" ${JAVA_CLASSES} COMMAND ${JAVA_ARCHIVE} cfm ${JAR_FILE} ${MANIFEST_FILE} ${JAVA_CLASSES}
WORKING_DIRECTORY "${OBJDIR}" WORKING_DIRECTORY ${OBJDIR})
VERBATIM)
add_custom_target(java ALL DEPENDS "${JAR_FILE}") add_custom_target(java ALL DEPENDS ${JAR_FILE})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${JAR_FILE}" DESTINATION classes) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${JAR_FILE} DESTINATION classes)

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C)2009-2014, 2016 D. R. Commander. All Rights Reserved. * Copyright (C)2009-2014, 2016-2017 D. R. Commander. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@@ -34,8 +34,8 @@ import org.libjpegturbo.turbojpeg.*;
class TJBench { class TJBench {
static int flags = 0, quiet = 0, pf = TJ.PF_BGR, yuvpad = 1, warmup = 1; static int flags = 0, quiet = 0, pf = TJ.PF_BGR, yuvpad = 1;
static boolean compOnly, decompOnly, doTile, doYUV, write; static boolean compOnly, decompOnly, doTile, doYUV, write = true;
static final String[] pixFormatStr = { static final String[] pixFormatStr = {
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY" "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY"
@@ -55,7 +55,7 @@ class TJBench {
static TJScalingFactor sf; static TJScalingFactor sf;
static int xformOp = TJTransform.OP_NONE, xformOpt = 0; static int xformOp = TJTransform.OP_NONE, xformOpt = 0;
static double benchTime = 5.0; static double benchTime = 5.0, warmup = 1.0;
static final double getTime() { static final double getTime() {
@@ -162,7 +162,7 @@ class TJBench {
} }
/* Benchmark */ /* Benchmark */
iter -= warmup; iter = -1;
elapsed = elapsedDecode = 0.0; elapsed = elapsedDecode = 0.0;
while (true) { while (true) {
int tile = 0; int tile = 0;
@@ -184,11 +184,14 @@ class TJBench {
tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags); tjd.decompress(dstBuf, x, y, width, pitch, height, pf, flags);
} }
} }
iter++; elapsed += getTime() - start;
if (iter >= 1) { if (iter >= 0) {
elapsed += getTime() - start; iter++;
if (elapsed >= benchTime) if (elapsed >= benchTime)
break; break;
} else if (elapsed >= warmup) {
iter = 0;
elapsed = elapsedDecode = 0.0;
} }
} }
if(doYUV) if(doYUV)
@@ -321,7 +324,7 @@ class TJBench {
} }
/* Benchmark */ /* Benchmark */
iter = -warmup; iter = -1;
elapsed = elapsedEncode = 0.0; elapsed = elapsedEncode = 0.0;
while (true) { while (true) {
int tile = 0; int tile = 0;
@@ -346,11 +349,14 @@ class TJBench {
totalJpegSize += jpegSize[tile]; totalJpegSize += jpegSize[tile];
} }
} }
iter++; elapsed += getTime() - start;
if (iter >= 1) { if (iter >= 0) {
elapsed += getTime() - start; iter++;
if (elapsed >= benchTime) if (elapsed >= benchTime)
break; break;
} else if (elapsed >= warmup) {
iter = 0;
elapsed = elapsedEncode = 0.0;
} }
} }
if (doYUV) if (doYUV)
@@ -541,17 +547,20 @@ class TJBench {
} }
} }
iter = -warmup; iter = -1;
elapsed = 0.; elapsed = 0.;
while (true) { while (true) {
start = getTime(); start = getTime();
tjt.transform(jpegBuf, t, flags); tjt.transform(jpegBuf, t, flags);
jpegSize = tjt.getTransformedSizes(); jpegSize = tjt.getTransformedSizes();
iter++; elapsed += getTime() - start;
if (iter >= 1) { if (iter >= 0) {
elapsed += getTime() - start; iter++;
if (elapsed >= benchTime) if (elapsed >= benchTime)
break; break;
} else if (elapsed >= warmup) {
iter = 0;
elapsed = 0.0;
} }
} }
t = null; t = null;
@@ -582,8 +591,8 @@ class TJBench {
System.out.print("N/A N/A "); System.out.print("N/A N/A ");
jpegBuf = new byte[1][TJ.bufSize(_tilew, _tileh, subsamp)]; jpegBuf = new byte[1][TJ.bufSize(_tilew, _tileh, subsamp)];
jpegSize = new int[1]; jpegSize = new int[1];
jpegBuf[0] = srcBuf;
jpegSize[0] = srcSize; jpegSize[0] = srcSize;
System.arraycopy(srcBuf, 0, jpegBuf[0], 0, srcSize);
} }
if (w == tilew) if (w == tilew)
@@ -659,8 +668,9 @@ class TJBench {
System.out.println("-grayscale = Perform lossless grayscale conversion prior to decompression"); System.out.println("-grayscale = Perform lossless grayscale conversion prior to decompression");
System.out.println(" test (can be combined with the other transforms above)"); System.out.println(" test (can be combined with the other transforms above)");
System.out.println("-benchtime <t> = Run each benchmark for at least <t> seconds (default = 5.0)"); System.out.println("-benchtime <t> = Run each benchmark for at least <t> seconds (default = 5.0)");
System.out.println("-warmup <w> = Execute each benchmark <w> times to prime the cache before"); System.out.println("-warmup <t> = Run each benchmark for <t> seconds (default = 1.0) prior to");
System.out.println(" taking performance measurements (default = 1)"); System.out.println(" starting the timer, in order to prime the caches and thus improve the");
System.out.println(" consistency of the results.");
System.out.println("-componly = Stop after running compression tests. Do not test decompression."); System.out.println("-componly = Stop after running compression tests. Do not test decompression.");
System.out.println("-nowrite = Do not write reference or output images (improves consistency"); System.out.println("-nowrite = Do not write reference or output images (improves consistency");
System.out.println(" of performance measurements.)\n"); System.out.println(" of performance measurements.)\n");
@@ -824,14 +834,15 @@ class TJBench {
if (argv[i].equalsIgnoreCase("-nowrite")) if (argv[i].equalsIgnoreCase("-nowrite"))
write = false; write = false;
if (argv[i].equalsIgnoreCase("-warmup") && i < argv.length - 1) { if (argv[i].equalsIgnoreCase("-warmup") && i < argv.length - 1) {
int temp = -1; double temp = -1;
try { try {
temp = Integer.parseInt(argv[++i]); temp = Double.parseDouble(argv[++i]);
} catch (NumberFormatException e) {} } catch (NumberFormatException e) {}
if (temp >= 0) { if (temp >= 0.0) {
warmup = temp; warmup = temp;
System.out.format("Warmup runs = %d\n\n", warmup); System.out.format("Warmup time = %.1f seconds\n\n", warmup);
} } else
usage();
} }
if (argv[i].equalsIgnoreCase("-?")) if (argv[i].equalsIgnoreCase("-?"))
usage(); usage();

View File

@@ -4,9 +4,10 @@
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1998, Thomas G. Lane. * Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding. * Modified 2003-2010 by Guido Vollbeding.
* libjpeg-turbo Modifications: * It was modified by The libjpeg-turbo Project to include only code relevant
* Copyright (C) 2014, D. R. Commander. * to libjpeg-turbo.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README.ijg
* file.
* *
* This file contains application interface code for the compression half * This file contains application interface code for the compression half
* of the JPEG library. These are the "minimum" API routines that may be * of the JPEG library. These are the "minimum" API routines that may be
@@ -22,8 +23,6 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jmemsys.h"
#include "jcmaster.h"
/* /*
@@ -93,16 +92,6 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
/* OK, I'm ready */ /* OK, I'm ready */
cinfo->global_state = CSTATE_START; cinfo->global_state = CSTATE_START;
/* The master struct is used to store extension parameters, so we allocate it
* here. It is later reallocated by jinit_c_master_control().
*/
cinfo->master = (struct jpeg_comp_master *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
sizeof(my_comp_master));
MEMZERO(cinfo->master, sizeof(my_comp_master));
cinfo->master->compress_profile = JCP_MAX_COMPRESSION;
} }

View File

@@ -3,9 +3,8 @@
* *
* Copyright (C) 1994-1996, Thomas G. Lane. * Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains application interface code for the compression half * This file contains application interface code for the compression half
* of the JPEG library. These are the "standard" API routines that are * of the JPEG library. These are the "standard" API routines that are
@@ -45,11 +44,6 @@ jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
if (write_all_tables) if (write_all_tables)
jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
/* setting up scan optimisation pattern failed, disable scan optimisation */
if (cinfo->master->num_scans_luma == 0 || cinfo->scan_info == NULL ||
cinfo->num_scans == 0)
cinfo->master->optimize_scans = FALSE;
/* (Re)initialize error mgr and destination modules */ /* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
(*cinfo->dest->init_destination) (cinfo); (*cinfo->dest->init_destination) (cinfo);

View File

@@ -3,9 +3,10 @@
* *
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Developed 1997-2009 by Guido Vollbeding. * Developed 1997-2009 by Guido Vollbeding.
* It was modified by The libjpeg-turbo Project to include only code relevant * libjpeg-turbo Modifications:
* to libjpeg-turbo. * Copyright (C) 2015, D. R. Commander.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README.ijg
* file.
* *
* This file contains portable arithmetic entropy encoding routines for JPEG * This file contains portable arithmetic entropy encoding routines for JPEG
* (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81). * (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81).
@@ -18,7 +19,7 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include <math.h>
/* Expanded entropy encoder object for arithmetic encoding. */ /* Expanded entropy encoder object for arithmetic encoding. */
@@ -120,10 +121,6 @@ emit_byte (int val, j_compress_ptr cinfo)
{ {
struct jpeg_destination_mgr *dest = cinfo->dest; struct jpeg_destination_mgr *dest = cinfo->dest;
/* Do not emit bytes during trellis passes */
if (cinfo->master->trellis_passes)
return;
*dest->next_output_byte++ = (JOCTET) val; *dest->next_output_byte++ = (JOCTET) val;
if (--dest->free_in_buffer == 0) if (--dest->free_in_buffer == 0)
if (! (*dest->empty_output_buffer) (cinfo)) if (! (*dest->empty_output_buffer) (cinfo))
@@ -830,7 +827,6 @@ start_pass (j_compress_ptr cinfo, boolean gather_statistics)
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
int ci, tbl; int ci, tbl;
jpeg_component_info *compptr; jpeg_component_info *compptr;
boolean progressive_mode;
if (gather_statistics) if (gather_statistics)
/* Make sure to avoid that in the master control logic! /* Make sure to avoid that in the master control logic!
@@ -841,12 +837,8 @@ start_pass (j_compress_ptr cinfo, boolean gather_statistics)
/* We assume jcmaster.c already validated the progressive scan parameters. */ /* We assume jcmaster.c already validated the progressive scan parameters. */
/* Trellis optimization does DC and AC in same pass and without refinement
* so consider progressive mode to be off in such case */
progressive_mode = (cinfo->master->trellis_passes) ? FALSE : cinfo->progressive_mode;
/* Select execution routines */ /* Select execution routines */
if (progressive_mode) { if (cinfo->progressive_mode) {
if (cinfo->Ah == 0) { if (cinfo->Ah == 0) {
if (cinfo->Ss == 0) if (cinfo->Ss == 0)
entropy->pub.encode_mcu = encode_mcu_DC_first; entropy->pub.encode_mcu = encode_mcu_DC_first;
@@ -865,7 +857,7 @@ start_pass (j_compress_ptr cinfo, boolean gather_statistics)
for (ci = 0; ci < cinfo->comps_in_scan; ci++) { for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci]; compptr = cinfo->cur_comp_info[ci];
/* DC needs no table for refinement scan */ /* DC needs no table for refinement scan */
if (progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) { if (cinfo->progressive_mode == 0 || (cinfo->Ss == 0 && cinfo->Ah == 0)) {
tbl = compptr->dc_tbl_no; tbl = compptr->dc_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS) if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl); ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
@@ -878,7 +870,7 @@ start_pass (j_compress_ptr cinfo, boolean gather_statistics)
entropy->dc_context[ci] = 0; entropy->dc_context[ci] = 0;
} }
/* AC needs no table when not present */ /* AC needs no table when not present */
if (progressive_mode == 0 || cinfo->Se) { if (cinfo->progressive_mode == 0 || cinfo->Se) {
tbl = compptr->ac_tbl_no; tbl = compptr->ac_tbl_no;
if (tbl < 0 || tbl >= NUM_ARITH_TBLS) if (tbl < 0 || tbl >= NUM_ARITH_TBLS)
ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl); ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl);
@@ -887,7 +879,7 @@ start_pass (j_compress_ptr cinfo, boolean gather_statistics)
((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS); ((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS);
MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS); MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS);
#ifdef CALCULATE_SPECTRAL_CONDITIONING #ifdef CALCULATE_SPECTRAL_CONDITIONING
if (progressive_mode) if (cinfo->progressive_mode)
/* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */ /* Section G.1.3.2: Set appropriate arithmetic conditioning value Kx */
cinfo->arith_ac_K[tbl] = cinfo->Ss + ((8 + cinfo->Se - cinfo->Ss) >> 4); cinfo->arith_ac_K[tbl] = cinfo->Ss + ((8 + cinfo->Se - cinfo->Ss) >> 4);
#endif #endif
@@ -934,34 +926,3 @@ jinit_arith_encoder (j_compress_ptr cinfo)
/* Initialize index for fixed probability estimation */ /* Initialize index for fixed probability estimation */
entropy->fixed_bin[0] = 113; entropy->fixed_bin[0] = 113;
} }
GLOBAL(void)
jget_arith_rates (j_compress_ptr cinfo, int dc_tbl_no, int ac_tbl_no, arith_rates *r)
{
int i;
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
r->arith_dc_L = cinfo->arith_dc_L[dc_tbl_no];
r->arith_dc_U = cinfo->arith_dc_U[dc_tbl_no];
r->arith_ac_K = cinfo->arith_ac_K[ac_tbl_no];
for (i = 0; i < DC_STAT_BINS; i++) {
int state = entropy->dc_stats[dc_tbl_no][i];
int mps_val = state >> 7;
float prob_lps = (jpeg_aritab[state & 0x7f] >> 16) / 46340.95; /* 32768*sqrt(2) */
float prob_0 = (mps_val) ? prob_lps : 1.0 - prob_lps;
float prob_1 = 1.0 - prob_0;
r->rate_dc[i][0] = -log(prob_0) / log(2.0);
r->rate_dc[i][1] = -log(prob_1) / log(2.0);
}
for (i = 0; i < AC_STAT_BINS; i++) {
int state = entropy->ac_stats[ac_tbl_no][i];
int mps_val = state >> 7;
float prob_lps = (jpeg_aritab[state & 0x7f] >> 16) / 46340.95;
float prob_0 = (mps_val) ? prob_lps : 1.0 - prob_lps;
float prob_1 = 1.0 - prob_0;
r->rate_ac[i][0] = -log(prob_0) / log(2.0);
r->rate_ac[i][1] = -log(prob_1) / log(2.0);
}
}

View File

@@ -5,9 +5,8 @@
* Copyright (C) 1994-1997, Thomas G. Lane. * Copyright (C) 1994-1997, Thomas G. Lane.
* It was modified by The libjpeg-turbo Project to include only code and * It was modified by The libjpeg-turbo Project to include only code and
* information relevant to libjpeg-turbo. * information relevant to libjpeg-turbo.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains the coefficient buffer controller for compression. * This file contains the coefficient buffer controller for compression.
* This controller is the top level of the JPEG compressor proper. * This controller is the top level of the JPEG compressor proper.
@@ -17,7 +16,7 @@
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jchuff.h"
/* We use a full-image coefficient buffer when doing Huffman optimization, /* We use a full-image coefficient buffer when doing Huffman optimization,
* and also for writing multiple-scan JPEG files. In all cases, the DCT * and also for writing multiple-scan JPEG files. In all cases, the DCT
@@ -53,10 +52,6 @@ typedef struct {
/* In multi-pass modes, we need a virtual block array for each component. */ /* In multi-pass modes, we need a virtual block array for each component. */
jvirt_barray_ptr whole_image[MAX_COMPONENTS]; jvirt_barray_ptr whole_image[MAX_COMPONENTS];
/* when using trellis quantization, need to keep a copy of all unquantized coefficients */
jvirt_barray_ptr whole_image_uq[MAX_COMPONENTS];
} my_coef_controller; } my_coef_controller;
typedef my_coef_controller *my_coef_ptr; typedef my_coef_controller *my_coef_ptr;
@@ -71,8 +66,6 @@ METHODDEF(boolean) compress_first_pass
METHODDEF(boolean) compress_output METHODDEF(boolean) compress_output
(j_compress_ptr cinfo, JSAMPIMAGE input_buf); (j_compress_ptr cinfo, JSAMPIMAGE input_buf);
#endif #endif
METHODDEF(boolean) compress_trellis_pass
(j_compress_ptr cinfo, JSAMPIMAGE input_buf);
LOCAL(void) LOCAL(void)
@@ -129,12 +122,6 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
coef->pub.compress_data = compress_output; coef->pub.compress_data = compress_output;
break; break;
#endif #endif
case JBUF_REQUANT:
if (coef->whole_image[0] == NULL)
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
coef->pub.compress_data = compress_trellis_pass;
break;
default: default:
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
break; break;
@@ -190,8 +177,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
(*cinfo->fdct->forward_DCT) (cinfo, compptr, (*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[compptr->component_index], input_buf[compptr->component_index],
coef->MCU_buffer[blkn], coef->MCU_buffer[blkn],
ypos, xpos, (JDIMENSION) blockcnt, ypos, xpos, (JDIMENSION) blockcnt);
NULL);
if (blockcnt < compptr->MCU_width) { if (blockcnt < compptr->MCU_width) {
/* Create some dummy blocks at the right edge of the image. */ /* Create some dummy blocks at the right edge of the image. */
jzero_far((void *) coef->MCU_buffer[blkn + blockcnt], jzero_far((void *) coef->MCU_buffer[blkn + blockcnt],
@@ -266,7 +252,6 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
jpeg_component_info *compptr; jpeg_component_info *compptr;
JBLOCKARRAY buffer; JBLOCKARRAY buffer;
JBLOCKROW thisblockrow, lastblockrow; JBLOCKROW thisblockrow, lastblockrow;
JBLOCKARRAY buffer_dst;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
@@ -275,12 +260,6 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
((j_common_ptr) cinfo, coef->whole_image[ci], ((j_common_ptr) cinfo, coef->whole_image[ci],
coef->iMCU_row_num * compptr->v_samp_factor, coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE); (JDIMENSION) compptr->v_samp_factor, TRUE);
buffer_dst = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image_uq[ci],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
/* Count non-dummy DCT block rows in this iMCU row. */ /* Count non-dummy DCT block rows in this iMCU row. */
if (coef->iMCU_row_num < last_iMCU_row) if (coef->iMCU_row_num < last_iMCU_row)
block_rows = compptr->v_samp_factor; block_rows = compptr->v_samp_factor;
@@ -303,8 +282,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
(*cinfo->fdct->forward_DCT) (cinfo, compptr, (*cinfo->fdct->forward_DCT) (cinfo, compptr,
input_buf[ci], thisblockrow, input_buf[ci], thisblockrow,
(JDIMENSION) (block_row * DCTSIZE), (JDIMENSION) (block_row * DCTSIZE),
(JDIMENSION) 0, blocks_across, (JDIMENSION) 0, blocks_across);
buffer_dst[block_row]);
if (ndummy > 0) { if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */ /* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */ thisblockrow += blocks_across; /* => first dummy block */
@@ -348,136 +326,6 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
return compress_output(cinfo, input_buf); return compress_output(cinfo, input_buf);
} }
METHODDEF(boolean)
compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
{
my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
JDIMENSION blocks_across, MCUs_across, MCUindex;
int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
JCOEF lastDC;
jpeg_component_info *compptr;
JBLOCKARRAY buffer;
JBLOCKROW thisblockrow, lastblockrow;
JBLOCKARRAY buffer_dst;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
c_derived_tbl dctbl_data;
c_derived_tbl *dctbl = &dctbl_data;
c_derived_tbl actbl_data;
c_derived_tbl *actbl = &actbl_data;
#ifdef C_ARITH_CODING_SUPPORTED
arith_rates arith_r_data;
arith_rates *arith_r = &arith_r_data;
#endif
compptr = cinfo->cur_comp_info[ci];
#ifdef C_ARITH_CODING_SUPPORTED
if (cinfo->arith_code)
jget_arith_rates(cinfo, compptr->dc_tbl_no, compptr->ac_tbl_no, arith_r);
else
#endif
{
jpeg_make_c_derived_tbl(cinfo, TRUE, compptr->dc_tbl_no, &dctbl);
jpeg_make_c_derived_tbl(cinfo, FALSE, compptr->ac_tbl_no, &actbl);
}
/* Align the virtual buffer for this component. */
buffer = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
buffer_dst = (*cinfo->mem->access_virt_barray)
((j_common_ptr) cinfo, coef->whole_image_uq[compptr->component_index],
coef->iMCU_row_num * compptr->v_samp_factor,
(JDIMENSION) compptr->v_samp_factor, TRUE);
/* Count non-dummy DCT block rows in this iMCU row. */
if (coef->iMCU_row_num < last_iMCU_row)
block_rows = compptr->v_samp_factor;
else {
/* NB: can't use last_row_height here, since may not be set! */
block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
if (block_rows == 0) block_rows = compptr->v_samp_factor;
}
blocks_across = compptr->width_in_blocks;
h_samp_factor = compptr->h_samp_factor;
/* Count number of dummy blocks to be added at the right margin. */
ndummy = (int) (blocks_across % h_samp_factor);
if (ndummy > 0)
ndummy = h_samp_factor - ndummy;
lastDC = 0;
/* 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];
lastblockrow = (block_row > 0) ? buffer[block_row-1] : NULL;
#ifdef C_ARITH_CODING_SUPPORTED
if (cinfo->arith_code)
quantize_trellis_arith(cinfo, arith_r, thisblockrow,
buffer_dst[block_row], blocks_across,
cinfo->quant_tbl_ptrs[compptr->quant_tbl_no],
cinfo->master->norm_src[compptr->quant_tbl_no],
cinfo->master->norm_coef[compptr->quant_tbl_no],
&lastDC, lastblockrow, buffer_dst[block_row-1]);
else
#endif
quantize_trellis(cinfo, dctbl, actbl, thisblockrow,
buffer_dst[block_row], blocks_across,
cinfo->quant_tbl_ptrs[compptr->quant_tbl_no],
cinfo->master->norm_src[compptr->quant_tbl_no],
cinfo->master->norm_coef[compptr->quant_tbl_no],
&lastDC, lastblockrow, buffer_dst[block_row-1]);
if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */
thisblockrow += blocks_across; /* => first dummy block */
jzero_far((void *) thisblockrow, ndummy * sizeof(JBLOCK));
lastDC = thisblockrow[-1][0];
for (bi = 0; bi < ndummy; bi++) {
thisblockrow[bi][0] = lastDC;
}
}
}
/* If at end of image, create dummy block rows as needed.
* The tricky part here is that within each MCU, we want the DC values
* of the dummy blocks to match the last real block's DC value.
* This squeezes a few more bytes out of the resulting file...
*/
if (coef->iMCU_row_num == last_iMCU_row) {
blocks_across += ndummy; /* include lower right corner */
MCUs_across = blocks_across / h_samp_factor;
for (block_row = block_rows; block_row < compptr->v_samp_factor;
block_row++) {
thisblockrow = buffer[block_row];
lastblockrow = buffer[block_row-1];
jzero_far((void *) thisblockrow,
(size_t) (blocks_across * sizeof(JBLOCK)));
for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
lastDC = lastblockrow[h_samp_factor-1][0];
for (bi = 0; bi < h_samp_factor; bi++) {
thisblockrow[bi][0] = lastDC;
}
thisblockrow += h_samp_factor; /* advance to next MCU in row */
lastblockrow += h_samp_factor;
}
}
}
}
/* NB: compress_output will increment iMCU_row_num if successful.
* A suspension return will result in redoing all the work above next time.
*/
/* Emit data to the entropy encoder, sharing code with subsequent passes */
return compress_output(cinfo, input_buf);
}
/* /*
* Process some data in subsequent passes of a multi-pass case. * Process some data in subsequent passes of a multi-pass case.
@@ -581,14 +429,6 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
(JDIMENSION) jround_up((long) compptr->height_in_blocks, (JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor), (long) compptr->v_samp_factor),
(JDIMENSION) compptr->v_samp_factor); (JDIMENSION) compptr->v_samp_factor);
coef->whole_image_uq[ci] = (*cinfo->mem->request_virt_barray)
((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
(JDIMENSION) jround_up((long) compptr->width_in_blocks,
(long) compptr->h_samp_factor),
(JDIMENSION) jround_up((long) compptr->height_in_blocks,
(long) compptr->v_samp_factor),
(JDIMENSION) compptr->v_samp_factor);
} }
#else #else
ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);

1065
jcdctmgr.c

File diff suppressed because it is too large Load Diff

219
jcext.c
View File

@@ -1,219 +0,0 @@
/*
* jcext.c
*
* Copyright (C) 2014, D. R. Commander.
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains accessor functions for extension parameters. These
* allow for extending the functionality of the libjpeg API without breaking
* backward ABI compatibility.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
GLOBAL(boolean)
jpeg_c_bool_param_supported (const j_compress_ptr cinfo, J_BOOLEAN_PARAM param)
{
switch (param) {
case JBOOLEAN_OPTIMIZE_SCANS:
case JBOOLEAN_TRELLIS_QUANT:
case JBOOLEAN_TRELLIS_QUANT_DC:
case JBOOLEAN_TRELLIS_EOB_OPT:
case JBOOLEAN_USE_LAMBDA_WEIGHT_TBL:
case JBOOLEAN_USE_SCANS_IN_TRELLIS:
case JBOOLEAN_TRELLIS_Q_OPT:
case JBOOLEAN_OVERSHOOT_DERINGING:
return TRUE;
}
return FALSE;
}
GLOBAL(void)
jpeg_c_set_bool_param (j_compress_ptr cinfo, J_BOOLEAN_PARAM param,
boolean value)
{
switch(param) {
case JBOOLEAN_OPTIMIZE_SCANS:
cinfo->master->optimize_scans = value;
break;
case JBOOLEAN_TRELLIS_QUANT:
cinfo->master->trellis_quant = value;
break;
case JBOOLEAN_TRELLIS_QUANT_DC:
cinfo->master->trellis_quant_dc = value;
break;
case JBOOLEAN_TRELLIS_EOB_OPT:
cinfo->master->trellis_eob_opt = value;
break;
case JBOOLEAN_USE_LAMBDA_WEIGHT_TBL:
cinfo->master->use_lambda_weight_tbl = value;
break;
case JBOOLEAN_USE_SCANS_IN_TRELLIS:
cinfo->master->use_scans_in_trellis = value;
break;
case JBOOLEAN_TRELLIS_Q_OPT:
cinfo->master->trellis_q_opt = value;
break;
case JBOOLEAN_OVERSHOOT_DERINGING:
cinfo->master->overshoot_deringing = value;
break;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
}
GLOBAL(boolean)
jpeg_c_get_bool_param (const j_compress_ptr cinfo, J_BOOLEAN_PARAM param)
{
switch(param) {
case JBOOLEAN_OPTIMIZE_SCANS:
return cinfo->master->optimize_scans;
case JBOOLEAN_TRELLIS_QUANT:
return cinfo->master->trellis_quant;
case JBOOLEAN_TRELLIS_QUANT_DC:
return cinfo->master->trellis_quant_dc;
case JBOOLEAN_TRELLIS_EOB_OPT:
return cinfo->master->trellis_eob_opt;
case JBOOLEAN_USE_LAMBDA_WEIGHT_TBL:
return cinfo->master->use_lambda_weight_tbl;
case JBOOLEAN_USE_SCANS_IN_TRELLIS:
return cinfo->master->use_scans_in_trellis;
case JBOOLEAN_TRELLIS_Q_OPT:
return cinfo->master->trellis_q_opt;
case JBOOLEAN_OVERSHOOT_DERINGING:
return cinfo->master->overshoot_deringing;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
return FALSE;
}
GLOBAL(boolean)
jpeg_c_float_param_supported (const j_compress_ptr cinfo, J_FLOAT_PARAM param)
{
switch (param) {
case JFLOAT_LAMBDA_LOG_SCALE1:
case JFLOAT_LAMBDA_LOG_SCALE2:
case JFLOAT_TRELLIS_DELTA_DC_WEIGHT:
return TRUE;
}
return FALSE;
}
GLOBAL(void)
jpeg_c_set_float_param (j_compress_ptr cinfo, J_FLOAT_PARAM param, float value)
{
switch (param) {
case JFLOAT_LAMBDA_LOG_SCALE1:
cinfo->master->lambda_log_scale1 = value;
break;
case JFLOAT_LAMBDA_LOG_SCALE2:
cinfo->master->lambda_log_scale2 = value;
break;
case JFLOAT_TRELLIS_DELTA_DC_WEIGHT:
cinfo->master->trellis_delta_dc_weight = value;
break;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
}
GLOBAL(float)
jpeg_c_get_float_param (const j_compress_ptr cinfo, J_FLOAT_PARAM param)
{
switch (param) {
case JFLOAT_LAMBDA_LOG_SCALE1:
return cinfo->master->lambda_log_scale1;
case JFLOAT_LAMBDA_LOG_SCALE2:
return cinfo->master->lambda_log_scale2;
case JFLOAT_TRELLIS_DELTA_DC_WEIGHT:
return cinfo->master->trellis_delta_dc_weight;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
return -1;
}
GLOBAL(boolean)
jpeg_c_int_param_supported (const j_compress_ptr cinfo, J_INT_PARAM param)
{
switch (param) {
case JINT_COMPRESS_PROFILE:
case JINT_TRELLIS_FREQ_SPLIT:
case JINT_TRELLIS_NUM_LOOPS:
case JINT_BASE_QUANT_TBL_IDX:
case JINT_DC_SCAN_OPT_MODE:
return TRUE;
}
return FALSE;
}
GLOBAL(void)
jpeg_c_set_int_param (j_compress_ptr cinfo, J_INT_PARAM param, int value)
{
switch (param) {
case JINT_COMPRESS_PROFILE:
switch (value) {
case JCP_MAX_COMPRESSION:
case JCP_FASTEST:
cinfo->master->compress_profile = value;
break;
default:
ERREXIT(cinfo, JERR_BAD_PARAM_VALUE);
}
break;
case JINT_TRELLIS_FREQ_SPLIT:
cinfo->master->trellis_freq_split = value;
break;
case JINT_TRELLIS_NUM_LOOPS:
cinfo->master->trellis_num_loops = value;
break;
case JINT_BASE_QUANT_TBL_IDX:
if (value >= 0 && value <= 8)
cinfo->master->quant_tbl_master_idx = value;
break;
case JINT_DC_SCAN_OPT_MODE:
cinfo->master->dc_scan_opt_mode = value;
break;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
}
GLOBAL(int)
jpeg_c_get_int_param (const j_compress_ptr cinfo, J_INT_PARAM param)
{
switch (param) {
case JINT_COMPRESS_PROFILE:
return cinfo->master->compress_profile;
case JINT_TRELLIS_FREQ_SPLIT:
return cinfo->master->trellis_freq_split;
case JINT_TRELLIS_NUM_LOOPS:
return cinfo->master->trellis_num_loops;
case JINT_BASE_QUANT_TBL_IDX:
return cinfo->master->quant_tbl_master_idx;
case JINT_DC_SCAN_OPT_MODE:
return cinfo->master->dc_scan_opt_mode;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
return -1;
}

View File

@@ -5,9 +5,8 @@
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* It was modified by The libjpeg-turbo Project to include only code relevant * It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo. * to libjpeg-turbo.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains declarations for Huffman entropy encoding routines * This file contains declarations for Huffman entropy encoding routines
* that are shared between the sequential encoder (jchuff.c) and the * that are shared between the sequential encoder (jchuff.c) and the
@@ -42,8 +41,3 @@ EXTERN(void) jpeg_make_c_derived_tbl
/* Generate an optimal table definition given the specified counts */ /* Generate an optimal table definition given the specified counts */
EXTERN(void) jpeg_gen_optimal_table EXTERN(void) jpeg_gen_optimal_table
(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[]); (j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[]);
EXTERN(void) quantize_trellis
(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef, JCOEF *last_dc_val,
JBLOCKROW coef_blocks_above, JBLOCKROW src_above);

View File

@@ -3,9 +3,8 @@
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains initialization logic for the JPEG compressor. * This file contains initialization logic for the JPEG compressor.
* This routine is in charge of selecting the modules to be executed and * This routine is in charge of selecting the modules to be executed and
@@ -62,8 +61,7 @@ jinit_compress_master (j_compress_ptr cinfo)
/* Need a full-image coefficient buffer in any multi-pass mode. */ /* Need a full-image coefficient buffer in any multi-pass mode. */
jinit_c_coef_controller(cinfo, jinit_c_coef_controller(cinfo,
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding || (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
cinfo->master->optimize_scans || cinfo->master->trellis_quant));
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo); jinit_marker_writer(cinfo);

View File

@@ -184,72 +184,6 @@ emit_dqt (j_compress_ptr cinfo, int index)
return prec; return prec;
} }
LOCAL(int)
emit_multi_dqt (j_compress_ptr cinfo)
/* Emits a DQT marker containing all quantization tables */
/* Returns number of emitted 16-bit tables, or -1 for failed for baseline checking. */
{
int prec[MAX_COMPONENTS];
int seen[MAX_COMPONENTS] = { 0 };
int fin_prec = 0;
int ci;
int size = 0;
if (cinfo->master->compress_profile == JCP_FASTEST)
return -1;
for (ci = 0; ci < cinfo->num_components; ci++) {
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;
int i;
JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[tbl_num];
if (qtbl == NULL || qtbl->sent_table == TRUE)
return -1;
prec[ci] = 0;
for (i = 0; i < DCTSIZE2; i++)
prec[ci] = !!(prec[ci] + (qtbl->quantval[i] > 255));
fin_prec += prec[ci];
}
emit_marker(cinfo, M_DQT);
for (ci = 0; ci < cinfo->num_components; ci++) {
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;
if (!seen[tbl_num]) {
size += DCTSIZE2 * (prec[ci] + 1) + 1;
seen[tbl_num] = 1;
}
}
size += 2;
emit_2bytes(cinfo, size);
for (ci = 0; ci < cinfo->num_components; ci++) {
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;
int i;
JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[tbl_num];
if (qtbl->sent_table == TRUE)
continue;
emit_byte(cinfo, tbl_num + (prec[ci] << 4));
for (i = 0; i < DCTSIZE2; i++) {
unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
if (prec[ci])
emit_byte(cinfo, (int) (qval >> 8));
emit_byte(cinfo, (int) (qval & 0xFF));
}
qtbl->sent_table = TRUE;
}
return fin_prec;
}
LOCAL(void) LOCAL(void)
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac) emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
@@ -288,115 +222,6 @@ emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
} }
} }
LOCAL(boolean)
emit_multi_dht (j_compress_ptr cinfo)
/* Emit all DHT markers */
/* Returns FALSE on failure, TRUE otherwise. */
{
int i, j;
int length = 2;
int dclens[NUM_HUFF_TBLS] = { 0 };
int aclens[NUM_HUFF_TBLS] = { 0 };
JHUFF_TBL *dcseen[NUM_HUFF_TBLS] = { NULL };
JHUFF_TBL *acseen[NUM_HUFF_TBLS] = { NULL };
if (cinfo->master->compress_profile == JCP_FASTEST)
return 0;
/* Calclate the total length. */
for (i = 0; i < cinfo->comps_in_scan; i++) {
jpeg_component_info *compptr = cinfo->cur_comp_info[i];
int dcidx = compptr->dc_tbl_no;
int acidx = compptr->ac_tbl_no;
JHUFF_TBL *dctbl = cinfo->dc_huff_tbl_ptrs[dcidx];
JHUFF_TBL *actbl = cinfo->ac_huff_tbl_ptrs[acidx];
int seen = 0;
/* Handle DC table lenghts */
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
if (dctbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dcidx);
if (dctbl->sent_table)
continue;
for (j = 0; j < NUM_HUFF_TBLS; j++)
seen += (dctbl == dcseen[j]);
if (seen)
continue;
dcseen[i] = dctbl;
for (j = 1; j <= 16; j++)
dclens[i] += dctbl->bits[j];
length += dclens[i] + 16 + 1;
}
/* Handle AC table lengths */
if (cinfo->Se) {
if (actbl == NULL)
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, acidx + 0x10);
if (actbl->sent_table)
continue;
seen = 0;
for (j = 0; j < NUM_HUFF_TBLS; j++)
seen += (actbl == acseen[j]);
if (seen)
continue;
acseen[i] = actbl;
for (j = 1; j <= 16; j++)
aclens[i] += actbl->bits[j];
length += aclens[i] + 16 + 1;
}
}
/* Make sure we can fit it all into one DHT marker */
if (length > (1 << 16) - 1)
return FALSE;
emit_marker(cinfo, M_DHT);
emit_2bytes(cinfo, length);
for (i = 0; i < cinfo->comps_in_scan; i++) {
jpeg_component_info *compptr = cinfo->cur_comp_info[i];
int dcidx = compptr->dc_tbl_no;
int acidx = compptr->ac_tbl_no;
JHUFF_TBL *dctbl = cinfo->dc_huff_tbl_ptrs[dcidx];
JHUFF_TBL *actbl = cinfo->ac_huff_tbl_ptrs[acidx];
acidx += 0x10;
/* DC */
if (cinfo->Ss == 0 && cinfo->Ah == 0 && !dctbl->sent_table) {
emit_byte(cinfo, dcidx);
for (j = 1; j <= 16; j++)
emit_byte(cinfo, dctbl->bits[j]);
for (j = 0; j < dclens[i]; j++)
emit_byte(cinfo, dctbl->huffval[j]);
dctbl->sent_table = TRUE;
}
if (cinfo->Se && !actbl->sent_table) {
emit_byte(cinfo, acidx);
for (j = 1; j <= 16; j++)
emit_byte(cinfo, actbl->bits[j]);
for (j = 0; j < aclens[i]; j++)
emit_byte(cinfo, actbl->huffval[j]);
actbl->sent_table = TRUE;
}
}
return TRUE;
}
LOCAL(void) LOCAL(void)
emit_dac (j_compress_ptr cinfo) emit_dac (j_compress_ptr cinfo)
@@ -680,14 +505,11 @@ write_frame_header (j_compress_ptr cinfo)
/* Emit DQT for each quantization table. /* Emit DQT for each quantization table.
* Note that emit_dqt() suppresses any duplicate tables. * Note that emit_dqt() suppresses any duplicate tables.
*/ */
prec = emit_multi_dqt(cinfo);
if (prec == -1) {
prec = 0; prec = 0;
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) { ci++, compptr++) {
prec += emit_dqt(cinfo, compptr->quant_tbl_no); prec += emit_dqt(cinfo, compptr->quant_tbl_no);
} }
}
/* now prec is nonzero iff there are any 16-bit quant tables. */ /* now prec is nonzero iff there are any 16-bit quant tables. */
/* Check for a non-baseline specification. /* Check for a non-baseline specification.
@@ -750,7 +572,6 @@ write_scan_header (j_compress_ptr cinfo)
/* Emit Huffman tables. /* Emit Huffman tables.
* Note that emit_dht() suppresses any duplicate tables. * Note that emit_dht() suppresses any duplicate tables.
*/ */
if (!emit_multi_dht(cinfo)) {
for (i = 0; i < cinfo->comps_in_scan; i++) { for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i]; compptr = cinfo->cur_comp_info[i];
/* DC needs no table for refinement scan */ /* DC needs no table for refinement scan */
@@ -761,7 +582,6 @@ write_scan_header (j_compress_ptr cinfo)
emit_dht(cinfo, compptr->ac_tbl_no, TRUE); emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
} }
} }
}
/* Emit DRI if required --- note that DRI value could change for each scan. /* Emit DRI if required --- note that DRI value could change for each scan.
* We avoid wasting space with unnecessary DRIs, however. * We avoid wasting space with unnecessary DRIs, however.

View File

@@ -6,9 +6,8 @@
* Modified 2003-2010 by Guido Vollbeding. * Modified 2003-2010 by Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2010, 2016, D. R. Commander. * Copyright (C) 2010, 2016, D. R. Commander.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains master control logic for the JPEG compressor. * This file contains master control logic for the JPEG compressor.
* These routines are concerned with parameter validation, initial setup, * These routines are concerned with parameter validation, initial setup,
@@ -21,11 +20,41 @@
#include "jpeglib.h" #include "jpeglib.h"
#include "jpegcomp.h" #include "jpegcomp.h"
#include "jconfigint.h" #include "jconfigint.h"
#include "jmemsys.h"
#include "jcmaster.h"
/* Private state */
typedef enum {
main_pass, /* input data, also do first output step */
huff_opt_pass, /* Huffman code optimization pass */
output_pass /* data output pass */
} c_pass_type;
typedef struct {
struct jpeg_comp_master pub; /* public fields */
c_pass_type pass_type; /* the type of the current pass */
int pass_number; /* # of passes completed */
int total_passes; /* total # of passes needed */
int scan_number; /* current index in scan_info[] */
/* /*
* This is here so we can add libjpeg-turbo version/build information to the
* global string table without introducing a new global symbol. Adding this
* information to the global string table allows one to examine a binary
* object and determine which version of libjpeg-turbo it was built from or
* linked against.
*/
const char *jpeg_version;
} my_comp_master;
typedef my_comp_master *my_master_ptr;
/*
* Support routines that do various essential calculations. * Support routines that do various essential calculations.
*/ */
@@ -160,14 +189,6 @@ validate_script (j_compress_ptr cinfo)
/* -1 until that coefficient has been seen; then last Al for it */ /* -1 until that coefficient has been seen; then last Al for it */
#endif #endif
if (cinfo->master->optimize_scans) {
cinfo->progressive_mode = TRUE;
/* When we optimize scans, there is redundancy in the scan list
* and this function will fail. Therefore skip all this checking
*/
return;
}
if (cinfo->num_scans <= 0) if (cinfo->num_scans <= 0)
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0); ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
@@ -296,27 +317,9 @@ select_scan_parameters (j_compress_ptr cinfo)
int ci; int ci;
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
my_master_ptr master = (my_master_ptr) cinfo->master; if (cinfo->scan_info != NULL) {
if (master->pass_number < master->pass_number_scan_opt_base) {
cinfo->comps_in_scan = 1;
if (cinfo->master->use_scans_in_trellis) {
cinfo->cur_comp_info[0] =
&cinfo->comp_info[master->pass_number /
(4 * cinfo->master->trellis_num_loops)];
cinfo->Ss = (master->pass_number % 4 < 2) ?
1 : cinfo->master->trellis_freq_split + 1;
cinfo->Se = (master->pass_number % 4 < 2) ?
cinfo->master->trellis_freq_split : DCTSIZE2 - 1;
} else {
cinfo->cur_comp_info[0] =
&cinfo->comp_info[master->pass_number /
(2 * cinfo->master->trellis_num_loops)];
cinfo->Ss = 1;
cinfo->Se = DCTSIZE2-1;
}
}
else if (cinfo->scan_info != NULL) {
/* Prepare for current scan --- the script is already validated */ /* Prepare for current scan --- the script is already validated */
my_master_ptr master = (my_master_ptr) cinfo->master;
const jpeg_scan_info *scanptr = cinfo->scan_info + master->scan_number; const jpeg_scan_info *scanptr = cinfo->scan_info + master->scan_number;
cinfo->comps_in_scan = scanptr->comps_in_scan; cinfo->comps_in_scan = scanptr->comps_in_scan;
@@ -328,21 +331,6 @@ select_scan_parameters (j_compress_ptr cinfo)
cinfo->Se = scanptr->Se; cinfo->Se = scanptr->Se;
cinfo->Ah = scanptr->Ah; cinfo->Ah = scanptr->Ah;
cinfo->Al = scanptr->Al; cinfo->Al = scanptr->Al;
if (cinfo->master->optimize_scans) {
/* luma frequency split passes */
if (master->scan_number >= cinfo->master->num_scans_luma_dc +
3 * cinfo->master->Al_max_luma + 2 &&
master->scan_number < cinfo->master->num_scans_luma)
cinfo->Al = master->best_Al_luma;
/* chroma frequency split passes */
if (master->scan_number >= cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc +
(6 * cinfo->master->Al_max_chroma + 4) &&
master->scan_number < cinfo->num_scans)
cinfo->Al = master->best_Al_chroma;
}
/* save value for later retrieval during printout of scans */
master->actual_Al[master->scan_number] = cinfo->Al;
} }
else else
#endif #endif
@@ -460,8 +448,6 @@ METHODDEF(void)
prepare_for_pass (j_compress_ptr cinfo) prepare_for_pass (j_compress_ptr cinfo)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master = (my_master_ptr) cinfo->master;
cinfo->master->trellis_passes =
master->pass_number < master->pass_number_scan_opt_base;
switch (master->pass_type) { switch (master->pass_type) {
case main_pass: case main_pass:
@@ -476,12 +462,12 @@ prepare_for_pass (j_compress_ptr cinfo)
(*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU); (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
} }
(*cinfo->fdct->start_pass) (cinfo); (*cinfo->fdct->start_pass) (cinfo);
(*cinfo->entropy->start_pass) (cinfo, (cinfo->optimize_coding || cinfo->master->trellis_quant) && !cinfo->arith_code); (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
(*cinfo->coef->start_pass) (cinfo, (*cinfo->coef->start_pass) (cinfo,
(master->total_passes > 1 ? (master->total_passes > 1 ?
JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
if (cinfo->optimize_coding || cinfo->master->trellis_quant) { if (cinfo->optimize_coding) {
/* No immediate data output; postpone writing frame/scan headers */ /* No immediate data output; postpone writing frame/scan headers */
master->pub.call_pass_startup = FALSE; master->pub.call_pass_startup = FALSE;
} else { } else {
@@ -514,13 +500,6 @@ prepare_for_pass (j_compress_ptr cinfo)
select_scan_parameters(cinfo); select_scan_parameters(cinfo);
per_scan_setup(cinfo); per_scan_setup(cinfo);
} }
if (cinfo->master->optimize_scans) {
master->saved_dest = cinfo->dest;
cinfo->dest = NULL;
master->scan_size[master->scan_number] = 0;
jpeg_mem_dest_internal(cinfo, &master->scan_buffer[master->scan_number], &master->scan_size[master->scan_number], JPOOL_IMAGE);
(*cinfo->dest->init_destination)(cinfo);
}
(*cinfo->entropy->start_pass) (cinfo, FALSE); (*cinfo->entropy->start_pass) (cinfo, FALSE);
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
/* We emit frame/scan headers now */ /* We emit frame/scan headers now */
@@ -529,24 +508,6 @@ prepare_for_pass (j_compress_ptr cinfo)
(*cinfo->marker->write_scan_header) (cinfo); (*cinfo->marker->write_scan_header) (cinfo);
master->pub.call_pass_startup = FALSE; master->pub.call_pass_startup = FALSE;
break; break;
case trellis_pass:
if (master->pass_number %
(cinfo->num_components * (cinfo->master->use_scans_in_trellis ? 4 : 2)) == 1 &&
cinfo->master->trellis_q_opt) {
int i, j;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
for (j = 1; j < DCTSIZE2; j++) {
cinfo->master->norm_src[i][j] = 0.0;
cinfo->master->norm_coef[i][j] = 0.0;
}
}
}
(*cinfo->entropy->start_pass) (cinfo, !cinfo->arith_code);
(*cinfo->coef->start_pass) (cinfo, JBUF_REQUANT);
master->pub.call_pass_startup = FALSE;
break;
default: default:
ERREXIT(cinfo, JERR_NOT_COMPILED); ERREXIT(cinfo, JERR_NOT_COMPILED);
} }
@@ -581,232 +542,6 @@ pass_startup (j_compress_ptr cinfo)
} }
LOCAL(void)
copy_buffer (j_compress_ptr cinfo, int scan_idx)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
unsigned long size = master->scan_size[scan_idx];
unsigned char * src = master->scan_buffer[scan_idx];
int i;
if (cinfo->err->trace_level > 0) {
fprintf(stderr, "SCAN ");
for (i = 0; i < cinfo->scan_info[scan_idx].comps_in_scan; i++)
fprintf(stderr, "%s%d", (i==0)?"":",", cinfo->scan_info[scan_idx].component_index[i]);
fprintf(stderr, ": %d %d", cinfo->scan_info[scan_idx].Ss, cinfo->scan_info[scan_idx].Se);
fprintf(stderr, " %d %d", cinfo->scan_info[scan_idx].Ah, master->actual_Al[scan_idx]);
fprintf(stderr, "\n");
}
while (size >= cinfo->dest->free_in_buffer)
{
MEMCOPY(cinfo->dest->next_output_byte, src, cinfo->dest->free_in_buffer);
src += cinfo->dest->free_in_buffer;
size -= cinfo->dest->free_in_buffer;
cinfo->dest->next_output_byte += cinfo->dest->free_in_buffer;
cinfo->dest->free_in_buffer = 0;
if (!(*cinfo->dest->empty_output_buffer)(cinfo))
ERREXIT(cinfo, JERR_UNSUPPORTED_SUSPEND);
}
MEMCOPY(cinfo->dest->next_output_byte, src, size);
cinfo->dest->next_output_byte += size;
cinfo->dest->free_in_buffer -= size;
}
LOCAL(void)
select_scans (j_compress_ptr cinfo, int next_scan_number)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
int base_scan_idx = 0;
int luma_freq_split_scan_start = cinfo->master->num_scans_luma_dc +
3 * cinfo->master->Al_max_luma + 2;
int chroma_freq_split_scan_start = cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc +
(6 * cinfo->master->Al_max_chroma + 4);
int passes_per_scan = cinfo->optimize_coding ? 2 : 1;
if (next_scan_number > 1 && next_scan_number <= luma_freq_split_scan_start) {
if ((next_scan_number - 1) % 3 == 2) {
int Al = (next_scan_number - 1) / 3;
int i;
unsigned long cost = 0;
cost += master->scan_size[next_scan_number-2];
cost += master->scan_size[next_scan_number-1];
for (i = 0; i < Al; i++)
cost += master->scan_size[3 + 3*i];
if (Al == 0 || cost < master->best_cost) {
master->best_cost = cost;
master->best_Al_luma = Al;
} else {
master->scan_number = luma_freq_split_scan_start - 1;
master->pass_number = passes_per_scan * (master->scan_number + 1) - 1 + master->pass_number_scan_opt_base;
}
}
} else if (next_scan_number > luma_freq_split_scan_start &&
next_scan_number <= cinfo->master->num_scans_luma) {
if (next_scan_number == luma_freq_split_scan_start + 1) {
master->best_freq_split_idx_luma = 0;
master->best_cost = master->scan_size[next_scan_number-1];
} else if ((next_scan_number - luma_freq_split_scan_start) % 2 == 1) {
int idx = (next_scan_number - luma_freq_split_scan_start) >> 1;
unsigned long cost = 0;
cost += master->scan_size[next_scan_number-2];
cost += master->scan_size[next_scan_number-1];
if (cost < master->best_cost) {
master->best_cost = cost;
master->best_freq_split_idx_luma = idx;
}
/* if after testing first 3, no split is the best, don't search further */
if ((idx == 2 && master->best_freq_split_idx_luma == 0) ||
(idx == 3 && master->best_freq_split_idx_luma != 2) ||
(idx == 4 && master->best_freq_split_idx_luma != 4)) {
master->scan_number = cinfo->master->num_scans_luma - 1;
master->pass_number = passes_per_scan * (master->scan_number + 1) - 1 + master->pass_number_scan_opt_base;
master->pub.is_last_pass = (master->pass_number == master->total_passes - 1);
}
}
} else if (cinfo->num_scans > cinfo->master->num_scans_luma) {
if (next_scan_number == cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc) {
base_scan_idx = cinfo->master->num_scans_luma;
master->interleave_chroma_dc = master->scan_size[base_scan_idx] <= master->scan_size[base_scan_idx+1] + master->scan_size[base_scan_idx+2];
} else if (next_scan_number > cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc &&
next_scan_number <= chroma_freq_split_scan_start) {
base_scan_idx = cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc;
if ((next_scan_number - base_scan_idx) % 6 == 4) {
int Al = (next_scan_number - base_scan_idx) / 6;
int i;
unsigned long cost = 0;
cost += master->scan_size[next_scan_number-4];
cost += master->scan_size[next_scan_number-3];
cost += master->scan_size[next_scan_number-2];
cost += master->scan_size[next_scan_number-1];
for (i = 0; i < Al; i++) {
cost += master->scan_size[base_scan_idx + 4 + 6*i];
cost += master->scan_size[base_scan_idx + 5 + 6*i];
}
if (Al == 0 || cost < master->best_cost) {
master->best_cost = cost;
master->best_Al_chroma = Al;
} else {
master->scan_number = chroma_freq_split_scan_start - 1;
master->pass_number = passes_per_scan * (master->scan_number + 1) - 1 + master->pass_number_scan_opt_base;
}
}
} else if (next_scan_number > chroma_freq_split_scan_start && next_scan_number <= cinfo->num_scans) {
if (next_scan_number == chroma_freq_split_scan_start + 2) {
master->best_freq_split_idx_chroma = 0;
master->best_cost = master->scan_size[next_scan_number-2];
master->best_cost += master->scan_size[next_scan_number-1];
} else if ((next_scan_number - chroma_freq_split_scan_start) % 4 == 2) {
int idx = (next_scan_number - chroma_freq_split_scan_start) >> 2;
unsigned long cost = 0;
cost += master->scan_size[next_scan_number-4];
cost += master->scan_size[next_scan_number-3];
cost += master->scan_size[next_scan_number-2];
cost += master->scan_size[next_scan_number-1];
if (cost < master->best_cost) {
master->best_cost = cost;
master->best_freq_split_idx_chroma = idx;
}
/* if after testing first 3, no split is the best, don't search further */
if ((idx == 2 && master->best_freq_split_idx_chroma == 0) ||
(idx == 3 && master->best_freq_split_idx_chroma != 2) ||
(idx == 4 && master->best_freq_split_idx_chroma != 4)) {
master->scan_number = cinfo->num_scans - 1;
master->pass_number = passes_per_scan * (master->scan_number + 1) - 1 + master->pass_number_scan_opt_base;
master->pub.is_last_pass = (master->pass_number == master->total_passes - 1);
}
}
}
}
if (master->scan_number == cinfo->num_scans - 1) {
int i, Al;
int min_Al = MIN(master->best_Al_luma, master->best_Al_chroma);
copy_buffer(cinfo, 0);
if (cinfo->num_scans > cinfo->master->num_scans_luma &&
cinfo->master->dc_scan_opt_mode != 0) {
base_scan_idx = cinfo->master->num_scans_luma;
if (master->interleave_chroma_dc && cinfo->master->dc_scan_opt_mode != 1)
copy_buffer(cinfo, base_scan_idx);
else {
copy_buffer(cinfo, base_scan_idx+1);
copy_buffer(cinfo, base_scan_idx+2);
}
}
if (master->best_freq_split_idx_luma == 0)
copy_buffer(cinfo, luma_freq_split_scan_start);
else {
copy_buffer(cinfo, luma_freq_split_scan_start+2*(master->best_freq_split_idx_luma-1)+1);
copy_buffer(cinfo, luma_freq_split_scan_start+2*(master->best_freq_split_idx_luma-1)+2);
}
/* copy the LSB refinements as well */
for (Al = master->best_Al_luma-1; Al >= min_Al; Al--)
copy_buffer(cinfo, 3 + 3*Al);
if (cinfo->num_scans > cinfo->master->num_scans_luma) {
if (master->best_freq_split_idx_chroma == 0) {
copy_buffer(cinfo, chroma_freq_split_scan_start);
copy_buffer(cinfo, chroma_freq_split_scan_start+1);
}
else {
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+2);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+3);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+4);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+5);
}
base_scan_idx = cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc;
for (Al = master->best_Al_chroma-1; Al >= min_Al; Al--) {
copy_buffer(cinfo, base_scan_idx + 6*Al + 4);
copy_buffer(cinfo, base_scan_idx + 6*Al + 5);
}
}
for (Al = min_Al-1; Al >= 0; Al--) {
copy_buffer(cinfo, 3 + 3*Al);
if (cinfo->num_scans > cinfo->master->num_scans_luma) {
copy_buffer(cinfo, base_scan_idx + 6*Al + 4);
copy_buffer(cinfo, base_scan_idx + 6*Al + 5);
}
}
/* free the memory allocated for buffers */
for (i = 0; i < cinfo->num_scans; i++)
if (master->scan_buffer[i])
free(master->scan_buffer[i]);
}
}
/* /*
* Finish up at end of pass. * Finish up at end of pass.
*/ */
@@ -827,54 +562,20 @@ finish_pass_master (j_compress_ptr cinfo)
/* next pass is either output of scan 0 (after optimization) /* next pass is either output of scan 0 (after optimization)
* or output of scan 1 (if no optimization). * or output of scan 1 (if no optimization).
*/ */
if (cinfo->master->trellis_quant)
master->pass_type = trellis_pass;
else {
master->pass_type = output_pass; master->pass_type = output_pass;
if (! cinfo->optimize_coding) if (! cinfo->optimize_coding)
master->scan_number++; master->scan_number++;
}
break; break;
case huff_opt_pass: case huff_opt_pass:
/* next pass is always output of current scan */ /* next pass is always output of current scan */
master->pass_type = (master->pass_number < master->pass_number_scan_opt_base-1) ? trellis_pass : output_pass; master->pass_type = output_pass;
break; break;
case output_pass: case output_pass:
/* next pass is either optimization or output of next scan */ /* next pass is either optimization or output of next scan */
if (cinfo->optimize_coding) if (cinfo->optimize_coding)
master->pass_type = huff_opt_pass; master->pass_type = huff_opt_pass;
if (cinfo->master->optimize_scans) {
(*cinfo->dest->term_destination)(cinfo);
cinfo->dest = master->saved_dest;
select_scans(cinfo, master->scan_number + 1);
}
master->scan_number++; master->scan_number++;
break; break;
case trellis_pass:
if (cinfo->optimize_coding)
master->pass_type = huff_opt_pass;
else
master->pass_type = (master->pass_number < master->pass_number_scan_opt_base-1) ? trellis_pass : output_pass;
if ((master->pass_number + 1) %
(cinfo->num_components * (cinfo->master->use_scans_in_trellis ? 4 : 2)) == 0 &&
cinfo->master->trellis_q_opt) {
int i, j;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
for (j = 1; j < DCTSIZE2; j++) {
if (cinfo->master->norm_coef[i][j] != 0.0) {
int q = (int)(cinfo->master->norm_src[i][j] /
cinfo->master->norm_coef[i][j] + 0.5);
if (q > 254) q = 254;
if (q < 1) q = 1;
cinfo->quant_tbl_ptrs[i]->quantval[j] = q;
}
}
}
}
break;
} }
master->pass_number++; master->pass_number++;
@@ -888,13 +589,16 @@ finish_pass_master (j_compress_ptr cinfo)
GLOBAL(void) GLOBAL(void)
jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
{ {
my_master_ptr master = (my_master_ptr) cinfo->master; my_master_ptr master;
master = (my_master_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
sizeof(my_comp_master));
cinfo->master = (struct jpeg_comp_master *) master;
master->pub.prepare_for_pass = prepare_for_pass; master->pub.prepare_for_pass = prepare_for_pass;
master->pub.pass_startup = pass_startup; master->pub.pass_startup = pass_startup;
master->pub.finish_pass = finish_pass_master; master->pub.finish_pass = finish_pass_master;
master->pub.is_last_pass = FALSE; master->pub.is_last_pass = FALSE;
master->pub.call_pass_startup = FALSE;
/* Validate parameters, determine derived values */ /* Validate parameters, determine derived values */
initial_setup(cinfo, transcode_only); initial_setup(cinfo, transcode_only);
@@ -932,25 +636,4 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
master->total_passes = cinfo->num_scans; master->total_passes = cinfo->num_scans;
master->jpeg_version = PACKAGE_NAME " version " VERSION " (build " BUILD ")"; master->jpeg_version = PACKAGE_NAME " version " VERSION " (build " BUILD ")";
master->pass_number_scan_opt_base = 0;
if (cinfo->master->trellis_quant) {
if (cinfo->optimize_coding)
master->pass_number_scan_opt_base =
((cinfo->master->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components *
cinfo->master->trellis_num_loops;
else
master->pass_number_scan_opt_base =
((cinfo->master->use_scans_in_trellis) ? 2 : 1) * cinfo->num_components *
cinfo->master->trellis_num_loops + 1;
master->total_passes += master->pass_number_scan_opt_base;
}
if (cinfo->master->optimize_scans) {
int i;
master->best_Al_chroma = 0;
for (i = 0; i < cinfo->num_scans; i++)
master->scan_buffer[i] = NULL;
}
} }

View File

@@ -1,56 +0,0 @@
/*
* jcmaster.h
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains the master control structures for the JPEG compressor.
*/
/* Private state */
typedef enum {
main_pass, /* input data, also do first output step */
huff_opt_pass, /* Huffman code optimization pass */
output_pass, /* data output pass */
trellis_pass /* trellis quantization pass */
} c_pass_type;
typedef struct {
struct jpeg_comp_master pub; /* public fields */
c_pass_type pass_type; /* the type of the current pass */
int pass_number; /* # of passes completed */
int total_passes; /* total # of passes needed */
int scan_number; /* current index in scan_info[] */
/* fields for scan optimisation */
int pass_number_scan_opt_base; /* pass number where scan optimization begins */
unsigned char * scan_buffer[64]; /* buffer for a given scan */
unsigned long scan_size[64]; /* size for a given scan */
int actual_Al[64]; /* actual value of Al used for a scan */
unsigned long best_cost; /* bit count for best frequency split */
int best_freq_split_idx_luma; /* index for best frequency split (luma) */
int best_freq_split_idx_chroma; /* index for best frequency split (chroma) */
int best_Al_luma; /* best value for Al found in scan search (luma) */
int best_Al_chroma; /* best value for Al found in scan search (luma) */
boolean interleave_chroma_dc; /* indicate whether to interleave chroma DC scans */
struct jpeg_destination_mgr * saved_dest; /* saved value of cinfo->dest */
/*
* This is here so we can add libjpeg-turbo version/build information to the
* global string table without introducing a new global symbol. Adding this
* information to the global string table allows one to examine a binary
* object and determine which version of libjpeg-turbo it was built from or
* linked against.
*/
const char *jpeg_version;
} my_comp_master;
typedef my_comp_master * my_master_ptr;

View File

@@ -71,6 +71,3 @@
/* Define to `unsigned int' if <sys/types.h> does not define. */ /* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t #undef size_t
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T

View File

@@ -115,7 +115,6 @@ typedef unsigned char boolean;
/* These defines indicate which image (non-JPEG) file formats are allowed. */ /* These defines indicate which image (non-JPEG) file formats are allowed. */
#define PNG_SUPPORTED /* PNG image file format */
#define BMP_SUPPORTED /* BMP image file format */ #define BMP_SUPPORTED /* BMP image file format */
#define GIF_SUPPORTED /* GIF image file format */ #define GIF_SUPPORTED /* GIF image file format */
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ #define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */

View File

@@ -1,6 +1,9 @@
/* libjpeg-turbo build number */ /* libjpeg-turbo build number */
#undef BUILD #undef BUILD
/* Compiler's inline keyword */
#undef inline
/* How to obtain function inlining. */ /* How to obtain function inlining. */
#undef INLINE #undef INLINE

477
jcparam.c
View File

@@ -6,9 +6,8 @@
* Modified 2003-2008 by Guido Vollbeding. * Modified 2003-2008 by Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, D. R. Commander. * Copyright (C) 2009-2011, D. R. Commander.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains optional default-setting code for the JPEG compressor. * This file contains optional default-setting code for the JPEG compressor.
* Applications do not have to use this file, but those that don't use it * Applications do not have to use this file, but those that don't use it
@@ -70,10 +69,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
* The spec says that the values given produce "good" quality, and * The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality. * when divided by 2, "very good" quality.
*/ */
static const unsigned int std_luminance_quant_tbl[9][DCTSIZE2] = { static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
{
/* JPEG Annex K
*/
16, 11, 10, 16, 24, 40, 51, 61, 16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55, 12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56, 14, 13, 16, 24, 40, 57, 69, 56,
@@ -82,105 +78,8 @@ static const unsigned int std_luminance_quant_tbl[9][DCTSIZE2] = {
24, 35, 55, 64, 81, 104, 113, 92, 24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101, 49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99 72, 92, 95, 98, 112, 100, 103, 99
},
{
/* flat
*/
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
},
{
12, 17, 20, 21, 30, 34, 56, 63,
18, 20, 20, 26, 28, 51, 61, 55,
19, 20, 21, 26, 33, 58, 69, 55,
26, 26, 26, 30, 46, 87, 86, 66,
31, 33, 36, 40, 46, 96, 100, 73,
40, 35, 46, 62, 81, 100, 111, 91,
46, 66, 76, 86, 102, 121, 120, 101,
68, 90, 90, 96, 113, 102, 105, 103
},
{
/* From http://www.imagemagick.org/discourse-server/viewtopic.php?f=22&t=20333&p=98008#p98008
*/
16, 16, 16, 18, 25, 37, 56, 85,
16, 17, 20, 27, 34, 40, 53, 75,
16, 20, 24, 31, 43, 62, 91, 135,
18, 27, 31, 40, 53, 74, 106, 156,
25, 34, 43, 53, 69, 94, 131, 189,
37, 40, 62, 74, 94, 124, 169, 238,
56, 53, 91, 106, 131, 169, 226, 311,
85, 75, 135, 156, 189, 238, 311, 418
},
{
9, 10, 12, 14, 27, 32, 51, 62,
11, 12, 14, 19, 27, 44, 59, 73,
12, 14, 18, 25, 42, 59, 79, 78,
17, 18, 25, 42, 61, 92, 87, 92,
23, 28, 42, 75, 79, 112, 112, 99,
40, 42, 59, 84, 88, 124, 132, 111,
42, 64, 78, 95, 105, 126, 125, 99,
70, 75, 100, 102, 116, 100, 107, 98
},
{
/* Relevance of human vision to JPEG-DCT compression (1992) Klein, Silverstein and Carney.
*/
10, 12, 14, 19, 26, 38, 57, 86,
12, 18, 21, 28, 35, 41, 54, 76,
14, 21, 25, 32, 44, 63, 92, 136,
19, 28, 32, 41, 54, 75, 107, 157,
26, 35, 44, 54, 70, 95, 132, 190,
38, 41, 63, 75, 95, 125, 170, 239,
57, 54, 92, 107, 132, 170, 227, 312,
86, 76, 136, 157, 190, 239, 312, 419
},
{
/* DCTune perceptual optimization of compressed dental X-Rays (1997) Watson, Taylor, Borthwick
*/
7, 8, 10, 14, 23, 44, 95, 241,
8, 8, 11, 15, 25, 47, 102, 255,
10, 11, 13, 19, 31, 58, 127, 255,
14, 15, 19, 27, 44, 83, 181, 255,
23, 25, 31, 44, 72, 136, 255, 255,
44, 47, 58, 83, 136, 255, 255, 255,
95, 102, 127, 181, 255, 255, 255, 255,
241, 255, 255, 255, 255, 255, 255, 255
},
{
/* A visual detection model for DCT coefficient quantization (12/9/93) Ahumada, Watson, Peterson
*/
15, 11, 11, 12, 15, 19, 25, 32,
11, 13, 10, 10, 12, 15, 19, 24,
11, 10, 14, 14, 16, 18, 22, 27,
12, 10, 14, 18, 21, 24, 28, 33,
15, 12, 16, 21, 26, 31, 36, 42,
19, 15, 18, 24, 31, 38, 45, 53,
25, 19, 22, 28, 36, 45, 55, 65,
32, 24, 27, 33, 42, 53, 65, 77
},
{
/* An improved detection model for DCT coefficient quantization (1993) Peterson, Ahumada and Watson
*/
14, 10, 11, 14, 19, 25, 34, 45,
10, 11, 11, 12, 15, 20, 26, 33,
11, 11, 15, 18, 21, 25, 31, 38,
14, 12, 18, 24, 28, 33, 39, 47,
19, 15, 21, 28, 36, 43, 51, 59,
25, 20, 25, 33, 43, 54, 64, 74,
34, 26, 31, 39, 51, 64, 77, 91,
45, 33, 38, 47, 59, 74, 91, 108
}
}; };
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
static const unsigned int std_chrominance_quant_tbl[9][DCTSIZE2] = {
{
/* JPEG Annex K
*/
17, 18, 24, 47, 99, 99, 99, 99, 17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99,
@@ -189,105 +88,9 @@ static const unsigned int std_chrominance_quant_tbl[9][DCTSIZE2] = {
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99 99, 99, 99, 99, 99, 99, 99, 99
},
{
/* flat
*/
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
},
{
8, 12, 15, 15, 86, 96, 96, 98,
13, 13, 15, 26, 90, 96, 99, 98,
12, 15, 18, 96, 99, 99, 99, 99,
17, 16, 90, 96, 99, 99, 99, 99,
96, 96, 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
},
{
/* From http://www.imagemagick.org/discourse-server/viewtopic.php?f=22&t=20333&p=98008#p98008
*/
16, 16, 16, 18, 25, 37, 56, 85,
16, 17, 20, 27, 34, 40, 53, 75,
16, 20, 24, 31, 43, 62, 91, 135,
18, 27, 31, 40, 53, 74, 106, 156,
25, 34, 43, 53, 69, 94, 131, 189,
37, 40, 62, 74, 94, 124, 169, 238,
56, 53, 91, 106, 131, 169, 226, 311,
85, 75, 135, 156, 189, 238, 311, 418
},
{
9, 10, 17, 19, 62, 89, 91, 97,
12, 13, 18, 29, 84, 91, 88, 98,
14, 19, 29, 93, 95, 95, 98, 97,
20, 26, 84, 88, 95, 95, 98, 94,
26, 86, 91, 93, 97, 99, 98, 99,
99, 100, 98, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
97, 97, 99, 99, 99, 99, 97, 99
},
{
/* Relevance of human vision to JPEG-DCT compression (1992) Klein, Silverstein and Carney.
* Copied from luma
*/
10, 12, 14, 19, 26, 38, 57, 86,
12, 18, 21, 28, 35, 41, 54, 76,
14, 21, 25, 32, 44, 63, 92, 136,
19, 28, 32, 41, 54, 75, 107, 157,
26, 35, 44, 54, 70, 95, 132, 190,
38, 41, 63, 75, 95, 125, 170, 239,
57, 54, 92, 107, 132, 170, 227, 312,
86, 76, 136, 157, 190, 239, 312, 419
},
{
/* DCTune perceptual optimization of compressed dental X-Rays (1997) Watson, Taylor, Borthwick
* Copied from luma
*/
7, 8, 10, 14, 23, 44, 95, 241,
8, 8, 11, 15, 25, 47, 102, 255,
10, 11, 13, 19, 31, 58, 127, 255,
14, 15, 19, 27, 44, 83, 181, 255,
23, 25, 31, 44, 72, 136, 255, 255,
44, 47, 58, 83, 136, 255, 255, 255,
95, 102, 127, 181, 255, 255, 255, 255,
241, 255, 255, 255, 255, 255, 255, 255
},
{
/* A visual detection model for DCT coefficient quantization (12/9/93) Ahumada, Watson, Peterson
* Copied from luma
*/
15, 11, 11, 12, 15, 19, 25, 32,
11, 13, 10, 10, 12, 15, 19, 24,
11, 10, 14, 14, 16, 18, 22, 27,
12, 10, 14, 18, 21, 24, 28, 33,
15, 12, 16, 21, 26, 31, 36, 42,
19, 15, 18, 24, 31, 38, 45, 53,
25, 19, 22, 28, 36, 45, 55, 65,
32, 24, 27, 33, 42, 53, 65, 77
},
{
/* An improved detection model for DCT coefficient quantization (1993) Peterson, Ahumada and Watson
* Copied from luma
*/
14, 10, 11, 14, 19, 25, 34, 45,
10, 11, 11, 12, 15, 20, 26, 33,
11, 11, 15, 18, 21, 25, 31, 38,
14, 12, 18, 24, 28, 33, 39, 47,
19, 15, 21, 28, 36, 43, 51, 59,
25, 20, 25, 33, 43, 54, 64, 74,
34, 26, 31, 39, 51, 64, 77, 91,
45, 33, 38, 47, 59, 74, 91, 108
}
}; };
#if JPEG_LIB_VERSION >= 70 #if JPEG_LIB_VERSION >= 70
GLOBAL(void) GLOBAL(void)
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline) jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
@@ -297,9 +100,9 @@ jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
*/ */
{ {
/* Set up two quantization tables using the specified scaling */ /* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl[cinfo->master->quant_tbl_master_idx], jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
cinfo->q_scale_factor[0], force_baseline); cinfo->q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl[cinfo->master->quant_tbl_master_idx], jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
cinfo->q_scale_factor[1], force_baseline); cinfo->q_scale_factor[1], force_baseline);
} }
#endif #endif
@@ -315,29 +118,23 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
*/ */
{ {
/* Set up two quantization tables using the specified scaling */ /* Set up two quantization tables using the specified scaling */
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl[cinfo->master->quant_tbl_master_idx], jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
scale_factor, force_baseline); scale_factor, force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl[cinfo->master->quant_tbl_master_idx], jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
scale_factor, force_baseline); scale_factor, force_baseline);
} }
GLOBAL(int) GLOBAL(int)
jpeg_quality_scaling (int quality) jpeg_quality_scaling (int quality)
{
return jpeg_float_quality_scaling(quality);
}
GLOBAL(float)
jpeg_float_quality_scaling(float quality)
/* Convert a user-specified quality rating to a percentage scaling factor /* Convert a user-specified quality rating to a percentage scaling factor
* for an underlying quantization table, using our recommended scaling curve. * for an underlying quantization table, using our recommended scaling curve.
* The input 'quality' factor should be 0 (terrible) to 100 (very good). * The input 'quality' factor should be 0 (terrible) to 100 (very good).
*/ */
{ {
/* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */ /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
if (quality <= 0.f) quality = 1.f; if (quality <= 0) quality = 1;
if (quality > 100.f) quality = 100.f; if (quality > 100) quality = 100;
/* The basic table is used as-is (scaling 100) for a quality of 50. /* The basic table is used as-is (scaling 100) for a quality of 50.
* Qualities 50..100 are converted to scaling percentage 200 - 2*Q; * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
@@ -345,10 +142,10 @@ jpeg_float_quality_scaling(float quality)
* to make all the table entries 1 (hence, minimum quantization loss). * to make all the table entries 1 (hence, minimum quantization loss).
* Qualities 1..50 are converted to scaling percentage 5000/Q. * Qualities 1..50 are converted to scaling percentage 5000/Q.
*/ */
if (quality < 50.f) if (quality < 50)
quality = 5000.f / quality; quality = 5000 / quality;
else else
quality = 200.f - quality*2.f; quality = 200 - quality*2;
return quality; return quality;
} }
@@ -427,18 +224,8 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Use Huffman coding, not arithmetic coding, by default */ /* Use Huffman coding, not arithmetic coding, by default */
cinfo->arith_code = FALSE; cinfo->arith_code = FALSE;
#ifdef ENTROPY_OPT_SUPPORTED
if (cinfo->master->compress_profile == JCP_MAX_COMPRESSION)
/* By default, do extra passes to optimize entropy coding */
cinfo->optimize_coding = TRUE;
else
/* By default, don't do extra passes to optimize entropy coding */ /* By default, don't do extra passes to optimize entropy coding */
cinfo->optimize_coding = FALSE; cinfo->optimize_coding = FALSE;
#else
/* By default, don't do extra passes to optimize entropy coding */
cinfo->optimize_coding = FALSE;
#endif
/* The standard Huffman tables are only valid for 8-bit data precision. /* The standard Huffman tables are only valid for 8-bit data precision.
* If the precision is higher, force optimization on so that usable * If the precision is higher, force optimization on so that usable
* tables will be computed. This test can be removed if default tables * tables will be computed. This test can be removed if default tables
@@ -455,9 +242,6 @@ jpeg_set_defaults (j_compress_ptr cinfo)
cinfo->do_fancy_downsampling = TRUE; cinfo->do_fancy_downsampling = TRUE;
#endif #endif
cinfo->master->overshoot_deringing =
cinfo->master->compress_profile == JCP_MAX_COMPRESSION;
/* No input smoothing */ /* No input smoothing */
cinfo->smoothing_factor = 0; cinfo->smoothing_factor = 0;
@@ -486,31 +270,6 @@ jpeg_set_defaults (j_compress_ptr cinfo)
/* Choose JPEG colorspace based on input space, set defaults accordingly */ /* Choose JPEG colorspace based on input space, set defaults accordingly */
jpeg_default_colorspace(cinfo); jpeg_default_colorspace(cinfo);
cinfo->master->dc_scan_opt_mode = 1;
#ifdef C_PROGRESSIVE_SUPPORTED
if (cinfo->master->compress_profile == JCP_MAX_COMPRESSION) {
cinfo->master->optimize_scans = TRUE;
jpeg_simple_progression(cinfo);
} else
cinfo->master->optimize_scans = FALSE;
#endif
cinfo->master->trellis_quant =
cinfo->master->compress_profile == JCP_MAX_COMPRESSION;
cinfo->master->lambda_log_scale1 = 14.75;
cinfo->master->lambda_log_scale2 = 16.5;
cinfo->master->quant_tbl_master_idx =
cinfo->master->compress_profile == JCP_MAX_COMPRESSION ? 3 : 0;
cinfo->master->use_lambda_weight_tbl = TRUE;
cinfo->master->use_scans_in_trellis = FALSE;
cinfo->master->trellis_freq_split = 8;
cinfo->master->trellis_num_loops = 1;
cinfo->master->trellis_q_opt = FALSE;
cinfo->master->trellis_quant_dc = TRUE;
cinfo->master->trellis_delta_dc_weight = 0.0;
} }
@@ -659,22 +418,6 @@ fill_a_scan (jpeg_scan_info *scanptr, int ci,
return scanptr; return scanptr;
} }
LOCAL(jpeg_scan_info *)
fill_a_scan_pair (jpeg_scan_info * scanptr, int ci,
int Ss, int Se, int Ah, int Al)
/* Support routine: generate one scan for pair of components */
{
scanptr->comps_in_scan = 2;
scanptr->component_index[0] = ci;
scanptr->component_index[1] = ci + 1;
scanptr->Ss = Ss;
scanptr->Se = Se;
scanptr->Ah = Ah;
scanptr->Al = Al;
scanptr++;
return scanptr;
}
LOCAL(jpeg_scan_info *) LOCAL(jpeg_scan_info *)
fill_scans (jpeg_scan_info *scanptr, int ncomps, fill_scans (jpeg_scan_info *scanptr, int ncomps,
int Ss, int Se, int Ah, int Al) int Ss, int Se, int Ah, int Al)
@@ -717,132 +460,6 @@ fill_dc_scans (jpeg_scan_info *scanptr, int ncomps, int Ah, int Al)
} }
/*
* List of scans to be tested
* cinfo->num_components and cinfo->jpeg_color_space must be correct.
*/
LOCAL(boolean)
jpeg_search_progression (j_compress_ptr cinfo)
{
int ncomps = cinfo->num_components;
int nscans;
jpeg_scan_info * scanptr;
int Al;
int frequency_split[] = { 2, 8, 5, 12, 18 };
int i;
/* Safety check to ensure start_compress not called yet. */
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Figure space needed for script. Calculation must match code below! */
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
/* Custom script for YCbCr color images. */
nscans = 64;
} else if (ncomps == 1) {
nscans = 23;
} else {
cinfo->master->num_scans_luma = 0;
return FALSE;
}
/* Allocate space for script.
* We need to put it in the permanent pool in case the application performs
* multiple compressions without changing the settings. To avoid a memory
* leak if jpeg_simple_progression is called repeatedly for the same JPEG
* object, we try to re-use previously allocated space, and we allocate
* enough space to handle YCbCr even if initially asked for grayscale.
*/
if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
cinfo->script_space_size = MAX(nscans, 64);
cinfo->script_space = (jpeg_scan_info *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
cinfo->script_space_size * sizeof(jpeg_scan_info));
}
scanptr = cinfo->script_space;
cinfo->scan_info = scanptr;
cinfo->num_scans = nscans;
cinfo->master->Al_max_luma = 3;
cinfo->master->num_scans_luma_dc = 1;
cinfo->master->num_frequency_splits = 5;
cinfo->master->num_scans_luma =
cinfo->master->num_scans_luma_dc + (3 * cinfo->master->Al_max_luma + 2) +
(2 * cinfo->master->num_frequency_splits + 1);
/* 23 scans for luma */
/* 1 scan for DC */
/* 11 scans to determine successive approximation */
/* 11 scans to determine frequency approximation */
/* after 12 scans need to update following 11 */
/* after 23 scans need to determine which to keep */
/* last 4 done conditionally */
/* luma DC by itself */
if (cinfo->master->dc_scan_opt_mode == 0)
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
else
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 0);
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 0);
for (Al = 0; Al < cinfo->master->Al_max_luma; Al++) {
scanptr = fill_a_scan(scanptr, 0, 1, 63, Al+1, Al);
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, Al+1);
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, Al+1);
}
scanptr = fill_a_scan(scanptr, 0, 1, 63, 0, 0);
for (i = 0; i < cinfo->master->num_frequency_splits; i++) {
scanptr = fill_a_scan(scanptr, 0, 1, frequency_split[i], 0, 0);
scanptr = fill_a_scan(scanptr, 0, frequency_split[i]+1, 63, 0, 0);
}
if (ncomps == 1) {
cinfo->master->Al_max_chroma = 0;
cinfo->master->num_scans_chroma_dc = 0;
} else {
cinfo->master->Al_max_chroma = 2;
cinfo->master->num_scans_chroma_dc = 3;
/* 41 scans for chroma */
/* chroma DC combined */
scanptr = fill_a_scan_pair(scanptr, 1, 0, 0, 0, 0);
/* chroma DC separate */
scanptr = fill_a_scan(scanptr, 1, 0, 0, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 0, 0, 0, 0);
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, 0);
scanptr = fill_a_scan(scanptr, 1, 9, 63, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, 0);
for (Al = 0; Al < cinfo->master->Al_max_chroma; Al++) {
scanptr = fill_a_scan(scanptr, 1, 1, 63, Al+1, Al);
scanptr = fill_a_scan(scanptr, 2, 1, 63, Al+1, Al);
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, Al+1);
scanptr = fill_a_scan(scanptr, 1, 9, 63, 0, Al+1);
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, Al+1);
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, Al+1);
}
scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 0);
for (i = 0; i < cinfo->master->num_frequency_splits; i++) {
scanptr = fill_a_scan(scanptr, 1, 1, frequency_split[i], 0, 0);
scanptr = fill_a_scan(scanptr, 1, frequency_split[i]+1, 63, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 1, frequency_split[i], 0, 0);
scanptr = fill_a_scan(scanptr, 2, frequency_split[i]+1, 63, 0, 0);
}
}
return TRUE;
}
/* /*
* Create a recommended progressive-JPEG script. * Create a recommended progressive-JPEG script.
* cinfo->num_components and cinfo->jpeg_color_space must be correct. * cinfo->num_components and cinfo->jpeg_color_space must be correct.
@@ -851,44 +468,25 @@ jpeg_search_progression (j_compress_ptr cinfo)
GLOBAL(void) GLOBAL(void)
jpeg_simple_progression (j_compress_ptr cinfo) jpeg_simple_progression (j_compress_ptr cinfo)
{ {
int ncomps; int ncomps = cinfo->num_components;
int nscans; int nscans;
jpeg_scan_info *scanptr; jpeg_scan_info *scanptr;
if (cinfo->master->optimize_scans) {
if (jpeg_search_progression(cinfo) == TRUE)
return;
}
/* Safety check to ensure start_compress not called yet. */ /* Safety check to ensure start_compress not called yet. */
if (cinfo->global_state != CSTATE_START) if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Figure space needed for script. Calculation must match code below! */ /* Figure space needed for script. Calculation must match code below! */
ncomps = cinfo->num_components;
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
/* Custom script for YCbCr color images. */ /* Custom script for YCbCr color images. */
if (cinfo->master->dc_scan_opt_mode == 0) { nscans = 10;
nscans = 8; /* 1 DC scan for all components */
} else if (cinfo->master->dc_scan_opt_mode == 1) {
nscans = 10; /* 1 DC scan for each component */
} else {
nscans = 9; /* 1 DC scan for luminance and 1 DC scan for chroma */
}
} else { } else {
/* All-purpose script for other color spaces. */ /* All-purpose script for other color spaces. */
if (cinfo->master->compress_profile == JCP_MAX_COMPRESSION) {
if (ncomps > MAX_COMPS_IN_SCAN) if (ncomps > MAX_COMPS_IN_SCAN)
nscans = 5 * ncomps; /* 2 DC + 4 AC scans per component */
else
nscans = 1 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
} else {
if (ncomps > MAX_COMPS_IN_SCAN)
nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */
else else
nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
} }
}
/* Allocate space for script. /* Allocate space for script.
* We need to put it in the permanent pool in case the application performs * We need to put it in the permanent pool in case the application performs
@@ -909,36 +507,7 @@ jpeg_simple_progression (j_compress_ptr cinfo)
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) { if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
/* Custom script for YCbCr color images. */ /* Custom script for YCbCr color images. */
if (cinfo->master->compress_profile == JCP_MAX_COMPRESSION) {
/* scan defined in jpeg_scan_rgb.txt in jpgcrush */
/* Initial DC scan */ /* Initial DC scan */
if (cinfo->master->dc_scan_opt_mode == 0) {
/* 1 DC scan for all components */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
} else if (cinfo->master->dc_scan_opt_mode == 1) {
/* 1 DC scan for each component */
scanptr = fill_a_scan(scanptr, 0, 0, 0, 0, 0);
scanptr = fill_a_scan(scanptr, 1, 0, 0, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 0, 0, 0, 0);
} else {
/* 1 DC scan for luminance and 1 DC scan for chroma */
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
scanptr = fill_a_scan_pair(scanptr, 1, 0, 0, 0, 0);
}
/* Low frequency AC scans */
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 2);
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, 0);
/* Complete spectral selection for luma AC */
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 2);
/* Finish luma AC successive approximation */
scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
/* Complete spectral selection for chroma AC */
scanptr = fill_a_scan(scanptr, 1, 9, 63, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, 0);
} else {
/* Initial DC scan */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
/* Initial AC scan: get some luma data out in a hurry */ /* Initial AC scan: get some luma data out in a hurry */
scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2); scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
@@ -956,22 +525,9 @@ jpeg_simple_progression (j_compress_ptr cinfo)
scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0); scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
/* Luma bottom bit comes last since it's usually largest scan */ /* Luma bottom bit comes last since it's usually largest scan */
scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0); scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
}
} else { } else {
/* All-purpose script for other color spaces. */ /* All-purpose script for other color spaces. */
if (cinfo->master->compress_profile == JCP_MAX_COMPRESSION) {
/* scan defined in jpeg_scan_bw.txt in jpgcrush */
/* DC component, no successive approximation */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
/* Successive approximation first pass */ /* Successive approximation first pass */
scanptr = fill_scans(scanptr, ncomps, 1, 8, 0, 2);
scanptr = fill_scans(scanptr, ncomps, 9, 63, 0, 2);
/* Successive approximation second pass */
scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
/* Successive approximation final pass */
scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
} else {
/* Successive approximation first pass */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 1); scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2); scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2); scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
@@ -982,6 +538,5 @@ jpeg_simple_progression (j_compress_ptr cinfo)
scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0); scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
} }
} }
}
#endif /* C_PROGRESSIVE_SUPPORTED */ #endif /* C_PROGRESSIVE_SUPPORTED */

View File

@@ -3,11 +3,10 @@
* *
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1995-1997, Thomas G. Lane. * Copyright (C) 1995-1997, Thomas G. Lane.
* It was modified by The libjpeg-turbo Project to include only code relevant * libjpeg-turbo Modifications:
* to libjpeg-turbo. * Copyright (C) 2015, D. R. Commander.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains Huffman entropy encoding routines for progressive JPEG. * This file contains Huffman entropy encoding routines for progressive JPEG.
* *
@@ -171,14 +170,6 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * sizeof(long)); 257 * sizeof(long));
MEMZERO(entropy->count_ptrs[tbl], 257 * sizeof(long)); MEMZERO(entropy->count_ptrs[tbl], 257 * sizeof(long));
if (cinfo->master->trellis_passes) {
/* When generating tables for trellis passes, make sure that all */
/* codewords have an assigned length */
int i, j;
for (i = 0; i < 16; i++)
for (j = 0; j < 12; j++)
entropy->count_ptrs[tbl][16 * i + j] = 1;
}
} else { } else {
/* Compute derived values for Huffman table */ /* Compute derived values for Huffman table */
/* We may do this more than once for a table, but it's not expensive */ /* We may do this more than once for a table, but it's not expensive */
@@ -480,8 +471,6 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
int Se = cinfo->Se; int Se = cinfo->Se;
int Al = cinfo->Al; int Al = cinfo->Al;
JBLOCKROW block; JBLOCKROW block;
int deadzone = (1 << Al) - 1;
int sign;
entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->next_output_byte = cinfo->dest->next_output_byte;
entropy->free_in_buffer = cinfo->dest->free_in_buffer; entropy->free_in_buffer = cinfo->dest->free_in_buffer;
@@ -499,24 +488,29 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
r = 0; /* r = run length of zeros */ r = 0; /* r = run length of zeros */
for (k = cinfo->Ss; k <= Se; k++) { for (k = cinfo->Ss; k <= Se; k++) {
temp = (*block)[jpeg_natural_order[k]]; if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
if ((unsigned)(temp + deadzone) <= 2*deadzone) {
r++; r++;
continue; continue;
} }
/* We must apply the point transform by Al. For AC coefficients this /* We must apply the point transform by Al. For AC coefficients this
* is an integer division with rounding towards 0. The code is * 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). * interwoven with finding the abs value (temp) and output bits (temp2).
*/ */
#ifdef RIGHT_SHIFT_IS_UNSIGNED if (temp < 0) {
sign = (temp < 0) ? ~0 : 0; temp = -temp; /* temp is abs value of input */
#else temp >>= Al; /* apply the point transform */
sign = temp >> (8*sizeof(temp)-1); /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
#endif temp2 = ~temp;
temp += sign; } else {
temp = (temp ^ sign) >> Al; temp >>= Al; /* apply the point transform */
temp2 = temp ^ sign; temp2 = temp;
}
/* Watch out for case that nonzero coef is zero after point transform */
if (temp == 0) {
r++;
continue;
}
/* Emit any pending EOBRUN */ /* Emit any pending EOBRUN */
if (entropy->EOBRUN > 0) if (entropy->EOBRUN > 0)

View File

@@ -6,9 +6,8 @@
* Modified 2000-2009 by Guido Vollbeding. * Modified 2000-2009 by Guido Vollbeding.
* It was modified by The libjpeg-turbo Project to include only code relevant * It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo. * to libjpeg-turbo.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains library routines for transcoding compression, * This file contains library routines for transcoding compression,
* that is, writing raw DCT coefficient arrays to an output JPEG file. * that is, writing raw DCT coefficient arrays to an output JPEG file.
@@ -42,10 +41,6 @@ LOCAL(void) transencode_coef_controller
GLOBAL(void) GLOBAL(void)
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays) jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
{ {
/* setting up scan optimisation pattern failed, disable scan optimisation */
if (cinfo->master->num_scans_luma == 0)
cinfo->master->optimize_scans = FALSE;
if (cinfo->global_state != CSTATE_START) if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
/* Mark all tables to be written */ /* Mark all tables to be written */
@@ -69,7 +64,7 @@ jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
*/ */
GLOBAL(void) GLOBAL(void)
jpeg_copy_critical_parameters (const j_decompress_ptr srcinfo, jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
j_compress_ptr dstinfo) j_compress_ptr dstinfo)
{ {
JQUANT_TBL **qtblptr; JQUANT_TBL **qtblptr;
@@ -93,8 +88,6 @@ jpeg_copy_critical_parameters (const j_decompress_ptr srcinfo,
#endif #endif
/* Initialize all parameters to default values */ /* Initialize all parameters to default values */
jpeg_set_defaults(dstinfo); jpeg_set_defaults(dstinfo);
dstinfo->master->trellis_quant = FALSE;
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
* Fix it to get the right header markers for the image colorspace. * Fix it to get the right header markers for the image colorspace.
*/ */

View File

@@ -343,7 +343,7 @@ jpeg_consume_input (j_decompress_ptr cinfo)
*/ */
GLOBAL(boolean) GLOBAL(boolean)
jpeg_input_complete (const j_decompress_ptr cinfo) jpeg_input_complete (j_decompress_ptr cinfo)
{ {
/* Check for valid jpeg object */ /* Check for valid jpeg object */
if (cinfo->global_state < DSTATE_START || if (cinfo->global_state < DSTATE_START ||
@@ -358,7 +358,7 @@ jpeg_input_complete (const j_decompress_ptr cinfo)
*/ */
GLOBAL(boolean) GLOBAL(boolean)
jpeg_has_multiple_scans (const j_decompress_ptr cinfo) jpeg_has_multiple_scans (j_decompress_ptr cinfo)
{ {
/* Only valid after jpeg_read_header completes */ /* Only valid after jpeg_read_header completes */
if (cinfo->global_state < DSTATE_READY || if (cinfo->global_state < DSTATE_READY ||

View File

@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Developed 1997-2015 by Guido Vollbeding. * Developed 1997-2015 by Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2015, D. R. Commander. * Copyright (C) 2015-2016, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
* *
@@ -21,6 +21,9 @@
#include "jpeglib.h" #include "jpeglib.h"
#define NEG_1 ((unsigned int)-1)
/* Expanded entropy decoder object for arithmetic decoding. */ /* Expanded entropy decoder object for arithmetic decoding. */
typedef struct { typedef struct {
@@ -382,7 +385,7 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
if (arith_decode(cinfo, st)) v |= m; if (arith_decode(cinfo, st)) v |= m;
v += 1; if (sign) v = -v; v += 1; if (sign) v = -v;
/* Scale and output coefficient in natural (dezigzagged) order */ /* Scale and output coefficient in natural (dezigzagged) order */
(*block)[jpeg_natural_order[k]] = (JCOEF) (v << cinfo->Al); (*block)[jpeg_natural_order[k]] = (JCOEF) ((unsigned)v << cinfo->Al);
} }
return TRUE; return TRUE;
@@ -450,7 +453,7 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
tbl = cinfo->cur_comp_info[0]->ac_tbl_no; tbl = cinfo->cur_comp_info[0]->ac_tbl_no;
p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ m1 = (NEG_1) << cinfo->Al; /* -1 in the bit position being coded */
/* Establish EOBx (previous stage end-of-block) index */ /* Establish EOBx (previous stage end-of-block) index */
for (kex = cinfo->Se; kex > 0; kex--) for (kex = cinfo->Se; kex > 0; kex--)

View File

@@ -208,9 +208,9 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE *outfile)
{ {
my_dest_ptr dest; my_dest_ptr dest;
/* The destination object is made permanent so that multiple JPEG images /* The destination object is made permanent so that multiple JPEG images
* can be written to the same file without re-executing jpeg_stdio_dest. * can be written to the same file without re-executing jpeg_stdio_dest.
*/ */
if (cinfo->dest == NULL) { /* first time for this JPEG object? */ if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *) cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
@@ -249,8 +249,8 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE *outfile)
*/ */
GLOBAL(void) GLOBAL(void)
jpeg_mem_dest_internal (j_compress_ptr cinfo, jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char **outbuffer, unsigned long *outsize, int pool_id) unsigned char **outbuffer, unsigned long *outsize)
{ {
my_mem_dest_ptr dest; my_mem_dest_ptr dest;
@@ -262,7 +262,7 @@ jpeg_mem_dest_internal (j_compress_ptr cinfo,
*/ */
if (cinfo->dest == NULL) { /* first time for this JPEG object? */ if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *) cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, pool_id, (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
sizeof(my_mem_destination_mgr)); sizeof(my_mem_destination_mgr));
} else if (cinfo->dest->init_destination != init_mem_destination) { } else if (cinfo->dest->init_destination != init_mem_destination) {
/* It is unsafe to reuse the existing destination manager unless it was /* It is unsafe to reuse the existing destination manager unless it was
@@ -290,15 +290,4 @@ jpeg_mem_dest_internal (j_compress_ptr cinfo,
dest->pub.next_output_byte = dest->buffer = *outbuffer; dest->pub.next_output_byte = dest->buffer = *outbuffer;
dest->pub.free_in_buffer = dest->bufsize = *outsize; dest->pub.free_in_buffer = dest->bufsize = *outsize;
} }
GLOBAL(void)
jpeg_mem_dest (j_compress_ptr cinfo,
unsigned char **outbuffer, unsigned long *outsize)
{
/* The destination object is made permanent so that multiple JPEG images
* can be written to the same file without re-executing jpeg_stdio_dest.
*/
jpeg_mem_dest_internal(cinfo, outbuffer, outsize, JPOOL_PERMANENT);
}
#endif #endif

View File

@@ -109,9 +109,9 @@ start_pass_huff_decoder (j_decompress_ptr cinfo)
actbl = compptr->ac_tbl_no; actbl = compptr->ac_tbl_no;
/* Compute derived values for Huffman tables */ /* Compute derived values for Huffman tables */
/* We may do this more than once for a table, but it's not expensive */ /* We may do this more than once for a table, but it's not expensive */
pdtbl = entropy->dc_derived_tbls + dctbl; pdtbl = (d_derived_tbl **)(entropy->dc_derived_tbls) + dctbl;
jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, pdtbl); jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, pdtbl);
pdtbl = entropy->ac_derived_tbls + actbl; pdtbl = (d_derived_tbl **)(entropy->ac_derived_tbls) + actbl;
jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, pdtbl); jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, pdtbl);
/* Initialize DC predictions to 0 */ /* Initialize DC predictions to 0 */
entropy->saved.last_dc_val[ci] = 0; entropy->saved.last_dc_val[ci] = 0;

View File

@@ -22,6 +22,7 @@
#include "jpeglib.h" #include "jpeglib.h"
#include "jpegcomp.h" #include "jpegcomp.h"
#include "jdmaster.h" #include "jdmaster.h"
#include "jsimd.h"
/* /*
@@ -69,6 +70,17 @@ use_merged_upsample (j_decompress_ptr cinfo)
cinfo->comp_info[1]._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) cinfo->comp_info[2]._DCT_scaled_size != cinfo->_min_DCT_scaled_size)
return FALSE; return FALSE;
#ifdef WITH_SIMD
/* If YCbCr-to-RGB color conversion is SIMD-accelerated but merged upsampling
isn't, then disabling merged upsampling is likely to be faster when
decompressing YCbCr JPEG images. */
if (!jsimd_can_h2v2_merged_upsample() && !jsimd_can_h2v1_merged_upsample() &&
jsimd_can_ycc_rgb() && cinfo->jpeg_color_space == JCS_YCbCr &&
(cinfo->out_color_space == JCS_RGB ||
(cinfo->out_color_space >= JCS_EXT_RGB &&
cinfo->out_color_space <= JCS_EXT_ARGB)))
return FALSE;
#endif
/* ??? also need to test for upsample-time rescaling, when & if supported */ /* ??? also need to test for upsample-time rescaling, when & if supported */
return TRUE; /* by golly, it'll work... */ return TRUE; /* by golly, it'll work... */
#else #else

View File

@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1995-1997, Thomas G. Lane. * Copyright (C) 1995-1997, Thomas G. Lane.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2015, D. R. Commander. * Copyright (C) 2015-2016, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
* *
@@ -170,12 +170,12 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo)
if (is_DC_band) { if (is_DC_band) {
if (cinfo->Ah == 0) { /* DC refinement needs no table */ if (cinfo->Ah == 0) { /* DC refinement needs no table */
tbl = compptr->dc_tbl_no; tbl = compptr->dc_tbl_no;
pdtbl = entropy->derived_tbls + tbl; pdtbl = (d_derived_tbl **)(entropy->derived_tbls) + tbl;
jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, pdtbl); jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, pdtbl);
} }
} else { } else {
tbl = compptr->ac_tbl_no; tbl = compptr->ac_tbl_no;
pdtbl = entropy->derived_tbls + tbl; pdtbl = (d_derived_tbl **)(entropy->derived_tbls) + tbl;
jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, pdtbl); jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, pdtbl);
/* remember the single active table */ /* remember the single active table */
entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; entropy->ac_derived_tbl = entropy->derived_tbls[tbl];

View File

@@ -303,6 +303,48 @@ h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,
} }
/*
* Fancy processing for 1:1 horizontal and 2:1 vertical (4:4:0 subsampling).
*
* This is a less common case, but it can be encountered when losslessly
* rotating/transposing a JPEG file that uses 4:2:2 chroma subsampling.
*/
METHODDEF(void)
h1v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,
JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
{
JSAMPARRAY output_data = *output_data_ptr;
JSAMPROW inptr0, inptr1, outptr;
#if BITS_IN_JSAMPLE == 8
int thiscolsum;
#else
JLONG thiscolsum;
#endif
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++];
for(colctr = 0; colctr < compptr->downsampled_width; colctr++) {
thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
*outptr++ = (JSAMPLE) ((thiscolsum + 1) >> 2);
}
}
inrow++;
}
}
/* /*
* Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
* Again a triangle filter; see comments for h2v1 case, above. * Again a triangle filter; see comments for h2v1 case, above.
@@ -431,6 +473,11 @@ jinit_upsampler (j_decompress_ptr cinfo)
else else
upsample->methods[ci] = h2v1_upsample; upsample->methods[ci] = h2v1_upsample;
} }
} else if (h_in_group == h_out_group &&
v_in_group * 2 == v_out_group && do_fancy) {
/* Non-fancy upsampling is handled by the generic method */
upsample->methods[ci] = h1v2_fancy_upsample;
upsample->pub.need_context_rows = TRUE;
} else if (h_in_group * 2 == h_out_group && } else if (h_in_group * 2 == h_out_group &&
v_in_group * 2 == v_out_group) { v_in_group * 2 == v_out_group) {
/* Special cases for 2h2v upsampling */ /* Special cases for 2h2v upsampling */

View File

@@ -208,10 +208,6 @@ JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
#endif #endif
#endif #endif
JMESSAGE(JERR_BAD_PARAM, "Bogus parameter")
JMESSAGE(JERR_BAD_PARAM_VALUE, "Bogus parameter value")
JMESSAGE(JERR_UNSUPPORTED_SUSPEND, "I/O suspension not supported in scan optimization")
#ifdef JMAKE_ENUM_LIST #ifdef JMAKE_ENUM_LIST

View File

@@ -32,6 +32,10 @@
#include "jinclude.h" #include "jinclude.h"
#include "jpeglib.h" #include "jpeglib.h"
#include "jmemsys.h" /* import the system-dependent declarations */ #include "jmemsys.h" /* import the system-dependent declarations */
#ifndef _WIN32
#include <stdint.h>
#endif
#include <limits.h>
#ifndef NO_GETENV #ifndef NO_GETENV
#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */ #ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
@@ -650,18 +654,26 @@ realize_virt_arrays (j_common_ptr cinfo)
maximum_space = 0; maximum_space = 0;
for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
if (sptr->mem_buffer == NULL) { /* if not realized yet */ if (sptr->mem_buffer == NULL) { /* if not realized yet */
size_t new_space = (long) sptr->rows_in_array *
(long) sptr->samplesperrow * sizeof(JSAMPLE);
space_per_minheight += (long) sptr->maxaccess * space_per_minheight += (long) sptr->maxaccess *
(long) sptr->samplesperrow * sizeof(JSAMPLE); (long) sptr->samplesperrow * sizeof(JSAMPLE);
maximum_space += (long) sptr->rows_in_array * if (SIZE_MAX - maximum_space < new_space)
(long) sptr->samplesperrow * sizeof(JSAMPLE); out_of_memory(cinfo, 10);
maximum_space += new_space;
} }
} }
for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
if (bptr->mem_buffer == NULL) { /* if not realized yet */ if (bptr->mem_buffer == NULL) { /* if not realized yet */
size_t new_space = (long) bptr->rows_in_array *
(long) bptr->blocksperrow * sizeof(JBLOCK);
space_per_minheight += (long) bptr->maxaccess * space_per_minheight += (long) bptr->maxaccess *
(long) bptr->blocksperrow * sizeof(JBLOCK); (long) bptr->blocksperrow * sizeof(JBLOCK);
maximum_space += (long) bptr->rows_in_array * if (SIZE_MAX - maximum_space < new_space)
(long) bptr->blocksperrow * sizeof(JBLOCK); out_of_memory(cinfo, 11);
maximum_space += new_space;
} }
} }

View File

@@ -3,8 +3,8 @@
* *
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1992-1996, Thomas G. Lane. * Copyright (C) 1992-1996, Thomas G. Lane.
* It was modified by The libjpeg-turbo Project to include only code and * libjpeg-turbo Modifications:
* information relevant to libjpeg-turbo. * Copyright (C) 2017, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
* *
@@ -15,7 +15,6 @@
* This is very portable in the sense that it'll compile on almost anything, * This is very portable in the sense that it'll compile on almost anything,
* but you'd better have lots of main memory (or virtual memory) if you want * but you'd better have lots of main memory (or virtual memory) if you want
* to process big images. * to process big images.
* Note that the max_memory_to_use option is ignored by this implementation.
*/ */
#define JPEG_INTERNALS #define JPEG_INTERNALS
@@ -66,14 +65,21 @@ jpeg_free_large (j_common_ptr cinfo, void *object, size_t sizeofobject)
/* /*
* This routine computes the total memory space available for allocation. * This routine computes the total memory space available for allocation.
* Here we always say, "we got all you want bud!"
*/ */
GLOBAL(size_t) GLOBAL(size_t)
jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed, jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed,
size_t max_bytes_needed, size_t already_allocated) size_t max_bytes_needed, size_t already_allocated)
{ {
return max_bytes_needed; if (cinfo->mem->max_memory_to_use) {
if (cinfo->mem->max_memory_to_use > already_allocated)
return cinfo->mem->max_memory_to_use - already_allocated;
else
return 0;
} else {
/* Here we always say, "we got all you want bud!" */
return max_bytes_needed;
}
} }

View File

@@ -7,8 +7,6 @@
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2015-2016, D. R. Commander. * Copyright (C) 2015-2016, D. R. Commander.
* Copyright (C) 2015, Google, Inc. * Copyright (C) 2015, Google, Inc.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
* *
@@ -25,8 +23,7 @@ typedef enum { /* Operating modes for buffer controllers */
/* Remaining modes require a full-image buffer to have been created */ /* Remaining modes require a full-image buffer to have been created */
JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
JBUF_SAVE_AND_PASS, /* Run both subobjects, save output */ JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
JBUF_REQUANT /* Requantize */
} J_BUF_MODE; } J_BUF_MODE;
/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ /* Values of global_state field (jdapi.c has some dependencies on ordering!) */
@@ -70,67 +67,8 @@ struct jpeg_comp_master {
/* State variables made visible to other modules */ /* State variables made visible to other modules */
boolean call_pass_startup; /* True if pass_startup must be called */ boolean call_pass_startup; /* True if pass_startup must be called */
boolean is_last_pass; /* True during last pass */ boolean is_last_pass; /* True during last pass */
/* Extension parameters */
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
boolean trellis_quant; /* TRUE=use trellis quantization */
boolean trellis_quant_dc; /* TRUE=use trellis quant for DC coefficient */
boolean trellis_eob_opt; /* TRUE=optimize for sequences of EOB */
boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */
boolean use_scans_in_trellis; /* TRUE=use scans in trellis optimization */
boolean trellis_passes; /* TRUE=currently doing trellis-related passes [not exposed] */
boolean trellis_q_opt; /* TRUE=optimize quant table in trellis loop */
boolean overshoot_deringing; /* TRUE=preprocess input to reduce ringing of edges on white background */
double norm_src[NUM_QUANT_TBLS][DCTSIZE2];
double norm_coef[NUM_QUANT_TBLS][DCTSIZE2];
int compress_profile; /* compression profile */
int dc_scan_opt_mode; /* DC scan optimization mode */
int quant_tbl_master_idx; /* Quantization table master index */
int trellis_freq_split; /* splitting point for frequency in trellis quantization */
int trellis_num_loops; /* number of trellis loops */
int num_scans_luma; /* # of entries in scan_info array pertaining to luma (used when optimize_scans is TRUE */
int num_scans_luma_dc;
int num_scans_chroma_dc;
int num_frequency_splits;
int Al_max_luma; /* maximum value of Al tested when optimizing scans (luma) */
int Al_max_chroma; /* maximum value of Al tested when optimizing scans (chroma) */
float lambda_log_scale1;
float lambda_log_scale2;
float trellis_delta_dc_weight;
}; };
#ifdef C_ARITH_CODING_SUPPORTED
/* 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
typedef struct {
float rate_dc[DC_STAT_BINS][2];
float rate_ac[AC_STAT_BINS][2];
int arith_dc_L;
int arith_dc_U;
int arith_ac_K;
} arith_rates;
#endif
/* Main buffer control (downsampled-data buffer) */ /* Main buffer control (downsampled-data buffer) */
struct jpeg_c_main_controller { struct jpeg_c_main_controller {
void (*start_pass) (j_compress_ptr cinfo, J_BUF_MODE pass_mode); void (*start_pass) (j_compress_ptr cinfo, J_BUF_MODE pass_mode);
@@ -179,7 +117,7 @@ struct jpeg_forward_dct {
void (*forward_DCT) (j_compress_ptr cinfo, jpeg_component_info *compptr, void (*forward_DCT) (j_compress_ptr cinfo, jpeg_component_info *compptr,
JSAMPARRAY sample_data, JBLOCKROW coef_blocks, JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
JDIMENSION start_row, JDIMENSION start_col, JDIMENSION start_row, JDIMENSION start_col,
JDIMENSION num_blocks, JBLOCKROW dst); JDIMENSION num_blocks);
}; };
/* Entropy encoding */ /* Entropy encoding */
@@ -217,8 +155,8 @@ struct jpeg_decomp_master {
/* Partial decompression variables */ /* Partial decompression variables */
JDIMENSION first_iMCU_col; JDIMENSION first_iMCU_col;
JDIMENSION last_iMCU_col; JDIMENSION last_iMCU_col;
JDIMENSION first_MCU_col[MAX_COMPS_IN_SCAN]; JDIMENSION first_MCU_col[MAX_COMPONENTS];
JDIMENSION last_MCU_col[MAX_COMPS_IN_SCAN]; JDIMENSION last_MCU_col[MAX_COMPONENTS];
boolean jinit_upsampler_no_alloc; boolean jinit_upsampler_no_alloc;
}; };
@@ -402,12 +340,6 @@ EXTERN(void) jinit_merged_upsampler (j_decompress_ptr cinfo);
/* Memory manager initialization */ /* Memory manager initialization */
EXTERN(void) jinit_memory_mgr (j_common_ptr cinfo); EXTERN(void) jinit_memory_mgr (j_common_ptr cinfo);
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
EXTERN(void)
jpeg_mem_dest_internal (j_compress_ptr cinfo,
unsigned char **outbuffer, unsigned long *outsize, int pool_id);
#endif
/* Utility routines in jutils.c */ /* Utility routines in jutils.c */
EXTERN(long) jdiv_round_up (long a, long b); EXTERN(long) jdiv_round_up (long a, long b);
EXTERN(long) jround_up (long a, long b); EXTERN(long) jround_up (long a, long b);
@@ -417,16 +349,6 @@ EXTERN(void) jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
EXTERN(void) jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, EXTERN(void) jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
JDIMENSION num_blocks); JDIMENSION num_blocks);
EXTERN(void) jzero_far (void *target, size_t bytestozero); EXTERN(void) jzero_far (void *target, size_t bytestozero);
#ifdef C_ARITH_CODING_SUPPORTED
EXTERN(void) jget_arith_rates (j_compress_ptr cinfo, int dc_tbl_no, int ac_tbl_no, arith_rates *r);
EXTERN(void) quantize_trellis_arith
(j_compress_ptr cinfo, arith_rates *r, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef, JCOEF *last_dc_val,
JBLOCKROW coef_blocks_above, JBLOCKROW src_above);
#endif
/* Constant tables in jutils.c */ /* Constant tables in jutils.c */
#if 0 /* This table is not actually needed in v6a */ #if 0 /* This table is not actually needed in v6a */
extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */

View File

@@ -7,8 +7,6 @@
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander. * Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander.
* Copyright (C) 2015, Google, Inc. * Copyright (C) 2015, Google, Inc.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
* *
@@ -267,52 +265,6 @@ typedef enum {
} J_DITHER_MODE; } J_DITHER_MODE;
/* These 32-bit GUIDs and the corresponding jpeg_*_get_*_param()/
* jpeg_*_set_*_param() functions allow for extending the libjpeg API without
* breaking backward ABI compatibility. The actual parameters are stored in
* the opaque jpeg_comp_master and jpeg_decomp_master structs.
*/
/* Boolean extension parameters */
typedef enum {
JBOOLEAN_OPTIMIZE_SCANS = 0x680C061E, /* TRUE=optimize progressive coding scans */
JBOOLEAN_TRELLIS_QUANT = 0xC5122033, /* TRUE=use trellis quantization */
JBOOLEAN_TRELLIS_QUANT_DC = 0x339D4C0C, /* TRUE=use trellis quant for DC coefficient */
JBOOLEAN_TRELLIS_EOB_OPT = 0xD7F73780, /* TRUE=optimize for sequences of EOB */
JBOOLEAN_USE_LAMBDA_WEIGHT_TBL = 0x339DB65F, /* TRUE=use lambda weighting table */
JBOOLEAN_USE_SCANS_IN_TRELLIS = 0xFD841435, /* TRUE=use scans in trellis optimization */
JBOOLEAN_TRELLIS_Q_OPT = 0xE12AE269, /* TRUE=optimize quant table in trellis loop */
JBOOLEAN_OVERSHOOT_DERINGING = 0x3F4BBBF9 /* TRUE=preprocess input to reduce ringing of edges on white background */
} J_BOOLEAN_PARAM;
/* Floating point parameters */
typedef enum {
JFLOAT_LAMBDA_LOG_SCALE1 = 0x5B61A599,
JFLOAT_LAMBDA_LOG_SCALE2 = 0xB9BBAE03,
JFLOAT_TRELLIS_DELTA_DC_WEIGHT = 0x13775453
} J_FLOAT_PARAM;
/* Integer parameters */
typedef enum {
JINT_COMPRESS_PROFILE = 0xE9918625, /* compression profile */
JINT_TRELLIS_FREQ_SPLIT = 0x6FAFF127, /* splitting point for frequency in trellis quantization */
JINT_TRELLIS_NUM_LOOPS = 0xB63EBF39, /* number of trellis loops */
JINT_BASE_QUANT_TBL_IDX = 0x44492AB1, /* base quantization table index */
JINT_DC_SCAN_OPT_MODE = 0x0BE7AD3C /* DC scan optimization mode */
} J_INT_PARAM;
/* Values for the JINT_COMPRESS_PROFILE parameter (32-bit GUIDs) */
enum {
JCP_MAX_COMPRESSION = 0x5D083AAD, /* best compression ratio (progressive, all mozjpeg extensions) */
JCP_FASTEST = 0x2AEA5CB4 /* libjpeg[-turbo] defaults (baseline, no mozjpeg extensions) */
};
/* Common fields between JPEG compression and decompression master structs. */ /* Common fields between JPEG compression and decompression master structs. */
#define jpeg_common_fields \ #define jpeg_common_fields \
@@ -991,7 +943,6 @@ EXTERN(void) jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table, const unsigned int *basic_table,
int scale_factor, boolean force_baseline); int scale_factor, boolean force_baseline);
EXTERN(int) jpeg_quality_scaling (int quality); EXTERN(int) jpeg_quality_scaling (int quality);
EXTERN(float) jpeg_float_quality_scaling (float quality);
EXTERN(void) jpeg_simple_progression (j_compress_ptr cinfo); EXTERN(void) jpeg_simple_progression (j_compress_ptr cinfo);
EXTERN(void) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress); EXTERN(void) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress);
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo); EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo);
@@ -1053,10 +1004,10 @@ EXTERN(JDIMENSION) jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
JDIMENSION max_lines); JDIMENSION max_lines);
/* Additional entry points for buffered-image mode. */ /* Additional entry points for buffered-image mode. */
EXTERN(boolean) jpeg_has_multiple_scans (const j_decompress_ptr cinfo); EXTERN(boolean) jpeg_has_multiple_scans (j_decompress_ptr cinfo);
EXTERN(boolean) jpeg_start_output (j_decompress_ptr cinfo, int scan_number); EXTERN(boolean) jpeg_start_output (j_decompress_ptr cinfo, int scan_number);
EXTERN(boolean) jpeg_finish_output (j_decompress_ptr cinfo); EXTERN(boolean) jpeg_finish_output (j_decompress_ptr cinfo);
EXTERN(boolean) jpeg_input_complete (const j_decompress_ptr cinfo); EXTERN(boolean) jpeg_input_complete (j_decompress_ptr cinfo);
EXTERN(void) jpeg_new_colormap (j_decompress_ptr cinfo); EXTERN(void) jpeg_new_colormap (j_decompress_ptr cinfo);
EXTERN(int) jpeg_consume_input (j_decompress_ptr cinfo); EXTERN(int) jpeg_consume_input (j_decompress_ptr cinfo);
/* Return value is one of: */ /* Return value is one of: */
@@ -1085,7 +1036,7 @@ EXTERN(void) jpeg_set_marker_processor (j_decompress_ptr cinfo,
EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients (j_decompress_ptr cinfo); EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients (j_decompress_ptr cinfo);
EXTERN(void) jpeg_write_coefficients (j_compress_ptr cinfo, EXTERN(void) jpeg_write_coefficients (j_compress_ptr cinfo,
jvirt_barray_ptr *coef_arrays); jvirt_barray_ptr *coef_arrays);
EXTERN(void) jpeg_copy_critical_parameters (const j_decompress_ptr srcinfo, EXTERN(void) jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
j_compress_ptr dstinfo); j_compress_ptr dstinfo);
/* If you choose to abort compression or decompression before completing /* If you choose to abort compression or decompression before completing
@@ -1106,28 +1057,6 @@ EXTERN(void) jpeg_destroy (j_common_ptr cinfo);
/* Default restart-marker-resync procedure for use by data source modules */ /* Default restart-marker-resync procedure for use by data source modules */
EXTERN(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired); EXTERN(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired);
/* Accessor functions for extension parameters */
#define JPEG_C_PARAM_SUPPORTED 1
EXTERN(boolean) jpeg_c_bool_param_supported (const j_compress_ptr cinfo,
J_BOOLEAN_PARAM param);
EXTERN(void) jpeg_c_set_bool_param (j_compress_ptr cinfo,
J_BOOLEAN_PARAM param, boolean value);
EXTERN(boolean) jpeg_c_get_bool_param (const j_compress_ptr cinfo,
J_BOOLEAN_PARAM param);
EXTERN(boolean) jpeg_c_float_param_supported (const j_compress_ptr cinfo,
J_FLOAT_PARAM param);
EXTERN(void) jpeg_c_set_float_param (j_compress_ptr cinfo, J_FLOAT_PARAM param,
float value);
EXTERN(float) jpeg_c_get_float_param (const j_compress_ptr cinfo,
J_FLOAT_PARAM param);
EXTERN(boolean) jpeg_c_int_param_supported (const j_compress_ptr cinfo,
J_INT_PARAM param);
EXTERN(void) jpeg_c_set_int_param (j_compress_ptr cinfo, J_INT_PARAM param,
int value);
EXTERN(int) jpeg_c_get_int_param (const j_compress_ptr cinfo, J_INT_PARAM param);
/* These marker codes are exported since applications and data source modules /* These marker codes are exported since applications and data source modules
* are likely to want to use them. * are likely to want to use them.

View File

@@ -1,4 +1,4 @@
.TH JPEGTRAN 1 "18 February 2016" .TH JPEGTRAN 1 "18 March 2017"
.SH NAME .SH NAME
jpegtran \- lossless transformation of JPEG files jpegtran \- lossless transformation of JPEG files
.SH SYNOPSIS .SH SYNOPSIS
@@ -222,7 +222,7 @@ Set limit for amount of memory to use in processing large images. Value is
in thousands of bytes, or millions of bytes if "M" is attached to the in thousands of bytes, or millions of bytes if "M" is attached to the
number. For example, number. For example,
.B \-max 4m .B \-max 4m
selects 4000000 bytes. If more space is needed, temporary files will be used. selects 4000000 bytes. If more space is needed, an error will occur.
.TP .TP
.BI \-outfile " name" .BI \-outfile " name"
Send output image to the named file, not to standard output. Send output image to the named file, not to standard output.

View File

@@ -4,10 +4,9 @@
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1995-2010, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1995-2010, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2010, 2014, D. R. Commander. * Copyright (C) 2010, 2014, 2017, D. R. Commander.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains a command-line user interface for JPEG transcoding. * This file contains a command-line user interface for JPEG transcoding.
* It is very similar to cjpeg.c, and partly to djpeg.c, but provides * It is very similar to cjpeg.c, and partly to djpeg.c, but provides
@@ -44,8 +43,6 @@ static const char *progname; /* program name for error messages */
static char *outfilename; /* for -outfile switch */ static char *outfilename; /* for -outfile switch */
static JCOPY_OPTION copyoption; /* -copy switch */ static JCOPY_OPTION copyoption; /* -copy switch */
static jpeg_transform_info transformoption; /* image transformation options */ static jpeg_transform_info transformoption; /* image transformation options */
boolean memsrc = FALSE; /* for -memsrc switch */
#define INPUT_BUF_SIZE 4096
LOCAL(void) LOCAL(void)
@@ -64,13 +61,11 @@ usage (void)
fprintf(stderr, " -copy comments Copy only comment markers (default)\n"); fprintf(stderr, " -copy comments Copy only comment markers (default)\n");
fprintf(stderr, " -copy all Copy all extra markers\n"); fprintf(stderr, " -copy all Copy all extra markers\n");
#ifdef ENTROPY_OPT_SUPPORTED #ifdef ENTROPY_OPT_SUPPORTED
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression, enabled by default)\n"); fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
#endif #endif
#ifdef C_PROGRESSIVE_SUPPORTED #ifdef C_PROGRESSIVE_SUPPORTED
fprintf(stderr, " -progressive Create progressive JPEG file (enabled by default)\n"); fprintf(stderr, " -progressive Create progressive JPEG file\n");
#endif #endif
fprintf(stderr, " -revert Revert to standard defaults (instead of mozjpeg defaults)\n");
fprintf(stderr, " -fastcrush Disable progressive scan optimization\n");
fprintf(stderr, "Switches for modifying the image:\n"); fprintf(stderr, "Switches for modifying the image:\n");
#if TRANSFORMS_SUPPORTED #if TRANSFORMS_SUPPORTED
fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n"); fprintf(stderr, " -crop WxH+X+Y Crop to a rectangular subarea\n");
@@ -95,7 +90,7 @@ usage (void)
fprintf(stderr, " -version Print version information and exit\n"); fprintf(stderr, " -version Print version information and exit\n");
fprintf(stderr, "Switches for wizards:\n"); fprintf(stderr, "Switches for wizards:\n");
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n"); fprintf(stderr, " -scans FILE Create multi-scan JPEG per script FILE\n");
#endif #endif
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -142,11 +137,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
char *scansarg = NULL; /* saves -scans parm if any */ char *scansarg = NULL; /* saves -scans parm if any */
/* Set up default JPEG parameters. */ /* Set up default JPEG parameters. */
#ifdef C_PROGRESSIVE_SUPPORTED
simple_progressive = cinfo->num_scans == 0 ? FALSE : TRUE;
#else
simple_progressive = FALSE; simple_progressive = FALSE;
#endif
outfilename = NULL; outfilename = NULL;
copyoption = JCOPYOPT_DEFAULT; copyoption = JCOPYOPT_DEFAULT;
transformoption.transform = JXFORM_NONE; transformoption.transform = JXFORM_NONE;
@@ -175,9 +166,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* Use arithmetic coding. */ /* Use arithmetic coding. */
#ifdef C_ARITH_CODING_SUPPORTED #ifdef C_ARITH_CODING_SUPPORTED
cinfo->arith_code = TRUE; cinfo->arith_code = TRUE;
/* No table optimization required for AC */
cinfo->optimize_coding = FALSE;
#else #else
fprintf(stderr, "%s: sorry, arithmetic coding not supported\n", fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
progname); progname);
@@ -242,9 +230,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
else else
usage(); usage();
} else if (keymatch(arg, "fastcrush", 4)) {
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OPTIMIZE_SCANS, FALSE);
} else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) { } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) {
/* Force to grayscale. */ /* Force to grayscale. */
#if TRANSFORMS_SUPPORTED #if TRANSFORMS_SUPPORTED
@@ -317,10 +302,6 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* restart_interval will be computed during startup */ /* restart_interval will be computed during startup */
} }
} else if (keymatch(arg, "revert", 3)) {
/* revert to old JPEG default */
jpeg_c_set_int_param(cinfo, JINT_COMPRESS_PROFILE, JCP_FASTEST);
} else if (keymatch(arg, "rotate", 2)) { } else if (keymatch(arg, "rotate", 2)) {
/* Rotate 90, 180, or 270 degrees (measured clockwise). */ /* Rotate 90, 180, or 270 degrees (measured clockwise). */
if (++argn >= argc) /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
@@ -404,10 +385,6 @@ main (int argc, char **argv)
* single file pointer for sequential input and output operation. * single file pointer for sequential input and output operation.
*/ */
FILE *fp; FILE *fp;
unsigned char *inbuffer = NULL;
unsigned long insize = 0;
unsigned char *outbuffer = NULL;
unsigned long outsize = 0;
/* On Mac, fetch a command line. */ /* On Mac, fetch a command line. */
#ifdef USE_CCOMMAND #ifdef USE_CCOMMAND
@@ -477,32 +454,6 @@ main (int argc, char **argv)
#endif #endif
/* Specify data source for decompression */ /* Specify data source for decompression */
if (jpeg_c_int_param_supported(&dstinfo, JINT_COMPRESS_PROFILE) &&
jpeg_c_get_int_param(&dstinfo, JINT_COMPRESS_PROFILE)
== JCP_MAX_COMPRESSION)
memsrc = TRUE; /* needed to revert to original */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (memsrc) {
size_t nbytes;
do {
inbuffer = (unsigned char *)realloc(inbuffer, insize + INPUT_BUF_SIZE);
if (inbuffer == NULL) {
fprintf(stderr, "%s: memory allocation failure\n", progname);
exit(EXIT_FAILURE);
}
nbytes = JFREAD(fp, &inbuffer[insize], INPUT_BUF_SIZE);
if (nbytes < INPUT_BUF_SIZE && ferror(fp)) {
if (file_index < argc)
fprintf(stderr, "%s: can't read from %s\n", progname,
argv[file_index]);
else
fprintf(stderr, "%s: can't read from stdin\n", progname);
}
insize += (unsigned long)nbytes;
} while (nbytes == INPUT_BUF_SIZE);
jpeg_mem_src(&srcinfo, inbuffer, insize);
} else
#endif
jpeg_stdio_src(&srcinfo, fp); jpeg_stdio_src(&srcinfo, fp);
/* Enable saving of extra markers that we want to copy */ /* Enable saving of extra markers that we want to copy */
@@ -565,13 +516,6 @@ main (int argc, char **argv)
file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE); file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
/* Specify data destination for compression */ /* Specify data destination for compression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (jpeg_c_int_param_supported(&dstinfo, JINT_COMPRESS_PROFILE) &&
jpeg_c_get_int_param(&dstinfo, JINT_COMPRESS_PROFILE)
== JCP_MAX_COMPRESSION)
jpeg_mem_dest(&dstinfo, &outbuffer, &outsize);
else
#endif
jpeg_stdio_dest(&dstinfo, fp); jpeg_stdio_dest(&dstinfo, fp);
/* Start compressor (note no image data is actually written here) */ /* Start compressor (note no image data is actually written here) */
@@ -589,29 +533,6 @@ main (int argc, char **argv)
/* Finish compression and release memory */ /* Finish compression and release memory */
jpeg_finish_compress(&dstinfo); jpeg_finish_compress(&dstinfo);
if (jpeg_c_int_param_supported(&dstinfo, JINT_COMPRESS_PROFILE) &&
jpeg_c_get_int_param(&dstinfo, JINT_COMPRESS_PROFILE)
== JCP_MAX_COMPRESSION) {
size_t nbytes;
unsigned char *buffer = outbuffer;
unsigned long size = outsize;
if (insize < size) {
size = insize;
buffer = inbuffer;
}
nbytes = JFWRITE(fp, buffer, size);
if (nbytes < size && ferror(fp)) {
if (file_index < argc)
fprintf(stderr, "%s: can't write to %s\n", progname,
argv[file_index]);
else
fprintf(stderr, "%s: can't write to stdout\n", progname);
}
}
jpeg_destroy_compress(&dstinfo); jpeg_destroy_compress(&dstinfo);
(void) jpeg_finish_decompress(&srcinfo); (void) jpeg_finish_decompress(&srcinfo);
jpeg_destroy_decompress(&srcinfo); jpeg_destroy_decompress(&srcinfo);
@@ -624,9 +545,6 @@ main (int argc, char **argv)
end_progress_monitor((j_common_ptr) &dstinfo); end_progress_monitor((j_common_ptr) &dstinfo);
#endif #endif
free(inbuffer);
free(outbuffer);
/* All done. */ /* All done. */
exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS); exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */ return 0; /* suppress no-return-value warnings */

172
jpegyuv.c
View File

@@ -1,172 +0,0 @@
/*
* Written by Josh Aas and Tim Terriberry
* Copyright (c) 2013, Mozilla Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the Mozilla Corporation nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Input: JPEG YUV 4:2:0 */
/* Output: YUV 4:2:0 */
/* gcc -std=c99 jpegyuv.c -I/opt/local/include/ -L/opt/local/lib/ -ljpeg -o jpegyuv */
#include <stdio.h>
#include <stdlib.h>
#include "jpeglib.h"
int main(int argc, char *argv[]) {
const char *jpg_path;
const char *yuv_path;
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *jpg_fd;
int luma_width;
int luma_height;
int chroma_width;
int chroma_height;
int frame_width;
int yuv_size;
JSAMPLE *jpg_buffer;
JSAMPROW yrow_pointer[16];
JSAMPROW cbrow_pointer[8];
JSAMPROW crrow_pointer[8];
JSAMPROW *plane_pointer[3];
unsigned char *yuv_buffer;
int x;
int y;
FILE *yuv_fd;
if (argc != 3) {
fprintf(stderr, "Required arguments:\n");
fprintf(stderr, "1. Path to JPG input file\n");
fprintf(stderr, "2. Path to YUV output file\n");
return 1;
}
/* Will check these for validity when opening via 'fopen'. */
jpg_path = argv[1];
yuv_path = argv[2];
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpg_fd = fopen(jpg_path, "rb");
if (!jpg_fd) {
fprintf(stderr, "Invalid path to JPEG file!\n");
return 1;
}
jpeg_stdio_src(&cinfo, jpg_fd);
jpeg_read_header(&cinfo, TRUE);
cinfo.raw_data_out = TRUE;
cinfo.do_fancy_upsampling = FALSE;
jpeg_start_decompress(&cinfo);
luma_width = cinfo.output_width;
luma_height = cinfo.output_height;
chroma_width = (luma_width + 1) >> 1;
chroma_height = (luma_height + 1) >> 1;
yuv_size = luma_width*luma_height + 2*chroma_width*chroma_height;
yuv_buffer = malloc(yuv_size);
if (!yuv_buffer) {
fclose(jpg_fd);
fprintf(stderr, "Memory allocation failure!\n");
return 1;
}
frame_width = (cinfo.output_width + (16 - 1)) & ~(16 - 1);
jpg_buffer = malloc(frame_width*16 + 2*(frame_width/2)*8);
if (!jpg_buffer) {
fclose(jpg_fd);
free(yuv_buffer);
fprintf(stderr, "Memory allocation failure!\n");
return 1;
}
plane_pointer[0] = yrow_pointer;
plane_pointer[1] = cbrow_pointer;
plane_pointer[2] = crrow_pointer;
for (y = 0; y < 16; y++) {
yrow_pointer[y] = &jpg_buffer[frame_width*y];
}
for (y = 0; y < 8; y++) {
cbrow_pointer[y] = &jpg_buffer[frame_width*16 + (frame_width/2)*y];
crrow_pointer[y] = &jpg_buffer[frame_width*16 + (frame_width/2)*(8 + y)];
}
while (cinfo.output_scanline < cinfo.output_height) {
int luma_scanline;
int chroma_scanline;
luma_scanline = cinfo.output_scanline;
chroma_scanline = (luma_scanline + 1) >> 1;
jpeg_read_raw_data(&cinfo, plane_pointer, 16);
for (y = 0; y < 16 && luma_scanline + y < luma_height; y++) {
for (x = 0; x < luma_width; x++) {
yuv_buffer[luma_width*(luma_scanline + y) + x] = yrow_pointer[y][x];
}
}
for (y = 0; y < 8 && chroma_scanline + y < chroma_height; y++) {
for (x = 0; x < chroma_width; x++) {
yuv_buffer[luma_width*luma_height +
chroma_width*(chroma_scanline + y) + x] = cbrow_pointer[y][x];
yuv_buffer[luma_width*luma_height + chroma_width*chroma_height +
chroma_width*(chroma_scanline + y) + x] = crrow_pointer[y][x];
}
}
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(jpg_fd);
free(jpg_buffer);
yuv_fd = fopen(yuv_path, "wb");
if (!yuv_fd) {
fprintf(stderr, "Invalid path to YUV file!");
free(yuv_buffer);
return 1;
}
if (fwrite(yuv_buffer, yuv_size, 1, yuv_fd) != 1) {
fprintf(stderr, "Error writing yuv file\n");
}
fclose(yuv_fd);
free(yuv_buffer);
return 0;
}

View File

@@ -4,10 +4,9 @@
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2010, 2012-2016, D. R. Commander. * Copyright (C) 2010, 2012-2017, D. R. Commander.
* mozjpeg Modifications: * For conditions of distribution and use, see the accompanying README.ijg
* Copyright (C) 2014, Mozilla Corporation. * file.
* For conditions of distribution and use, see the accompanying README file.
* *
* This file contains software version identification. * This file contains software version identification.
*/ */
@@ -36,11 +35,10 @@
* their code * their code
*/ */
#define JCOPYRIGHT "Copyright (C) 2009-2016 D. R. Commander\n" \ #define JCOPYRIGHT "Copyright (C) 2009-2017 D. R. Commander\n" \
"Copyright (C) 2011-2016 Siarhei Siamashka\n" \ "Copyright (C) 2011-2016 Siarhei Siamashka\n" \
"Copyright (C) 2015-2016 Matthieu Darbois\n" \ "Copyright (C) 2015-2016 Matthieu Darbois\n" \
"Copyright (C) 2015 Google, Inc.\n" \ "Copyright (C) 2015 Google, Inc.\n" \
"Copyright (C) 2014 Mozilla Corporation\n" \
"Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \ "Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \
"Copyright (C) 2013 Linaro Limited\n" \ "Copyright (C) 2013 Linaro Limited\n" \
"Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \ "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
@@ -48,4 +46,4 @@
"Copyright (C) 1999-2006 MIYASAKA Masaru\n" \ "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
"Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding" \ "Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding" \
#define JCOPYRIGHT_SHORT "Copyright (C) 1991-2016 The libjpeg-turbo Project and many others" #define JCOPYRIGHT_SHORT "Copyright (C) 1991-2017 The libjpeg-turbo Project and many others"

View File

@@ -3,7 +3,7 @@ USING THE IJG JPEG LIBRARY
This file was part of the Independent JPEG Group's software: This file was part of the Independent JPEG Group's software:
Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding. Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding.
libjpeg-turbo Modifications: libjpeg-turbo Modifications:
Copyright (C) 2010, 2014-2016, D. R. Commander. Copyright (C) 2010, 2014-2017, D. R. Commander.
Copyright (C) 2015, Google, Inc. Copyright (C) 2015, Google, Inc.
For conditions of distribution and use, see the accompanying README.ijg file. For conditions of distribution and use, see the accompanying README.ijg file.
@@ -34,6 +34,7 @@ Basic library usage:
Data formats Data formats
Compression details Compression details
Decompression details Decompression details
Partial image decompression
Mechanics of usage: include files, linking, etc Mechanics of usage: include files, linking, etc
Advanced features: Advanced features:
Compression parameter selection Compression parameter selection
@@ -2941,13 +2942,6 @@ Some operating modes (eg, two-pass color quantization) require full-image
buffers. Such buffers are treated as "virtual arrays": only the current strip buffers. Such buffers are treated as "virtual arrays": only the current strip
need be in memory, and the rest can be swapped out to a temporary file. need be in memory, and the rest can be swapped out to a temporary file.
If you use the simplest memory manager back end (jmemnobs.c), then no
temporary files are used; virtual arrays are simply malloc()'d. Images bigger
than memory can be processed only if your system supports virtual memory.
The other memory manager back ends support temporary files of various flavors
and thus work in machines without virtual memory. They may also be useful on
Unix machines if you need to process images that exceed available swap space.
When using temporary files, the library will make the in-memory buffers for When using temporary files, the library will make the in-memory buffers for
its virtual arrays just big enough to stay within a "maximum memory" setting. its virtual arrays just big enough to stay within a "maximum memory" setting.
Your application can set this limit by setting cinfo->mem->max_memory_to_use Your application can set this limit by setting cinfo->mem->max_memory_to_use
@@ -2960,6 +2954,11 @@ that space allocated with alloc_small() is ignored, on the assumption that
it's too small to be worth worrying about; so a reasonable safety margin it's too small to be worth worrying about; so a reasonable safety margin
should be left when setting max_memory_to_use. should be left when setting max_memory_to_use.
NOTE: Unless you develop your own memory manager back end, then temporary files
will never be used. The back end provided in libjpeg-turbo (jmemnobs.c) simply
malloc()s and free()s virtual arrays, and an error occurs if the required
memory exceeds the limit specified in cinfo->mem->max_memory_to_use.
Memory usage Memory usage
------------ ------------

View File

@@ -31,6 +31,15 @@
#include "./md5.h" #include "./md5.h"
#ifdef __amigaos4__
#include <machine/endian.h>
#define le32toh(x) (((x & 0xff) << 24) | \
((x & 0xff00) << 8) | \
((x & 0xff0000) >> 8) | \
((x & 0xff000000) >> 24))
#define htole32(x) le32toh(x)
#endif
static void MD5Transform(unsigned int [4], const unsigned char [64]); static void MD5Transform(unsigned int [4], const unsigned char [64]);
#if (BYTE_ORDER == LITTLE_ENDIAN) #if (BYTE_ORDER == LITTLE_ENDIAN)

View File

@@ -1,15 +0,0 @@
#!/bin/bash
set -e
if [ $# == 0 ]; then
echo "usage: OUTPUT=<label> $0 *.out"
exit 1
fi
TOTAL=total.out
if [ -n "$OUTPUT" ]; then
TOTAL="$OUTPUT.out"
fi
awk '{size[FNR]+=$2;bytes[FNR]+=$3;psnr[FNR]+=$2*$4;psnrhvs[FNR]+=$2*$5;ssim[FNR]+=$2*$6;fastssim[FNR]+=$2*$7;}END{for(i=1;i<=FNR;i++)print i-1,size[i],bytes[i],psnr[i]/size[i],psnrhvs[i]/size[i],ssim[i]/size[i],fastssim[i]/size[i];}' $@ > $TOTAL

View File

@@ -1,106 +0,0 @@
#!/bin/bash
set -e
if [ $# == 0 ]; then
echo "usage: DAALA_ROOT=<daala_root> MOZJPEG_ROOT=<mozjpeg_root> $0 *.y4m"
exit 1
fi
if [ -z $MOZJPEG_ROOT ]; then
MOZJPEG_ROOT=.
fi
if [ -z $DAALA_ROOT ]; then
echo "DAALA_ROOT not set."
exit 1
fi
if [ -z "$PLANE" ]; then
export PLANE=0
fi
if [ $PLANE != 0 ] && [ $PLANE != 1 ] && [ $PLANE != 2 ]; then
echo "Invalid plane $PLANE. Must be 0, 1 or 2."
exit 1
fi
if [ -z "$YUVJPEG" ]; then
export YUVJPEG=$MOZJPEG_ROOT/yuvjpeg
fi
if [ -z "$JPEGYUV" ]; then
export JPEGYUV=$MOZJPEG_ROOT/jpegyuv
fi
if [ ! -x "$YUVJPEG" ]; then
echo "Executable not found YUVJPEG=$YUVJPEG"
echo "Do you have the right MOZJPEG_ROOT=$MOZJPEG_ROOT"
exit 1
fi
if [ ! -x "$JPEGYUV" ]; then
echo "Executable not found JPEGYUV=$JPEGYUV"
echo "Do you have the right MOZJPEG_ROOT=$MOZJPEG_ROOT"
exit 1
fi
# TODO refactor these out of the daala project into a metrics project
if [ -z "$YUV2YUV4MPEG" ]; then
export YUV2YUV4MPEG=$DAALA_ROOT/tools/yuv2yuv4mpeg
fi
if [ -z "$DUMP_PSNR" ]; then
export DUMP_PSNR=$DAALA_ROOT/tools/dump_psnr
fi
if [ -z "$DUMP_PSNRHVS" ]; then
export DUMP_PSNRHVS=$DAALA_ROOT/tools/dump_psnrhvs
fi
if [ -z "$DUMP_SSIM" ]; then
export DUMP_SSIM=$DAALA_ROOT/tools/dump_ssim
fi
if [ -z "$DUMP_FASTSSIM" ]; then
export DUMP_FASTSSIM=$DAALA_ROOT/tools/dump_fastssim
fi
if [ ! -x "$YUV2YUV4MPEG" ]; then
echo "Executable not found YUV2YUV4MPEG=$YUV2YUV4MPEG"
echo "Do you have the right DAALA_ROOT=$DAALA_ROOT"
exit 1
fi
if [ ! -x "$DUMP_PSNR" ]; then
echo "Executable not found DUMP_PSNR=$DUMP_PSNR"
echo "Do you have the right DAALA_ROOT=$DAALA_ROOT"
exit 1
fi
if [ ! -x "$DUMP_PSNRHVS" ]; then
echo "Executable not found DUMP_PSNRHVS=$DUMP_PSNRHVS"
echo "Do you have the right DAALA_ROOT=$DAALA_ROOT"
exit 1
fi
if [ ! -x "$DUMP_SSIM" ]; then
echo "Executable not found DUMP_SSIM=$DUMP_SSIM"
echo "Do you have the right DAALA_ROOT=$DAALA_ROOT"
exit 1
fi
if [ ! -x "$DUMP_FASTSSIM" ]; then
echo "Executable not found DUMP_FASTSSIM=$DUMP_FASTSSIM"
echo "Do you have the right DAALA_ROOT=$DAALA_ROOT"
exit 1
fi
RD_COLLECT_SUB=$(dirname "$0")/rd_collect_sub.sh
if [ -z "$CORES" ]; then
CORES=`grep -i processor /proc/cpuinfo | wc -l`
#echo "CORES not set, using $CORES"
fi
find $@ -type f -name "*.y4m" -print0 | xargs -0 -n1 -P$CORES $RD_COLLECT_SUB

View File

@@ -1,28 +0,0 @@
#!/bin/bash
set -e
FILE=$1
BASENAME=$(basename $FILE)
rm $BASENAME.out 2> /dev/null || true
echo $BASENAME
tail -n+3 $FILE > $BASENAME-in.yuv
WIDTH=$(head -1 $FILE | cut -d\ -f 2 | tr -d 'W')
HEIGHT=$(head -1 $FILE | cut -d\ -f 3 | tr -d 'H')
for x in {0..100}; do
$YUVJPEG $x "$WIDTH"x$HEIGHT $BASENAME-in.yuv $BASENAME.jpeg
$JPEGYUV $BASENAME.jpeg $BASENAME.yuv
$YUV2YUV4MPEG $BASENAME -w$WIDTH -h$HEIGHT -an0 -ad0 -c420mpeg2
PIXELS=$(($WIDTH*$HEIGHT))
SIZE=$(wc -c $BASENAME.jpeg | awk '{ print $1 }')
PSNR=$($DUMP_PSNR $FILE $BASENAME.y4m 2> /dev/null | grep Total | tr -s ' ' | cut -d\ -f $((4+$PLANE*2)))
PSNRHVS=$($DUMP_PSNRHVS $FILE $BASENAME.y4m 2> /dev/null | grep Total | tr -s ' ' | cut -d\ -f $((4+$PLANE*2)))
SSIM=$($DUMP_SSIM $FILE $BASENAME.y4m 2> /dev/null | grep Total | tr -s ' ' | cut -d\ -f $((4+$PLANE*2)))
FASTSSIM=$($DUMP_FASTSSIM -c $FILE $BASENAME.y4m 2> /dev/null | grep Total | tr -s ' ' | cut -d\ -f $((4+$PLANE*2)))
rm $BASENAME.jpeg $BASENAME.yuv $BASENAME.y4m
echo $x $PIXELS $SIZE $PSNR $PSNRHVS $SSIM $FASTSSIM >> $BASENAME.out
#tail -1 $BASENAME.out
done
rm $BASENAME-in.yuv

View File

@@ -1,47 +0,0 @@
#!/bin/bash
set -e
# Use this to average data from multiple runs
#awk '{size[FNR]+=$2;bytes[FNR]+=$3;psnr[FNR]+=$2*$4;psnrhvs[FNR]+=$2*$5;ssim[FNR]+=$2*$6;fastssim[FNR]+=$2*$7;}END{for(i=1;i<=FNR;i++)print i+1,size[i],bytes[i],psnr[i]/size[i],psnrhvs[i]/size[i],ssim[i]/size[i],fastssim[i]/size[i];}' *.out > total.out
if [ -n "$IMAGE" ]; then
IMAGE="$IMAGE-"
fi
if [ $# == 0 ]; then
echo "usage: IMAGE=<prefix> $0 *.out"
exit 1
fi
if [ -z "$GNUPLOT" -a -n "`type -p gnuplot`" ]; then
GNUPLOT=`type -p gnuplot`
fi
if [ ! -x "$GNUPLOT" ]; then
echo "Executable not found GNUPLOT=$GNUPLOT"
echo "Please install it or set GNUPLOT to point to an installed copy"
exit 1
fi
CMDS="$CMDS set term pngcairo dashed size 1024,768;"
CMDS="$CMDS set log x;"
CMDS="$CMDS set xlabel 'Bits/Pixel';"
CMDS="$CMDS set ylabel 'dB';"
CMDS="$CMDS set key bot right;"
for FILE in "$@"; do
BASENAME=$(basename $FILE)
PSNR="$PSNR $PREFIX '$FILE' using (\$3*8/\$2):4 with lines title '${BASENAME%.*} (PSNR)'"
PSNRHVS="$PSNRHVS $PREFIX '$FILE' using (\$3*8/\$2):5 with lines title '${BASENAME%.*} (PSNR-HVS)'"
SSIM="$SSIM $PREFIX '$FILE' using (\$3*8/\$2):6 with lines title '${BASENAME%.*} (SSIM)'"
FASTSSIM="$FASTSSIM $PREFIX '$FILE' using (\$3*8/\$2):7 with lines title '${BASENAME%.*} (FAST SSIM)'"
PREFIX=","
done
SUFFIX="psnr.png"
$GNUPLOT -e "$CMDS set output \"$IMAGE$SUFFIX\"; plot $PSNR;" 2> /dev/null
SUFFIX="psnrhvs.png"
$GNUPLOT -e "$CMDS set output \"$IMAGE$SUFFIX\"; plot $PSNRHVS;" 2> /dev/null
SUFFIX="ssim.png"
$GNUPLOT -e "$CMDS set output \"$IMAGE$SUFFIX\"; plot $SSIM;" 2> /dev/null
SUFFIX="fastssim.png"
$GNUPLOT -e "$CMDS set output \"$IMAGE$SUFFIX\"; plot $FASTSSIM;" 2> /dev/null

View File

@@ -383,7 +383,7 @@ start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
return; return;
} }
if (biWidth <= 0 || biHeight <= 0 || biWidth > 0x7fffffffL || biHeight > 0x7fffffffL) if (biWidth <= 0 || biHeight <= 0)
ERREXIT(cinfo, JERR_BMP_EMPTY); ERREXIT(cinfo, JERR_BMP_EMPTY);
if (biPlanes != 1) if (biPlanes != 1)
ERREXIT(cinfo, JERR_BMP_BADPLANES); ERREXIT(cinfo, JERR_BMP_BADPLANES);

160
rdjpeg.c
View File

@@ -1,160 +0,0 @@
/*
* rdjpeg.c
*
* Copyright (C) 1991-1996, Thomas G. Lane.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
*/
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#if JPEG_RAW_READER
#define NUM_ROWS 32
#endif
/* Private version of data source object */
typedef struct _jpeg_source_struct * jpeg_source_ptr;
typedef struct _jpeg_source_struct {
struct cjpeg_source_struct pub; /* public fields */
j_compress_ptr cinfo; /* back link saves passing separate parm */
struct jpeg_decompress_struct dinfo;
struct jpeg_error_mgr jerr;
} jpeg_source_struct;
METHODDEF(JDIMENSION)
get_rows (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
#if !JPEG_RAW_READER
return jpeg_read_scanlines(&source->dinfo, source->pub.buffer, source->pub.buffer_height);
#else
jpeg_read_raw_data(&source->dinfo, source->pub.plane_pointer, 8*cinfo->max_v_samp_factor);
return 8*cinfo->max_v_samp_factor;
#endif
}
/*
* Read the file header; return image size and component count.
*/
METHODDEF(void)
start_input_jpeg (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
#if JPEG_RAW_READER
int i;
#endif
int m;
jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
source->dinfo.err = jpeg_std_error(&source->jerr);
jpeg_create_decompress(&source->dinfo);
jpeg_stdio_src(&source->dinfo, source->pub.input_file);
jpeg_save_markers(&source->dinfo, JPEG_COM, 0xFFFF);
for (m = 0; m < 16; m++)
jpeg_save_markers(&source->dinfo, JPEG_APP0 + m, 0xFFFF);
jpeg_read_header(&source->dinfo, TRUE);
source->pub.marker_list = source->dinfo.marker_list;
#if !JPEG_RAW_READER
source->dinfo.raw_data_out = FALSE;
jpeg_start_decompress(&source->dinfo);
cinfo->in_color_space = source->dinfo.out_color_space;
cinfo->input_components = source->dinfo.output_components;
cinfo->data_precision = source->dinfo.data_precision;
cinfo->image_width = source->dinfo.image_width;
cinfo->image_height = source->dinfo.image_height;
cinfo->raw_data_in = FALSE;
source->pub.buffer = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) (cinfo->image_width * cinfo->input_components), (JDIMENSION) 1);
source->pub.buffer_height = 1;
#else
source->dinfo.raw_data_out = TRUE;
source->dinfo.do_fancy_upsampling = FALSE;
jpeg_start_decompress(&source->dinfo);
cinfo->in_color_space = source->dinfo.out_color_space;
cinfo->input_components = source->dinfo.output_components;
cinfo->data_precision = source->dinfo.data_precision;
cinfo->image_width = source->dinfo.image_width;
cinfo->image_height = source->dinfo.image_height;
jpeg_set_colorspace(cinfo, source->dinfo.jpeg_color_space);
cinfo->max_v_samp_factor = source->dinfo.max_v_samp_factor;
cinfo->max_h_samp_factor = source->dinfo.max_h_samp_factor;
cinfo->raw_data_in = TRUE;
#if JPEG_LIB_VERSION >= 70
cinfo->do_fancy_upsampling = FALSE;
#endif
for (i = 0; i < cinfo->input_components; i++) {
cinfo->comp_info[i].h_samp_factor = source->dinfo.comp_info[i].h_samp_factor;
cinfo->comp_info[i].v_samp_factor = source->dinfo.comp_info[i].v_samp_factor;
source->pub.plane_pointer[i] = (*cinfo->mem->alloc_sarray)
((j_common_ptr) cinfo, JPOOL_IMAGE,
(JDIMENSION) cinfo->image_width, (JDIMENSION) NUM_ROWS);
}
#endif
source->pub.get_pixel_rows = get_rows;
}
/*
* Finish up at the end of the file.
*/
METHODDEF(void)
finish_input_jpeg (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
jpeg_source_ptr source = (jpeg_source_ptr) sinfo;
jpeg_finish_decompress(&source->dinfo);
jpeg_destroy_decompress(&source->dinfo);
}
/*
* The module selection routine for JPEG format input.
*/
GLOBAL(cjpeg_source_ptr)
jinit_read_jpeg (j_compress_ptr cinfo)
{
jpeg_source_ptr source;
/* Create module interface object */
source = (jpeg_source_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
sizeof(jpeg_source_struct));
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_jpeg;
source->pub.finish_input = finish_input_jpeg;
return (cjpeg_source_ptr) source;
}

120
rdpng.c
View File

@@ -1,120 +0,0 @@
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#ifdef PNG_SUPPORTED
#include <png.h> /* if this fails, you need to install libpng-devel */
typedef struct png_source_struct {
struct cjpeg_source_struct pub;
png_structp png_ptr;
png_infop info_ptr;
JDIMENSION current_row;
} png_source_struct;
METHODDEF(void)
finish_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
METHODDEF(JDIMENSION)
get_pixel_rows_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
METHODDEF(void)
start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
GLOBAL(cjpeg_source_ptr)
jinit_read_png(j_compress_ptr cinfo)
{
png_source_struct *source = (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_IMAGE, sizeof(png_source_struct));
memset(source, 0, sizeof(*source));
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_png;
source->pub.finish_input = finish_input_png;
return &source->pub;
}
METHODDEF(void) error_input_png(png_structp png_ptr, png_const_charp msg) {
j_compress_ptr cinfo = png_get_error_ptr(png_ptr);
ERREXITS(cinfo, JERR_PNG_ERROR, msg);
}
METHODDEF(void)
start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_struct *source = (png_source_struct *)sinfo;
source->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, cinfo, error_input_png, NULL);
source->info_ptr = png_create_info_struct(source->png_ptr);
if (!source->png_ptr || !source->info_ptr) {
ERREXITS(cinfo, JERR_PNG_ERROR, "Can't create read/info_struct");
return;
}
png_set_palette_to_rgb(source->png_ptr);
png_set_expand_gray_1_2_4_to_8(source->png_ptr);
png_set_strip_alpha(source->png_ptr);
png_set_interlace_handling(source->png_ptr);
png_init_io(source->png_ptr, source->pub.input_file);
png_read_info(source->png_ptr, source->info_ptr);
png_uint_32 width, height;
int bit_depth, color_type;
png_get_IHDR(source->png_ptr, source->info_ptr, &width, &height,
&bit_depth, &color_type, NULL, NULL, NULL);
if (color_type == PNG_COLOR_TYPE_GRAY) {
cinfo->in_color_space = JCS_GRAYSCALE;
cinfo->input_components = 1;
} else {
cinfo->in_color_space = JCS_RGB;
cinfo->input_components = 3;
}
if (bit_depth == 16)
png_set_strip_16(source->png_ptr);
cinfo->data_precision = 8;
cinfo->image_width = width;
cinfo->image_height = height;
double gamma = 0.45455;
if (!png_get_valid(source->png_ptr, source->info_ptr, PNG_INFO_sRGB)) {
png_get_gAMA(source->png_ptr, source->info_ptr, &gamma);
}
cinfo->input_gamma = gamma;
sinfo->get_pixel_rows = get_pixel_rows_png;
png_read_update_info(source->png_ptr, source->info_ptr);
png_size_t rowbytes = png_get_rowbytes(source->png_ptr, source->info_ptr);
source->pub.buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)rowbytes, 1);
source->pub.buffer_height = 1;
}
METHODDEF(JDIMENSION)
get_pixel_rows_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_struct *source = (png_source_struct *)sinfo;
png_read_row(source->png_ptr, source->pub.buffer[0], NULL);
return 1;
}
METHODDEF(void)
finish_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_struct *source = (png_source_struct *)sinfo;
png_read_end(source->png_ptr, source->info_ptr);
png_destroy_read_struct(&source->png_ptr, &source->info_ptr, NULL);
}
#endif

View File

@@ -251,7 +251,7 @@ get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
ptr = source->pub.buffer[0]; ptr = source->pub.buffer[0];
bufferptr = source->iobuffer; bufferptr = source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) { for (col = cinfo->image_width; col > 0; col--) {
register int temp; register unsigned int temp;
temp = UCH(*bufferptr++) << 8; temp = UCH(*bufferptr++) << 8;
temp |= UCH(*bufferptr++); temp |= UCH(*bufferptr++);
if (temp > maxval) if (temp > maxval)
@@ -278,7 +278,7 @@ get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
ptr = source->pub.buffer[0]; ptr = source->pub.buffer[0];
bufferptr = source->iobuffer; bufferptr = source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) { for (col = cinfo->image_width; col > 0; col--) {
register int temp; register unsigned int temp;
temp = UCH(*bufferptr++) << 8; temp = UCH(*bufferptr++) << 8;
temp |= UCH(*bufferptr++); temp |= UCH(*bufferptr++);
if (temp > maxval) if (temp > maxval)

View File

@@ -267,9 +267,6 @@ bogus:
MEMCOPY(scanptr, scans, scanno * sizeof(jpeg_scan_info)); MEMCOPY(scanptr, scans, scanno * sizeof(jpeg_scan_info));
cinfo->scan_info = scanptr; cinfo->scan_info = scanptr;
cinfo->num_scans = scanno; cinfo->num_scans = scanno;
/* Disable scan optimization if using custom scan */
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OPTIMIZE_SCANS, FALSE);
} }
fclose(fp); fclose(fp);
@@ -284,10 +281,7 @@ bogus:
* The spec says that the values given produce "good" quality, and * The spec says that the values given produce "good" quality, and
* when divided by 2, "very good" quality. * when divided by 2, "very good" quality.
*/ */
static const unsigned int std_luminance_quant_tbl[9][DCTSIZE2] = { static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
{
/* JPEG Annex K
*/
16, 11, 10, 16, 24, 40, 51, 61, 16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55, 12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56, 14, 13, 16, 24, 40, 57, 69, 56,
@@ -296,105 +290,8 @@ static const unsigned int std_luminance_quant_tbl[9][DCTSIZE2] = {
24, 35, 55, 64, 81, 104, 113, 92, 24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101, 49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99 72, 92, 95, 98, 112, 100, 103, 99
},
{
/* flat
*/
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
},
{
12, 17, 20, 21, 30, 34, 56, 63,
18, 20, 20, 26, 28, 51, 61, 55,
19, 20, 21, 26, 33, 58, 69, 55,
26, 26, 26, 30, 46, 87, 86, 66,
31, 33, 36, 40, 46, 96, 100, 73,
40, 35, 46, 62, 81, 100, 111, 91,
46, 66, 76, 86, 102, 121, 120, 101,
68, 90, 90, 96, 113, 102, 105, 103
},
{
/* From http://www.imagemagick.org/discourse-server/viewtopic.php?f=22&t=20333&p=98008#p98008
*/
16, 16, 16, 18, 25, 37, 56, 85,
16, 17, 20, 27, 34, 40, 53, 75,
16, 20, 24, 31, 43, 62, 91, 135,
18, 27, 31, 40, 53, 74, 106, 156,
25, 34, 43, 53, 69, 94, 131, 189,
37, 40, 62, 74, 94, 124, 169, 238,
56, 53, 91, 106, 131, 169, 226, 311,
85, 75, 135, 156, 189, 238, 311, 418
},
{
9, 10, 12, 14, 27, 32, 51, 62,
11, 12, 14, 19, 27, 44, 59, 73,
12, 14, 18, 25, 42, 59, 79, 78,
17, 18, 25, 42, 61, 92, 87, 92,
23, 28, 42, 75, 79, 112, 112, 99,
40, 42, 59, 84, 88, 124, 132, 111,
42, 64, 78, 95, 105, 126, 125, 99,
70, 75, 100, 102, 116, 100, 107, 98
},
{
/* Relevance of human vision to JPEG-DCT compression (1992) Klein, Silverstein and Carney.
*/
10, 12, 14, 19, 26, 38, 57, 86,
12, 18, 21, 28, 35, 41, 54, 76,
14, 21, 25, 32, 44, 63, 92, 136,
19, 28, 32, 41, 54, 75, 107, 157,
26, 35, 44, 54, 70, 95, 132, 190,
38, 41, 63, 75, 95, 125, 170, 239,
57, 54, 92, 107, 132, 170, 227, 312,
86, 76, 136, 157, 190, 239, 312, 419
},
{
/* DCTune perceptual optimization of compressed dental X-Rays (1997) Watson, Taylor, Borthwick
*/
7, 8, 10, 14, 23, 44, 95, 241,
8, 8, 11, 15, 25, 47, 102, 255,
10, 11, 13, 19, 31, 58, 127, 255,
14, 15, 19, 27, 44, 83, 181, 255,
23, 25, 31, 44, 72, 136, 255, 255,
44, 47, 58, 83, 136, 255, 255, 255,
95, 102, 127, 181, 255, 255, 255, 255,
241, 255, 255, 255, 255, 255, 255, 255
},
{
/* A visual detection model for DCT coefficient quantization (12/9/93) Ahumada, Watson, Peterson
*/
15, 11, 11, 12, 15, 19, 25, 32,
11, 13, 10, 10, 12, 15, 19, 24,
11, 10, 14, 14, 16, 18, 22, 27,
12, 10, 14, 18, 21, 24, 28, 33,
15, 12, 16, 21, 26, 31, 36, 42,
19, 15, 18, 24, 31, 38, 45, 53,
25, 19, 22, 28, 36, 45, 55, 65,
32, 24, 27, 33, 42, 53, 65, 77
},
{
/* An improved detection model for DCT coefficient quantization (1993) Peterson, Ahumada and Watson
*/
14, 10, 11, 14, 19, 25, 34, 45,
10, 11, 11, 12, 15, 20, 26, 33,
11, 11, 15, 18, 21, 25, 31, 38,
14, 12, 18, 24, 28, 33, 39, 47,
19, 15, 21, 28, 36, 43, 51, 59,
25, 20, 25, 33, 43, 54, 64, 74,
34, 26, 31, 39, 51, 64, 77, 91,
45, 33, 38, 47, 59, 74, 91, 108
}
}; };
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
static const unsigned int std_chrominance_quant_tbl[9][DCTSIZE2] = {
{
/* JPEG Annex K
*/
17, 18, 24, 47, 99, 99, 99, 99, 17, 18, 24, 47, 99, 99, 99, 99,
18, 21, 26, 66, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99,
24, 26, 56, 99, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99,
@@ -403,115 +300,15 @@ static const unsigned int std_chrominance_quant_tbl[9][DCTSIZE2] = {
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99 99, 99, 99, 99, 99, 99, 99, 99
},
{
/* flat
*/
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
},
{
8, 12, 15, 15, 86, 96, 96, 98,
13, 13, 15, 26, 90, 96, 99, 98,
12, 15, 18, 96, 99, 99, 99, 99,
17, 16, 90, 96, 99, 99, 99, 99,
96, 96, 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
},
{
/* From http://www.imagemagick.org/discourse-server/viewtopic.php?f=22&t=20333&p=98008#p98008
*/
16, 16, 16, 18, 25, 37, 56, 85,
16, 17, 20, 27, 34, 40, 53, 75,
16, 20, 24, 31, 43, 62, 91, 135,
18, 27, 31, 40, 53, 74, 106, 156,
25, 34, 43, 53, 69, 94, 131, 189,
37, 40, 62, 74, 94, 124, 169, 238,
56, 53, 91, 106, 131, 169, 226, 311,
85, 75, 135, 156, 189, 238, 311, 418
},
{
9, 10, 17, 19, 62, 89, 91, 97,
12, 13, 18, 29, 84, 91, 88, 98,
14, 19, 29, 93, 95, 95, 98, 97,
20, 26, 84, 88, 95, 95, 98, 94,
26, 86, 91, 93, 97, 99, 98, 99,
99, 100, 98, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
97, 97, 99, 99, 99, 99, 97, 99
},
{
/* Relevance of human vision to JPEG-DCT compression (1992) Klein, Silverstein and Carney.
* Copied from luma
*/
10, 12, 14, 19, 26, 38, 57, 86,
12, 18, 21, 28, 35, 41, 54, 76,
14, 21, 25, 32, 44, 63, 92, 136,
19, 28, 32, 41, 54, 75, 107, 157,
26, 35, 44, 54, 70, 95, 132, 190,
38, 41, 63, 75, 95, 125, 170, 239,
57, 54, 92, 107, 132, 170, 227, 312,
86, 76, 136, 157, 190, 239, 312, 419
},
{
/* DCTune perceptual optimization of compressed dental X-Rays (1997) Watson, Taylor, Borthwick
* Copied from luma
*/
7, 8, 10, 14, 23, 44, 95, 241,
8, 8, 11, 15, 25, 47, 102, 255,
10, 11, 13, 19, 31, 58, 127, 255,
14, 15, 19, 27, 44, 83, 181, 255,
23, 25, 31, 44, 72, 136, 255, 255,
44, 47, 58, 83, 136, 255, 255, 255,
95, 102, 127, 181, 255, 255, 255, 255,
241, 255, 255, 255, 255, 255, 255, 255
},
{
/* A visual detection model for DCT coefficient quantization (12/9/93) Ahumada, Watson, Peterson
* Copied from luma
*/
15, 11, 11, 12, 15, 19, 25, 32,
11, 13, 10, 10, 12, 15, 19, 24,
11, 10, 14, 14, 16, 18, 22, 27,
12, 10, 14, 18, 21, 24, 28, 33,
15, 12, 16, 21, 26, 31, 36, 42,
19, 15, 18, 24, 31, 38, 45, 53,
25, 19, 22, 28, 36, 45, 55, 65,
32, 24, 27, 33, 42, 53, 65, 77
},
{
/* An improved detection model for DCT coefficient quantization (1993) Peterson, Ahumada and Watson
* Copied from luma
*/
14, 10, 11, 14, 19, 25, 34, 45,
10, 11, 11, 12, 15, 20, 26, 33,
11, 11, 15, 18, 21, 25, 31, 38,
14, 12, 18, 24, 28, 33, 39, 47,
19, 15, 21, 28, 36, 43, 51, 59,
25, 20, 25, 33, 43, 54, 64, 74,
34, 26, 31, 39, 51, 64, 77, 91,
45, 33, 38, 47, 59, 74, 91, 108
}
}; };
LOCAL(void) LOCAL(void)
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline) jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
{ {
int quant_tbl_master_idx = 0; jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
if (jpeg_c_int_param_supported(cinfo, JINT_BASE_QUANT_TBL_IDX))
quant_tbl_master_idx = jpeg_c_get_int_param(cinfo, JINT_BASE_QUANT_TBL_IDX);
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl[quant_tbl_master_idx],
q_scale_factor[0], force_baseline); q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl[quant_tbl_master_idx], jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
q_scale_factor[1], force_baseline); q_scale_factor[1], force_baseline);
} }
#endif #endif
@@ -524,46 +321,35 @@ set_quality_ratings (j_compress_ptr cinfo, char *arg, boolean force_baseline)
* If there are more q-table slots than parameters, the last value is replicated. * If there are more q-table slots than parameters, the last value is replicated.
*/ */
{ {
float val = 75.f; /* default value */ int val = 75; /* default value */
int tblno; int tblno;
char ch; char ch;
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
if (*arg) { if (*arg) {
ch = ','; /* if not set by sscanf, will be ',' */ ch = ','; /* if not set by sscanf, will be ',' */
if (sscanf(arg, "%f%c", &val, &ch) < 1) if (sscanf(arg, "%d%c", &val, &ch) < 1)
return FALSE; return FALSE;
if (ch != ',') /* syntax check */ if (ch != ',') /* syntax check */
return FALSE; return FALSE;
/* Convert user 0-100 rating to percentage scaling */ /* Convert user 0-100 rating to percentage scaling */
#if JPEG_LIB_VERSION >= 70 #if JPEG_LIB_VERSION >= 70
cinfo->q_scale_factor[tblno] = jpeg_float_quality_scaling(val); cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
#else #else
q_scale_factor[tblno] = jpeg_float_quality_scaling(val); q_scale_factor[tblno] = jpeg_quality_scaling(val);
#endif #endif
while (*arg && *arg++ != ',') /* advance to next segment of arg string */ while (*arg && *arg++ != ',') /* advance to next segment of arg string */
; ;
} else { } else {
/* reached end of parameter, set remaining factors to last value */ /* reached end of parameter, set remaining factors to last value */
#if JPEG_LIB_VERSION >= 70 #if JPEG_LIB_VERSION >= 70
cinfo->q_scale_factor[tblno] = jpeg_float_quality_scaling(val); cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
#else #else
q_scale_factor[tblno] = jpeg_float_quality_scaling(val); q_scale_factor[tblno] = jpeg_quality_scaling(val);
#endif #endif
} }
} }
jpeg_default_qtables(cinfo, force_baseline); jpeg_default_qtables(cinfo, force_baseline);
/* For some images chroma subsampling significantly degrades color quality,
making it impossible to achieve high visual quality regardless of quality setting.
To make the quality setting more intuitive, disable subsampling when high-quality
color is desired. */
if (val >= 90) {
set_sample_factors(cinfo, "1x1");
} else if (val >= 80) {
set_sample_factors(cinfo, "2x1");
}
return TRUE; return TRUE;
} }

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="1"> <installer-gui-script minSpecVersion="1">
<title>mozjpeg</title> <title>libjpeg-turbo</title>
<welcome file="Welcome.rtf" /> <welcome file="Welcome.rtf" />
<readme file="ReadMe.txt" /> <readme file="ReadMe.txt" />
<license file="License.rtf" /> <license file="License.rtf" />
@@ -12,13 +12,13 @@
<options customize="never" /> <options customize="never" />
<choices-outline> <choices-outline>
<line choice="default"> <line choice="default">
<line choice="com.mozilla.mozjpeg"/> <line choice="com.libjpeg-turbo.libjpeg-turbo"/>
</line> </line>
</choices-outline> </choices-outline>
<choice id="default"/> <choice id="default"/>
<choice id="com.mozilla.mozjpeg" visible="false"> <choice id="com.libjpeg-turbo.libjpeg-turbo" visible="false">
<pkg-ref id="com.mozilla.mozjpeg"/> <pkg-ref id="com.libjpeg-turbo.libjpeg-turbo"/>
</choice> </choice>
<pkg-ref auth="root" <pkg-ref auth="root"
id="com.mozilla.mozjpeg">mozjpeg.pkg</pkg-ref> id="com.libjpeg-turbo.libjpeg-turbo">libjpeg-turbo.pkg</pkg-ref>
</installer-gui-script> </installer-gui-script>

View File

@@ -12,7 +12,7 @@
\pard\tx220\tx720\pardeftab720\li720\fi-720 \pard\tx220\tx720\pardeftab720\li720\fi-720
\ls1\ilvl0\cf0 {\listtext \'95 }Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\ \ls1\ilvl0\cf0 {\listtext \'95 }Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\
{\listtext \'95 }Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\ {\listtext \'95 }Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\
{\listtext \'95 }Neither the name of the mozjpeg Project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\ {\listtext \'95 }Neither the name of the libjpeg-turbo Project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\
\pard\pardeftab720\qc \pard\pardeftab720\qc
\cf0 \ \cf0 \
\pard\pardeftab720 \pard\pardeftab720

View File

@@ -1,18 +1,17 @@
{\rtf1\ansi\ansicpg1252\cocoartf1404\cocoasubrtf460 {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360
{\fonttbl\f0\fnil\fcharset0 Menlo-Regular;} {\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 CourierNewPSMT;}
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red203\green233\blue242;} {\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\deftab720 \deftab720
\pard\tx529\tx1059\tx1589\tx2119\tx2649\tx3178\tx3708\tx4238\tx4768\tx5298\tx5827\tx6357\tx6887\tx7417\tx7947\tx8476\tx9006\tx9536\tx10066\tx10596\tx11125\tx11655\tx12185\tx12715\tx13245\tx13774\tx14304\tx14834\tx15364\tx15894\tx16423\tx16953\tx17483\tx18013\tx18543\tx19072\tx19602\tx20132\tx20662\tx21192\tx21722\tx22251\tx22781\tx23311\tx23841\tx24371\tx24900\tx25430\tx25960\tx26490\tx27020\tx27549\tx28079\tx28609\tx29139\tx29669\tx30198\tx30728\tx31258\tx31788\tx32318\tx32847\tx33377\tx33907\tx34437\tx34967\tx35496\tx36026\tx36556\tx37086\tx37616\tx38145\tx38675\tx39205\tx39735\tx40265\tx40794\tx41324\tx41854\tx42384\tx42914\tx43443\tx43973\tx44503\tx45033\tx45563\tx46093\tx46622\tx47152\tx47682\tx48212\tx48742\tx49271\tx49801\tx50331\tx50861\tx51391\tx51920\tx52450\tx52980\pardeftab720\li529\fi-530\partightenfactor0 \pard\pardeftab720\ql\qnatural
\f0\fs22 \cf2 \CocoaLigature0 TThi /opt/mozjpeg/bin/uninstall\ \f0\fs24 \cf0 This installer will install the libjpeg-turbo SDK and run-time libraries onto your computer so that you can use libjpeg-turbo to build new applications or accelerate existing ones. To remove the libjpeg-turbo package, run\
\pard\tx529\tx1059\tx1589\tx2119\tx2649\tx3178\tx3708\tx4238\tx4768\tx5298\tx5827\tx6357\tx6887\tx7417\tx7947\tx8476\tx9006\tx9536\tx10066\tx10596\tx11125\tx11655\tx12185\tx12715\tx13245\tx13774\tx14304\tx14834\tx15364\tx15894\tx16423\tx16953\tx17483\tx18013\tx18543\tx19072\tx19602\tx20132\tx20662\tx21192\tx21722\tx22251\tx22781\tx23311\tx23841\tx24371\tx24900\tx25430\tx25960\tx26490\tx27020\tx27549\tx28079\tx28609\tx29139\tx29669\tx30198\tx30728\tx31258\tx31788\tx32318\tx32847\tx33377\tx33907\tx34437\tx34967\tx35496\tx36026\tx36556\tx37086\tx37616\tx38145\tx38675\tx39205\tx39735\tx40265\tx40794\tx41324\tx41854\tx42384\tx42914\tx43443\tx43973\tx44503\tx45033\tx45563\tx46093\tx46622\tx47152\tx47682\tx48212\tx48742\tx49271\tx49801\tx50331\tx50861\tx51391\tx51920\tx52450\tx52980\pardeftab720\li662\fi-663\partightenfactor0
\cf2 installer will install the mozjpeg SDK and run-time libraries onto your computer so that you can use mozjpeg to build new applications. To remove the mozjpeg package, run\
\pard\tx529\tx1059\tx1589\tx2119\tx2649\tx3178\tx3708\tx4238\tx4768\tx5298\tx5827\tx6357\tx6887\tx7417\tx7947\tx8476\tx9006\tx9536\tx10066\tx10596\tx11125\tx11655\tx12185\tx12715\tx13245\tx13774\tx14304\tx14834\tx15364\tx15894\tx16423\tx16953\tx17483\tx18013\tx18543\tx19072\tx19602\tx20132\tx20662\tx21192\tx21722\tx22251\tx22781\tx23311\tx23841\tx24371\tx24900\tx25430\tx25960\tx26490\tx27020\tx27549\tx28079\tx28609\tx29139\tx29669\tx30198\tx30728\tx31258\tx31788\tx32318\tx32847\tx33377\tx33907\tx34437\tx34967\tx35496\tx36026\tx36556\tx37086\tx37616\tx38145\tx38675\tx39205\tx39735\tx40265\tx40794\tx41324\tx41854\tx42384\tx42914\tx43443\tx43973\tx44503\tx45033\tx45563\tx46093\tx46622\tx47152\tx47682\tx48212\tx48742\tx49271\tx49801\tx50331\tx50861\tx51391\tx51920\tx52450\tx52980\pardeftab720\li529\fi-530\partightenfactor0
\cf2 is installer will install the \cb3 mozjpeg\cb1 SDK and run-time libraries onto your computer so that you can use \cb3 mozjpeg\cb1 to build new applications. To remove the \cb3 mozjpeg\cb1 package, run\
\ \
\pard\tx529\tx1059\tx1589\tx2119\tx2649\tx3178\tx3708\tx4238\tx4768\tx5298\tx5827\tx6357\tx6887\tx7417\tx7947\tx8476\tx9006\tx9536\tx10066\tx10596\tx11125\tx11655\tx12185\tx12715\tx13245\tx13774\tx14304\tx14834\tx15364\tx15894\tx16423\tx16953\tx17483\tx18013\tx18543\tx19072\tx19602\tx20132\tx20662\tx21192\tx21722\tx22251\tx22781\tx23311\tx23841\tx24371\tx24900\tx25430\tx25960\tx26490\tx27020\tx27549\tx28079\tx28609\tx29139\tx29669\tx30198\tx30728\tx31258\tx31788\tx32318\tx32847\tx33377\tx33907\tx34437\tx34967\tx35496\tx36026\tx36556\tx37086\tx37616\tx38145\tx38675\tx39205\tx39735\tx40265\tx40794\tx41324\tx41854\tx42384\tx42914\tx43443\tx43973\tx44503\tx45033\tx45563\tx46093\tx46622\tx47152\tx47682\tx48212\tx48742\tx49271\tx49801\tx50331\tx50861\tx51391\tx51920\tx52450\tx52980\pardeftab720\li794\fi-795\partightenfactor0 \pard\pardeftab720\ql\qnatural
\cf2 /opt/\cb3 mozjpeg\cb1 /bin/uninstall\
\pard\tx529\tx1059\tx1589\tx2119\tx2649\tx3178\tx3708\tx4238\tx4768\tx5298\tx5827\tx6357\tx6887\tx7417\tx7947\tx8476\tx9006\tx9536\tx10066\tx10596\tx11125\tx11655\tx12185\tx12715\tx13245\tx13774\tx14304\tx14834\tx15364\tx15894\tx16423\tx16953\tx17483\tx18013\tx18543\tx19072\tx19602\tx20132\tx20662\tx21192\tx21722\tx22251\tx22781\tx23311\tx23841\tx24371\tx24900\tx25430\tx25960\tx26490\tx27020\tx27549\tx28079\tx28609\tx29139\tx29669\tx30198\tx30728\tx31258\tx31788\tx32318\tx32847\tx33377\tx33907\tx34437\tx34967\tx35496\tx36026\tx36556\tx37086\tx37616\tx38145\tx38675\tx39205\tx39735\tx40265\tx40794\tx41324\tx41854\tx42384\tx42914\tx43443\tx43973\tx44503\tx45033\tx45563\tx46093\tx46622\tx47152\tx47682\tx48212\tx48742\tx49271\tx49801\tx50331\tx50861\tx51391\tx51920\tx52450\tx52980\pardeftab720\li560\fi-561\partightenfactor0 \f1 \cf0 /opt/libjpeg-turbo/bin/uninstall\
\cf2 \ \pard\pardeftab720\ql\qnatural
\f0 \cf0 \
from the command line.\ from the command line.\
} }

View File

@@ -4,21 +4,28 @@ Section: misc
Priority: optional Priority: optional
Architecture: {__ARCH} Architecture: {__ARCH}
Essential: no Essential: no
Maintainer: Mozilla Research <joshmoz@gmail.com> Maintainer: The libjpeg-turbo Project <information@libjpeg-turbo.org>
Homepage: https://github.com/mozilla/mozjpeg Homepage: http://www.libjpeg-turbo.org
Installed-Size: {__SIZE} Installed-Size: {__SIZE}
Description: A JPEG codec that provides increased compression for JPEG images (at the expense of compression performance) Description: A SIMD-accelerated JPEG codec that provides both the libjpeg and TurboJPEG APIs
mozjpeg is a fork of libjpeg-turbo that aims to speed up load times of web libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
pages by reducing the size (and, by extension, the transmission time) of JPEG NEON, AltiVec) to accelerate baseline JPEG compression and decompression on
files. It accomplishes this by enabling optimized Huffman trees and x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
progressive entropy coding by default in the JPEG compressor, as well as generally 2-6x as fast as libjpeg, all else being equal. On other types of
splitting the spectrum of DCT coefficients into separate scans and using systems, libjpeg-turbo can still outperform libjpeg by a significant amount,
Trellis quantisation. by virtue of its highly-optimized Huffman coding routines. In many cases, the
performance of libjpeg-turbo rivals that of proprietary high-speed JPEG
codecs.
. .
Although it is based on libjpeg-turbo, mozjpeg is not intended to be a libjpeg-turbo implements both the traditional libjpeg API as well as the less
general-purpose or high-performance JPEG library. Its performance is highly powerful but more straightforward TurboJPEG API. libjpeg-turbo also features
"asymmetric". That is, the JPEG files it generates require much more time to colorspace extensions that allow it to compress from/decompress to 32-bit and
compress than to decompress. When the default settings are used, mozjpeg is big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java
considerably slower than libjpeg-turbo or even libjpeg at compressing images. interface.
Thus, it is not generally suitable for real-time compression. It is best used .
as part of a web encoding workflow. libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated
derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and
VirtualGL projects made numerous enhancements to the codec in 2009, and in
early 2010, libjpeg-turbo spun off into an independent project, with the goal
of making high-speed JPEG compression/decompression technology available to a
broader range of users and developers.

View File

@@ -80,7 +80,7 @@ Section "@CMAKE_PROJECT_NAME@ SDK for @INST_PLATFORM@ (required)"
File "@CMAKE_SOURCE_DIR@\turbojpeg.h" File "@CMAKE_SOURCE_DIR@\turbojpeg.h"
SetOutPath $INSTDIR\doc SetOutPath $INSTDIR\doc
File "@CMAKE_SOURCE_DIR@\README.ijg" File "@CMAKE_SOURCE_DIR@\README.ijg"
File "@CMAKE_SOURCE_DIR@\README-mozilla.txt" File "@CMAKE_SOURCE_DIR@\README.md"
File "@CMAKE_SOURCE_DIR@\LICENSE.md" File "@CMAKE_SOURCE_DIR@\LICENSE.md"
File "@CMAKE_SOURCE_DIR@\example.c" File "@CMAKE_SOURCE_DIR@\example.c"
File "@CMAKE_SOURCE_DIR@\libjpeg.txt" File "@CMAKE_SOURCE_DIR@\libjpeg.txt"
@@ -142,7 +142,7 @@ Section "Uninstall"
Delete $INSTDIR\include\turbojpeg.h" Delete $INSTDIR\include\turbojpeg.h"
Delete $INSTDIR\uninstall_@VERSION@.exe Delete $INSTDIR\uninstall_@VERSION@.exe
Delete $INSTDIR\doc\README.ijg Delete $INSTDIR\doc\README.ijg
Delete $INSTDIR\doc\README-mozilla.txt Delete $INSTDIR\doc\README.md
Delete $INSTDIR\doc\LICENSE.md Delete $INSTDIR\doc\LICENSE.md
Delete $INSTDIR\doc\example.c Delete $INSTDIR\doc\example.c
Delete $INSTDIR\doc\libjpeg.txt Delete $INSTDIR\doc\libjpeg.txt

View File

@@ -1,4 +1,4 @@
# Path under which mozjpeg should be installed # Path under which libjpeg-turbo should be installed
%define _prefix %{__prefix} %define _prefix %{__prefix}
# Path under which executables should be installed # Path under which executables should be installed
@@ -17,7 +17,7 @@
%ifarch x86_64 %ifarch x86_64
%define _lib lib64 %define _lib lib64
%else %else
%if "%{_prefix}" == "/opt/mozjpeg" %if "%{_prefix}" == "/opt/libjpeg-turbo"
%define _lib lib32 %define _lib lib32
%endif %endif
%endif %endif
@@ -25,13 +25,13 @@
# Path under which man pages should be installed # Path under which man pages should be installed
%define _mandir %{__mandir} %define _mandir %{__mandir}
Summary: A JPEG codec that provides increased compression for JPEG images (at the expense of compression performance) Summary: A SIMD-accelerated JPEG codec that provides both the libjpeg and TurboJPEG APIs
Name: @PKGNAME@ Name: @PKGNAME@
Version: @VERSION@ Version: @VERSION@
Vendor: Mozilla Research Vendor: The libjpeg-turbo Project
URL: https://github.com/mozilla/mozjpeg URL: http://www.libjpeg-turbo.org
Group: System Environment/Libraries Group: System Environment/Libraries
#-->Source0: https://github.com/mozilla/mozjpeg/archive/v%{version}.tar.gz #-->Source0: http://prdownloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-%{version}.tar.gz
Release: @BUILD@ Release: @BUILD@
License: BSD-style License: BSD-style
BuildRoot: %{_blddir}/%{name}-buildroot-%{version}-%{release} BuildRoot: %{_blddir}/%{name}-buildroot-%{version}-%{release}
@@ -43,23 +43,29 @@ Provides: %{name} = %{version}-%{release}, @PACKAGE_NAME@ = %{version}-%{release
%endif %endif
%description %description
mozjpeg is a fork of libjpeg-turbo that aims to speed up load times of web libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2,
pages by reducing the size (and, by extension, the transmission time) of JPEG NEON, AltiVec) to accelerate baseline JPEG compression and decompression on
files. It accomplishes this by enabling optimized Huffman trees and x86, x86-64, ARM, and PowerPC systems. On such systems, libjpeg-turbo is
progressive entropy coding by default in the JPEG compressor, as well as generally 2-6x as fast as libjpeg, all else being equal. On other types of
splitting the spectrum of DCT coefficients into separate scans and using systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by
Trellis quantisation. virtue of its highly-optimized Huffman coding routines. In many cases, the
performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.
Although it is based on libjpeg-turbo, mozjpeg is not intended to be a libjpeg-turbo implements both the traditional libjpeg API as well as the less
general-purpose or high-performance JPEG library. Its performance is highly powerful but more straightforward TurboJPEG API. libjpeg-turbo also features
"asymmetric". That is, the JPEG files it generates require much more time to colorspace extensions that allow it to compress from/decompress to 32-bit and
compress than to decompress. When the default settings are used, mozjpeg is big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java
considerably slower than libjpeg-turbo or even libjpeg at compressing images. interface.
Thus, it is not generally suitable for real-time compression. It is best used
as part of a web encoding workflow. libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated
derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and
VirtualGL projects made numerous enhancements to the codec in 2009, and in
early 2010, libjpeg-turbo spun off into an independent project, with the goal
of making high-speed JPEG compression/decompression technology available to a
broader range of users and developers.
#-->%prep #-->%prep
#-->%setup -q -n mozjpeg-%{version} #-->%setup -q -n libjpeg-turbo-%{version}
#-->%build #-->%build
#-->./configure prefix=%{_prefix} bindir=%{_bindir} datadir=%{_datadir} \ #-->./configure prefix=%{_prefix} bindir=%{_bindir} datadir=%{_datadir} \
@@ -80,14 +86,14 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
LJT_LIBDIR=%{__libdir} LJT_LIBDIR=%{__libdir}
if [ ! "$LJT_LIBDIR" = "%{_libdir}" ]; then if [ ! "$LJT_LIBDIR" = "%{_libdir}" ]; then
echo ERROR: mozjpeg must be configured with libdir=%{_prefix}/%{_lib} when generating an in-tree RPM for this architecture. echo ERROR: libjpeg-turbo must be configured with libdir=%{_prefix}/%{_lib} when generating an in-tree RPM for this architecture.
exit 1 exit 1
fi fi
#-->%endif #-->%endif
LJT_DOCDIR=%{__docdir} LJT_DOCDIR=%{__docdir}
if [ "%{_prefix}" = "/opt/mozjpeg" -a "$LJT_DOCDIR" = "/opt/mozjpeg/doc" ]; then if [ "%{_prefix}" = "/opt/libjpeg-turbo" -a "$LJT_DOCDIR" = "/opt/libjpeg-turbo/doc" ]; then
ln -fs %{_docdir} $RPM_BUILD_ROOT/$LJT_DOCDIR ln -fs %{_docdir} $RPM_BUILD_ROOT/$LJT_DOCDIR
fi fi
@@ -103,7 +109,7 @@ rm -rf $RPM_BUILD_ROOT
%dir %{_docdir} %dir %{_docdir}
%doc %{_docdir}/* %doc %{_docdir}/*
%dir %{_prefix} %dir %{_prefix}
%if "%{_prefix}" == "/opt/mozjpeg" && "%{_docdir}" != "%{_prefix}/doc" %if "%{_prefix}" == "/opt/libjpeg-turbo" && "%{_docdir}" != "%{_prefix}/doc"
%{_prefix}/doc %{_prefix}/doc
%endif %endif
%dir %{_bindir} %dir %{_bindir}

View File

@@ -31,7 +31,7 @@ __PWD=`pwd`
make install DESTDIR=$TMPDIR/pkg docdir=/usr/share/doc/$PACKAGE_NAME-$VERSION \ make install DESTDIR=$TMPDIR/pkg docdir=/usr/share/doc/$PACKAGE_NAME-$VERSION \
exampledir=/usr/share/doc/$PACKAGE_NAME-$VERSION exampledir=/usr/share/doc/$PACKAGE_NAME-$VERSION
rm $TMPDIR/pkg$LIBDIR/*.la rm $TMPDIR/pkg$LIBDIR/*.la
if [ "$PREFIX" = "/opt/mozjpeg" -a "$DOCDIR" = "/opt/mozjpeg/doc" ]; then if [ "$PREFIX" = "/opt/libjpeg-turbo" -a "$DOCDIR" = "/opt/libjpeg-turbo/doc" ]; then
ln -fs /usr/share/doc/$PACKAGE_NAME-$VERSION $TMPDIR/pkg$DOCDIR ln -fs /usr/share/doc/$PACKAGE_NAME-$VERSION $TMPDIR/pkg$DOCDIR
fi fi
cd $TMPDIR/pkg cd $TMPDIR/pkg

View File

@@ -45,7 +45,7 @@ makedeb()
make install DESTDIR=$TMPDIR docdir=/usr/share/doc/$DIRNAME-$VERSION \ make install DESTDIR=$TMPDIR docdir=/usr/share/doc/$DIRNAME-$VERSION \
exampledir=/usr/share/doc/$DIRNAME-$VERSION exampledir=/usr/share/doc/$DIRNAME-$VERSION
rm -f $TMPDIR$LIBDIR/*.la rm -f $TMPDIR$LIBDIR/*.la
if [ "$PREFIX" = "/opt/mozjpeg" -a "$DOCDIR" = "/opt/mozjpeg/doc" ]; then if [ "$PREFIX" = "/opt/libjpeg-turbo" -a "$DOCDIR" = "/opt/libjpeg-turbo/doc" ]; then
ln -fs /usr/share/doc/$DIRNAME-$VERSION $TMPDIR$DOCDIR ln -fs /usr/share/doc/$DIRNAME-$VERSION $TMPDIR$DOCDIR
fi fi
fi fi

View File

@@ -109,7 +109,7 @@ make install DESTDIR=$PKGROOT docdir=/Library/Documentation/$PACKAGE_NAME \
exampledir=/Library/Documentation/$PACKAGE_NAME exampledir=/Library/Documentation/$PACKAGE_NAME
rm -f $PKGROOT$LIBDIR/*.la rm -f $PKGROOT$LIBDIR/*.la
if [ "$PREFIX" = "/opt/mozjpeg" -a "$DOCDIR" = "/opt/mozjpeg/doc" ]; then if [ "$PREFIX" = "/opt/libjpeg-turbo" -a "$DOCDIR" = "/opt/libjpeg-turbo/doc" ]; then
ln -fs /Library/Documentation/$PACKAGE_NAME $PKGROOT$DOCDIR ln -fs /Library/Documentation/$PACKAGE_NAME $PKGROOT$DOCDIR
fi fi
@@ -440,7 +440,7 @@ install_name_tool -id $LIBDIR/libturbojpeg.0.dylib $PKGROOT/$LIBDIR/libturbojpeg
if [ $WITH_JAVA = 1 ]; then if [ $WITH_JAVA = 1 ]; then
ln -fs libturbojpeg.0.dylib $PKGROOT/$LIBDIR/libturbojpeg.jnilib ln -fs libturbojpeg.0.dylib $PKGROOT/$LIBDIR/libturbojpeg.jnilib
fi fi
if [ "$PREFIX" = "/opt/mozjpeg" -a "$LIBDIR" = "/opt/mozjpeg/lib" ]; then if [ "$PREFIX" = "/opt/libjpeg-turbo" -a "$LIBDIR" = "/opt/libjpeg-turbo/lib" ]; then
if [ ! -h $PKGROOT/$PREFIX/lib32 ]; then if [ ! -h $PKGROOT/$PREFIX/lib32 ]; then
ln -fs lib $PKGROOT/$PREFIX/lib32 ln -fs lib $PKGROOT/$PREFIX/lib32
fi fi
@@ -459,7 +459,7 @@ cp $SRCDIR/release/License.rtf $SRCDIR/release/Welcome.rtf $SRCDIR/release/ReadM
mkdir $TMPDIR/dmg mkdir $TMPDIR/dmg
pkgbuild --root $PKGROOT --version $VERSION.$BUILD \ pkgbuild --root $PKGROOT --version $VERSION.$BUILD \
--identifier com.mozilla.$PACKAGE_NAME $TMPDIR/pkg/$PACKAGE_NAME.pkg --identifier com.libjpeg-turbo.libjpeg-turbo $TMPDIR/pkg/$PACKAGE_NAME.pkg
productbuild --distribution $SRCDIR/release/Distribution.xml \ productbuild --distribution $SRCDIR/release/Distribution.xml \
--package-path $TMPDIR/pkg/ --resources $TMPDIR/pkg/ \ --package-path $TMPDIR/pkg/ --resources $TMPDIR/pkg/ \
$TMPDIR/dmg/$PACKAGE_NAME.pkg $TMPDIR/dmg/$PACKAGE_NAME.pkg

View File

@@ -8,7 +8,7 @@
# - Redistributions in binary form must reproduce the above copyright notice, # - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation # this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution. # and/or other materials provided with the distribution.
# - Neither the name of the mozjpeg Project nor the names of its # - Neither the name of the libjpeg-turbo Project nor the names of its
# contributors may be used to endorse or promote products derived from this # contributors may be used to endorse or promote products derived from this
# software without specific prior written permission. # software without specific prior written permission.
# #
@@ -32,7 +32,7 @@ if [ ! "`id -u`" = "0" ]; then
fi fi
PACKAGE=@PKGNAME@ PACKAGE=@PKGNAME@
MACPACKAGE=com.mozilla.$PACKAGE MACPACKAGE=com.$PACKAGE.$PACKAGE
RECEIPT=/Library/Receipts/$PACKAGE.pkg RECEIPT=/Library/Receipts/$PACKAGE.pkg
LSBOM= LSBOM=
@@ -75,7 +75,7 @@ fi
if [ -d $INCLUDEDIR ]; then if [ -d $INCLUDEDIR ]; then
rmdir $INCLUDEDIR 2>&1 || EXITSTATUS=-1 rmdir $INCLUDEDIR 2>&1 || EXITSTATUS=-1
fi fi
if [ "$PREFIX" = "/opt/mozjpeg" -a "$LIBDIR" = "/opt/mozjpeg/lib" ]; then if [ "$PREFIX" = "/opt/libjpeg-turbo" -a "$LIBDIR" = "/opt/libjpeg-turbo/lib" ]; then
if [ -h $LIBDIR\32 ]; then if [ -h $LIBDIR\32 ]; then
rm $LIBDIR\32 2>&1 || EXITSTATUS=-1 rm $LIBDIR\32 2>&1 || EXITSTATUS=-1
fi fi
@@ -95,7 +95,7 @@ fi
if [ -d $DATADIR -a "$DATADIR" != "$PREFIX" ]; then if [ -d $DATADIR -a "$DATADIR" != "$PREFIX" ]; then
rmdir $DATADIR 2>&1 || EXITSTATUS=-1 rmdir $DATADIR 2>&1 || EXITSTATUS=-1
fi fi
if [ "$PREFIX" = "/opt/mozjpeg" -a -h "$PREFIX/doc" ]; then if [ "$PREFIX" = "/opt/libjpeg-turbo" -a -h "$PREFIX/doc" ]; then
rm $PREFIX/doc 2>&1 || EXITSTATUS=-1 rm $PREFIX/doc 2>&1 || EXITSTATUS=-1
fi fi
rmdir $PREFIX 2>&1 || EXITSTATUS=-1 rmdir $PREFIX 2>&1 || EXITSTATUS=-1

View File

@@ -16,7 +16,7 @@ if(MSVC)
endif() endif()
foreach(src ${JPEG_SOURCES}) foreach(src ${JPEG_SOURCES})
list(APPEND JPEG_SRCS "${CMAKE_SOURCE_DIR}/${src}") set(JPEG_SRCS ${JPEG_SRCS} ${CMAKE_SOURCE_DIR}/${src})
endforeach() endforeach()
if(WITH_SIMD) if(WITH_SIMD)
@@ -26,10 +26,10 @@ endif()
if(WITH_MEM_SRCDST AND NOT WITH_JPEG8) if(WITH_MEM_SRCDST AND NOT WITH_JPEG8)
add_library(jpeg SHARED ${JPEG_SRCS} ${SIMD_OBJS} add_library(jpeg SHARED ${JPEG_SRCS} ${SIMD_OBJS}
"${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}-memsrcdst.def") ${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}-memsrcdst.def)
else() else()
add_library(jpeg SHARED ${JPEG_SRCS} ${SIMD_OBJS} add_library(jpeg SHARED ${JPEG_SRCS} ${SIMD_OBJS}
"${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}.def") ${CMAKE_SOURCE_DIR}/win/jpeg${DLL_VERSION}.def)
endif() endif()
set_target_properties(jpeg PROPERTIES SOVERSION ${DLL_VERSION} set_target_properties(jpeg PROPERTIES SOVERSION ${DLL_VERSION}
VERSION ${FULLVERSION}) VERSION ${FULLVERSION})
@@ -50,7 +50,7 @@ else()
set(DJPEG_BMP_SOURCES ../wrbmp.c ../wrtarga.c) set(DJPEG_BMP_SOURCES ../wrbmp.c ../wrtarga.c)
endif() endif()
add_executable(cjpeg ../cjpeg.c ../cdjpeg.c ../rdgif.c ../rdppm.c ../rdjpeg.c add_executable(cjpeg ../cjpeg.c ../cdjpeg.c ../rdgif.c ../rdppm.c
../rdswitch.c ${CJPEG_BMP_SOURCES}) ../rdswitch.c ${CJPEG_BMP_SOURCES})
set_property(TARGET cjpeg PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS}) set_property(TARGET cjpeg PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
target_link_libraries(cjpeg jpeg) target_link_libraries(cjpeg jpeg)

View File

@@ -1,6 +1,7 @@
if(NOT DEFINED NASM) if(NOT DEFINED NASM)
set(NASM nasm CACHE FILEPATH "Path to NASM/YASM executable") find_program(NASM NAMES nasm yasm DOC "Path to NASM/YASM executable")
endif() endif()
message(STATUS "NASM = ${NASM}")
if(SIMD_X86_64) if(SIMD_X86_64)
set(NAFLAGS -fwin64 -DWIN64 -D__x86_64__) set(NAFLAGS -fwin64 -DWIN64 -D__x86_64__)
@@ -41,7 +42,7 @@ endif()
if(MSVC_IDE) if(MSVC_IDE)
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
else() else()
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}") set(OBJDIR ${CMAKE_CURRENT_BINARY_DIR})
endif() endif()
file(GLOB INC_FILES *.inc) file(GLOB INC_FILES *.inc)

View File

@@ -73,19 +73,24 @@ endif
if SIMD_POWERPC if SIMD_POWERPC
libsimd_la_SOURCES = jsimd_powerpc.c jsimd_altivec.h jcsample.h \ noinst_LTLIBRARIES += libsimd_altivec.la
libsimd_altivec_la_SOURCES = \
jccolor-altivec.c jcgray-altivec.c jcsample-altivec.c \ jccolor-altivec.c jcgray-altivec.c jcsample-altivec.c \
jdcolor-altivec.c jdmerge-altivec.c jdsample-altivec.c \ jdcolor-altivec.c jdmerge-altivec.c jdsample-altivec.c \
jfdctfst-altivec.c jfdctint-altivec.c \ jfdctfst-altivec.c jfdctint-altivec.c \
jidctfst-altivec.c jidctint-altivec.c \ jidctfst-altivec.c jidctint-altivec.c \
jquanti-altivec.c jquanti-altivec.c
libsimd_la_CFLAGS = -maltivec libsimd_altivec_la_CFLAGS = -maltivec
jccolor-altivec.lo: jccolext-altivec.c jccolor-altivec.lo: jccolext-altivec.c
jcgray-altivec.lo: jcgryext-altivec.c jcgray-altivec.lo: jcgryext-altivec.c
jdcolor-altivec.lo: jdcolext-altivec.c jdcolor-altivec.lo: jdcolext-altivec.c
jdmerge-altivec.lo: jdmrgext-altivec.c jdmerge-altivec.lo: jdmrgext-altivec.c
libsimd_la_SOURCES = jsimd_powerpc.c jsimd_altivec.h jcsample.h
libsimd_la_LIBADD = libsimd_altivec.la
endif endif
AM_CPPFLAGS = -I$(top_srcdir) AM_CPPFLAGS = -I$(top_srcdir)

View File

@@ -1,7 +1,7 @@
; ;
; jchuff-sse2.asm - Huffman entropy encoding (SSE2) ; jchuff-sse2.asm - Huffman entropy encoding (SSE2)
; ;
; Copyright (C) 2009-2011, 2014-2016, D. R. Commander. ; Copyright (C) 2009-2011, 2014-2017, D. R. Commander.
; Copyright (C) 2015, Matthieu Darbois. ; Copyright (C) 2015, Matthieu Darbois.
; ;
; Based on the x86 SIMD extension for IJG JPEG library ; Based on the x86 SIMD extension for IJG JPEG library
@@ -288,13 +288,13 @@ EXTN(jsimd_huff_encode_one_block_sse2):
.BLOOP: .BLOOP:
bsf ecx, edx ; r = __builtin_ctzl(index); bsf ecx, edx ; r = __builtin_ctzl(index);
jz .ELOOP jz near .ELOOP
lea esi, [esi+ecx*2] ; k += r; lea esi, [esi+ecx*2] ; k += r;
shr edx, cl ; index >>= r; shr edx, cl ; index >>= r;
mov DWORD [esp+temp3], edx mov DWORD [esp+temp3], edx
.BRLOOP: .BRLOOP:
cmp ecx, 16 ; while (r > 15) { cmp ecx, 16 ; while (r > 15) {
jl .ERLOOP jl near .ERLOOP
sub ecx, 16 ; r -= 16; sub ecx, 16 ; r -= 16;
mov DWORD [esp+temp], ecx mov DWORD [esp+temp], ecx
mov eax, INT [ebp + 240 * 4] ; code_0xf0 = actbl->ehufco[0xf0]; mov eax, INT [ebp + 240 * 4] ; code_0xf0 = actbl->ehufco[0xf0];
@@ -348,7 +348,7 @@ EXTN(jsimd_huff_encode_one_block_sse2):
sub eax, esi sub eax, esi
shr eax, 1 shr eax, 1
bsf ecx, edx ; r = __builtin_ctzl(index); bsf ecx, edx ; r = __builtin_ctzl(index);
jz .ELOOP2 jz near .ELOOP2
shr edx, cl ; index >>= r; shr edx, cl ; index >>= r;
add ecx, eax add ecx, eax
lea esi, [esi+ecx*2] ; k += r; lea esi, [esi+ecx*2] ; k += r;
@@ -356,13 +356,13 @@ EXTN(jsimd_huff_encode_one_block_sse2):
jmp .BRLOOP2 jmp .BRLOOP2
.BLOOP2: .BLOOP2:
bsf ecx, edx ; r = __builtin_ctzl(index); bsf ecx, edx ; r = __builtin_ctzl(index);
jz .ELOOP2 jz near .ELOOP2
lea esi, [esi+ecx*2] ; k += r; lea esi, [esi+ecx*2] ; k += r;
shr edx, cl ; index >>= r; shr edx, cl ; index >>= r;
mov DWORD [esp+temp3], edx mov DWORD [esp+temp3], edx
.BRLOOP2: .BRLOOP2:
cmp ecx, 16 ; while (r > 15) { cmp ecx, 16 ; while (r > 15) {
jl .ERLOOP2 jl near .ERLOOP2
sub ecx, 16 ; r -= 16; sub ecx, 16 ; r -= 16;
mov DWORD [esp+temp], ecx mov DWORD [esp+temp], ecx
mov eax, INT [ebp + 240 * 4] ; code_0xf0 = actbl->ehufco[0xf0]; mov eax, INT [ebp + 240 * 4] ; code_0xf0 = actbl->ehufco[0xf0];

View File

@@ -2,6 +2,7 @@
* jsimd_arm.c * jsimd_arm.c
* *
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander. * Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander.
* Copyright (C) 2015-2016, Matthieu Darbois. * Copyright (C) 2015-2016, Matthieu Darbois.
* *
@@ -125,7 +126,7 @@ init_simd (void)
/* Force different settings through environment variables */ /* Force different settings through environment variables */
env = getenv("JSIMD_FORCENEON"); env = getenv("JSIMD_FORCENEON");
if ((env != NULL) && (strcmp(env, "1") == 0)) if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support &= JSIMD_ARM_NEON; simd_support = JSIMD_ARM_NEON;
env = getenv("JSIMD_FORCENONE"); env = getenv("JSIMD_FORCENONE");
if ((env != NULL) && (strcmp(env, "1") == 0)) if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support = 0; simd_support = 0;

View File

@@ -2,6 +2,7 @@
* jsimd_arm64.c * jsimd_arm64.c
* *
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
* Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander. * Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander.
* Copyright (C) 2015-2016, Matthieu Darbois. * Copyright (C) 2015-2016, Matthieu Darbois.
* *
@@ -142,7 +143,7 @@ init_simd (void)
/* Force different settings through environment variables */ /* Force different settings through environment variables */
env = getenv("JSIMD_FORCENEON"); env = getenv("JSIMD_FORCENEON");
if ((env != NULL) && (strcmp(env, "1") == 0)) if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support &= JSIMD_ARM_NEON; simd_support = JSIMD_ARM_NEON;
env = getenv("JSIMD_FORCENONE"); env = getenv("JSIMD_FORCENONE");
if ((env != NULL) && (strcmp(env, "1") == 0)) if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support = 0; simd_support = 0;

View File

@@ -210,10 +210,16 @@ asm_function jsimd_idct_islow_neon
TMP7 .req x13 TMP7 .req x13
TMP8 .req x14 TMP8 .req x14
/* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
guarantee that the upper (unused) 32 bits of x3 are valid. This
instruction ensures that those bits are set to zero. */
uxtw x3, w3
sub sp, sp, #64 sub sp, sp, #64
adr x15, Ljsimd_idct_islow_neon_consts adr x15, Ljsimd_idct_islow_neon_consts
st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], #32 mov x10, sp
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], #32 st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [x10], #32
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [x10], #32
ld1 {v0.8h, v1.8h}, [x15] ld1 {v0.8h, v1.8h}, [x15]
ld1 {v2.8h, v3.8h, v4.8h, v5.8h}, [COEF_BLOCK], #64 ld1 {v2.8h, v3.8h, v4.8h, v5.8h}, [COEF_BLOCK], #64
ld1 {v18.8h, v19.8h, v20.8h, v21.8h}, [DCT_TABLE], #64 ld1 {v18.8h, v19.8h, v20.8h, v21.8h}, [DCT_TABLE], #64
@@ -238,7 +244,6 @@ asm_function jsimd_idct_islow_neon
shl v10.8h, v2.8h, #(PASS1_BITS) shl v10.8h, v2.8h, #(PASS1_BITS)
sqxtn v16.8b, v15.8h sqxtn v16.8b, v15.8h
mov TMP1, v16.d[0] mov TMP1, v16.d[0]
sub sp, sp, #64
mvn TMP2, TMP1 mvn TMP2, TMP1
cbnz TMP2, 2f cbnz TMP2, 2f
@@ -807,6 +812,11 @@ asm_function jsimd_idct_ifast_neon
TMP7 .req x13 TMP7 .req x13
TMP8 .req x14 TMP8 .req x14
/* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
guarantee that the upper (unused) 32 bits of x3 are valid. This
instruction ensures that those bits are set to zero. */
uxtw x3, w3
/* Load and dequantize coefficients into NEON registers /* Load and dequantize coefficients into NEON registers
* with the following allocation: * with the following allocation:
* 0 1 2 3 | 4 5 6 7 * 0 1 2 3 | 4 5 6 7
@@ -1101,19 +1111,18 @@ asm_function jsimd_idct_4x4_neon
TMP3 .req x2 TMP3 .req x2
TMP4 .req x15 TMP4 .req x15
/* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
guarantee that the upper (unused) 32 bits of x3 are valid. This
instruction ensures that those bits are set to zero. */
uxtw x3, w3
/* Save all used NEON registers */ /* Save all used NEON registers */
sub sp, sp, 272 sub sp, sp, 64
str x15, [sp], 16 mov x9, sp
/* Load constants (v3.4h is just used for padding) */ /* Load constants (v3.4h is just used for padding) */
adr TMP4, Ljsimd_idct_4x4_neon_consts adr TMP4, Ljsimd_idct_4x4_neon_consts
st1 {v0.8b, v1.8b, v2.8b, v3.8b}, [sp], 32 st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
st1 {v4.8b, v5.8b, v6.8b, v7.8b}, [sp], 32 st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
st1 {v16.8b, v17.8b, v18.8b, v19.8b}, [sp], 32
st1 {v20.8b, v21.8b, v22.8b, v23.8b}, [sp], 32
st1 {v24.8b, v25.8b, v26.8b, v27.8b}, [sp], 32
st1 {v28.8b, v29.8b, v30.8b, v31.8b}, [sp], 32
ld1 {v0.4h, v1.4h, v2.4h, v3.4h}, [TMP4] ld1 {v0.4h, v1.4h, v2.4h, v3.4h}, [TMP4]
/* Load all COEF_BLOCK into NEON registers with the following allocation: /* Load all COEF_BLOCK into NEON registers with the following allocation:
@@ -1222,16 +1231,8 @@ asm_function jsimd_idct_4x4_neon
#endif #endif
/* vpop {v8.4h - v15.4h} ;not available */ /* vpop {v8.4h - v15.4h} ;not available */
sub sp, sp, #272
ldr x15, [sp], 16
ld1 {v0.8b, v1.8b, v2.8b, v3.8b}, [sp], 32
ld1 {v4.8b, v5.8b, v6.8b, v7.8b}, [sp], 32
ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32 ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
ld1 {v16.8b, v17.8b, v18.8b, v19.8b}, [sp], 32
ld1 {v20.8b, v21.8b, v22.8b, v23.8b}, [sp], 32
ld1 {v24.8b, v25.8b, v26.8b, v27.8b}, [sp], 32
ld1 {v28.8b, v29.8b, v30.8b, v31.8b}, [sp], 32
blr x30 blr x30
.unreq DCT_TABLE .unreq DCT_TABLE
@@ -1299,19 +1300,19 @@ asm_function jsimd_idct_2x2_neon
TMP1 .req x0 TMP1 .req x0
TMP2 .req x15 TMP2 .req x15
/* OUTPUT_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
guarantee that the upper (unused) 32 bits of x3 are valid. This
instruction ensures that those bits are set to zero. */
uxtw x3, w3
/* vpush {v8.4h - v15.4h} ; not available */ /* vpush {v8.4h - v15.4h} ; not available */
sub sp, sp, 208 sub sp, sp, 64
str x15, [sp], 16 mov x9, sp
/* Load constants */ /* Load constants */
adr TMP2, Ljsimd_idct_2x2_neon_consts adr TMP2, Ljsimd_idct_2x2_neon_consts
st1 {v4.8b, v5.8b, v6.8b, v7.8b}, [sp], 32 st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
st1 {v16.8b, v17.8b, v18.8b, v19.8b}, [sp], 32
st1 {v21.8b, v22.8b}, [sp], 16
st1 {v24.8b, v25.8b, v26.8b, v27.8b}, [sp], 32
st1 {v30.8b, v31.8b}, [sp], 16
ld1 {v14.4h}, [TMP2] ld1 {v14.4h}, [TMP2]
/* Load all COEF_BLOCK into NEON registers with the following allocation: /* Load all COEF_BLOCK into NEON registers with the following allocation:
@@ -1411,15 +1412,8 @@ asm_function jsimd_idct_2x2_neon
st1 {v26.b}[1], [TMP2], 1 st1 {v26.b}[1], [TMP2], 1
st1 {v27.b}[5], [TMP2], 1 st1 {v27.b}[5], [TMP2], 1
sub sp, sp, #208
ldr x15, [sp], 16
ld1 {v4.8b, v5.8b, v6.8b, v7.8b}, [sp], 32
ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32 ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
ld1 {v16.8b, v17.8b, v18.8b, v19.8b}, [sp], 32
ld1 {v21.8b, v22.8b}, [sp], 16
ld1 {v24.8b, v25.8b, v26.8b, v27.8b}, [sp], 32
ld1 {v30.8b, v31.8b}, [sp], 16
blr x30 blr x30
.unreq DCT_TABLE .unreq DCT_TABLE
@@ -1688,24 +1682,24 @@ asm_function jsimd_ycc_\colorid\()_convert_neon
.else .else
asm_function jsimd_ycc_\colorid\()_convert_neon_slowst3 asm_function jsimd_ycc_\colorid\()_convert_neon_slowst3
.endif .endif
OUTPUT_WIDTH .req x0 OUTPUT_WIDTH .req w0
INPUT_BUF .req x1 INPUT_BUF .req x1
INPUT_ROW .req x2 INPUT_ROW .req w2
OUTPUT_BUF .req x3 OUTPUT_BUF .req x3
NUM_ROWS .req x4 NUM_ROWS .req w4
INPUT_BUF0 .req x5 INPUT_BUF0 .req x5
INPUT_BUF1 .req x6 INPUT_BUF1 .req x6
INPUT_BUF2 .req x1 INPUT_BUF2 .req x1
RGB .req x7 RGB .req x7
Y .req x8 Y .req x9
U .req x9 U .req x10
V .req x10 V .req x11
N .req x15 N .req w15
sub sp, sp, 336 sub sp, sp, 64
str x15, [sp], 16 mov x9, sp
/* Load constants to d1, d2, d3 (v0.4h is just used for padding) */ /* Load constants to d1, d2, d3 (v0.4h is just used for padding) */
.if \fast_st3 == 1 .if \fast_st3 == 1
@@ -1715,23 +1709,11 @@ asm_function jsimd_ycc_\colorid\()_convert_neon_slowst3
.endif .endif
/* Save NEON registers */ /* Save NEON registers */
st1 {v0.8b, v1.8b, v2.8b, v3.8b}, [sp], 32 st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
st1 {v4.8b, v5.8b, v6.8b, v7.8b}, [sp], 32 st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
st1 {v16.8b, v17.8b, v18.8b, v19.8b}, [sp], 32
st1 {v20.8b, v21.8b, v22.8b, v23.8b}, [sp], 32
st1 {v24.8b, v25.8b, v26.8b, v27.8b}, [sp], 32
st1 {v28.8b, v29.8b, v30.8b, v31.8b}, [sp], 32
ld1 {v0.4h, v1.4h}, [x15], 16 ld1 {v0.4h, v1.4h}, [x15], 16
ld1 {v2.8h}, [x15] ld1 {v2.8h}, [x15]
/* Save ARM registers and handle input arguments */
/* push {x4, x5, x6, x7, x8, x9, x10, x30} */
stp x4, x5, [sp], 16
stp x6, x7, [sp], 16
stp x8, x9, [sp], 16
stp x10, x30, [sp], 16
ldr INPUT_BUF0, [INPUT_BUF] ldr INPUT_BUF0, [INPUT_BUF]
ldr INPUT_BUF1, [INPUT_BUF, #8] ldr INPUT_BUF1, [INPUT_BUF, #8]
ldr INPUT_BUF2, [INPUT_BUF, #16] ldr INPUT_BUF2, [INPUT_BUF, #16]
@@ -1745,11 +1727,10 @@ asm_function jsimd_ycc_\colorid\()_convert_neon_slowst3
cmp NUM_ROWS, #1 cmp NUM_ROWS, #1
b.lt 9f b.lt 9f
0: 0:
lsl x16, INPUT_ROW, #3 ldr Y, [INPUT_BUF0, INPUT_ROW, uxtw #3]
ldr Y, [INPUT_BUF0, x16] ldr U, [INPUT_BUF1, INPUT_ROW, uxtw #3]
ldr U, [INPUT_BUF1, x16]
mov N, OUTPUT_WIDTH mov N, OUTPUT_WIDTH
ldr V, [INPUT_BUF2, x16] ldr V, [INPUT_BUF2, INPUT_ROW, uxtw #3]
add INPUT_ROW, INPUT_ROW, #1 add INPUT_ROW, INPUT_ROW, #1
ldr RGB, [OUTPUT_BUF], #8 ldr RGB, [OUTPUT_BUF], #8
@@ -1799,21 +1780,8 @@ asm_function jsimd_ycc_\colorid\()_convert_neon_slowst3
b.gt 0b b.gt 0b
9: 9:
/* Restore all registers and return */ /* Restore all registers and return */
sub sp, sp, #336
ldr x15, [sp], 16
ld1 {v0.8b, v1.8b, v2.8b, v3.8b}, [sp], 32
ld1 {v4.8b, v5.8b, v6.8b, v7.8b}, [sp], 32
ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32 ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
ld1 {v16.8b, v17.8b, v18.8b, v19.8b}, [sp], 32
ld1 {v20.8b, v21.8b, v22.8b, v23.8b}, [sp], 32
ld1 {v24.8b, v25.8b, v26.8b, v27.8b}, [sp], 32
ld1 {v28.8b, v29.8b, v30.8b, v31.8b}, [sp], 32
/* pop {r4, r5, r6, r7, r8, r9, r10, pc} */
ldp x4, x5, [sp], 16
ldp x6, x7, [sp], 16
ldp x8, x9, [sp], 16
ldp x10, x30, [sp], 16
br x30 br x30
.unreq OUTPUT_WIDTH .unreq OUTPUT_WIDTH
.unreq INPUT_ROW .unreq INPUT_ROW
@@ -2054,8 +2022,8 @@ asm_function jsimd_\colorid\()_ycc_convert_neon_slowld3
OUTPUT_WIDTH .req w0 OUTPUT_WIDTH .req w0
INPUT_BUF .req x1 INPUT_BUF .req x1
OUTPUT_BUF .req x2 OUTPUT_BUF .req x2
OUTPUT_ROW .req x3 OUTPUT_ROW .req w3
NUM_ROWS .req x4 NUM_ROWS .req w4
OUTPUT_BUF0 .req x5 OUTPUT_BUF0 .req x5
OUTPUT_BUF1 .req x6 OUTPUT_BUF1 .req x6
@@ -2082,17 +2050,18 @@ asm_function jsimd_\colorid\()_ycc_convert_neon_slowld3
/* Save NEON registers */ /* Save NEON registers */
sub sp, sp, #64 sub sp, sp, #64
st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 mov x9, sp
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32 st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [x9], 32
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [x9], 32
/* Outer loop over scanlines */ /* Outer loop over scanlines */
cmp NUM_ROWS, #1 cmp NUM_ROWS, #1
b.lt 9f b.lt 9f
0: 0:
ldr Y, [OUTPUT_BUF0, OUTPUT_ROW, lsl #3] ldr Y, [OUTPUT_BUF0, OUTPUT_ROW, uxtw #3]
ldr U, [OUTPUT_BUF1, OUTPUT_ROW, lsl #3] ldr U, [OUTPUT_BUF1, OUTPUT_ROW, uxtw #3]
mov N, OUTPUT_WIDTH mov N, OUTPUT_WIDTH
ldr V, [OUTPUT_BUF2, OUTPUT_ROW, lsl #3] ldr V, [OUTPUT_BUF2, OUTPUT_ROW, uxtw #3]
add OUTPUT_ROW, OUTPUT_ROW, #1 add OUTPUT_ROW, OUTPUT_ROW, #1
ldr RGB, [INPUT_BUF], #8 ldr RGB, [INPUT_BUF], #8
@@ -2136,7 +2105,6 @@ asm_function jsimd_\colorid\()_ycc_convert_neon_slowld3
b.gt 0b b.gt 0b
9: 9:
/* Restore all registers and return */ /* Restore all registers and return */
sub sp, sp, #64
ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32 ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
br x30 br x30
@@ -2199,6 +2167,11 @@ asm_function jsimd_convsamp_neon
TMP8 .req x4 TMP8 .req x4
TMPDUP .req w3 TMPDUP .req w3
/* START_COL is a JDIMENSION (unsigned int) argument, so the ABI doesn't
guarantee that the upper (unused) 32 bits of x1 are valid. This
instruction ensures that those bits are set to zero. */
uxtw x1, w1
mov TMPDUP, #128 mov TMPDUP, #128
ldp TMP1, TMP2, [SAMPLE_DATA], 16 ldp TMP1, TMP2, [SAMPLE_DATA], 16
ldp TMP3, TMP4, [SAMPLE_DATA], 16 ldp TMP3, TMP4, [SAMPLE_DATA], 16
@@ -2335,8 +2308,9 @@ asm_function jsimd_fdct_islow_neon
/* Save NEON registers */ /* Save NEON registers */
sub sp, sp, #64 sub sp, sp, #64
st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 mov x10, sp
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32 st1 {v8.8b, v9.8b, v10.8b, v11.8b}, [x10], 32
st1 {v12.8b, v13.8b, v14.8b, v15.8b}, [x10], 32
/* Load all DATA into NEON registers with the following allocation: /* Load all DATA into NEON registers with the following allocation:
* 0 1 2 3 | 4 5 6 7 * 0 1 2 3 | 4 5 6 7
@@ -2566,7 +2540,6 @@ asm_function jsimd_fdct_islow_neon
st1 {v20.8h, v21.8h, v22.8h, v23.8h}, [DATA] st1 {v20.8h, v21.8h, v22.8h, v23.8h}, [DATA]
/* Restore NEON registers */ /* Restore NEON registers */
sub sp, sp, #64
ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32 ld1 {v8.8b, v9.8b, v10.8b, v11.8b}, [sp], 32
ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32 ld1 {v12.8b, v13.8b, v14.8b, v15.8b}, [sp], 32
@@ -3080,7 +3053,7 @@ asm_function jsimd_huff_encode_one_block_neon_slowtbl
sub sp, sp, 272 sub sp, sp, 272
sub BUFFER, BUFFER, #0x1 /* BUFFER=buffer-- */ sub BUFFER, BUFFER, #0x1 /* BUFFER=buffer-- */
/* Save ARM registers */ /* Save ARM registers */
stp x19, x20, [sp], 16 stp x19, x20, [sp]
.if \fast_tbl == 1 .if \fast_tbl == 1
adr x15, Ljsimd_huff_encode_one_block_neon_consts adr x15, Ljsimd_huff_encode_one_block_neon_consts
.else .else
@@ -3294,7 +3267,7 @@ asm_function jsimd_huff_encode_one_block_neon_slowtbl
and v18.16b, v18.16b, v23.16b and v18.16b, v18.16b, v23.16b
add x3, x4, #0x400 /* r1 = dctbl->ehufsi */ add x3, x4, #0x400 /* r1 = dctbl->ehufsi */
and v20.16b, v20.16b, v23.16b and v20.16b, v20.16b, v23.16b
add x15, sp, #0x80 /* x15 = t2 */ add x15, sp, #0x90 /* x15 = t2 */
and v22.16b, v22.16b, v23.16b and v22.16b, v22.16b, v23.16b
ldr w10, [x4, x12, lsl #2] ldr w10, [x4, x12, lsl #2]
addp v16.16b, v16.16b, v18.16b addp v16.16b, v16.16b, v18.16b
@@ -3317,7 +3290,7 @@ asm_function jsimd_huff_encode_one_block_neon_slowtbl
rbit x9, x9 /* x9 = index0 */ rbit x9, x9 /* x9 = index0 */
ldrb w14, [x4, #0xf0] /* x14 = actbl->ehufsi[0xf0] */ ldrb w14, [x4, #0xf0] /* x14 = actbl->ehufsi[0xf0] */
cmp w12, #(64-8) cmp w12, #(64-8)
mov x11, sp add x11, sp, #16
b.lt 4f b.lt 4f
cbz x9, 6f cbz x9, 6f
st1 {v0.8h, v1.8h, v2.8h, v3.8h}, [x11], #64 st1 {v0.8h, v1.8h, v2.8h, v3.8h}, [x11], #64
@@ -3421,7 +3394,7 @@ asm_function jsimd_huff_encode_one_block_neon_slowtbl
put_bits x3, x11 put_bits x3, x11
cbnz x9, 1b cbnz x9, 1b
6: 6:
add x13, sp, #0xfe add x13, sp, #0x10e
cmp x15, x13 cmp x15, x13
b.hs 1f b.hs 1f
ldr w12, [x5] ldr w12, [x5]
@@ -3429,7 +3402,6 @@ asm_function jsimd_huff_encode_one_block_neon_slowtbl
checkbuf47 checkbuf47
put_bits x12, x14 put_bits x12, x14
1: 1:
sub sp, sp, 16
str PUT_BUFFER, [x0, #0x10] str PUT_BUFFER, [x0, #0x10]
str PUT_BITSw, [x0, #0x18] str PUT_BITSw, [x0, #0x18]
ldp x19, x20, [sp], 16 ldp x19, x20, [sp], 16

View File

@@ -2,7 +2,7 @@
* jsimd_mips.c * jsimd_mips.c
* *
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009-2011, 2014, D. R. Commander. * Copyright (C) 2009-2011, 2014, 2016, D. R. Commander.
* Copyright (C) 2013-2014, MIPS Technologies, Inc., California. * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
* Copyright (C) 2015, Matthieu Darbois. * Copyright (C) 2015, Matthieu Darbois.
* *
@@ -63,6 +63,8 @@ parse_proc_cpuinfo(const char* search_string)
LOCAL(void) LOCAL(void)
init_simd (void) init_simd (void)
{ {
char *env = NULL;
if (simd_support != ~0U) if (simd_support != ~0U)
return; return;
@@ -77,6 +79,14 @@ init_simd (void)
if (!parse_proc_cpuinfo("MIPS 74K")) if (!parse_proc_cpuinfo("MIPS 74K"))
return; return;
#endif #endif
/* Force different settings through environment variables */
env = getenv("JSIMD_FORCEDSPR2");
if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support = JSIMD_MIPS_DSPR2;
env = getenv("JSIMD_FORCENONE");
if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support = 0;
} }
static const int mips_idct_ifast_coefs[4] = { static const int mips_idct_ifast_coefs[4] = {

View File

@@ -2,7 +2,7 @@
* jsimd_powerpc.c * jsimd_powerpc.c
* *
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009-2011, 2014-2015, D. R. Commander. * Copyright (C) 2009-2011, 2014-2016, D. R. Commander.
* Copyright (C) 2015, Matthieu Darbois. * Copyright (C) 2015, Matthieu Darbois.
* *
* Based on the x86 SIMD extension for IJG JPEG library, * Based on the x86 SIMD extension for IJG JPEG library,
@@ -14,6 +14,11 @@
* PowerPC architecture. * PowerPC architecture.
*/ */
#ifdef __amigaos4__
/* This must be defined first as it re-defines GLOBAL otherwise */
#include <proto/exec.h>
#endif
#define JPEG_INTERNALS #define JPEG_INTERNALS
#include "../jinclude.h" #include "../jinclude.h"
#include "../jpeglib.h" #include "../jpeglib.h"
@@ -22,19 +27,125 @@
#include "../jsimddct.h" #include "../jsimddct.h"
#include "jsimd.h" #include "jsimd.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#if defined(__OpenBSD__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <machine/cpu.h>
#endif
static unsigned int simd_support = ~0; static unsigned int simd_support = ~0;
#if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
#define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
LOCAL(int)
check_feature (char *buffer, char *feature)
{
char *p;
if (*feature == 0)
return 0;
if (strncmp(buffer, "cpu", 3) != 0)
return 0;
buffer += 3;
while (isspace(*buffer))
buffer++;
/* Check if 'feature' is present in the buffer as a separate word */
while ((p = strstr(buffer, feature))) {
if (p > buffer && !isspace(*(p - 1))) {
buffer++;
continue;
}
p += strlen(feature);
if (*p != 0 && !isspace(*p)) {
buffer++;
continue;
}
return 1;
}
return 0;
}
LOCAL(int)
parse_proc_cpuinfo (int bufsize)
{
char *buffer = (char *)malloc(bufsize);
FILE *fd;
simd_support = 0;
if (!buffer)
return 0;
fd = fopen("/proc/cpuinfo", "r");
if (fd) {
while (fgets(buffer, bufsize, fd)) {
if (!strchr(buffer, '\n') && !feof(fd)) {
/* "impossible" happened - insufficient size of the buffer! */
fclose(fd);
free(buffer);
return 0;
}
if (check_feature(buffer, "altivec"))
simd_support |= JSIMD_ALTIVEC;
}
fclose(fd);
}
free(buffer);
return 1;
}
#endif
/*
* Check what SIMD accelerations are supported.
*
* FIXME: This code is racy under a multi-threaded environment.
*/
LOCAL(void) LOCAL(void)
init_simd (void) init_simd (void)
{ {
char *env = NULL; char *env = NULL;
#if !defined(__ALTIVEC__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
int bufsize = 1024; /* an initial guess for the line buffer size limit */
#elif defined(__amigaos4__)
uint32 altivec = 0;
#elif defined(__OpenBSD__)
int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
int altivec;
size_t len = sizeof(altivec);
#endif
if (simd_support != ~0U) if (simd_support != ~0U)
return; return;
simd_support = JSIMD_ALTIVEC; simd_support = 0;
#if defined(__ALTIVEC__) || defined(__APPLE__)
simd_support |= JSIMD_ALTIVEC;
#elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
while (!parse_proc_cpuinfo(bufsize)) {
bufsize *= 2;
if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
break;
}
#elif defined(__amigaos4__)
IExec->GetCPUInfoTags(GCIT_VectorUnit, &altivec, TAG_DONE);
if(altivec == VECTORTYPE_ALTIVEC)
simd_support |= JSIMD_ALTIVEC;
#elif defined(__OpenBSD__)
if (sysctl(mib, 2, &altivec, &len, NULL, 0) == 0 && altivec != 0)
simd_support |= JSIMD_ALTIVEC;
#endif
/* Force different settings through environment variables */ /* Force different settings through environment variables */
env = getenv("JSIMD_FORCEALTIVEC");
if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support = JSIMD_ALTIVEC;
env = getenv("JSIMD_FORCENONE"); env = getenv("JSIMD_FORCENONE");
if ((env != NULL) && (strcmp(env, "1") == 0)) if ((env != NULL) && (strcmp(env, "1") == 0))
simd_support = 0; simd_support = 0;

View File

@@ -832,21 +832,19 @@ read_backing_store, manipulate a backing-store object
write_backing_store, write_backing_store,
close_backing_store close_backing_store
On some systems there will be more than one type of backing-store object On some systems there will be more than one type of backing-store object.
(specifically, in MS-DOS a backing store file might be an area of extended jpeg_open_backing_store is responsible for choosing how to implement a given
memory as well as a disk file). jpeg_open_backing_store is responsible for object. The read/write/close routines are method pointers in the structure
choosing how to implement a given object. The read/write/close routines that describes a given object; this lets them be different for different object
are method pointers in the structure that describes a given object; this types.
lets them be different for different object types.
It may be necessary to ensure that backing store objects are explicitly It may be necessary to ensure that backing store objects are explicitly
released upon abnormal program termination. For example, MS-DOS won't free released upon abnormal program termination. To support this, we will expect
extended memory by itself. To support this, we will expect the main program the main program or surrounding application to arrange to call self_destruct
or surrounding application to arrange to call self_destruct (typically via (typically via jpeg_destroy) upon abnormal termination. This may require a
jpeg_destroy) upon abnormal termination. This may require a SIGINT signal SIGINT signal handler or equivalent. We don't want to have the back end module
handler or equivalent. We don't want to have the back end module install its install its own signal handler, because that would pre-empt the surrounding
own signal handler, because that would pre-empt the surrounding application's application's ability to control signal handling.
ability to control signal handling.
The IJG distribution includes several memory manager back end implementations. The IJG distribution includes several memory manager back end implementations.
Usually the same back end should be suitable for all applications on a given Usually the same back end should be suitable for all applications on a given

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C)2009-2016 D. R. Commander. All Rights Reserved. * Copyright (C)2009-2017 D. R. Commander. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@@ -40,13 +40,13 @@
#define _throw(op, err) { \ #define _throw(op, err) { \
printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \ printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \
retval=-1; goto bailout;} retval=-1; goto bailout;}
#define _throwunix(m) _throw(m, strerror(errno)) #define _throwunix(m) _throw(m, strerror(errno))
#define _throwtj(m) _throw(m, tjGetErrorStr()) #define _throwtj(m) _throw(m, tjGetErrorStr())
#define _throwbmp(m) _throw(m, bmpgeterr()) #define _throwbmp(m) _throw(m, bmpgeterr())
int flags=TJFLAG_NOREALLOC, componly=0, decomponly=0, doyuv=0, quiet=0, int flags=TJFLAG_NOREALLOC, componly=0, decomponly=0, doyuv=0, quiet=0,
dotile=0, pf=TJPF_BGR, yuvpad=1, warmup=1, dowrite=1; dotile=0, pf=TJPF_BGR, yuvpad=1, dowrite=1;
char *ext="ppm"; char *ext="ppm";
const char *pixFormatStr[TJ_NUMPF]= const char *pixFormatStr[TJ_NUMPF]=
{ {
@@ -64,7 +64,7 @@ const char *subName[TJ_NUMSAMP]={"444", "422", "420", "GRAY", "440", "411"};
tjscalingfactor *scalingfactors=NULL, sf={1, 1}; int nsf=0; tjscalingfactor *scalingfactors=NULL, sf={1, 1}; int nsf=0;
int xformop=TJXOP_NONE, xformopt=0; int xformop=TJXOP_NONE, xformopt=0;
int (*customFilter)(short *, tjregion, tjregion, int, int, tjtransform *); int (*customFilter)(short *, tjregion, tjregion, int, int, tjtransform *);
double benchtime=5.0; double benchtime=5.0, warmup=1.0;
char *formatName(int subsamp, int cs, char *buf) char *formatName(int subsamp, int cs, char *buf)
@@ -146,7 +146,7 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
} }
/* Benchmark */ /* Benchmark */
iter=-warmup; iter=-1;
elapsed=elapsedDecode=0.; elapsed=elapsedDecode=0.;
while(1) while(1)
{ {
@@ -176,12 +176,17 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
_throwtj("executing tjDecompress2()"); _throwtj("executing tjDecompress2()");
} }
} }
iter++; elapsed+=gettime()-start;
if(iter>=1) if(iter>=0)
{ {
elapsed+=gettime()-start; iter++;
if(elapsed>=benchtime) break; if(elapsed>=benchtime) break;
} }
else if(elapsed>=warmup)
{
iter=0;
elapsed=elapsedDecode=0.;
}
} }
if(doyuv) elapsed-=elapsedDecode; if(doyuv) elapsed-=elapsedDecode;
@@ -207,7 +212,7 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
(double)(w*h)/1000000.*(double)iter/elapsed); (double)(w*h)/1000000.*(double)iter/elapsed);
if(doyuv) if(doyuv)
{ {
printf("YUV Decode --> Frame rate:  %f fps\n", printf("YUV Decode --> Frame rate: %f fps\n",
(double)iter/elapsedDecode); (double)iter/elapsedDecode);
printf(" Throughput: %f Megapixels/sec\n", printf(" Throughput: %f Megapixels/sec\n",
(double)(w*h)/1000000.*(double)iter/elapsedDecode); (double)(w*h)/1000000.*(double)iter/elapsedDecode);
@@ -248,7 +253,8 @@ int decomp(unsigned char *srcbuf, unsigned char **jpegbuf,
int y=(int)((double)srcbuf[rindex]*0.299 int y=(int)((double)srcbuf[rindex]*0.299
+ (double)srcbuf[gindex]*0.587 + (double)srcbuf[gindex]*0.587
+ (double)srcbuf[bindex]*0.114 + 0.5); + (double)srcbuf[bindex]*0.114 + 0.5);
if(y>255) y=255; if(y<0) y=0; if(y>255) y=255;
if(y<0) y=0;
dstbuf[rindex]=abs(dstbuf[rindex]-y); dstbuf[rindex]=abs(dstbuf[rindex]-y);
dstbuf[gindex]=abs(dstbuf[gindex]-y); dstbuf[gindex]=abs(dstbuf[gindex]-y);
dstbuf[bindex]=abs(dstbuf[bindex]-y); dstbuf[bindex]=abs(dstbuf[bindex]-y);
@@ -300,7 +306,8 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
for(tilew=dotile? 8:w, tileh=dotile? 8:h; ; tilew*=2, tileh*=2) for(tilew=dotile? 8:w, tileh=dotile? 8:h; ; tilew*=2, tileh*=2)
{ {
if(tilew>w) tilew=w; if(tileh>h) tileh=h; if(tilew>w) tilew=w;
if(tileh>h) tileh=h;
ntilesw=(w+tilew-1)/tilew; ntilesh=(h+tileh-1)/tileh; ntilesw=(w+tilew-1)/tilew; ntilesh=(h+tileh-1)/tileh;
if((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *) if((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *)
@@ -338,7 +345,7 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
} }
/* Benchmark */ /* Benchmark */
iter=-warmup; iter=-1;
elapsed=elapsedEncode=0.; elapsed=elapsedEncode=0.;
while(1) while(1)
{ {
@@ -372,12 +379,17 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
totaljpegsize+=jpegsize[tile]; totaljpegsize+=jpegsize[tile];
} }
} }
iter++; elapsed+=gettime()-start;
if(iter>=1) if(iter>=0)
{ {
elapsed+=gettime()-start; iter++;
if(elapsed>=benchtime) break; if(elapsed>=benchtime) break;
} }
else if(elapsed>=warmup)
{
iter=0;
elapsed=elapsedEncode=0.;
}
} }
if(doyuv) elapsed-=elapsedEncode; if(doyuv) elapsed-=elapsedEncode;
@@ -447,7 +459,8 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
for(i=0; i<ntilesw*ntilesh; i++) for(i=0; i<ntilesw*ntilesh; i++)
{ {
if(jpegbuf[i]) tjFree(jpegbuf[i]); jpegbuf[i]=NULL; if(jpegbuf[i]) tjFree(jpegbuf[i]);
jpegbuf[i]=NULL;
} }
free(jpegbuf); jpegbuf=NULL; free(jpegbuf); jpegbuf=NULL;
free(jpegsize); jpegsize=NULL; free(jpegsize); jpegsize=NULL;
@@ -465,7 +478,8 @@ int fullTest(unsigned char *srcbuf, int w, int h, int subsamp, int jpegqual,
{ {
for(i=0; i<ntilesw*ntilesh; i++) for(i=0; i<ntilesw*ntilesh; i++)
{ {
if(jpegbuf[i]) tjFree(jpegbuf[i]); jpegbuf[i]=NULL; if(jpegbuf[i]) tjFree(jpegbuf[i]);
jpegbuf[i]=NULL;
} }
free(jpegbuf); jpegbuf=NULL; free(jpegbuf); jpegbuf=NULL;
} }
@@ -532,7 +546,8 @@ int decompTest(char *filename)
for(tilew=dotile? 16:w, tileh=dotile? 16:h; ; tilew*=2, tileh*=2) for(tilew=dotile? 16:w, tileh=dotile? 16:h; ; tilew*=2, tileh*=2)
{ {
if(tilew>w) tilew=w; if(tileh>h) tileh=h; if(tilew>w) tilew=w;
if(tileh>h) tileh=h;
ntilesw=(w+tilew-1)/tilew; ntilesh=(h+tileh-1)/tileh; ntilesw=(w+tilew-1)/tilew; ntilesh=(h+tileh-1)/tileh;
if((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *) if((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *)
@@ -618,7 +633,7 @@ int decompTest(char *filename)
} }
} }
iter=-warmup; iter=-1;
elapsed=0.; elapsed=0.;
while(1) while(1)
{ {
@@ -626,12 +641,17 @@ int decompTest(char *filename)
if(tjTransform(handle, srcbuf, srcsize, _ntilesw*_ntilesh, jpegbuf, if(tjTransform(handle, srcbuf, srcsize, _ntilesw*_ntilesh, jpegbuf,
jpegsize, t, flags)==-1) jpegsize, t, flags)==-1)
_throwtj("executing tjTransform()"); _throwtj("executing tjTransform()");
iter++; elapsed+=gettime()-start;
if(iter>=1) if(iter>=0)
{ {
elapsed+=gettime()-start; iter++;
if(elapsed>=benchtime) break; if(elapsed>=benchtime) break;
} }
else if(elapsed>=warmup)
{
iter=0;
elapsed=0.;
}
} }
free(t); t=NULL; free(t); t=NULL;
@@ -663,7 +683,9 @@ int decompTest(char *filename)
{ {
if(quiet==1) printf("N/A N/A "); if(quiet==1) printf("N/A N/A ");
jpegsize[0]=srcsize; jpegsize[0]=srcsize;
memcpy(jpegbuf[0], srcbuf, srcsize); free(jpegbuf[0]);
jpegbuf[0]=srcbuf;
srcbuf=NULL;
} }
if(w==tilew) _tilew=_w; if(w==tilew) _tilew=_w;
@@ -692,7 +714,8 @@ int decompTest(char *filename)
{ {
for(i=0; i<ntilesw*ntilesh; i++) for(i=0; i<ntilesw*ntilesh; i++)
{ {
if(jpegbuf[i]) tjFree(jpegbuf[i]); jpegbuf[i]=NULL; if(jpegbuf[i]) tjFree(jpegbuf[i]);
jpegbuf[i]=NULL;
} }
free(jpegbuf); jpegbuf=NULL; free(jpegbuf); jpegbuf=NULL;
} }
@@ -757,8 +780,9 @@ void usage(char *progname)
printf("-grayscale = Perform lossless grayscale conversion prior to decompression\n"); printf("-grayscale = Perform lossless grayscale conversion prior to decompression\n");
printf(" test (can be combined with the other transforms above)\n"); printf(" test (can be combined with the other transforms above)\n");
printf("-benchtime <t> = Run each benchmark for at least <t> seconds (default = 5.0)\n"); printf("-benchtime <t> = Run each benchmark for at least <t> seconds (default = 5.0)\n");
printf("-warmup <w> = Execute each benchmark <w> times to prime the cache before\n"); printf("-warmup <t> = Run each benchmark for <t> seconds (default = 1.0) prior to\n");
printf(" taking performance measurements (default = 1)\n"); printf(" starting the timer, in order to prime the caches and thus improve the\n");
printf(" consistency of the results.\n");
printf("-componly = Stop after running compression tests. Do not test decompression.\n"); printf("-componly = Stop after running compression tests. Do not test decompression.\n");
printf("-nowrite = Do not write reference or output images (improves consistency of\n"); printf("-nowrite = Do not write reference or output images (improves consistency of\n");
printf(" performance measurements.)\n\n"); printf(" performance measurements.)\n\n");
@@ -872,13 +896,10 @@ int main(int argc, char *argv[])
} }
if(!strcasecmp(argv[i], "-warmup") && i<argc-1) if(!strcasecmp(argv[i], "-warmup") && i<argc-1)
{ {
int temp=atoi(argv[++i]); double temp=atof(argv[++i]);
if(temp>=0) if(temp>=0.0) warmup=temp;
{
warmup=temp;
printf("Warmup runs = %d\n\n", warmup);
}
else usage(argv[0]); else usage(argv[0]);
printf("Warmup time = %.1f seconds\n\n", warmup);
} }
if(!strcmp(argv[i], "-?")) usage(argv[0]); if(!strcmp(argv[i], "-?")) usage(argv[0]);
if(!strcasecmp(argv[i], "-alloc")) flags&=(~TJFLAG_NOREALLOC); if(!strcasecmp(argv[i], "-alloc")) flags&=(~TJFLAG_NOREALLOC);

View File

@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software: * This file was part of the Independent JPEG Group's software:
* Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1997-2011, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2010, D. R. Commander. * Copyright (C) 2010, 2017, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
* *
@@ -1177,7 +1177,6 @@ transpose_critical_parameters (j_compress_ptr dstinfo)
* We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible. * We try to adjust the Tags ExifImageWidth and ExifImageHeight if possible.
*/ */
#if JPEG_LIB_VERSION >= 70
LOCAL(void) LOCAL(void)
adjust_exif_parameters (JOCTET *data, unsigned int length, adjust_exif_parameters (JOCTET *data, unsigned int length,
JDIMENSION new_width, JDIMENSION new_height) JDIMENSION new_width, JDIMENSION new_height)
@@ -1327,7 +1326,6 @@ adjust_exif_parameters (JOCTET *data, unsigned int length,
offset += 12; offset += 12;
} while (--number_of_tags); } while (--number_of_tags);
} }
#endif
/* Adjust output image parameters as needed. /* Adjust output image parameters as needed.
@@ -1384,7 +1382,7 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
/* Correct the destination's image dimensions as necessary /* Correct the destination's image dimensions as necessary
* for rotate/flip, resize, and crop operations. * for rotate/flip, resize, and crop operations.
*/ */
#if JPEG_LIB_VERSION >= 70 #if JPEG_LIB_VERSION >= 80
dstinfo->jpeg_width = info->output_width; dstinfo->jpeg_width = info->output_width;
dstinfo->jpeg_height = info->output_height; dstinfo->jpeg_height = info->output_height;
#endif #endif
@@ -1395,14 +1393,14 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
case JXFORM_TRANSVERSE: case JXFORM_TRANSVERSE:
case JXFORM_ROT_90: case JXFORM_ROT_90:
case JXFORM_ROT_270: case JXFORM_ROT_270:
#if JPEG_LIB_VERSION < 70 #if JPEG_LIB_VERSION < 80
dstinfo->image_width = info->output_height; dstinfo->image_width = info->output_height;
dstinfo->image_height = info->output_width; dstinfo->image_height = info->output_width;
#endif #endif
transpose_critical_parameters(dstinfo); transpose_critical_parameters(dstinfo);
break; break;
default: default:
#if JPEG_LIB_VERSION < 70 #if JPEG_LIB_VERSION < 80
dstinfo->image_width = info->output_width; dstinfo->image_width = info->output_width;
dstinfo->image_height = info->output_height; dstinfo->image_height = info->output_height;
#endif #endif
@@ -1421,14 +1419,21 @@ jtransform_adjust_parameters (j_decompress_ptr srcinfo,
GETJOCTET(srcinfo->marker_list->data[5]) == 0) { GETJOCTET(srcinfo->marker_list->data[5]) == 0) {
/* Suppress output of JFIF marker */ /* Suppress output of JFIF marker */
dstinfo->write_JFIF_header = FALSE; dstinfo->write_JFIF_header = FALSE;
#if JPEG_LIB_VERSION >= 70
/* Adjust Exif image parameters */ /* Adjust Exif image parameters */
#if JPEG_LIB_VERSION >= 80
if (dstinfo->jpeg_width != srcinfo->image_width || if (dstinfo->jpeg_width != srcinfo->image_width ||
dstinfo->jpeg_height != srcinfo->image_height) dstinfo->jpeg_height != srcinfo->image_height)
/* Align data segment to start of TIFF structure for parsing */ /* Align data segment to start of TIFF structure for parsing */
adjust_exif_parameters(srcinfo->marker_list->data + 6, adjust_exif_parameters(srcinfo->marker_list->data + 6,
srcinfo->marker_list->data_length - 6, srcinfo->marker_list->data_length - 6,
dstinfo->jpeg_width, dstinfo->jpeg_height); dstinfo->jpeg_width, dstinfo->jpeg_height);
#else
if (dstinfo->image_width != srcinfo->image_width ||
dstinfo->image_height != srcinfo->image_height)
/* Align data segment to start of TIFF structure for parsing */
adjust_exif_parameters(srcinfo->marker_list->data + 6,
srcinfo->marker_list->data_length - 6,
dstinfo->image_width, dstinfo->image_height);
#endif #endif
} }

View File

@@ -1,7 +1,5 @@
/* /*
* Copyright (C)2009-2016 D. R. Commander. All Rights Reserved. * Copyright (C)2009-2017 D. R. Commander. All Rights Reserved.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@@ -219,8 +217,6 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
} }
cinfo->input_components=tjPixelSize[pixelFormat]; cinfo->input_components=tjPixelSize[pixelFormat];
if((env=getenv("TJ_REVERT"))!=NULL && strlen(env)>0 && !strcmp(env, "1"))
cinfo->master->compress_profile=JCP_FASTEST;
jpeg_set_defaults(cinfo); jpeg_set_defaults(cinfo);
#ifndef NO_GETENV #ifndef NO_GETENV
@@ -262,10 +258,6 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
jpeg_simple_progression(cinfo); jpeg_simple_progression(cinfo);
#endif #endif
/* Set scan pattern again as colorspace might have changed */
if(cinfo->master->compress_profile == JCP_MAX_COMPRESSION)
jpeg_simple_progression(cinfo);
cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8;
cinfo->comp_info[1].h_samp_factor=1; cinfo->comp_info[1].h_samp_factor=1;
cinfo->comp_info[2].h_samp_factor=1; cinfo->comp_info[2].h_samp_factor=1;
@@ -376,6 +368,29 @@ static int getSubsamp(j_decompress_ptr dinfo)
retval=i; break; retval=i; break;
} }
} }
/* Handle 4:2:2 and 4:4:0 images whose sampling factors are specified
in non-standard ways. */
if(dinfo->comp_info[0].h_samp_factor==2 &&
dinfo->comp_info[0].v_samp_factor==2 &&
(i==TJSAMP_422 || i==TJSAMP_440))
{
int match=0;
for(k=1; k<dinfo->num_components; k++)
{
int href=tjMCUHeight[i]/8, vref=tjMCUWidth[i]/8;
if(dinfo->jpeg_color_space==JCS_YCCK && k==3)
{
href=vref=2;
}
if(dinfo->comp_info[k].h_samp_factor==href
&& dinfo->comp_info[k].v_samp_factor==vref)
match++;
}
if(match==dinfo->num_components-1)
{
retval=i; break;
}
}
} }
} }
return retval; return retval;
@@ -578,7 +593,8 @@ static tjhandle _tjInitCompress(tjinstance *this)
if(setjmp(this->jerr.setjmp_buffer)) if(setjmp(this->jerr.setjmp_buffer))
{ {
/* If we get here, the JPEG code has signaled an error. */ /* If we get here, the JPEG code has signaled an error. */
if(this) free(this); return NULL; if(this) free(this);
return NULL;
} }
jpeg_create_compress(&this->cinfo); jpeg_create_compress(&this->cinfo);
@@ -756,13 +772,6 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf,
|| jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100) || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100)
_throw("tjCompress2(): Invalid argument"); _throw("tjCompress2(): Invalid argument");
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
#ifndef JCS_EXTENSIONS #ifndef JCS_EXTENSIONS
@@ -775,6 +784,16 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf,
} }
#endif #endif
if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL)
_throw("tjCompress2(): Memory allocation failure");
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
cinfo->image_width=width; cinfo->image_width=width;
cinfo->image_height=height; cinfo->image_height=height;
@@ -791,8 +810,6 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf,
return -1; return -1;
jpeg_start_compress(cinfo, TRUE); jpeg_start_compress(cinfo, TRUE);
if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL)
_throw("tjCompress2(): Memory allocation failure");
for(i=0; i<height; i++) for(i=0; i<height; i++)
{ {
if(flags&TJFLAG_BOTTOMUP) if(flags&TJFLAG_BOTTOMUP)
@@ -872,13 +889,6 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle,
if(subsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) if(subsamp!=TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2]))
_throw("tjEncodeYUVPlanes(): Invalid argument"); _throw("tjEncodeYUVPlanes(): Invalid argument");
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
if(pixelFormat==TJPF_CMYK) if(pixelFormat==TJPF_CMYK)
_throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels"); _throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels");
@@ -894,6 +904,13 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle,
} }
#endif #endif
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
cinfo->image_width=width; cinfo->image_width=width;
cinfo->image_height=height; cinfo->image_height=height;
@@ -970,6 +987,13 @@ DLLEXPORT int DLLCALL tjEncodeYUVPlanes(tjhandle handle,
} }
} }
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
for(row=0; row<ph0; row+=cinfo->max_v_samp_factor) for(row=0; row<ph0; row+=cinfo->max_v_samp_factor)
{ {
(*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0, (*cinfo->cconvert->color_convert)(cinfo, &row_pointer[row], tmpbuf, 0,
@@ -1144,6 +1168,13 @@ DLLEXPORT int DLLCALL tjCompressFromYUVPlanes(tjhandle handle,
} }
} }
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
for(row=0; row<(int)cinfo->image_height; for(row=0; row<(int)cinfo->image_height;
row+=cinfo->max_v_samp_factor*DCTSIZE) row+=cinfo->max_v_samp_factor*DCTSIZE)
{ {
@@ -1239,7 +1270,8 @@ static tjhandle _tjInitDecompress(tjinstance *this)
if(setjmp(this->jerr.setjmp_buffer)) if(setjmp(this->jerr.setjmp_buffer))
{ {
/* If we get here, the JPEG code has signaled an error. */ /* If we get here, the JPEG code has signaled an error. */
if(this) free(this); return NULL; if(this) free(this);
return NULL;
} }
jpeg_create_decompress(&this->dinfo); jpeg_create_decompress(&this->dinfo);
@@ -1421,6 +1453,12 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle,
if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)
*dinfo->output_height))==NULL) *dinfo->output_height))==NULL)
_throw("tjDecompress2(): Memory allocation failure"); _throw("tjDecompress2(): Memory allocation failure");
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
for(i=0; i<(int)dinfo->output_height; i++) for(i=0; i<(int)dinfo->output_height; i++)
{ {
if(flags&TJFLAG_BOTTOMUP) if(flags&TJFLAG_BOTTOMUP)
@@ -1643,6 +1681,13 @@ DLLEXPORT int DLLCALL tjDecodeYUVPlanes(tjhandle handle,
} }
} }
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
for(row=0; row<ph0; row+=dinfo->max_v_samp_factor) for(row=0; row<ph0; row+=dinfo->max_v_samp_factor)
{ {
JDIMENSION inrow=0, outrow=0; JDIMENSION inrow=0, outrow=0;
@@ -1823,6 +1868,13 @@ DLLEXPORT int DLLCALL tjDecompressToYUVPlanes(tjhandle handle,
} }
} }
if(setjmp(this->jerr.setjmp_buffer))
{
/* If we get here, the JPEG code has signaled an error. */
retval=-1;
goto bailout;
}
if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE;
if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST; if(flags&TJFLAG_FASTDCT) dinfo->dct_method=JDCT_FASTEST;
dinfo->raw_data_out=TRUE; dinfo->raw_data_out=TRUE;
@@ -2000,6 +2052,11 @@ DLLEXPORT int DLLCALL tjTransform(tjhandle handle,
else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1");
else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n))
==NULL)
_throw("tjTransform(): Memory allocation failure");
MEMZERO(xinfo, sizeof(jpeg_transform_info)*n);
if(setjmp(this->jerr.setjmp_buffer)) if(setjmp(this->jerr.setjmp_buffer))
{ {
/* If we get here, the JPEG code has signaled an error. */ /* If we get here, the JPEG code has signaled an error. */
@@ -2009,11 +2066,6 @@ DLLEXPORT int DLLCALL tjTransform(tjhandle handle,
jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
if((xinfo=(jpeg_transform_info *)malloc(sizeof(jpeg_transform_info)*n))
==NULL)
_throw("tjTransform(): Memory allocation failure");
MEMZERO(xinfo, sizeof(jpeg_transform_info)*n);
for(i=0; i<n; i++) for(i=0; i<n; i++)
{ {
xinfo[i].transform=xformtypes[t[i].op]; xinfo[i].transform=xformtypes[t[i].op];

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C)2009-2015 D. R. Commander. All Rights Reserved. * Copyright (C)2009-2015, 2017 D. R. Commander. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@@ -348,7 +348,7 @@ enum TJCS
* The uncompressed source/destination image is stored in bottom-up (Windows, * The uncompressed source/destination image is stored in bottom-up (Windows,
* OpenGL) order, not top-down (X11) order. * OpenGL) order, not top-down (X11) order.
*/ */
#define TJFLAG_BOTTOMUP 2 #define TJFLAG_BOTTOMUP 2
/** /**
* When decompressing an image that was compressed using chrominance * When decompressing an image that was compressed using chrominance
* subsampling, use the fastest chrominance upsampling algorithm available in * subsampling, use the fastest chrominance upsampling algorithm available in
@@ -358,11 +358,11 @@ enum TJCS
*/ */
#define TJFLAG_FASTUPSAMPLE 256 #define TJFLAG_FASTUPSAMPLE 256
/** /**
* Disable buffer (re)allocation. If passed to #tjCompress2() or * Disable buffer (re)allocation. If passed to one of the JPEG compression or
* #tjTransform(), this flag will cause those functions to generate an error if * transform functions, this flag will cause those functions to generate an
* the JPEG image buffer is invalid or too small rather than attempting to * error if the JPEG image buffer is invalid or too small rather than
* allocate or reallocate that buffer. This reproduces the behavior of earlier * attempting to allocate or reallocate that buffer. This reproduces the
* versions of TurboJPEG. * behavior of earlier versions of TurboJPEG.
*/ */
#define TJFLAG_NOREALLOC 1024 #define TJFLAG_NOREALLOC 1024
/** /**
@@ -645,7 +645,7 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
* for you, or * for you, or
* -# pre-allocate the buffer to a "worst case" size determined by calling * -# pre-allocate the buffer to a "worst case" size determined by calling
* #tjBufSize(). This should ensure that the buffer never has to be * #tjBufSize(). This should ensure that the buffer never has to be
* re-allocated (setting #TJFLAG_NOREALLOC guarantees this.) * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.)
* . * .
* If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your * If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your
* pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC, * pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC,
@@ -713,7 +713,7 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, const unsigned char *srcBuf,
* for you, or * for you, or
* -# pre-allocate the buffer to a "worst case" size determined by calling * -# pre-allocate the buffer to a "worst case" size determined by calling
* #tjBufSize(). This should ensure that the buffer never has to be * #tjBufSize(). This should ensure that the buffer never has to be
* re-allocated (setting #TJFLAG_NOREALLOC guarantees this.) * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.)
* . * .
* If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your * If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your
* pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC, * pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC,
@@ -783,7 +783,7 @@ DLLEXPORT int DLLCALL tjCompressFromYUV(tjhandle handle,
* for you, or * for you, or
* -# pre-allocate the buffer to a "worst case" size determined by calling * -# pre-allocate the buffer to a "worst case" size determined by calling
* #tjBufSize(). This should ensure that the buffer never has to be * #tjBufSize(). This should ensure that the buffer never has to be
* re-allocated (setting #TJFLAG_NOREALLOC guarantees this.) * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.)
* . * .
* If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your * If you choose option 1, <tt>*jpegSize</tt> should be set to the size of your
* pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC, * pre-allocated buffer. In any case, unless you have set #TJFLAG_NOREALLOC,
@@ -1392,9 +1392,13 @@ DLLEXPORT tjhandle DLLCALL tjInitTransform(void);
* -# set <tt>dstBufs[i]</tt> to NULL to tell TurboJPEG to allocate the buffer * -# set <tt>dstBufs[i]</tt> to NULL to tell TurboJPEG to allocate the buffer
* for you, or * for you, or
* -# pre-allocate the buffer to a "worst case" size determined by calling * -# pre-allocate the buffer to a "worst case" size determined by calling
* #tjBufSize() with the transformed or cropped width and height. This should * #tjBufSize() with the transformed or cropped width and height. Under normal
* ensure that the buffer never has to be re-allocated (setting * circumstances, this should ensure that the buffer never has to be
* #TJFLAG_NOREALLOC guarantees this.) * re-allocated (setting #TJFLAG_NOREALLOC guarantees that it won't be.) Note,
* however, that there are some rare cases (such as transforming images with a
* large amount of embedded EXIF or ICC profile data) in which the output image
* will be larger than the worst-case size, and #TJFLAG_NOREALLOC cannot be
* used in those cases.
* . * .
* If you choose option 1, <tt>dstSizes[i]</tt> should be set to the size of * If you choose option 1, <tt>dstSizes[i]</tt> should be set to the size of
* your pre-allocated buffer. In any case, unless you have set * your pre-allocated buffer. In any case, unless you have set
@@ -1435,8 +1439,8 @@ DLLEXPORT int DLLCALL tjDestroy(tjhandle handle);
/** /**
* Allocate an image buffer for use with TurboJPEG. You should always use * Allocate an image buffer for use with TurboJPEG. You should always use
* this function to allocate the JPEG destination buffer(s) for #tjCompress2() * this function to allocate the JPEG destination buffer(s) for the compression
* and #tjTransform() unless you are disabling automatic buffer * and transform functions unless you are disabling automatic buffer
* (re)allocation (by setting #TJFLAG_NOREALLOC.) * (re)allocation (by setting #TJFLAG_NOREALLOC.)
* *
* @param bytes the number of bytes to allocate * @param bytes the number of bytes to allocate
@@ -1452,8 +1456,8 @@ DLLEXPORT unsigned char* DLLCALL tjAlloc(int bytes);
/** /**
* Free an image buffer previously allocated by TurboJPEG. You should always * Free an image buffer previously allocated by TurboJPEG. You should always
* use this function to free JPEG destination buffer(s) that were automatically * use this function to free JPEG destination buffer(s) that were automatically
* (re)allocated by #tjCompress2() or #tjTransform() or that were manually * (re)allocated by the compression and transform functions or that were
* allocated using #tjAlloc(). * manually allocated using #tjAlloc().
* *
* @param buffer address of the buffer to free * @param buffer address of the buffer to free
* *

View File

@@ -212,7 +212,7 @@ Switches for advanced users:
large images. Value is in thousands of bytes, or large images. Value is in thousands of bytes, or
millions of bytes if "M" is attached to the number. millions of bytes if "M" is attached to the number.
For example, -max 4m selects 4000000 bytes. If more For example, -max 4m selects 4000000 bytes. If more
space is needed, temporary files will be used. space is needed, an error will occur.
-verbose Enable debug printout. More -v's give more printout. -verbose Enable debug printout. More -v's give more printout.
or -debug Also, version information is printed at startup. or -debug Also, version information is printed at startup.
@@ -233,7 +233,12 @@ factor will visibly blur the image, however.
Switches for wizards: Switches for wizards:
-baseline Create baseline JPEG file (disable progressive coding) -baseline Force baseline-compatible quantization tables to be
generated. This clamps quantization values to 8 bits
even at low quality settings. (This switch is poorly
named, since it does not ensure that the output is
actually baseline JPEG. For example, you can use
-baseline and -progressive together.)
-qtables file Use the quantization tables given in the specified -qtables file Use the quantization tables given in the specified
text file. text file.
@@ -372,7 +377,7 @@ Switches for advanced users:
large images. Value is in thousands of bytes, or large images. Value is in thousands of bytes, or
millions of bytes if "M" is attached to the number. millions of bytes if "M" is attached to the number.
For example, -max 4m selects 4000000 bytes. If more For example, -max 4m selects 4000000 bytes. If more
space is needed, temporary files will be used. space is needed, an error will occur.
-verbose Enable debug printout. More -v's give more printout. -verbose Enable debug printout. More -v's give more printout.
or -debug Also, version information is printed at startup. or -debug Also, version information is printed at startup.
@@ -418,11 +423,6 @@ When producing a color-quantized image, "-onepass -dither ordered" is fast but
much lower quality than the default behavior. "-dither none" may give much lower quality than the default behavior. "-dither none" may give
acceptable results in two-pass mode, but is seldom tolerable in one-pass mode. acceptable results in two-pass mode, but is seldom tolerable in one-pass mode.
Two-pass color quantization requires a good deal of memory; on MS-DOS machines
it may run out of memory even with -maxmemory 0. In that case you can still
decompress, with some loss of image quality, by specifying -onepass for
one-pass quantization.
To avoid the Unisys LZW patent (now expired), djpeg produces uncompressed GIF To avoid the Unisys LZW patent (now expired), djpeg produces uncompressed GIF
files. These are larger than they should be, but are readable by standard GIF files. These are larger than they should be, but are readable by standard GIF
decoders. decoders.
@@ -430,24 +430,9 @@ decoders.
HINTS FOR BOTH PROGRAMS HINTS FOR BOTH PROGRAMS
If more space is needed than will fit in the available main memory (as If the memory needed by cjpeg or djpeg exceeds the limit specified by
determined by -maxmemory), temporary files will be used. (MS-DOS versions -maxmemory, an error will occur. You can leave out -progressive and -optimize
will try to get extended or expanded memory first.) The temporary files are (for cjpeg) or specify -onepass (for djpeg) to reduce memory usage.
often rather large: in typical cases they occupy three bytes per pixel, for
example 3*800*600 = 1.44Mb for an 800x600 image. If you don't have enough
free disk space, leave out -progressive and -optimize (for cjpeg) or specify
-onepass (for djpeg).
On MS-DOS, the temporary files are created in the directory named by the TMP
or TEMP environment variable, or in the current directory if neither of those
exist. Amiga implementations put the temp files in the directory named by
JPEGTMP:, so be sure to assign JPEGTMP: to a disk partition with adequate free
space.
The default memory usage limit (-maxmemory) is set when the software is
compiled. If you get an "insufficient memory" error, try specifying a smaller
-maxmemory value, even -maxmemory 0 to use the absolute minimum space. You
may want to recompile with a smaller default value if this happens often.
On machines that have "environment" variables, you can define the environment On machines that have "environment" variables, you can define the environment
variable JPEGMEM to set the default memory limit. The value is specified as variable JPEGMEM to set the default memory limit. The value is specified as
@@ -455,11 +440,6 @@ described for the -maxmemory switch. JPEGMEM overrides the default value
specified when the program was compiled, and itself is overridden by an specified when the program was compiled, and itself is overridden by an
explicit -maxmemory switch. explicit -maxmemory switch.
On MS-DOS machines, -maxmemory is the amount of main (conventional) memory to
use. (Extended or expanded memory is also used if available.) Most
DOS-specific versions of this software do their own memory space estimation
and do not need you to specify -maxmemory.
JPEGTRAN JPEGTRAN

10
win/jpeg62-memsrcdst.def Normal file → Executable file
View File

@@ -104,13 +104,3 @@ EXPORTS
jpeg_mem_src @ 103 ; jpeg_mem_src @ 103 ;
jpeg_skip_scanlines @ 104 ; jpeg_skip_scanlines @ 104 ;
jpeg_crop_scanline @ 105 ; jpeg_crop_scanline @ 105 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

10
win/jpeg62.def Normal file → Executable file
View File

@@ -102,13 +102,3 @@ EXPORTS
jzero_far @ 101 ; jzero_far @ 101 ;
jpeg_skip_scanlines @ 102 ; jpeg_skip_scanlines @ 102 ;
jpeg_crop_scanline @ 103 ; jpeg_crop_scanline @ 103 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

View File

@@ -104,13 +104,5 @@ EXPORTS
jzero_far @ 103 ; jzero_far @ 103 ;
jpeg_mem_dest @ 104 ; jpeg_mem_dest @ 104 ;
jpeg_mem_src @ 105 ; jpeg_mem_src @ 105 ;
jpeg_c_bool_param_supported @ 200 ; jpeg_skip_scanlines @ 106 ;
jpeg_c_set_bool_param @ 201 ; jpeg_crop_scanline @ 107 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

View File

@@ -104,13 +104,3 @@ EXPORTS
jzero_far @ 103 ; jzero_far @ 103 ;
jpeg_skip_scanlines @ 104 ; jpeg_skip_scanlines @ 104 ;
jpeg_crop_scanline @ 105 ; jpeg_crop_scanline @ 105 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

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